2 * Simulator of microcontrollers (inst.cc)
4 * Copyright (C) 1999,2002 Drotos Daniel, Talker Bt.
6 * To contact author send email to drdani@mazsola.iit.uni-miskolc.hu
7 * Other contributors include:
8 * Karl Bongers karl@turbobit.com,
9 * Johan Knol johan.knol@iduna.nl
13 /* This file is part of microcontroller simulator: ucsim.
15 UCSIM is free software; you can redistribute it and/or modify
16 it under the terms of the GNU General Public License as published by
17 the Free Software Foundation; either version 2 of the License, or
18 (at your option) any later version.
20 UCSIM is distributed in the hope that it will be useful,
21 but WITHOUT ANY WARRANTY; without even the implied warranty of
22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 GNU General Public License for more details.
25 You should have received a copy of the GNU General Public License
26 along with UCSIM; see the file COPYING. If not, write to the Free
27 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
39 void cl_xa::store1(t_addr addr, unsigned char val)
42 set_idata1(addr, val);
44 set_xdata1(addr, val);
48 void cl_xa::store2(t_addr addr, unsigned short val)
51 set_idata2(addr, val);
53 set_xdata2(addr, val);
57 unsigned char cl_xa::get1(t_addr addr)
60 return get_idata1(addr);
62 return get_xdata1(addr);
66 unsigned short cl_xa::get2(t_addr addr)
69 return get_idata2(addr);
71 return get_xdata2(addr);
75 int cl_xa::get_reg(int word_flag, unsigned int index)
80 result = get_word_direct(index);
83 result = get_byte_direct(index);
88 bool cl_xa::get_bit(int bit) {
97 result = get_byte_direct(offset + (bit/8)) & (1 << (bit%8));
99 //return mem_direct[offset + (bit/8)] & (1 << (bit%8));
102 void cl_xa::set_bit(int bit, int value) {
111 i = get_byte_direct(offset + (bit/8));
113 set_byte_direct(offset + (bit/8), i | (1 << (bit%8)) );
114 //mem_direct[offset + (bit/8)] |= (1 << (bit%8));
116 set_byte_direct(offset + (bit/8), i & ~(1 << (bit%8)) );
117 //mem_direct[offset + (bit/8)] &= ~(1 << (bit%8));
121 #define RI_F0 ((code >> 4) & 0xf)
122 #define RI_70 ((code >> 4) & 0x7)
123 #define RI_0F (code & 0xf)
124 #define RI_07 (code & 0x7)
126 int cl_xa::inst_ADD(uint code, int operands)
132 #include "inst_gen.cc"
137 int cl_xa::inst_ADDC(uint code, int operands)
143 #include "inst_gen.cc"
148 int cl_xa::inst_ADDS(uint code, int operands)
153 int cl_xa::inst_AND(uint code, int operands)
159 #include "inst_gen.cc"
163 int cl_xa::inst_ANL(uint code, int operands)
168 int cl_xa::inst_ASL(uint code, int operands)
173 int cl_xa::inst_ASR(uint code, int operands)
178 int cl_xa::inst_BCC(uint code, int operands)
180 short jmpAddr = fetch1()*2;
181 if (!(get_psw() & BIT_C)) {
182 PC=(PC+jmpAddr)&0xfffffe;
187 int cl_xa::inst_BCS(uint code, int operands)
189 short jmpAddr = fetch1()*2;
190 if (get_psw() & BIT_C) {
191 PC=(PC+jmpAddr)&0xfffffe;
196 int cl_xa::inst_BEQ(uint code, int operands)
198 short jmpAddr = fetch1()*2;
199 if (get_psw() & BIT_Z) {
200 PC=(PC+jmpAddr)&0xfffffe;
205 int cl_xa::inst_BG(uint code, int operands)
207 short jmpAddr = fetch1()*2;
208 short flags=get_psw();
209 bool Z=flags&BIT_Z, C=flags&BIT_C;
211 PC=(PC+jmpAddr)&0xfffffe;
215 int cl_xa::inst_BGE(uint code, int operands)
217 short jmpAddr = fetch1()*2;
218 short flags=get_psw();
219 bool N=flags&BIT_N, V=flags&BIT_V;
221 PC=(PC+jmpAddr)&0xfffffe;
225 int cl_xa::inst_BGT(uint code, int operands)
227 short jmpAddr = fetch1()*2;
228 short flags=get_psw();
229 bool Z=flags&BIT_Z, N=flags&BIT_N, V=flags&BIT_V;
231 PC=(PC+jmpAddr)&0xfffffe;
235 int cl_xa::inst_BKPT(uint code, int operands)
239 int cl_xa::inst_BL(uint code, int operands)
241 short jmpAddr = fetch1()*2;
242 short flags=get_psw();
243 bool Z=flags&BIT_Z, C=flags&BIT_C;
245 PC=(PC+jmpAddr)&0xfffffe;
249 int cl_xa::inst_BLE(uint code, int operands)
251 short jmpAddr = fetch1()*2;
252 short flags=get_psw();
253 bool Z=flags&BIT_Z, N=flags&BIT_N, V=flags&BIT_V;
255 PC=(PC+jmpAddr)&0xfffffe;
259 int cl_xa::inst_BLT(uint code, int operands)
261 short jmpAddr = fetch1()*2;
262 short flags=get_psw();
263 bool N=flags&BIT_N, V=flags&BIT_V;
265 PC=(PC+jmpAddr)&0xfffffe;
269 int cl_xa::inst_BMI(uint code, int operands)
271 short jmpAddr = fetch1()*2;
272 if (get_psw()&BIT_N) {
273 PC=(PC+jmpAddr)&0xfffffe;
277 int cl_xa::inst_BNE(uint code, int operands)
279 short jmpAddr = fetch1()*2;
280 if (!(get_psw()&BIT_Z)) {
281 PC=(PC+jmpAddr)&0xfffffe;
285 int cl_xa::inst_BNV(uint code, int operands)
287 short jmpAddr = fetch1()*2;
288 if (!(get_psw()&BIT_V)) {
289 PC=(PC+jmpAddr)&0xfffffe;
293 int cl_xa::inst_BOV(uint code, int operands)
295 short jmpAddr = fetch1()*2;
296 if (get_psw()&BIT_V) {
297 PC=(PC+jmpAddr)&0xfffffe;
301 int cl_xa::inst_BPL(uint code, int operands)
303 short jmpAddr = fetch1()*2;
304 if (!(get_psw()&BIT_N)) {
305 PC=(PC+jmpAddr)&0xfffffe;
310 int cl_xa::inst_BR(uint code, int operands)
312 short jmpAddr = fetch1()*2;
313 PC=(PC+jmpAddr)&0xfffffe;
317 int cl_xa::inst_CALL(uint code, int operands)
321 bool pageZero=get_scr()&1;
326 jmpaddr = (signed short)fetch2();
327 sp = get_sp() - (pageZero ? 2 : 4);
329 store2(sp, PC&0xffff);
331 store2(sp+2, (PC>>16)&0xff);
334 PC = (PC + jmpaddr) & 0xfffffe;
339 sp = get_sp() - (pageZero ? 2 : 4);
341 store2(sp, PC&0xffff);
343 store2(sp+2, (PC>>16)&0xff);
345 jmpaddr = reg2(RI_07);
347 PC = (PC + jmpaddr) & 0xfffffe;
354 int cl_xa::inst_CJNE(uint code, int operands)
357 case REG_DIRECT_REL8:
360 if (code & 0x800) { // word op
362 int src = get_word_direct( ((code & 0x7)<<4) | fetch1());
363 int addr = (fetch1() * 2);
364 int dst = reg2(RI_F0);
367 flags &= ~BIT_ALL; /* clear these bits */
369 if (result == 0) flags |= BIT_Z;
370 if (result > 0xffff) flags |= BIT_C;
371 if (dst < src) flags |= BIT_N;
377 int src = get_byte_direct( ((code & 0x7)<<4) | fetch1());
378 int addr = (fetch1() * 2);
379 int dst = reg1(RI_F0);
382 flags &= ~BIT_ALL; /* clear these bits */
384 if (result == 0) flags |= BIT_Z;
385 if (result > 0xff) flags |= BIT_C;
386 if (dst < src) flags |= BIT_N;
396 int daddr = ((code & 0x7) << 8) | fetch();
397 int addr = fetch() * 2;
399 if (code & 0x800) { // word op
400 unsigned short tmp = get_word_direct(daddr)-1;
401 set_word_direct(daddr, tmp);
405 unsigned char tmp = get_word_direct(daddr)-1;
406 set_byte_direct(daddr, tmp);
416 int cl_xa::inst_CLR(uint code, int operands)
418 unsigned short bitAddr = (code&0x03 << 8) + fetch();
419 set_bit (bitAddr, 0);
423 int cl_xa::inst_CMP(uint code, int operands)
429 #include "inst_gen.cc"
432 int cl_xa::inst_CPL(uint code, int operands)
436 int cl_xa::inst_DA(uint code, int operands)
440 int cl_xa::inst_DIV(uint code, int operands)
445 int cl_xa::inst_DJNZ(uint code, int operands)
451 int addr = ( ((char)fetch1()) * 2);
452 if (code & 0x800) { // word op
453 unsigned short tmp = mov2(0, reg2(RI_F0)-1);
454 set_reg2(RI_F0, tmp);
456 PC = (PC + addr) & 0xfffffe;
458 unsigned char tmp = mov1(0, reg1(RI_F0)-1);
459 set_reg1(RI_F0, tmp);
461 PC = (PC + addr) & 0xfffffe;
468 int daddr = ((code & 0x7) << 8) | fetch();
469 int addr = fetch() * 2;
471 if (code & 0x800) { // word op
472 unsigned short tmp = get_word_direct(daddr)-1;
473 set_word_direct(daddr, tmp);
477 unsigned char tmp = get_word_direct(daddr)-1;
478 set_byte_direct(daddr, tmp);
489 int cl_xa::inst_FCALL(uint code, int operands)
494 int cl_xa::inst_FJMP(uint code, int operands)
499 int cl_xa::inst_JB(uint code, int operands)
501 short bitAddr=((code&0x3)<<8) + fetch1();
502 short jmpAddr = (fetch1() * 2);
503 if (get_bit(bitAddr)) {
504 PC = (PC+jmpAddr)&0xfffffe;
508 int cl_xa::inst_JBC(uint code, int operands)
512 int cl_xa::inst_JNB(uint code, int operands)
514 short bitAddr=((code&0x3)<<8) + fetch1();
515 short jmpAddr = (fetch1() * 2);
516 if (!get_bit(bitAddr)) {
517 PC = (PC+jmpAddr)&0xfffffe;
522 int cl_xa::inst_JMP(uint code, int operands)
529 jmpAddr = (signed short)fetch2()*2;
530 PC = (PC + jmpAddr) & 0xfffffe;
535 PC |= (reg2(RI_07) & 0xfffe); /* word aligned */
537 /* fixme 2 more... */
541 int cl_xa::inst_JNZ(uint code, int operands)
543 short saddr = (fetch1() * 2);
544 /* reg1(8) = R4L, is ACC for MCS51 compatiblility */
546 PC = (PC + saddr) & 0xfffffe;
550 int cl_xa::inst_JZ(uint code, int operands)
552 /* reg1(8) = R4L, is ACC for MCS51 compatiblility */
553 short saddr = (fetch1() * 2);
559 int cl_xa::inst_LEA(uint code, int operands)
563 int cl_xa::inst_LSR(uint code, int operands)
567 int cl_xa::inst_MOV(uint code, int operands)
573 #include "inst_gen.cc"
576 int cl_xa::inst_MOVC(uint code, int operands)
581 short srcreg = reg2(RI_07);
582 if (code & 0x0800) { /* word op */
595 if (operands == REG_IREGINC) {
596 set_reg2(RI_07, srcreg+1);
601 { /* R4l=ACC, R6=DPTR */
602 unsigned int addr = (PC & 0xff0000) | (reg1(4) + reg2(6));
603 unsigned short result;
607 flags &= ~(BIT_Z | BIT_N); /* clear these bits */
608 result = getcode1(addr);
609 set_reg1( 4, result);
610 if (result == 0) flags |= BIT_Z;
611 if (result & 0x80) flags |= BIT_N;
616 { /* R4l=ACC, R6=DPTR */
617 unsigned int addr = (PC + reg1(4));
618 unsigned short result;
622 flags &= ~(BIT_Z | BIT_N); /* clear these bits */
623 result = getcode1(addr);
624 set_reg1( 4, result);
625 if (result == 0) flags |= BIT_Z;
626 if (result & 0x80) flags |= BIT_N;
633 int cl_xa::inst_MOVS(uint code, int operands)
637 int cl_xa::inst_MOVX(uint code, int operands)
641 int cl_xa::inst_MUL(uint code, int operands)
645 int cl_xa::inst_NEG(uint code, int operands)
649 int cl_xa::inst_NOP(uint code, int operands)
653 int cl_xa::inst_NORM(uint code, int operands)
657 int cl_xa::inst_OR(uint code, int operands)
663 #include "inst_gen.cc"
667 int cl_xa::inst_ORL(uint code, int operands)
672 int cl_xa::inst_POP(uint code, int operands)
674 unsigned short sp=get_sp();
678 unsigned short direct_addr = ((operands & 0x7) << 8) | fetch();
680 if (code & 0x0800) { /* word op */
681 set_word_direct(direct_addr, get2(sp) );
683 set_byte_direct(direct_addr, get2(sp) & 0xff );
691 unsigned char rlist = fetch();
692 if (code & 0x0800) { // word op
693 if (code & 0x4000) { // R8-R15
694 if (rlist&0x01) { set_reg2(8, get2(sp)); sp+=2; }
695 if (rlist&0x02) { set_reg2(9, get2(sp)); sp+=2; }
696 if (rlist&0x04) { set_reg2(10, get2(sp)); sp+=2; }
697 if (rlist&0x08) { set_reg2(11, get2(sp)); sp+=2; }
698 if (rlist&0x10) { set_reg2(12, get2(sp)); sp+=2; }
699 if (rlist&0x20) { set_reg2(13, get2(sp)); sp+=2; }
700 if (rlist&0x40) { set_reg2(14, get2(sp)); sp+=2; }
701 if (rlist&0x80) { set_reg2(15, get2(sp)); sp+=2; }
703 if (rlist&0x01) { set_reg2(0, get2(sp)); sp+=2; }
704 if (rlist&0x02) { set_reg2(1, get2(sp)); sp+=2; }
705 if (rlist&0x04) { set_reg2(2, get2(sp)); sp+=2; }
706 if (rlist&0x08) { set_reg2(3, get2(sp)); sp+=2; }
707 if (rlist&0x10) { set_reg2(4, get2(sp)); sp+=2; }
708 if (rlist&0x20) { set_reg2(5, get2(sp)); sp+=2; }
709 if (rlist&0x40) { set_reg2(6, get2(sp)); sp+=2; }
710 if (rlist&0x80) { set_reg2(7, get2(sp)); sp+=2; }
713 if (code & 0x4000) { // R4l-R7h
714 if (rlist&0x01) { set_reg1(8, get1(sp)); sp+=2; }
715 if (rlist&0x02) { set_reg1(9, get1(sp)); sp+=2; }
716 if (rlist&0x04) { set_reg1(10, get1(sp)); sp+=2; }
717 if (rlist&0x08) { set_reg1(11, get1(sp)); sp+=2; }
718 if (rlist&0x10) { set_reg1(12, get1(sp)); sp+=2; }
719 if (rlist&0x20) { set_reg1(13, get1(sp)); sp+=2; }
720 if (rlist&0x40) { set_reg1(14, get1(sp)); sp+=2; }
721 if (rlist&0x80) { set_reg1(15, get1(sp)); sp+=2; }
723 if (rlist&0x01) { set_reg1(0, get1(sp)); sp+=2; }
724 if (rlist&0x02) { set_reg1(1, get1(sp)); sp+=2; }
725 if (rlist&0x04) { set_reg1(2, get1(sp)); sp+=2; }
726 if (rlist&0x08) { set_reg1(3, get1(sp)); sp+=2; }
727 if (rlist&0x10) { set_reg1(4, get1(sp)); sp+=2; }
728 if (rlist&0x20) { set_reg1(5, get1(sp)); sp+=2; }
729 if (rlist&0x40) { set_reg1(6, get1(sp)); sp+=2; }
730 if (rlist&0x80) { set_reg1(7, get1(sp)); sp+=2; }
739 int cl_xa::inst_PUSH(uint code, int operands)
745 unsigned short direct_addr = ((operands & 0x7) << 8) | fetch();
749 if (code & 0x0800) { /* word op */
750 store2( sp, get_word_direct(direct_addr));
752 store2( sp, get_byte_direct(direct_addr));
759 unsigned short sp=get_sp();
760 unsigned char rlist = fetch();
761 if (code & 0x0800) { // word op
762 if (code & 0x4000) { // R15-R8
763 if (rlist&0x80) { sp-=2; store2(sp, reg2(15)); }
764 if (rlist&0x40) { sp-=2; store2(sp, reg2(14)); }
765 if (rlist&0x20) { sp-=2; store2(sp, reg2(13)); }
766 if (rlist&0x10) { sp-=2; store2(sp, reg2(12)); }
767 if (rlist&0x08) { sp-=2; store2(sp, reg2(11)); }
768 if (rlist&0x04) { sp-=2; store2(sp, reg2(10)); }
769 if (rlist&0x02) { sp-=2; store2(sp, reg2(9)); }
770 if (rlist&0x01) { sp-=2; store2(sp, reg2(8)); }
772 if (rlist&0x80) { sp-=2; store2(sp, reg2(7)); }
773 if (rlist&0x40) { sp-=2; store2(sp, reg2(6)); }
774 if (rlist&0x20) { sp-=2; store2(sp, reg2(5)); }
775 if (rlist&0x10) { sp-=2; store2(sp, reg2(4)); }
776 if (rlist&0x08) { sp-=2; store2(sp, reg2(3)); }
777 if (rlist&0x04) { sp-=2; store2(sp, reg2(2)); }
778 if (rlist&0x02) { sp-=2; store2(sp, reg2(1)); }
779 if (rlist&0x01) { sp-=2; store2(sp, reg2(0)); }
782 if (code & 0x4000) { // R7h-R4l
783 if (rlist&0x80) { sp-=2; store2(sp, reg1(15)); }
784 if (rlist&0x40) { sp-=2; store2(sp, reg1(14)); }
785 if (rlist&0x20) { sp-=2; store2(sp, reg1(13)); }
786 if (rlist&0x10) { sp-=2; store2(sp, reg1(12)); }
787 if (rlist&0x08) { sp-=2; store2(sp, reg1(11)); }
788 if (rlist&0x04) { sp-=2; store2(sp, reg1(10)); }
789 if (rlist&0x02) { sp-=2; store2(sp, reg1(9)); }
790 if (rlist&0x01) { sp-=2; store2(sp, reg1(8)); }
792 if (rlist&0x80) { sp-=2; store2(sp, reg1(7)); }
793 if (rlist&0x40) { sp-=2; store2(sp, reg1(6)); }
794 if (rlist&0x20) { sp-=2; store2(sp, reg1(5)); }
795 if (rlist&0x10) { sp-=2; store2(sp, reg1(4)); }
796 if (rlist&0x08) { sp-=2; store2(sp, reg1(3)); }
797 if (rlist&0x04) { sp-=2; store2(sp, reg1(2)); }
798 if (rlist&0x02) { sp-=2; store2(sp, reg1(1)); }
799 if (rlist&0x01) { sp-=2; store2(sp, reg1(0)); }
808 int cl_xa::inst_RESET(uint code, int operands)
812 int cl_xa::inst_RET(uint code, int operands)
814 unsigned int retaddr;
816 bool pageZero=get_scr()&1;
821 retaddr |= get2(sp+2) << 16;
829 int cl_xa::inst_RETI(uint code, int operands)
831 unsigned int retaddr;
833 bool pageZero=get_scr()&1;
837 retaddr = get2(sp+2);
839 retaddr |= get2(sp+4) << 16;
847 int cl_xa::inst_RL(uint code, int operands)
851 int cl_xa::inst_RLC(uint code, int operands)
855 int cl_xa::inst_RR(uint code, int operands)
859 int cl_xa::inst_RRC(uint code, int operands)
863 int cl_xa::inst_SETB(uint code, int operands)
865 unsigned short bitAddr = (code&0x03 << 8) + fetch();
866 set_bit (bitAddr, 1);
870 int cl_xa::inst_SEXT(uint code, int operands)
872 bool neg=get_psw()&BIT_N;
873 if (code & 0x0800) { // word op
874 set_reg2(RI_F0, neg ? 0xffff : 0);
876 set_reg1(RI_F0, neg ? 0xff : 0);
881 int cl_xa::inst_SUB(uint code, int operands)
887 #include "inst_gen.cc"
891 int cl_xa::inst_SUBB(uint code, int operands)
897 #include "inst_gen.cc"
901 int cl_xa::inst_TRAP(uint code, int operands)
903 // steal a few opcodes for simulator only putchar() and exit()
904 // functions. Used in SDCC regression testing.
905 switch (code & 0x0f) {
907 // implement a simulator putchar() routine
908 //printf("PUTCHAR-----> %xH\n", reg1(0));
920 int cl_xa::inst_XCH(uint code, int operands)
924 int cl_xa::inst_XOR(uint code, int operands)
930 #include "inst_gen.cc"
934 /* End of xa.src/inst.cc */