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