Imported Upstream version 2.9.0
[debian/cc1111] / 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 == IREGOFF8_REG) {
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_07) + offset;
99         unsigned short wtotal;
100         wtotal = FUNC2( get2(addr), reg2(RI_F0) );
101         store2(addr, wtotal);
102       } else {
103         t_mem addr = reg2(RI_07) + offset;
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         set_reg1( RI_F0,
129                   FUNC1( reg1(RI_F0),
130                         get1(reg2(RI_07)+offset)
131                       )
132                 );
133       }
134     }
135     break;
136
137     case DIRECT_REG :
138     {
139       int addr = ((code & 0x7) << 8) | fetch();
140       if (code & 0x0800) {  /* word op */
141         unsigned short wtmp = get_word_direct(addr);
142         set_word_direct( addr,
143                   FUNC2( wtmp, reg2(RI_F0) )
144                 );
145       } else {
146         unsigned char tmp = get_byte_direct(addr);
147         set_byte_direct( addr,
148                   FUNC1( tmp, reg1(RI_F0) )
149                 );
150       }
151     }
152     break;
153
154     case REG_DIRECT :
155     {
156       int addr = ((code & 0x7) << 8) | fetch();
157       if (code & 0x0800) {  /* word op */
158         set_reg2( RI_F0,
159                   FUNC2( reg2(RI_F0),
160                         get_word_direct(addr)
161                       )
162                 );
163       } else {
164         set_reg1( RI_F0,
165                   FUNC1( reg1(RI_F0),
166                         get_byte_direct(addr)
167                       )
168                 );
169       }
170     }
171     break;
172
173     case REG_DATA8 :
174 #if 0
175       {
176         unsigned char dat = fetch();
177         unsigned char res;
178         res = FUNC1( reg1(RI_F0), dat);
179         set_reg1( RI_F0, res );
180    printf("reg_data8 code=%x dat=%x, res=%x r=%x\n", code, dat, res, reg1( RI_F0) );
181       }
182 #endif
183       set_reg1( RI_F0, FUNC1( reg1(RI_F0), fetch()) );
184     break;
185
186     case REG_DATA16 :
187       {
188         unsigned short dat = fetch2();
189         set_reg2( RI_F0, FUNC2( reg2(RI_F0), dat) );
190       }
191     break;
192
193     case IREGINC_DATA8 :
194     case IREG_DATA8 :
195     {
196       unsigned char total;
197       unsigned char tmp;
198       t_mem addr = reg2(RI_70);
199       tmp = get1(addr);
200       total = FUNC1(tmp, fetch() );
201       store1(addr, total);
202       if (operands == IREGINC_DATA8) {
203         set_reg2(RI_70, addr+1);
204       }
205     }
206     break;
207
208     case IREGINC_DATA16 :
209     case IREG_DATA16 :
210     {
211       unsigned short total;
212       unsigned short tmp;
213       t_mem addr = reg2(RI_70);
214       tmp = get2(addr);
215       total = FUNC2(tmp, fetch2() );
216       store2(addr, total);
217       if (operands == IREGINC_DATA16) {
218         set_reg2(RI_70, addr+1);
219       }
220     }
221     break;
222
223     case IREGOFF8_DATA8 :
224     case IREGOFF16_DATA8 :
225     {
226       unsigned short addr;
227       int offset;
228       unsigned char tmp;
229       if (operands == IREGOFF8_DATA8) {
230         offset = (int)((char) fetch());
231       } else {
232         offset = (int)((short)fetch2());
233       }
234       tmp = fetch();
235       addr = reg2(RI_70);
236
237       store1( addr+offset,
238                   FUNC1( tmp,
239                         get1(addr+offset)
240                       )
241                 );
242     }
243     break;
244
245     case IREGOFF8_DATA16 :
246     case IREGOFF16_DATA16 :
247     {
248       unsigned short addr;
249       int offset;
250       unsigned short tmp;
251       if (operands == IREGOFF8_DATA16) {
252         offset = (int)((char) fetch());
253       } else {
254         offset = (int)((short)fetch2());
255       }
256       tmp = fetch2();
257       addr = reg2(RI_70);
258
259       store2( addr+offset,
260                   FUNC2( tmp,
261                         get2(addr+offset)
262                       )
263                 );
264     }
265     break;
266
267     case DIRECT_DATA8 :
268     {
269       int addr = ((code & 0x70) << 4) | fetch();
270       unsigned char bdir = get_byte_direct(addr);
271       unsigned char bdat = fetch();
272       set_byte_direct( addr,  FUNC1( bdir, bdat) );
273     }
274     break;
275
276     case DIRECT_DATA16 :
277     {
278       int addr = ((code & 0x70) << 4) | fetch();
279       unsigned short wdir = get_word_direct(addr);
280       unsigned short wdat = fetch2();
281       set_word_direct( addr,  FUNC2( wdir, wdat) );
282     }
283     break;
284   }
285