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));
101 void cl_xa::set_bit(int bit, int value) {
110 i = get_byte_direct(offset + (bit/8));
112 set_byte_direct(offset + (bit/8), i | (1 << (bit%8)) );
114 set_byte_direct(offset + (bit/8), i & ~(1 << (bit%8)) );
118 #define RI_F0 ((code >> 4) & 0xf)
119 #define RI_70 ((code >> 4) & 0x7)
120 #define RI_0F (code & 0xf)
121 #define RI_07 (code & 0x7)
123 int cl_xa::inst_ADD(uint code, int operands)
129 #include "inst_gen.cc"
134 int cl_xa::inst_ADDC(uint code, int operands)
140 #include "inst_gen.cc"
145 int cl_xa::inst_ADDS(uint code, int operands)
150 int cl_xa::inst_AND(uint code, int operands)
156 #include "inst_gen.cc"
160 int cl_xa::inst_ANL(uint code, int operands)
165 int cl_xa::inst_ASL(uint code, int operands)
170 int cl_xa::inst_ASR(uint code, int operands)
175 int cl_xa::inst_BCC(uint code, int operands)
177 short jmpAddr = fetch1()*2;
178 if (!(get_psw() & BIT_C)) {
179 PC=(PC+jmpAddr)&0xfffffe;
184 int cl_xa::inst_BCS(uint code, int operands)
186 short jmpAddr = fetch1()*2;
187 if (get_psw() & BIT_C) {
188 PC=(PC+jmpAddr)&0xfffffe;
193 int cl_xa::inst_BEQ(uint code, int operands)
195 short jmpAddr = fetch1()*2;
196 if (get_psw() & BIT_Z) {
197 PC=(PC+jmpAddr)&0xfffffe;
202 int cl_xa::inst_BG(uint code, int operands)
204 short jmpAddr = fetch1()*2;
205 short flags=get_psw();
206 bool Z=flags&BIT_Z, C=flags&BIT_C;
208 PC=(PC+jmpAddr)&0xfffffe;
212 int cl_xa::inst_BGE(uint code, int operands)
214 short jmpAddr = fetch1()*2;
215 short flags=get_psw();
216 bool N=flags&BIT_N, V=flags&BIT_V;
218 PC=(PC+jmpAddr)&0xfffffe;
222 int cl_xa::inst_BGT(uint code, int operands)
224 short jmpAddr = fetch1()*2;
225 short flags=get_psw();
226 bool Z=flags&BIT_Z, N=flags&BIT_N, V=flags&BIT_V;
228 PC=(PC+jmpAddr)&0xfffffe;
232 int cl_xa::inst_BKPT(uint code, int operands)
236 int cl_xa::inst_BL(uint code, int operands)
238 short jmpAddr = fetch1()*2;
239 short flags=get_psw();
240 bool Z=flags&BIT_Z, C=flags&BIT_C;
242 PC=(PC+jmpAddr)&0xfffffe;
246 int cl_xa::inst_BLE(uint code, int operands)
248 short jmpAddr = fetch1()*2;
249 short flags=get_psw();
250 bool Z=flags&BIT_Z, N=flags&BIT_N, V=flags&BIT_V;
252 PC=(PC+jmpAddr)&0xfffffe;
256 int cl_xa::inst_BLT(uint code, int operands)
258 short jmpAddr = fetch1()*2;
259 short flags=get_psw();
260 bool N=flags&BIT_N, V=flags&BIT_V;
262 PC=(PC+jmpAddr)&0xfffffe;
266 int cl_xa::inst_BMI(uint code, int operands)
268 short jmpAddr = fetch1()*2;
269 if (get_psw()&BIT_N) {
270 PC=(PC+jmpAddr)&0xfffffe;
274 int cl_xa::inst_BNE(uint code, int operands)
276 short jmpAddr = fetch1()*2;
277 if (!(get_psw()&BIT_Z)) {
278 PC=(PC+jmpAddr)&0xfffffe;
282 int cl_xa::inst_BNV(uint code, int operands)
284 short jmpAddr = fetch1()*2;
285 if (!(get_psw()&BIT_V)) {
286 PC=(PC+jmpAddr)&0xfffffe;
290 int cl_xa::inst_BOV(uint code, int operands)
292 short jmpAddr = fetch1()*2;
293 if (get_psw()&BIT_V) {
294 PC=(PC+jmpAddr)&0xfffffe;
298 int cl_xa::inst_BPL(uint code, int operands)
300 short jmpAddr = fetch1()*2;
301 if (!(get_psw()&BIT_N)) {
302 PC=(PC+jmpAddr)&0xfffffe;
307 int cl_xa::inst_BR(uint code, int operands)
309 short jmpAddr = fetch1()*2;
310 PC=(PC+jmpAddr)&0xfffffe;
314 int cl_xa::inst_CALL(uint code, int operands)
318 bool pageZero=get_scr()&1;
323 jmpaddr = (signed short)fetch2();
324 sp = get_sp() - (pageZero ? 2 : 4);
326 store2(sp, PC&0xffff);
328 store2(sp+2, (PC>>16)&0xff);
331 PC = (PC + jmpaddr) & 0xfffffe;
336 sp = get_sp() - (pageZero ? 2 : 4);
338 store2(sp, PC&0xffff);
340 store2(sp+2, (PC>>16)&0xff);
342 jmpaddr = reg2(RI_07);
344 PC = (PC + jmpaddr) & 0xfffffe;
351 int cl_xa::inst_CJNE(uint code, int operands)
354 case REG_DIRECT_REL8:
357 if (code & 0x800) { // word op
359 int src = get_word_direct( ((code & 0x7)<<4) | fetch1());
360 int addr = (fetch1() * 2);
361 int dst = reg2(RI_F0);
364 flags &= ~BIT_ALL; /* clear these bits */
366 if (result == 0) flags |= BIT_Z;
367 if (result > 0xffff) flags |= BIT_C;
368 if (dst < src) flags |= BIT_N;
374 int src = get_byte_direct( ((code & 0x7)<<4) | fetch1());
375 int addr = (fetch1() * 2);
376 int dst = reg1(RI_F0);
379 flags &= ~BIT_ALL; /* clear these bits */
381 if (result == 0) flags |= BIT_Z;
382 if (result > 0xff) flags |= BIT_C;
383 if (dst < src) flags |= BIT_N;
393 int daddr = ((code & 0x7) << 8) | fetch();
394 int addr = fetch() * 2;
396 if (code & 0x800) { // word op
397 unsigned short tmp = get_word_direct(daddr)-1;
398 set_word_direct(daddr, tmp);
402 unsigned char tmp = get_word_direct(daddr)-1;
403 set_byte_direct(daddr, tmp);
413 int cl_xa::inst_CLR(uint code, int operands)
415 unsigned short bitAddr = (code&0x03 << 8) + fetch();
416 set_bit (bitAddr, 0);
420 int cl_xa::inst_CMP(uint code, int operands)
426 #include "inst_gen.cc"
429 int cl_xa::inst_CPL(uint code, int operands)
433 int cl_xa::inst_DA(uint code, int operands)
437 int cl_xa::inst_DIV(uint code, int operands)
442 int cl_xa::inst_DJNZ(uint code, int operands)
448 int addr = ( ((char)fetch1()) * 2);
449 if (code & 0x800) { // word op
450 unsigned short tmp = mov2(0, reg2(RI_F0)-1);
451 set_reg2(RI_F0, tmp);
453 PC = (PC + addr) & 0xfffffe;
455 unsigned char tmp = mov1(0, reg1(RI_F0)-1);
456 set_reg1(RI_F0, tmp);
458 PC = (PC + addr) & 0xfffffe;
465 int daddr = ((code & 0x7) << 8) | fetch();
466 int addr = fetch() * 2;
468 if (code & 0x800) { // word op
469 unsigned short tmp = get_word_direct(daddr)-1;
470 set_word_direct(daddr, tmp);
474 unsigned char tmp = get_word_direct(daddr)-1;
475 set_byte_direct(daddr, tmp);
486 int cl_xa::inst_FCALL(uint code, int operands)
491 int cl_xa::inst_FJMP(uint code, int operands)
496 int cl_xa::inst_JB(uint code, int operands)
498 short bitAddr=((code&0x3)<<8) + fetch1();
499 short jmpAddr = (fetch1() * 2);
500 if (get_bit(bitAddr)) {
501 PC = (PC+jmpAddr)&0xfffffe;
505 int cl_xa::inst_JBC(uint code, int operands)
507 short bitAddr=((code&0x3)<<8) + fetch1();
508 short jmpAddr = (fetch1() * 2);
509 if (get_bit(bitAddr)) {
510 PC = (PC+jmpAddr)&0xfffffe;
515 int cl_xa::inst_JNB(uint code, int operands)
517 short bitAddr=((code&0x3)<<8) + fetch1();
518 short jmpAddr = (fetch1() * 2);
519 if (!get_bit(bitAddr)) {
520 PC = (PC+jmpAddr)&0xfffffe;
524 int cl_xa::inst_JMP(uint code, int operands)
531 jmpAddr = (signed short)fetch2()*2;
532 PC = (PC + jmpAddr) & 0xfffffe;
537 PC |= (reg2(RI_07) & 0xfffe); /* word aligned */
539 /* fixme 2 more... */
543 int cl_xa::inst_JNZ(uint code, int operands)
545 short saddr = (fetch1() * 2);
546 /* reg1(8) = R4L, is ACC for MCS51 compatiblility */
548 PC = (PC + saddr) & 0xfffffe;
552 int cl_xa::inst_JZ(uint code, int operands)
554 /* reg1(8) = R4L, is ACC for MCS51 compatiblility */
555 short saddr = (fetch1() * 2);
561 int cl_xa::inst_LEA(uint code, int operands)
566 char offset=fetch1();
567 set_reg2(RI_70, reg2(RI_07)+offset);
572 short offset=fetch2();
573 set_reg2(RI_70, reg2(RI_07)+offset);
579 int cl_xa::inst_LSR(uint code, int operands)
583 int cl_xa::inst_MOV(uint code, int operands)
589 #include "inst_gen.cc"
592 int cl_xa::inst_MOVC(uint code, int operands)
597 short srcreg = reg2(RI_07);
598 if (code & 0x0800) { /* word op */
611 if (operands == REG_IREGINC) {
612 set_reg2(RI_07, srcreg+1);
617 { /* R4l=ACC, R6=DPTR */
618 unsigned int addr = (PC & 0xff0000) | (reg1(4) + reg2(6));
619 unsigned short result;
623 flags &= ~(BIT_Z | BIT_N); /* clear these bits */
624 result = getcode1(addr);
625 set_reg1( 4, result);
626 if (result == 0) flags |= BIT_Z;
627 if (result & 0x80) flags |= BIT_N;
632 { /* R4l=ACC, R6=DPTR */
633 unsigned int addr = (PC + reg1(4));
634 unsigned short result;
638 flags &= ~(BIT_Z | BIT_N); /* clear these bits */
639 result = getcode1(addr);
640 set_reg1( 4, result);
641 if (result == 0) flags |= BIT_Z;
642 if (result & 0x80) flags |= BIT_N;
649 int cl_xa::inst_MOVS(uint code, int operands)
653 int cl_xa::inst_MOVX(uint code, int operands)
657 int cl_xa::inst_MUL(uint code, int operands)
661 int cl_xa::inst_NEG(uint code, int operands)
665 int cl_xa::inst_NOP(uint code, int operands)
669 int cl_xa::inst_NORM(uint code, int operands)
673 int cl_xa::inst_OR(uint code, int operands)
679 #include "inst_gen.cc"
683 int cl_xa::inst_ORL(uint code, int operands)
688 int cl_xa::inst_POP(uint code, int operands)
690 unsigned short sp=get_sp();
694 unsigned short direct_addr = ((operands & 0x7) << 8) | fetch();
696 if (code & 0x0800) { /* word op */
697 set_word_direct(direct_addr, get2(sp) );
699 set_byte_direct(direct_addr, get2(sp) & 0xff );
707 unsigned char rlist = fetch();
708 if (code & 0x0800) { // word op
709 if (code & 0x4000) { // R8-R15
710 if (rlist&0x01) { set_reg2(8, get2(sp)); sp+=2; }
711 if (rlist&0x02) { set_reg2(9, get2(sp)); sp+=2; }
712 if (rlist&0x04) { set_reg2(10, get2(sp)); sp+=2; }
713 if (rlist&0x08) { set_reg2(11, get2(sp)); sp+=2; }
714 if (rlist&0x10) { set_reg2(12, get2(sp)); sp+=2; }
715 if (rlist&0x20) { set_reg2(13, get2(sp)); sp+=2; }
716 if (rlist&0x40) { set_reg2(14, get2(sp)); sp+=2; }
717 if (rlist&0x80) { set_reg2(15, get2(sp)); sp+=2; }
719 if (rlist&0x01) { set_reg2(0, get2(sp)); sp+=2; }
720 if (rlist&0x02) { set_reg2(1, get2(sp)); sp+=2; }
721 if (rlist&0x04) { set_reg2(2, get2(sp)); sp+=2; }
722 if (rlist&0x08) { set_reg2(3, get2(sp)); sp+=2; }
723 if (rlist&0x10) { set_reg2(4, get2(sp)); sp+=2; }
724 if (rlist&0x20) { set_reg2(5, get2(sp)); sp+=2; }
725 if (rlist&0x40) { set_reg2(6, get2(sp)); sp+=2; }
726 if (rlist&0x80) { set_reg2(7, get2(sp)); sp+=2; }
729 if (code & 0x4000) { // R4l-R7h
730 if (rlist&0x01) { set_reg1(8, get1(sp)); sp+=2; }
731 if (rlist&0x02) { set_reg1(9, get1(sp)); sp+=2; }
732 if (rlist&0x04) { set_reg1(10, get1(sp)); sp+=2; }
733 if (rlist&0x08) { set_reg1(11, get1(sp)); sp+=2; }
734 if (rlist&0x10) { set_reg1(12, get1(sp)); sp+=2; }
735 if (rlist&0x20) { set_reg1(13, get1(sp)); sp+=2; }
736 if (rlist&0x40) { set_reg1(14, get1(sp)); sp+=2; }
737 if (rlist&0x80) { set_reg1(15, get1(sp)); sp+=2; }
739 if (rlist&0x01) { set_reg1(0, get1(sp)); sp+=2; }
740 if (rlist&0x02) { set_reg1(1, get1(sp)); sp+=2; }
741 if (rlist&0x04) { set_reg1(2, get1(sp)); sp+=2; }
742 if (rlist&0x08) { set_reg1(3, get1(sp)); sp+=2; }
743 if (rlist&0x10) { set_reg1(4, get1(sp)); sp+=2; }
744 if (rlist&0x20) { set_reg1(5, get1(sp)); sp+=2; }
745 if (rlist&0x40) { set_reg1(6, get1(sp)); sp+=2; }
746 if (rlist&0x80) { set_reg1(7, get1(sp)); sp+=2; }
755 int cl_xa::inst_PUSH(uint code, int operands)
761 unsigned short direct_addr = ((operands & 0x7) << 8) | fetch();
765 if (code & 0x0800) { /* word op */
766 store2( sp, get_word_direct(direct_addr));
768 store2( sp, get_byte_direct(direct_addr));
775 unsigned short sp=get_sp();
776 unsigned char rlist = fetch();
777 if (code & 0x0800) { // word op
778 if (code & 0x4000) { // R15-R8
779 if (rlist&0x80) { sp-=2; store2(sp, reg2(15)); }
780 if (rlist&0x40) { sp-=2; store2(sp, reg2(14)); }
781 if (rlist&0x20) { sp-=2; store2(sp, reg2(13)); }
782 if (rlist&0x10) { sp-=2; store2(sp, reg2(12)); }
783 if (rlist&0x08) { sp-=2; store2(sp, reg2(11)); }
784 if (rlist&0x04) { sp-=2; store2(sp, reg2(10)); }
785 if (rlist&0x02) { sp-=2; store2(sp, reg2(9)); }
786 if (rlist&0x01) { sp-=2; store2(sp, reg2(8)); }
788 if (rlist&0x80) { sp-=2; store2(sp, reg2(7)); }
789 if (rlist&0x40) { sp-=2; store2(sp, reg2(6)); }
790 if (rlist&0x20) { sp-=2; store2(sp, reg2(5)); }
791 if (rlist&0x10) { sp-=2; store2(sp, reg2(4)); }
792 if (rlist&0x08) { sp-=2; store2(sp, reg2(3)); }
793 if (rlist&0x04) { sp-=2; store2(sp, reg2(2)); }
794 if (rlist&0x02) { sp-=2; store2(sp, reg2(1)); }
795 if (rlist&0x01) { sp-=2; store2(sp, reg2(0)); }
798 if (code & 0x4000) { // R7h-R4l
799 if (rlist&0x80) { sp-=2; store2(sp, reg1(15)); }
800 if (rlist&0x40) { sp-=2; store2(sp, reg1(14)); }
801 if (rlist&0x20) { sp-=2; store2(sp, reg1(13)); }
802 if (rlist&0x10) { sp-=2; store2(sp, reg1(12)); }
803 if (rlist&0x08) { sp-=2; store2(sp, reg1(11)); }
804 if (rlist&0x04) { sp-=2; store2(sp, reg1(10)); }
805 if (rlist&0x02) { sp-=2; store2(sp, reg1(9)); }
806 if (rlist&0x01) { sp-=2; store2(sp, reg1(8)); }
808 if (rlist&0x80) { sp-=2; store2(sp, reg1(7)); }
809 if (rlist&0x40) { sp-=2; store2(sp, reg1(6)); }
810 if (rlist&0x20) { sp-=2; store2(sp, reg1(5)); }
811 if (rlist&0x10) { sp-=2; store2(sp, reg1(4)); }
812 if (rlist&0x08) { sp-=2; store2(sp, reg1(3)); }
813 if (rlist&0x04) { sp-=2; store2(sp, reg1(2)); }
814 if (rlist&0x02) { sp-=2; store2(sp, reg1(1)); }
815 if (rlist&0x01) { sp-=2; store2(sp, reg1(0)); }
824 int cl_xa::inst_RESET(uint code, int operands)
828 int cl_xa::inst_RET(uint code, int operands)
830 unsigned int retaddr;
832 bool pageZero=get_scr()&1;
837 retaddr |= get2(sp+2) << 16;
845 int cl_xa::inst_RETI(uint code, int operands)
847 unsigned int retaddr;
849 bool pageZero=get_scr()&1;
853 retaddr = get2(sp+2);
855 retaddr |= get2(sp+4) << 16;
863 int cl_xa::inst_RL(uint code, int operands)
867 int cl_xa::inst_RLC(uint code, int operands)
871 int cl_xa::inst_RR(uint code, int operands)
875 int cl_xa::inst_RRC(uint code, int operands)
879 int cl_xa::inst_SETB(uint code, int operands)
881 unsigned short bitAddr = (code&0x03 << 8) + fetch();
882 set_bit (bitAddr, 1);
886 int cl_xa::inst_SEXT(uint code, int operands)
888 bool neg=get_psw()&BIT_N;
889 if (code & 0x0800) { // word op
890 set_reg2(RI_F0, neg ? 0xffff : 0);
892 set_reg1(RI_F0, neg ? 0xff : 0);
897 int cl_xa::inst_SUB(uint code, int operands)
903 #include "inst_gen.cc"
907 int cl_xa::inst_SUBB(uint code, int operands)
913 #include "inst_gen.cc"
917 int cl_xa::inst_TRAP(uint code, int operands)
919 // steal a few opcodes for simulator only putchar() and exit()
920 // functions. Used in SDCC regression testing.
921 switch (code & 0x0f) {
923 // implement a simulator putchar() routine
924 //printf("PUTCHAR-----> %xH\n", reg1(0));
936 int cl_xa::inst_XCH(uint code, int operands)
940 int cl_xa::inst_XOR(uint code, int operands)
946 #include "inst_gen.cc"
950 /* End of xa.src/inst.cc */