2 * Simulator of microcontrollers (arith_inst.cc)
4 * Copyright (C) 1999,99 Drotos Daniel, Talker Bt.
6 * To contact author send email to drdani@mazsola.iit.uni-miskolc.hu
10 /* This file is part of microcontroller simulator: ucsim.
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.
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.
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
33 * Compare with Immediate
34 * CPI Rd,K 16<=d<=31, 0<=K<=255
36 *____________________________________________________________________________
40 cl_avr::cpi_Rd_K(t_mem code)
43 t_mem D, K, result, res;
46 K= (code&0xf) | ((code&0xf00)>>8);
53 t_mem sreg= ram->get(SREG);
54 (signed)result= (signed)D-(signed)K;
57 sreg= sreg & ~(BIT_H|BIT_S|BIT_V|BIT_N|BIT_C|BIT_Z);
58 if (0x08 & (((~D)&K) | (K&res) | (res&(~D))))
61 if (0x80 & ((D&(~K)&(~res)) | ((~D)&K&res)))
75 if (0x80 & (((~D)&K) | (K&res) | (res&(~D))))
83 * Substract Immediate with Carry
84 * SBCI Rd,K 16<=d<=31, 0<=K<=255
86 *____________________________________________________________________________
90 cl_avr::sbci_Rd_K(t_mem code)
93 t_mem D, K, result, res;
96 K= (code&0xf) | ((code&0xf00)>>8);
103 t_mem sreg= ram->get(SREG);
104 (signed)result= (signed)D-(signed)K-(sreg&BIT_C)?1:0;
108 sreg= sreg & ~(BIT_H|BIT_S|BIT_V|BIT_N|BIT_C);
109 if (0x08 & (((~D)&K) | (K&res) | (res&(~D))))
112 if (0x80 & ((D&(~K)&(~res)) | ((~D)&K&res)))
126 if (0x80 & (((~D)&K) | (K&res) | (res&(~D))))
128 ram->set(SREG, sreg);
134 * Substract Immediate
135 * SUBI Rd,K 16<=d<=31, 0<=K<=255
136 * 0101 KKKK dddd KKKK
137 *____________________________________________________________________________
141 cl_avr::subi_Rd_K(t_mem code)
144 t_mem D, K, result, res;
146 d= 16+(code&0xf0)>>4;
147 K= (code&0xf) | ((code&0xf00)>>8);
154 (signed)result= (signed)D-(signed)K;
158 t_mem sreg= ram->get(SREG) & ~(BIT_H|BIT_S|BIT_V|BIT_N|BIT_Z|BIT_C);
159 if (0x08 & (((~D)&K) | (K&res) | (res&(~D))))
162 if (0x80 & ((D&(~K)&(~res)) | ((~D)&K&res)))
176 if (0x80 & (((~D)&K) | (K&res) | (res&(~D))))
178 ram->set(SREG, sreg);
184 cl_avr::muls_Rd_Rr(t_mem code)
191 cl_avr::mulsu_Rd_Rr(t_mem code)
198 cl_avr::fmul_Rd_Rr(t_mem code)
205 cl_avr::fmuls_Rd_Rr(t_mem code)
212 cl_avr::fmulsu_Rd_Rr(t_mem code)
220 * CPC Rd,Rr 0<=d<=31, 0<=r<=31
221 * 0000 01rd dddd rrrr
222 *____________________________________________________________________________
226 cl_avr::cpc_Rd_Rr(t_mem code)
229 t_mem R, D, result, res;
232 r= ((code&0x200)>>5)|(code&0xf);
239 t_mem sreg= ram->get(SREG);
240 (signed)result= (signed)D-(signed)R-(sreg&BIT_C)?1:0;
243 sreg= sreg & ~(BIT_H|BIT_S|BIT_V|BIT_N|BIT_C);
244 if (0x08 & (((~D)&R) | (R&res) | (res&(~D))))
247 if (0x80 & ((D&(~R)&(~res)) | ((~D)&R&res)))
261 if (0x80 & (((~D)&R) | (R&res) | (res&(~D))))
263 ram->set(SREG, sreg);
269 * Substract with Carry
270 * SBC Rd,Rr 0<=d<=31, 0<=r<=31
271 * 0000 10rd dddd rrrr
272 *____________________________________________________________________________
276 cl_avr::sbc_Rd_Rr(t_mem code)
279 t_mem R, D, result, res;
282 r= ((code&0x200)>>5)|(code&0xf);
289 t_mem sreg= ram->get(SREG);
290 (signed)result= (signed)D-(signed)R-(sreg&BIT_C)?1:0;
294 sreg= sreg & ~(BIT_H|BIT_S|BIT_V|BIT_N|BIT_C);
295 if (0x08 & (((~D)&R) | (R&res) | (res&(~D))))
298 if (0x80 & ((D&(~R)&(~res)) | ((~D)&R&res)))
312 if (0x80 & (((~D)&R) | (R&res) | (res&(~D))))
314 ram->set(SREG, sreg);
321 * ADD Rd,Rr 0<=d<=31, 0<=r<=31
322 * 0000 11rd dddd rrrr
323 *____________________________________________________________________________
327 cl_avr::add_Rd_Rr(t_mem code)
330 t_mem R, D, result, res;
333 r= ((code&0x200)>>5)|(code&0xf);
340 t_mem sreg= ram->get(SREG);
345 if (((D&R&~res)&0x80) ||
347 sreg|= (BIT_V|BIT_S);
349 sreg&= ~(BIT_V|BIT_S);
361 if ((R&0xf) + (D&0xf) > 15)
365 ram->set(SREG, sreg);
373 * CP Rd,Rr 0<=d<=31, 0<=r<=31
374 * 0001 01rd dddd rrrr
375 *____________________________________________________________________________
379 cl_avr::cp_Rd_Rr(t_mem code)
382 t_mem R, D, result, res;
385 r= ((code&0x200)>>5)|(code&0xf);
392 (signed)result= (signed)D-(signed)R;
395 t_mem sreg= ram->get(SREG) & ~(BIT_H|BIT_S|BIT_V|BIT_N|BIT_Z|BIT_C);
396 if (0x08 & (((~D)&R) | (R&res) | (res&(~D))))
399 if (0x80 & ((D&(~R)&(~res)) | ((~D)&R&res)))
413 if (0x80 & (((~D)&R) | (R&res) | (res&(~D))))
415 ram->set(SREG, sreg);
421 * Substract without Carry
422 * SUB Rd,Rr 0<=d<=31, 0<=r<=31
423 * 0001 10rd dddd rrrr
424 *____________________________________________________________________________
428 cl_avr::sub_Rd_Rr(t_mem code)
431 t_mem R, D, result, res;
434 r= ((code&0x200)>>5)|(code&0xf);
441 (signed)result= (signed)D-(signed)R;
445 t_mem sreg= ram->get(SREG) & ~(BIT_H|BIT_S|BIT_V|BIT_N|BIT_Z|BIT_C);
446 if (0x08 & (((~D)&R) | (R&res) | (res&(~D))))
449 if (0x80 & ((D&(~R)&(~res)) | ((~D)&R&res)))
463 if (0x80 & (((~D)&R) | (R&res) | (res&(~D))))
465 ram->set(SREG, sreg);
472 * ADC Rd,Rr 0<=d<=31, 0<=r<=31
473 * 0001 11rd dddd rrrr
474 *____________________________________________________________________________
478 cl_avr::adc_Rd_Rr(t_mem code)
481 t_mem R, D, result, res;
484 r= ((code&0x200)>>5)|(code&0xf);
487 t_mem sreg= ram->get(SREG);
488 result= D+R+((sreg&BIT_C)?1:0);
496 if (((D&R&~res)&0x80) ||
498 sreg|= (BIT_V|BIT_S);
500 sreg&= ~(BIT_V|BIT_S);
512 if ((R&0xf) + (D&0xf) > 15)
516 ram->set(SREG, sreg);
525 * 1001 010d dddd 0000
526 *____________________________________________________________________________
530 cl_avr::com_Rd(t_mem code)
533 t_mem D, result, res;
541 t_mem sreg= ram->get(SREG);
548 sreg|= (BIT_N|BIT_S);
550 sreg&= ~(BIT_N|BIT_S);
552 ram->set(SREG, sreg);
561 * 1001 010d dddd 0001
562 *____________________________________________________________________________
566 cl_avr::neg_Rd(t_mem code)
569 t_mem D, result, res;
577 t_mem sreg= ram->get(SREG);
578 if (res & (~d) & 0x08)
604 ram->set(SREG, sreg);
613 * 1001 010d dddd 0011
614 *____________________________________________________________________________
618 cl_avr::inc_Rd(t_mem code)
623 t_mem data= ram->read(d)+1;
626 t_mem sreg= ram->get(SREG);
645 sreg&= ~(BIT_N|BIT_V|BIT_S);
651 ram->set(SREG, sreg);
657 * Arithmetic Shift Right
659 * 1001 010d dddd 0101
660 *____________________________________________________________________________
664 cl_avr::asr_Rd(t_mem code)
667 t_mem D, result, res;
671 t_mem sreg= ram->read(SREG) & ~(BIT_S|BIT_V|BIT_N|BIT_Z|BIT_C);
697 ram->write(SREG, sreg);
703 * Logical Shift Right
705 * 1001 010d dddd 0110
706 *____________________________________________________________________________
710 cl_avr::lsr_Rd(t_mem code)
713 t_mem D, result, res;
717 t_mem sreg= ram->read(SREG) & ~(BIT_S|BIT_V|BIT_N|BIT_Z|BIT_C);
719 sreg|= (BIT_C|BIT_V|BIT_S);
725 ram->write(SREG, sreg);
731 * Rotate Right trough Carry
733 * 1001 010d dddd 0111
734 *____________________________________________________________________________
738 cl_avr::ror_Rd(t_mem code)
741 t_mem D, result, res;
745 t_mem sreg= ram->read(SREG);
746 int oldc= sreg & BIT_C;
747 sreg= sreg & ~(BIT_S|BIT_V|BIT_N|BIT_Z|BIT_C);
748 int n= 0, v= 0, c= 0;
754 result= (D >> 1) | oldc?0x80:0;
771 ram->write(SREG, sreg);
779 * 1001 010d dddd 1010
780 *____________________________________________________________________________
784 cl_avr::dec_Rd(t_mem code)
787 t_mem D, result, res;
795 t_mem sreg= ram->get(SREG);
819 ram->set(SREG, sreg);
827 * MUL Rd,Rr 0<=d<=31, 0<=r<=31
828 * 1001 11rd dddd rrrr
829 *____________________________________________________________________________
833 cl_avr::mul_Rd_Rr(t_mem code)
836 t_mem D, R, result, resl, resh;
839 r= ((code&0x200)>>5) | (code&0xf);
844 resh= (result>>8) & 0xff;
847 t_mem sreg= ram->read(SREG) & ~BIT_C;
850 ram->write(SREG, sreg);
857 * Add Immediate to Word
858 * ADIW Rdl,K dl={24,26,28,30}, 0<=K<=63
859 * 1001 0110 KK dd KKKK
860 *____________________________________________________________________________
864 cl_avr::adiw_Rdl_K(t_mem code)
867 t_mem D, K, result, res;
869 dl= 24+(2*((code&0x30)>>4));
870 K= ((code&0xc0)>>2)|(code&0xf);
871 D= ram->read(dl+1)*256 + ram->read(dl);
873 res= result & 0xffff;
874 t_mem resl= result&0xff, resh= (result>>8)&0xff;
875 ram->write(dl+1, resh);
876 ram->write(dl, resl);
878 t_mem sreg= ram->get(SREG);
884 sreg|= (BIT_V|BIT_S);
886 sreg&= ~(BIT_V|BIT_S);
898 ram->set(SREG, sreg);
906 * Substract Immediate from Word
907 * SBIW Rdl,K dl={24,26,28,30}, 0<=K<=63
908 * 1001 0111 KK dd KKKK
909 *____________________________________________________________________________
913 cl_avr::sbiw_Rdl_K(t_mem code)
916 t_mem D, K, result, res;
918 dl= 24+(2*((code&0x30)>>4));
919 K= ((code&0xc0)>>2)|(code&0xf);
920 D= ram->read(dl+1)*256 + ram->read(dl);
925 (signed)result= (signed)D-(signed)K;
926 res= result & 0xffff;
927 t_mem resl= res&0xff, resh= (res>>8)&0xff;
928 ram->write(dl+1, resh);
929 ram->write(dl, resl);
931 t_mem sreg= ram->get(SREG) & ~(BIT_S|BIT_V|BIT_N|BIT_Z|BIT_C);
933 if (0x8000 & D & (~res))
947 if (0x8000 & res & (~D))
949 ram->set(SREG, sreg);
956 /* End of avr.src/arith_inst.cc */