[ucsim] Update email and file info, fix stm8 flash controller
[sdcc.git] / sdcc / sim / ucsim / src / sims / tlcs.src / inst_arith.cc
blob499bebc35d1083823c98a84908b64b0be24aca25
1 /*
2 * Simulator of microcontrollers (inst_arith.cc)
4 * Copyright (C) 2016 Drotos Daniel
5 *
6 * To contact author send email to dr.dkdb@gmail.com
8 */
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
25 02111-1307, USA. */
26 /*@1@*/
28 #include "tlcscl.h"
31 // INC 8-bit
32 u8_t
33 cl_tlcs::op_inc(u8_t data)
35 u16_t n= data+1;
36 reg.raf.f&= ~(FLAG_S|FLAG_Z|FLAG_H|FLAG_X);
38 if (n > 255)
39 reg.raf.f|= FLAG_X;
40 if (n & 0x80)
41 reg.raf.f|= FLAG_S;
42 if ((n & 0xff) == 0)
43 reg.raf.f|= FLAG_Z;
44 if (data == 0x7f)
45 reg.raf.f|= FLAG_V;
46 if ((n & 0x0f) == 0x00)
47 reg.raf.f|= FLAG_H;
49 return n;
53 // INC mem
54 void
55 cl_tlcs::inst_inc(cl_memory_cell *cell)
57 u8_t d= cell->read();
58 d= op_inc(d);
59 cell->write(d);
60 vc.rd++;
61 vc.wr++;
65 // INCX mem
66 void
67 cl_tlcs::inst_incx(cl_memory_cell *cell)
69 if (reg.raf.f & FLAG_X)
71 u8_t d= cell->read();
72 d= op_inc(d);
73 cell->write(d);
74 vc.rd++;
75 vc.wr++;
80 // INC 8-bit
81 u8_t
82 cl_tlcs::op_dec(u8_t data)
84 u16_t n= data-1;
85 reg.raf.f&= ~(FLAG_S|FLAG_Z|FLAG_H|FLAG_X);
86 reg.raf.f|= FLAG_N;
88 if (n > 255)
89 reg.raf.f|= FLAG_X;
90 if (n & 0x80)
91 reg.raf.f|= FLAG_S;
92 if ((n & 0xff) == 0)
93 reg.raf.f|= FLAG_Z;
94 if (data == 0x80)
95 reg.raf.f|= FLAG_V;
96 if ((n & 0x0f) == 0x00)
97 reg.raf.f|= FLAG_H;
99 return n & 0xff;
103 // DEC mem
104 void
105 cl_tlcs::inst_dec(cl_memory_cell *cell)
107 u8_t d= cell->read();
108 d= op_dec(d);
109 cell->write(d);
110 vc.rd++;
111 vc.wr++;
115 // DECX mem
116 void
117 cl_tlcs::inst_decx(cl_memory_cell *cell)
119 if (reg.raf.f & FLAG_X)
121 u8_t d= cell->read();
122 d= op_dec(d);
123 cell->write(d);
124 vc.rd++;
125 vc.wr++;
130 // INC 16-bit
131 u16_t
132 cl_tlcs::op_inc16(u16_t data)
134 u16_t n= data+1;
135 reg.raf.f&= ~(FLAG_X);
137 if (n == 0)
138 reg.raf.f|= FLAG_X;
140 return n;
144 // INCW mem
145 u16_t
146 cl_tlcs::inst_inc16gg(u8_t gg, t_addr addr)
148 cl_address_space *as= nas;
150 if ((gg&7)==4)
151 as= xas;
152 else if ((gg&7)==5)
153 as= yas;
154 u8_t l= as->read(addr);
155 u8_t h= as->read(addr+1);
156 vc.rd+= 2;
157 u16_t d= h*256 + l;
159 if (((int)d + 1) > 0xffff)
160 reg.raf.f|= FLAG_V;
162 d= op_inc16(d);
163 reg.raf.f&= ~FLAG_N;
164 if (d & 0x8000)
165 reg.raf.f|= FLAG_S;
166 if (d == 0)
167 reg.raf.f|= FLAG_Z;
169 as->write(addr, d & 0xff);
170 as->write(addr+1, d >> 8);
171 vc.wr+= 2;
173 return d;
177 // INCW mem
178 u16_t
179 cl_tlcs::inst_inc16(t_addr addr)
181 return inst_inc16gg(0, addr);
185 // INCW mem
186 u16_t
187 cl_tlcs::inst_inc16ix(u8_t ix, t_addr addr)
189 if ((ix&3) == 0)
190 return inst_inc16gg(4, addr);
191 else if ((ix&3) == 1)
192 return inst_inc16gg(5, addr);
193 return inst_inc16gg(0, addr);
197 // DEC 16-bit
198 u16_t
199 cl_tlcs::op_dec16(t_mem data)
201 u16_t n= data-1;
202 reg.raf.f&= ~(FLAG_X);
204 if (n == 0xffff)
205 reg.raf.f|= FLAG_X;
207 return n;
211 // DECW mem
212 u16_t
213 cl_tlcs::inst_dec16gg(u8_t gg, t_addr addr)
215 class cl_address_space *as= nas;
217 if ((gg&7)==4)
218 as= xas;
219 else if ((gg&7)==5)
220 as= yas;
221 u8_t l= as->read(addr);
222 u8_t h= as->read(addr+1);
223 vc.rd+= 2;
224 u16_t d= h*256 + l;
226 if (((int)d - 1) < 0)
227 reg.raf.f|= FLAG_V;
229 d= op_dec16(d);
230 reg.raf.f&= ~FLAG_N;
231 if (d & 0x8000)
232 reg.raf.f|= FLAG_S;
233 if (d == 0)
234 reg.raf.f|= FLAG_Z;
236 as->write(addr, d & 0xff);
237 as->write(addr+1, d >> 8);
238 vc.wr+= 2;
240 return d;
244 // DECW mem
245 u16_t
246 cl_tlcs::inst_dec16(t_addr addr)
248 return inst_dec16gg(0, addr);
252 // DECW mem
253 u16_t
254 cl_tlcs::inst_dec16ix(u8_t ix, t_addr addr)
256 if ((ix&3)==0)
257 return inst_dec16gg(4, addr);
258 else if ((ix&3)==1)
259 return inst_dec16gg(5, addr);
260 return inst_dec16gg(0, addr);
264 // ADD 8-bit
265 u8_t
266 cl_tlcs::op_add8(u8_t d1, u8_t d2)
268 reg.raf.f&= ~(FLAG_S|FLAG_Z|FLAG_H|FLAG_X|FLAG_V|FLAG_N|FLAG_C);
270 int r= d1 + d2;
271 int new_c= 0, new_c6;
273 if (((d1 & 0xf) + (d2 & 0xf)) > 0xf)
274 reg.raf.f|= FLAG_H;
275 new_c6= (((d1&0x7f) + (d2&0x7f)) > 0x7f)?1:0;
277 if (r & 0x80)
278 reg.raf.f|= FLAG_S;
279 if ((r&0xff) == 0)
280 reg.raf.f|= FLAG_Z;
281 if (r > 255)
283 reg.raf.f|= FLAG_X|FLAG_C;
284 new_c= 1;
286 if (new_c ^ new_c6)
287 reg.raf.f|= FLAG_V;
289 return r & 0xff;
293 // ADD A,8-bit
294 u8_t
295 cl_tlcs::op_add_a(u8_t d)
297 return op_add8(reg.raf.a, d);
301 // ADD A,mem
303 cl_tlcs::inst_add_a(class cl_memory_cell *cell)
305 reg.raf.a= op_add_a((u8_t)(cell->read()));
306 vc.rd++;
307 return resGO;
311 // ADC 8-bit
312 u8_t
313 cl_tlcs::op_adc8(u8_t d1, u8_t d2)
315 int oldc= (reg.raf.f&FLAG_C)?1:0;
316 reg.raf.f&= ~(FLAG_S|FLAG_Z|FLAG_H|FLAG_X|FLAG_V|FLAG_N|FLAG_C);
318 int r= d1 + d2 + oldc;
319 int new_c= 0, new_c6;
321 if (((d1 & 0xf) + (d2 & 0xf) + oldc) > 0xf)
322 reg.raf.f|= FLAG_H;
323 new_c6= (((d1&0x7f) + (d2&0x7f) + oldc) > 0x7f)?1:0;
325 if (r & 0x80)
326 reg.raf.f|= FLAG_S;
327 if ((r & 0xff) == 0)
328 reg.raf.f|= FLAG_Z;
329 if (r > 255)
331 reg.raf.f|= FLAG_X|FLAG_C;
332 new_c= 1;
334 if (new_c ^ new_c6)
335 reg.raf.f|= FLAG_V;
337 return r;
341 // ADC A,8-bit
343 cl_tlcs::inst_adc_a(u8_t d)
345 reg.raf.a= op_adc8(reg.raf.a, d);
346 return resGO;
350 // ADC A,mem
352 cl_tlcs::inst_adc_a(class cl_memory_cell *cell)
354 vc.rd++;
355 return inst_adc_a((u8_t)(cell->read()));
359 // SUB 8-bit
360 u8_t
361 cl_tlcs::op_sub8(u8_t d1, u8_t d2)
363 unsigned int op1= (unsigned int)d1;
364 unsigned int op2= (unsigned int)d2;
365 signed int res= (signed char)d1 - (signed char)d2;
366 u8_t r;
368 reg.raf.f&= ~(FLAG_H|FLAG_V|FLAG_C|FLAG_Z|FLAG_S);
369 reg.raf.f|= FLAG_N;
371 if ((op1 & 0xf) < (op2 & 0xf))
372 reg.raf.f|= FLAG_H;
373 if ((res < -128) || (res > 127))
374 reg.raf.f|= FLAG_V;
375 if (op1 < op2)
376 reg.raf.f|= FLAG_C|FLAG_X;
378 r= d1 - op2;
379 //r= op_add8(d1, ~d2 + 1);
380 if (r == 0)
381 reg.raf.f|= FLAG_Z;
382 if (r & 0x80)
383 reg.raf.f|= FLAG_S;
385 //reg.raf.f|= FLAG_N;
386 return r;
390 // SUB A,8-bit
392 cl_tlcs::inst_sub_a(u8_t d)
394 reg.raf.a= op_sub8(reg.raf.a, d);
395 return resGO;
399 // SUB A,mem
401 cl_tlcs::inst_sub_a(class cl_memory_cell *cell)
403 vc.rd++;
404 return inst_sub_a((u8_t)(cell->read()));
408 // SBC 8-bit
409 u8_t
410 cl_tlcs::op_sbc8(u8_t d1, u8_t d2)
412 u8_t r;
413 unsigned int op1= (unsigned int)d1;
414 unsigned int op2= (unsigned int)d2;
415 signed int res= (signed char)d1 - (signed char)d2;
417 if (reg.raf.f & FLAG_C)
419 ++op2;
420 --res;
422 reg.raf.f&= ~(FLAG_H|FLAG_V|FLAG_C|FLAG_S|FLAG_Z);
423 reg.raf.f|= FLAG_N;
425 if ((op1 & 0xf) < (op2 & 0xf))
426 reg.raf.f|= FLAG_H;
427 if ((res < -128) || (res > 127))
428 reg.raf.f|= FLAG_V;
429 if (d1 < op2)
430 reg.raf.f|= FLAG_C;
432 r= d1 - op2;
434 if (r == 0)
435 reg.raf.f|= FLAG_Z;
436 if (r & 0x80)
437 reg.raf.f|= FLAG_S;
439 //r= op_adc8(d1, ~d2 + 1);
440 //reg.raf.f|= FLAG_N;
441 return r;
445 // SBC A,8-bit
447 cl_tlcs::inst_sbc_a(u8_t d)
449 reg.raf.a= op_sbc8(reg.raf.a, d);
450 return resGO;
454 // SBC A,mem
456 cl_tlcs::inst_sbc_a(class cl_memory_cell *cell)
458 vc.rd++;
459 return inst_sbc_a((u8_t)(cell->read()));
463 // AND 8-bit
464 u8_t
465 cl_tlcs::op_and8(u8_t d1, u8_t d2)
467 reg.raf.f&= ~(FLAG_S|FLAG_Z|FLAG_X|FLAG_N|FLAG_C);
468 reg.raf.f|= FLAG_H;
470 u8_t r= d1 & d2;
471 set_p(r);
472 if (r & 0x80)
473 reg.raf.f|= FLAG_S;
474 if (r == 0)
475 reg.raf.f|= FLAG_Z;
477 return r;
481 // AND A,8-bit
483 cl_tlcs::inst_and_a(u8_t d)
485 reg.raf.a= op_and8(reg.raf.a, d);
486 return resGO;
490 // AND A,mem
492 cl_tlcs::inst_and_a(class cl_memory_cell *cell)
494 vc.rd++;
495 return inst_and_a((u8_t)(cell->read()));
499 // XOR 8-bit
500 u8_t
501 cl_tlcs::op_xor8(u8_t d1, u8_t d2)
503 reg.raf.f&= ~(FLAG_S|FLAG_Z|FLAG_H|FLAG_X|FLAG_N|FLAG_C);
505 u8_t r= d1 ^ d2;
506 set_p(r);
507 if (r & 0x80)
508 reg.raf.f|= FLAG_S;
509 if (r == 0)
510 reg.raf.f|= FLAG_Z;
512 return r;
516 // XOR A,8-bit
518 cl_tlcs::inst_xor_a(u8_t d)
520 reg.raf.a= op_xor8(reg.raf.a, d);
521 return resGO;
525 // XOR A,mem
527 cl_tlcs::inst_xor_a(class cl_memory_cell *cell)
529 vc.rd++;
530 return inst_xor_a((u8_t)(cell->read()));
534 // OR 8-bit
535 u8_t
536 cl_tlcs::op_or8(u8_t d1, u8_t d2)
538 reg.raf.f&= ~(FLAG_S|FLAG_Z|FLAG_H|FLAG_X|FLAG_N|FLAG_C);
540 u8_t r= d1 | d2;
541 set_p(r);
542 if (r & 0x80)
543 reg.raf.f|= FLAG_S;
544 if (r == 0)
545 reg.raf.f|= FLAG_Z;
547 return r;
551 // OR A,8-bit
553 cl_tlcs::inst_or_a(u8_t d)
555 reg.raf.a= op_or8(reg.raf.a, d);
556 return resGO;
560 // OR A,mem
562 cl_tlcs::inst_or_a(class cl_memory_cell *cell)
564 vc.rd++;
565 return inst_or_a((u8_t)(cell->read()));
569 // CP 8-bit
570 u8_t
571 cl_tlcs::op_cp8(u8_t d1, u8_t d2)
573 u8_t r= op_sub8(d1, d2);
574 reg.raf.f|= FLAG_N;
575 return r;
579 // CP A,8-bit
581 cl_tlcs::op_cp_a(u8_t d)
583 op_cp8(reg.raf.a, d);
584 return resGO;
588 // CP A,mem
590 cl_tlcs::op_cp_a(class cl_memory_cell *cell)
592 vc.rd++;
593 return op_cp_a((u8_t)(cell->read()));
597 // ADD 16-bit
598 u16_t
599 cl_tlcs::op_add16(t_mem op1, t_mem op2)
601 u16_t d1, d;
602 int r, newc15;
604 reg.raf.f&= ~(FLAG_S|FLAG_Z|FLAG_X|FLAG_N|FLAG_C);
606 d1= op1;
607 d= op2;
609 r= d1 + d;
610 newc15= (((d1&0x7fff)+(d&0x7fff)) > 0x7fff)?0x10000:0;
612 if (r & 0x8000)
613 reg.raf.f|= FLAG_S;
614 if ((r & 0xffff) == 0)
615 reg.raf.f|= FLAG_Z;
616 if (r > 0xffff)
617 reg.raf.f|= FLAG_C|FLAG_X;
618 if (newc15 ^ (r&0x10000))
619 reg.raf.f|= FLAG_V;
621 return r & 0xffff;
625 // ADD HL,mem
626 u16_t
627 cl_tlcs::op_add_hl_a(t_addr addr)
629 u8_t dh, dl;
630 u16_t d;
632 dl= nas->read(addr);
633 dh= nas->read(addr+1);
634 d= dh*256 + dl;
635 vc.rd+= 2;
637 return op_add16(reg.hl, d);
641 // ADD HL,16-bit
642 u16_t
643 cl_tlcs::op_add_hl_v(t_mem val)
645 return op_add16(reg.hl, val);
649 // ADC HL,mem
650 u16_t
651 cl_tlcs::op_adc_hl_v(t_mem val)
653 u8_t dl= val & 0xff;
654 u8_t dh= val / 256;
655 u16_t d= dh*256 + dl;
656 int oldc= (reg.raf.f & FLAG_C)?1:0;
658 return op_add_hl_v(d + oldc);
662 // ADC HL,mem
663 u16_t
664 cl_tlcs::op_adc_hl_a(t_addr addr)
666 u8_t dl= nas->read(addr);
667 u8_t dh= nas->read(addr+1);
668 u16_t d= dh*256 + dl;
669 int oldc= (reg.raf.f & FLAG_C)?1:0;
670 vc.rd+= 2;
672 return op_add_hl_v(d + oldc);
676 // SUB 16-bit
677 u16_t
678 cl_tlcs::op_sub16(t_mem d1, t_mem d2)
680 u16_t r;
682 unsigned int op1= (unsigned int)d1;
683 unsigned int op2= (unsigned int)d2;
684 signed int res= (i16_t)d1 - (i16_t)d2;
686 reg.raf.f&= ~(FLAG_C|FLAG_V|FLAG_Z|FLAG_S);
687 reg.raf.f|= FLAG_N;
689 if ((res < -32768) || (res > 32767))
690 reg.raf.f|= FLAG_V;
691 if (op1 < op2)
692 reg.raf.f|= FLAG_C|FLAG_X;
694 r= d1 - op2;
696 if (r == 0)
697 reg.raf.f|= FLAG_Z;
698 if (r & 0x8000)
699 reg.raf.f|= FLAG_S;
701 return r;
705 // SUB HL,16-bit
706 u16_t
707 cl_tlcs::op_sub_hl_v(t_mem val)
709 return op_sub16(reg.hl, val);
713 // SUB HL,mem
714 u16_t
715 cl_tlcs::op_sub_hl_a(t_addr addr)
717 u8_t dl= nas->read(addr);
718 u8_t dh= nas->read(addr+1);
719 u16_t d= dh*256 + dl;
720 vc.rd+= 2;
722 return op_sub16(reg.hl, d);
726 // SBC HL,16-bit
727 u16_t
728 cl_tlcs::op_sbc_hl_v(t_mem val)
730 u16_t r;
732 unsigned int op1= (unsigned int)reg.hl;
733 unsigned int op2= (unsigned int)val;
734 signed int res= (i16_t)reg.hl - (i16_t)val;
736 if (reg.raf.f & FLAG_C)
738 ++op2;
739 --res;
741 reg.raf.f&= ~(FLAG_C|FLAG_V|FLAG_Z|FLAG_S);
742 reg.raf.f|= FLAG_N;
744 if ((op1 & 0xfff) < (op2 & 0xfff))
745 reg.raf.f|= FLAG_H;
746 if ((res < -32768) || (res > 32767))
747 reg.raf.f|= FLAG_V;
748 if (op1 < op2)
749 reg.raf.f|= FLAG_C;
751 r= reg.hl - op2;
753 if (r == 0)
754 reg.raf.f|= FLAG_Z;
755 if (r & 0x8000)
756 reg.raf.f|= FLAG_S;
758 return r;
762 // SBC HL,mem
763 u16_t
764 cl_tlcs::op_sbc_hl_a(t_addr addr)
766 u8_t dl= nas->read(addr);
767 u8_t dh= nas->read(addr+1);
768 u16_t d= dh*256 + dl;
769 vc.rd+= 2;
771 return op_sbc_hl_v(d);
775 // AND HL,16-bit
776 u16_t
777 cl_tlcs::op_and_hl_v(t_mem val)
779 u16_t d= val;
780 u16_t r;
782 reg.raf.f&= ~(FLAG_S|FLAG_Z|FLAG_X|FLAG_N|FLAG_C);
783 reg.raf.f|= FLAG_H;
785 r= reg.hl & d;
786 if (r & 0x8000)
787 reg.raf.f|= FLAG_S;
788 if (r == 0)
789 reg.raf.f|= FLAG_Z;
791 return r;
795 // AND HL,mem
796 u16_t
797 cl_tlcs::op_and_hl_a(t_addr addr)
799 u8_t dl= nas->read(addr);
800 u8_t dh= nas->read(addr+1);
801 u16_t d= dh*256 + dl;
802 vc.rd+= 2;
804 return op_and_hl_v(d);
808 // XOR HL,16-bit
809 u16_t
810 cl_tlcs::op_xor_hl_v(t_mem val)
812 u16_t d= val;
813 u16_t r;
815 reg.raf.f&= ~(FLAG_S|FLAG_Z|FLAG_H|FLAG_X|FLAG_N|FLAG_C);
817 r= reg.hl ^ d;
818 if (r & 0x8000)
819 reg.raf.f|= FLAG_S;
820 if (r == 0)
821 reg.raf.f|= FLAG_Z;
823 return r;
827 // XOR HL,mem
828 u16_t
829 cl_tlcs::op_xor_hl_a(t_addr addr)
831 u8_t dl= nas->read(addr);
832 u8_t dh= nas->read(addr+1);
833 u16_t d= dh*256 + dl;
834 vc.rd+= 2;
836 return op_xor_hl_v(d);
840 // OR HL,16-bit
841 u16_t
842 cl_tlcs::op_or_hl_v(t_mem val)
844 u16_t d= val;
845 u16_t r;
847 reg.raf.f&= ~(FLAG_S|FLAG_Z|FLAG_H|FLAG_X|FLAG_N|FLAG_C);
849 r= reg.hl | d;
850 if (r & 0x8000)
851 reg.raf.f|= FLAG_S;
852 if (r == 0)
853 reg.raf.f|= FLAG_Z;
855 return r;
859 // OR HL,mem
860 u16_t
861 cl_tlcs::op_or_hl_a(t_addr addr)
863 u8_t dl= nas->read(addr);
864 u8_t dh= nas->read(addr+1);
865 u16_t d= dh*256 + dl;
866 vc.rd+= 2;
868 return op_or_hl_v(d);
872 /* End of tlcs/inst_arith.cc */