11f7e1681835619bab9a07445bba754c489fc679
[fw/sdcc] / sim / ucsim / avr.src / arith_inst.cc
1 /*
2  * Simulator of microcontrollers (arith_inst.cc)
3  *
4  * Copyright (C) 1999,99 Drotos Daniel, Talker Bt.
5  * 
6  * To contact author send email to drdani@mazsola.iit.uni-miskolc.hu
7  *
8  */
9
10 /* This file is part of microcontroller simulator: ucsim.
11
12 UCSIM is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 2 of the License, or
15 (at your option) any later version.
16
17 UCSIM is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20 GNU General Public License for more details.
21
22 You should have received a copy of the GNU General Public License
23 along with UCSIM; see the file COPYING.  If not, write to the Free
24 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
25 02111-1307, USA. */
26 /*@1@*/
27
28 #include "avrcl.h"
29 #include "regsavr.h"
30
31
32 int
33 cl_avr::cpi_Rd_K(t_mem code)
34 {
35   return(resGO);
36 }
37
38
39 int
40 cl_avr::sbci_Rd_K(t_mem code)
41 {
42   return(resGO);
43 }
44
45
46 int
47 cl_avr::subi_Rd_K(t_mem code)
48 {
49   return(resGO);
50 }
51
52
53 int
54 cl_avr::muls_Rd_Rr(t_mem code)
55 {
56   return(resGO);
57 }
58
59
60 int
61 cl_avr::mulsu_Rd_Rr(t_mem code)
62 {
63   return(resGO);
64 }
65
66
67 int
68 cl_avr::fmul_Rd_Rr(t_mem code)
69 {
70   return(resGO);
71 }
72
73
74 int
75 cl_avr::fmuls_Rd_Rr(t_mem code)
76 {
77   return(resGO);
78 }
79
80
81 int
82 cl_avr::fmulsu_Rd_Rr(t_mem code)
83 {
84   return(resGO);
85 }
86
87
88 int
89 cl_avr::cpc_Rd_Rr(t_mem code)
90 {
91   return(resGO);
92 }
93
94
95 int
96 cl_avr::sbc_Rd_Rr(t_mem code)
97 {
98   return(resGO);
99 }
100
101
102 /*
103  * Add without Carry
104  * ADD Rd,Rr 0<=d<=31, 0<=r<=31
105  * 0000 11rd dddd rrrr
106  *____________________________________________________________________________
107  */
108
109 int
110 cl_avr::add_Rd_Rr(t_mem code)
111 {
112   t_addr r, d;
113   t_mem R, D, result, res;
114
115   d= (code&0x1f0)>>4;
116   r= ((code&0x200)>>5)|(code&0xf);
117   R= ram->read(r);
118   D= ram->read(d);
119   result= D+R;
120   res= result & 0xff;
121   ram->write(d, &res);
122   
123   t_mem sreg= ram->get(SREG);
124   if (!res)
125     sreg|= BIT_Z;
126   else
127     sreg&= ~BIT_Z;
128   if (((D&R&~res)&0x80) ||
129       ((~D&~R&res)&0x80))
130     sreg|= (BIT_V|BIT_S);
131   else
132     sreg&= ~(BIT_V|BIT_S);
133   if (res & 0x80)
134     {
135       sreg|= BIT_N;
136       sreg^= BIT_S;
137     }
138   else
139     sreg&= ~BIT_N;
140   if (result & ~0xff)
141     sreg|= BIT_C;
142   else
143     sreg&= ~BIT_C;
144   if ((R&0xf) + (D&0xf) > 15)
145     sreg|= BIT_H;
146   else
147     sreg&= ~BIT_H;
148   ram->set(SREG, sreg);
149
150   return(resGO);
151 }
152
153
154 int
155 cl_avr::cp_Rd_Rr(t_mem code)
156 {
157   return(resGO);
158 }
159
160
161 int
162 cl_avr::sub_Rd_Rr(t_mem code)
163 {
164   return(resGO);
165 }
166
167
168 /*
169  * Add with Carry
170  * ADC Rd,Rr 0<=d<=31, 0<=r<=31
171  * 0001 11rd dddd rrrr
172  *____________________________________________________________________________
173  */
174
175 int
176 cl_avr::adc_Rd_Rr(t_mem code)
177 {
178   t_addr r, d;
179   t_mem R, D, result, res;
180
181   d= (code&0x1f0)>>4;
182   r= ((code&0x200)>>5)|(code&0xf);
183   R= ram->read(r);
184   D= ram->read(d);
185   t_mem sreg= ram->get(SREG);
186   result= D+R+((sreg&BIT_C)?1:0);
187   res= result & 0xff;
188   ram->write(d, &res);
189   
190   if (!res)
191     sreg|= BIT_Z;
192   else
193     sreg&= ~BIT_Z;
194   if (((D&R&~res)&0x80) ||
195       ((~D&~R&res)&0x80))
196     sreg|= (BIT_V|BIT_S);
197   else
198     sreg&= ~(BIT_V|BIT_S);
199   if (res & 0x80)
200     {
201       sreg|= BIT_N;
202       sreg^= BIT_S;
203     }
204   else
205     sreg&= ~BIT_N;
206   if (result & ~0xff)
207     sreg|= BIT_C;
208   else
209     sreg&= ~BIT_C;
210   if ((R&0xf) + (D&0xf) > 15)
211     sreg|= BIT_H;
212   else
213     sreg&= ~BIT_H;
214   ram->set(SREG, sreg);
215
216   return(resGO);
217 }
218
219
220 int
221 cl_avr::com_Rd(t_mem code)
222 {
223   return(resGO);
224 }
225
226
227 int
228 cl_avr::neg_Rd(t_mem code)
229 {
230   return(resGO);
231 }
232
233
234 /*
235  * Increment
236  * INC Rd 0<=d<=31
237  * 1001 010d dddd 0011
238  *____________________________________________________________________________
239  */
240
241 int
242 cl_avr::inc_Rd(t_mem code)
243 {
244   t_addr d;
245
246   d= (code&0x1f0)>>4;
247   t_mem data= ram->read(d)+1;
248   ram->write(d, &data);
249
250   t_mem sreg= ram->get(SREG);
251   data= data&0xff;
252   if (data & 0x80)
253     {
254       sreg|= (BIT_N);
255       if (data == 0x80)
256         {
257           sreg|= BIT_V;
258           sreg&= ~BIT_S;
259         }
260       else
261         {
262           sreg&= ~BIT_V;
263           sreg|= BIT_S;
264         }
265       sreg&= ~BIT_Z;
266     }
267   else
268     {
269       sreg&= ~(BIT_N|BIT_V|BIT_S);
270       if (!data)
271         sreg|= BIT_Z;
272       else
273         sreg&= ~BIT_Z;
274     }
275   ram->set(SREG, sreg);
276   return(resGO);
277 }
278
279
280 int
281 cl_avr::asr_Rd(t_mem code)
282 {
283   return(resGO);
284 }
285
286
287 int
288 cl_avr::lsr_Rd(t_mem code)
289 {
290   return(resGO);
291 }
292
293
294 int
295 cl_avr::ror_Rd(t_mem code)
296 {
297   return(resGO);
298 }
299
300
301 int
302 cl_avr::dec_Rd(t_mem code)
303 {
304   return(resGO);
305 }
306
307
308 int
309 cl_avr::mul_Rd_Rr(t_mem code)
310 {
311   return(resGO);
312 }
313
314
315 /*
316  * Add Immediate to Word
317  * ADIW Rdl,K dl={24,26,28,30}, 0<=K<=63
318  * 1001 0110 KK dd KKKK
319  *____________________________________________________________________________
320  */
321
322 int
323 cl_avr::adiw_Rdl_K(t_mem code)
324 {
325   t_addr dl;
326   t_mem D, K, result, res;
327
328   dl= 24+(2*((code&0x30)>>4));
329   K= ((code&0xc0)>>2)|(code&0xf);
330   D= ram->read(dl+1)*256 + ram->read(dl);
331   result= D+K;
332   res= result & 0xffff;
333   t_mem resl= result&0xff, resh= (result>>8)&0xff;
334   ram->write(dl+1, &resh);
335   ram->write(dl, &resl);
336   
337   t_mem sreg= ram->get(SREG);
338   if (!res)
339     sreg|= BIT_Z;
340   else
341     sreg&= ~BIT_Z;
342   if (D&res&0x8000)
343     sreg|= (BIT_V|BIT_S);
344   else
345     sreg&= ~(BIT_V|BIT_S);
346   if (res & 0x8000)
347     {
348       sreg|= BIT_N;
349       sreg^= BIT_S;
350     }
351   else
352     sreg&= ~BIT_N;
353   if ((~res)&D&0x8000)
354     sreg|= BIT_C;
355   else
356     sreg&= ~BIT_C;
357   ram->set(SREG, sreg);
358   tick(1);
359
360   return(resGO);
361 }
362
363
364 /* End of avr.src/arith_inst.cc */