d37890dd76522aa579e96d325f725dc73a2d1468
[fw/sdcc] / sim / ucsim / xa.src / inst_gen.cc
1 /*
2  * Simulator of microcontrollers (inst_gen.cc)
3  * this code pulled into various parts
4    of inst.cc with FUNC1 and FUNC2 defined as
5    various operations to implement ADD, ADDC, ...
6  *
7  * Written by Karl Bongers karl@turbobit.com
8  *
9  * Copyright (C) 1999,99 Drotos Daniel, Talker Bt.
10  * 
11  * To contact author send email to drdani@mazsola.iit.uni-miskolc.hu
12  *
13  */
14
15 /* This file is part of microcontroller simulator: ucsim.
16
17 UCSIM is free software; you can redistribute it and/or modify
18 it under the terms of the GNU General Public License as published by
19 the Free Software Foundation; either version 2 of the License, or
20 (at your option) any later version.
21
22 UCSIM is distributed in the hope that it will be useful,
23 but WITHOUT ANY WARRANTY; without even the implied warranty of
24 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
25 GNU General Public License for more details.
26
27 You should have received a copy of the GNU General Public License
28 along with UCSIM; see the file COPYING.  If not, write to the Free
29 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
30 02111-1307, USA. */
31 /*@1@*/
32
33   switch (operands) {
34     case REG_REG:
35       if (code & 0x0800) {  /* word op */
36         set_reg2( RI_F0,
37                   FUNC2( reg2(RI_F0), reg2(RI_0F) )
38                 );
39       } else {
40         set_reg1( RI_F0,
41                   FUNC1( reg1(RI_F0), reg1(RI_0F) )
42                 );
43       }
44     break;
45     case REG_IREGINC :
46     case REG_IREG:
47     {
48       short srcreg = reg2(RI_0F);
49       if (code & 0x0800) {  /* word op */
50         set_reg2( RI_F0,
51                   FUNC2( reg2(RI_F0),
52                         get2(srcreg)
53                       )
54                 );
55       } else {
56         set_reg1( RI_F0,
57                   FUNC1( reg1(RI_F0),
58                         get1(srcreg)
59                       )
60                 );
61       }
62       if (operands == REG_IREGINC) {
63         set_reg2(RI_0F,  srcreg+1);
64       }
65     }
66     break;
67     case IREGINC_REG :
68     case IREG_REG :
69     {
70       short addr = reg2(RI_07);
71       if (code & 0x0800) {  /* word op */
72         unsigned short wtmp, wtotal;
73         wtmp = get2(addr);
74         wtotal = FUNC2( wtmp, reg2(RI_F0) );
75         store2(addr, wtotal);
76       } else {
77         unsigned char total;
78         total = FUNC1( get1(addr), reg1(RI_F0) );
79         store1(addr, total);
80       }
81       if (operands == IREGINC_REG) {
82         set_reg2(RI_0F, addr+1);
83       }
84     }
85     break;
86
87     case IREGOFF8_REG :
88     case IREGOFF16_REG :
89     {
90       int offset;
91       if (operands == REG_IREGOFF8) {
92         offset = (int)((char) fetch());
93       } else {
94         offset = (int)((short)fetch2());
95       }
96       if (code & 0x0800) {  /* word op */
97         t_mem addr = reg2(RI_07) + offset;
98         unsigned short wtmp, wtotal;
99         wtmp = get2(addr);
100         wtotal = FUNC2( wtmp, reg2(RI_F0) );
101         store2(addr, wtotal);
102       } else {
103         t_mem addr = reg2(RI_07) + ((short) fetch2());
104         unsigned char total;
105         total = FUNC1( get1(addr), reg1(RI_F0) );
106         store1(addr, total);
107       }
108     }
109     break;
110
111     case REG_IREGOFF8 :
112     case REG_IREGOFF16 :
113     {
114       int offset;
115       if (operands == REG_IREGOFF8) {
116         offset = (int)((char) fetch());
117       } else {
118         offset = (int)((short)fetch2());
119       }
120
121       if (code & 0x0800) {  /* word op */
122         set_reg2( RI_F0,
123                   FUNC2( reg2(RI_F0),
124                         get2(reg2(RI_07)+offset)
125                       )
126                 );
127       } else {
128         int offset = (int)((short)fetch2());
129         set_reg1( RI_F0,
130                   FUNC1( reg1(RI_F0),
131                         get1(reg2(RI_07)+offset)
132                       )
133                 );
134       }
135     }
136     break;
137
138     case DIRECT_REG :
139     {
140       int addr = ((code & 0x3) << 8) | fetch();
141       if (code & 0x0800) {  /* word op */
142         unsigned short wtmp = get_word_direct(addr);
143         set_word_direct( addr,
144                   FUNC2( wtmp, reg2(RI_F0) )
145                 );
146       } else {
147         unsigned char tmp = get_byte_direct(addr);
148         set_byte_direct( addr,
149                   FUNC1( tmp, reg1(RI_F0) )
150                 );
151       }
152     }
153     break;
154
155     case REG_DIRECT :
156     {
157       int addr = ((code & 0x3) << 8) | fetch();
158       if (code & 0x0800) {  /* word op */
159         set_reg2( RI_F0,
160                   FUNC2( reg2(RI_F0),
161                         get_word_direct(addr)
162                       )
163                 );
164       } else {
165         set_reg1( RI_F0,
166                   FUNC1( reg1(RI_F0),
167                         get_byte_direct(addr)
168                       )
169                 );
170       }
171     }
172     break;
173
174     case REG_DATA8 :
175       set_reg1( RI_F0, FUNC1( reg1(RI_F0), fetch()) );
176     break;
177
178     case REG_DATA16 :
179       set_reg2( RI_F0, FUNC2( reg2(RI_F0), fetch()) );
180     break;
181
182     case IREGINC_DATA8 :
183     case IREG_DATA8 :
184     {
185       unsigned char total;
186       unsigned char tmp;
187       t_mem addr = reg2(RI_07);
188       tmp = get1(addr);
189       total = FUNC1(tmp, fetch() );
190       store1(addr, total);
191       if (operands == IREGINC_DATA8) {
192         set_reg2(RI_07, addr+1);
193       }
194     }
195     break;
196
197     case IREGINC_DATA16 :
198     case IREG_DATA16 :
199     {
200       unsigned short total;
201       unsigned short tmp;
202       t_mem addr = reg2(RI_70);
203       tmp = get2(addr);
204       total = FUNC2(tmp, fetch2() );
205       store2(addr, total);
206       if (operands == IREGINC_DATA16) {
207         set_reg2(RI_07, addr+1);
208       }
209     }
210     break;
211
212     case IREGOFF8_DATA8 :
213     case IREGOFF16_DATA8 :
214     {
215       unsigned short addr;
216       int offset;
217       unsigned char tmp;
218       if (operands == IREGOFF8_DATA8) {
219         offset = (int)((char) fetch());
220       } else {
221         offset = (int)((short)fetch2());
222       }
223       tmp = fetch();
224       addr = reg2(RI_07);
225
226       store1( addr, 
227                   FUNC1( tmp,
228                         get1(addr+offset)
229                       )
230                 );
231     }
232     break;
233
234     case IREGOFF8_DATA16 :
235     case IREGOFF16_DATA16 :
236     {
237       unsigned short addr;
238       int offset;
239       unsigned short tmp;
240       if (operands == IREGOFF8_DATA16) {
241         offset = (int)((char) fetch());
242       } else {
243         offset = (int)((short)fetch2());
244       }
245       tmp = fetch2();
246       addr = reg2(RI_07);
247
248       store2( addr, 
249                   FUNC2( tmp,
250                         get2(addr+offset)
251                       )
252                 );
253     }
254     break;
255
256     case DIRECT_DATA8 :
257     {
258       int addr = ((code & 0x3) << 8) | fetch();
259       unsigned char bdir = get_byte_direct(addr);
260       unsigned char bdat = fetch();
261       set_byte_direct( addr,  FUNC1( bdir, bdat) );
262     }
263     break;
264
265     case DIRECT_DATA16 :
266     {
267       int addr = ((code & 0x3) << 8) | fetch();
268       unsigned short wdir = get_word_direct(addr);
269       unsigned short wdat = fetch2();
270       set_word_direct( addr,  FUNC2( wdir, wdat) );
271     }
272     break;
273   }
274