jb302@28: /* iset.c jb302@28: * IR functions */ jb302@28: #include jb302@28: #include "iset.h" jb302@28: #include "mem.h" jb302@28: jb302@28: /* useful macros */ jb302@28: #define NNN (IR & 0x07) jb302@28: #define MMM ((IR & 0x38) >> 3) jb302@28: jb302@28: /* 0x00 - NOP */ jb302@28: void jb302@28: NOP(void) { jb302@28: } jb302@28: jb302@28: /* 0x08 - SET C jb302@28: * 0x0A - SET BS jb302@28: * 0x0C - SET IE */ jb302@28: void jb302@28: SET(void) { jb302@28: switch (IR) { jb302@28: jb302@28: case 0x08: jb302@29: set_flag(C, 0x01); jb302@28: break; jb302@28: jb302@28: case 0x0A: jb302@29: set_flag(BS, 0x01); jb302@28: break; jb302@28: jb302@28: case 0x0C: jb302@29: set_flag(IE, 0x01); jb302@28: break; jb302@28: jb302@28: default: jb302@28: break; jb302@28: } jb302@28: } jb302@28: jb302@28: /* 0x09 - CLR C jb302@28: * 0x0B - CLR BS jb302@28: * 0x0D - CLR IE */ jb302@28: void jb302@28: CLR(void) { jb302@28: switch (IR) { jb302@28: jb302@28: case 0x09: jb302@29: set_flag(C, 0x00); jb302@28: break; jb302@28: jb302@28: case 0x0B: jb302@29: set_flag(BS, 0x00); jb302@28: break; jb302@28: jb302@28: case 0x0D: jb302@29: set_flag(IE, 0x00); jb302@28: break; jb302@28: jb302@28: default: jb302@28: break; jb302@28: } jb302@28: } jb302@28: jb302@28: /* 0x0E - CPL C jb302@28: * 0x0F - CPL A */ jb302@28: void jb302@28: CPL(void) { jb302@28: switch (IR) { jb302@28: jb302@28: case 0x0E: jb302@29: if (get_flag(C) == 0) { jb302@29: set_flag(C, 0x01); jb302@28: } jb302@28: else { jb302@29: set_flag(C, 0x00); jb302@28: } jb302@28: jb302@28: case 0x0F: jb302@28: A = ~A; jb302@28: break; jb302@28: jb302@28: default: jb302@28: break; jb302@28: } jb302@28: } jb302@28: jb302@28: /* 0x10 - XCSD */ jb302@28: void jb302@28: XCSD(void) { jb302@28: tmpw = get_wide(SP); jb302@28: set_wide(SP, get_wide(DPTR)); jb302@28: set_wide(DPTR, tmpw); jb302@28: } jb302@28: jb302@28: /* 0x11 - SFA */ jb302@28: void jb302@28: SFA(void) { jb302@28: A = flags; jb302@28: } jb302@28: jb302@28: /* 0x12 - LAF */ jb302@28: void jb302@28: LAF(void) { jb302@28: flags = A; jb302@28: } jb302@28: jb302@28: /* 0b00010XXX - special MOVs jb302@28: * 0b00011XXX - direct, indirect and indexed MOVs jb302@28: * 0b00100nnn - register-indirect MOVs - MOV @DPTR, Rn jb302@28: * 0b00101nnn - immediate movs - MOV Rn, #data8 jb302@28: * 0b00110nnn - MOV Rn, A jb302@28: * 0b00111nnn - MOV A, Rn jb302@28: * 0b01mmmnnn - 64 register move instructions jb302@28: * jb302@28: * this is a mess */ jb302@28: void jb302@28: MOV(void) { jb302@28: switch (IR & 0x40) { jb302@28: jb302@28: case 0x00: jb302@28: switch (IR & 0xF8) { jb302@28: jb302@29: /* 0b00010XXX - special MOVs*/ jb302@28: case 0x10: jb302@28: switch (NNN) { jb302@28: jb302@28: /* MOV DPTR, SP */ jb302@28: case 3: jb302@28: set_wide(DPTR, get_wide(SP)); jb302@28: break; jb302@28: jb302@28: /* MOV SP, DPTR */ jb302@28: case 4: jb302@28: set_wide(SP, get_wide(DPTR)); jb302@28: break; jb302@28: jb302@28: /* MOV A, #data8 */ jb302@28: case 5: jb302@28: A = fetch(); jb302@28: break; jb302@28: jb302@28: /* MOV SP, #data16 */ jb302@28: case 6: jb302@28: set_wide(SP, fetch_wide()); jb302@28: break; jb302@28: jb302@28: /* MOV DPTR, #data16 */ jb302@28: case 7: jb302@28: set_wide(DPTR, fetch_wide()); jb302@28: break; jb302@28: jb302@28: default: jb302@28: break; jb302@28: } jb302@28: break; jb302@28: jb302@29: /* 0b00011XXX - direct, indirect and indexed MOVs*/ jb302@28: case 0x18: jb302@28: switch (NNN) { jb302@28: jb302@28: /* MOV A, addr16 */ jb302@28: case 0: jb302@28: set_wide(TMP, fetch_wide()); jb302@28: A = mem[get_wide(TMP)]; jb302@28: break; jb302@28: jb302@28: /* MOV addr16, A */ jb302@28: case 1: jb302@28: set_wide(TMP, fetch_wide()); jb302@28: mem[get_wide(TMP)] = A; jb302@28: break; jb302@28: jb302@28: /* MOV A, @A+DPTR */ jb302@28: case 2: jb302@29: set_wide(TMP, A + get_wide(DPTR)); jb302@29: A = mem[get_wide(TMP)]; jb302@28: break; jb302@28: jb302@28: /* MOV A, @A+PC */ jb302@28: case 3: jb302@29: set_wide(TMP, A + get_wide(PC)); jb302@29: A = mem[TMP]; jb302@28: break; jb302@28: jb302@28: /* MOV A, @addr16 */ jb302@28: case 4: jb302@28: set_wide(TMP, fetch_wide()); jb302@28: A = mem[mem[get_wide(TMP)]]; jb302@28: break; jb302@28: jb302@28: /* MOV @addr16, A */ jb302@28: case 5: jb302@28: set_wide(TMP, fetch_wide()); jb302@28: mem[mem[get_wide(TMP)]] = A; jb302@28: break; jb302@28: jb302@28: /* MOV A, @DPTR */ jb302@28: case 6: jb302@29: set_wide(TMP, get_wide(DPTR)); jb302@29: A = mem[get_wide(TMP)]; jb302@28: break; jb302@28: jb302@28: /* MOV @DPTR, A */ jb302@28: case 7: jb302@29: set_wide(TMP, get_wide(DPTR)); jb302@29: mem[get_wide(TMP)] = A; jb302@28: break; jb302@28: jb302@28: default: jb302@28: break; jb302@28: } jb302@28: break; jb302@28: jb302@29: /* 0b00100nnn - MOV @DPTR, Rn*/ jb302@28: case 0x20: jb302@29: set_wide(TMP, get_wide(DPTR)); jb302@30: mem[get_wide(TMP)] = get_reg(NNN); jb302@28: break; jb302@28: jb302@29: /* 0b00101nnn - immediate movs - MOV Rn, #data8*/ jb302@28: case 0x28: jb302@29: set_reg(NNN, fetch()); jb302@28: break; jb302@28: jb302@29: /* 0b00110nnn - MOV Rn, A */ jb302@28: case 0x30: jb302@29: set_reg(NNN, A); jb302@28: break; jb302@28: jb302@30: /* 0b00111nnn MOV A, Rn */ jb302@28: case 0x38: jb302@29: A = get_reg(NNN); jb302@28: break; jb302@28: jb302@28: default: jb302@28: break; jb302@28: } jb302@29: break;; jb302@28: jb302@30: /* 0b01mmmnnn MOV Rm Rn jb302@30: * if m == n: MOV Rm, @DPTR */ jb302@28: case 0x40: jb302@29: if (NNN == MMM) { jb302@29: set_wide(TMP, get_wide(DPTR)); jb302@29: set_reg(NNN, mem[get_wide(TMP)]); jb302@29: } jb302@29: else { jb302@29: set_reg(MMM, get_reg(NNN)); jb302@29: } jb302@28: break; jb302@28: jb302@28: default: jb302@28: break; jb302@28: } jb302@28: } jb302@28: jb302@30: jb302@30: /* 0x80 - ANL A, R0 jb302@30: * 0x81 - ANL A, R1 jb302@30: * 0x82 - ANL A, R2 jb302@30: * 0x83 - ANL A, R3 jb302@30: * 0x84 - ANL A, DPH jb302@30: * 0x85 - ANL A, DPL jb302@30: * 0x86 - ANL A, #data8 jb302@30: * 0x87 - ANL A, @DPTR */ jb302@28: void jb302@28: ANL(void) { jb302@30: if (NNN < 6) { jb302@30: A = A & get_reg(NNN); jb302@30: } jb302@30: else { jb302@30: switch (NNN) { jb302@30: jb302@30: case 6: jb302@30: A = A & fetch(); jb302@30: break; jb302@30: jb302@30: case 7: jb302@30: set_wide(TMP, get_wide(DPTR)); jb302@30: A = A & mem[TMP]; jb302@30: break; jb302@30: } jb302@30: } jb302@30: set_zp(A); jb302@28: } jb302@28: jb302@30: /* 0x88 - ORL A, R0 jb302@30: * 0x89 - ORL A, R1 jb302@30: * 0x8A - ORL A, R2 jb302@30: * 0x8B - ORL A, R3 jb302@30: * 0x8C - ORL A, DPH jb302@30: * 0x8D - ORL A, DPL jb302@30: * 0x8E - ORL A, #data8 jb302@30: * 0x8F - ORL A, @DPTR */ jb302@28: void jb302@28: ORL(void) { jb302@30: if (NNN < 6) { jb302@30: A = A | get_reg(NNN); jb302@30: } jb302@30: else { jb302@30: switch (NNN) { jb302@30: jb302@30: case 6: jb302@30: A = A | fetch(); jb302@30: break; jb302@30: jb302@30: case 7: jb302@30: set_wide(TMP, get_wide(DPTR)); jb302@30: A = A | mem[TMP]; jb302@30: break; jb302@30: } jb302@30: } jb302@30: set_zp(A); jb302@28: } jb302@28: jb302@30: /* 0x90 - XRL A, R0 jb302@30: * 0x91 - XRL A, R1 jb302@30: * 0x92 - XRL A, R2 jb302@30: * 0x93 - XRL A, R3 jb302@30: * 0x94 - XRL A, DPH jb302@30: * 0x95 - XRL A, DPL jb302@30: * 0x96 - XRL A, #data8 jb302@30: * 0x97 - XRL A, @DPTR */ jb302@28: void jb302@28: XRL(void) { jb302@30: if (NNN < 6) { jb302@30: A = A ^ get_reg(NNN); jb302@30: } jb302@30: else { jb302@30: switch (NNN) { jb302@30: jb302@30: case 6: jb302@30: A = A ^ fetch(); jb302@30: break; jb302@28: jb302@30: case 7: jb302@30: set_wide(TMP, get_wide(DPTR)); jb302@30: A = A ^ mem[TMP]; jb302@30: break; jb302@30: } jb302@30: } jb302@30: set_zp(A); jb302@28: } jb302@28: jb302@28: /* 0x98 - RL A */ jb302@28: void jb302@28: RL(void) { jb302@28: A = (A << 1) | (A >> 7); jb302@28: } jb302@28: jb302@28: /* 0x99 - RLC A */ jb302@28: void jb302@28: RLC(void) { jb302@30: tmpb = A; jb302@30: A = (A << 1) | get_flag(C); jb302@30: set_flag(C, tmpb >> 7); jb302@28: } jb302@28: jb302@28: /* 0x9A - RR A */ jb302@28: void jb302@28: RR(void) { jb302@28: A = (A >> 1) | (A << 7); jb302@28: } jb302@28: jb302@28: /* 0x9B - RRC A */ jb302@28: void jb302@28: RRC(void) { jb302@30: tmpb = A; jb302@30: A = (A >> 1) | (get_flag(C) << 7); jb302@30: set_flag(C, tmpb & 0x01); jb302@28: } jb302@28: jb302@28: /* 0x9C - INC DPTR jb302@28: * 0x9E - INC A */ jb302@28: void jb302@30: INC(void) { jb302@30: switch (IR) { jb302@30: jb302@30: case 0x9C: jb302@30: tmpw = get_wide(DPTR); jb302@30: if ((tmpw + 1) > 0xFFFF) { jb302@30: set_flag(OV, 1); jb302@30: } jb302@30: set_wide(DPTR, tmpw + 1); jb302@30: set_zp(DPL); jb302@30: set_zp(DPH); jb302@30: break; jb302@30: jb302@30: case 0x9E: jb302@30: if ((A + 1) > 0xFF) { jb302@30: set_flag(OV, 1); jb302@30: } jb302@30: A++; jb302@30: set_zp(A); jb302@30: jb302@30: } jb302@28: } jb302@28: jb302@28: /* 0x9D - DEC DPTR jb302@28: * 0x9F - DEC A */ jb302@28: void jb302@28: DEC(void) { jb302@30: switch (IR) { jb302@30: jb302@30: case 0x9D: jb302@30: tmpw = get_wide(DPTR); jb302@30: if ((tmpw - 1) < 0) { jb302@30: set_flag(OV, 1); jb302@30: } jb302@30: set_wide(DPTR, tmpw - 1); jb302@30: set_zp(DPL); jb302@30: set_zp(DPH); jb302@30: jb302@30: case 0x9F: jb302@30: if ((A - 1) < 0) { jb302@30: set_flag(OV, 1); jb302@30: } jb302@30: A--; jb302@30: set_zp(A); jb302@30: } jb302@28: } jb302@28: jb302@30: /* 0xA0 - ADD A, R0 jb302@30: * 0xA1 - ADD A, R1 jb302@30: * 0xA2 - ADD A, R2 jb302@30: * 0xA3 - ADD A, R3 jb302@30: * 0xA4 - ADD A, DPH jb302@30: * 0xA5 - ADD A, DPL jb302@30: * 0xA6 - ADD A, #data8 jb302@30: * 0xA7 - ADD A, @DPTR */ jb302@28: void jb302@28: ADD(void) { jb302@30: if (NNN < 6) { jb302@31: if ((A + get_reg(NNN)) > 0xFF) { jb302@31: set_flag(OV, 1); jb302@31: } jb302@31: else { jb302@31: set_flag(OV, 0); jb302@30: } jb302@30: A = A + get_reg(NNN); jb302@30: set_zp(A); jb302@30: } jb302@30: else { jb302@30: switch (NNN) { jb302@30: jb302@30: case 6: jb302@31: tmpb = fetch(); jb302@31: if ((A + tmpb) > 0xFF) { jb302@31: set_flag(OV, 1); jb302@31: } jb302@31: else { jb302@31: set_flag(OV, 0); jb302@31: } jb302@31: A = A + tmpb; jb302@30: set_zp(A); jb302@30: break; jb302@30: jb302@30: case 7: jb302@30: set_wide(TMP, get_wide(DPTR)); jb302@31: if ((A + mem[TMP]) > 0xFF) { jb302@31: set_flag(OV, 1); jb302@31: } jb302@31: else { jb302@31: set_flag(OV, 0); jb302@31: } jb302@30: A = A + mem[TMP]; jb302@30: set_zp(A); jb302@30: break; jb302@30: } jb302@30: } jb302@30: jb302@28: } jb302@28: jb302@35: /* 0xA8 - ADDC A, R0 jb302@35: * 0xA9 - ADDC A, R1 jb302@35: * 0xAA - ADDC A, R2 jb302@35: * 0xAB - ADDC A, R3 jb302@35: * 0xAC - ADDC A, DPH jb302@35: * 0xAD - ADDC A, DPL jb302@35: * 0xAE - ADDC A, #data8 jb302@35: * 0xAF - ADDC A, @DPTR */ jb302@28: void jb302@28: ADDC(void) { jb302@35: if (NNN < 6) { jb302@35: if ((A + get_reg(NNN) + get_flag(C)) > 0xFF) { jb302@35: set_flag(C, 1); jb302@35: } jb302@35: else { jb302@35: set_flag(C, 0); jb302@35: } jb302@35: A = A + get_reg(NNN) + get_flag(C); jb302@35: set_zp(A); jb302@35: } jb302@35: else { jb302@35: switch (NNN) { jb302@35: jb302@35: case 6: jb302@35: tmpb = fetch(); jb302@35: if ((A + tmpb + get_flag(C)) > 0xFF) { jb302@35: set_flag(C, 1); jb302@35: } jb302@35: else { jb302@35: set_flag(C, 0); jb302@35: } jb302@35: A = A + tmpb + get_flag(C); jb302@35: set_zp(A); jb302@35: break; jb302@35: jb302@35: case 7: jb302@35: set_wide(TMP, get_wide(DPTR)); jb302@35: if ((A + mem[TMP] + get_flag(C)) > 0xFF) { jb302@35: set_flag(C, 1); jb302@35: } jb302@35: else { jb302@35: set_flag(C, 0); jb302@35: } jb302@35: A = A + mem[TMP] + get_flag(C); jb302@35: set_zp(A); jb302@35: break; jb302@35: } jb302@35: } jb302@35: jb302@35: jb302@28: } jb302@28: jb302@30: /* 0xB0 - SUB A, R0 jb302@30: * 0xB1 - SUB A, R1 jb302@30: * 0xB2 - SUB A, R2 jb302@30: * 0xB3 - SUB A, R3 jb302@35: * 0xB4 - SB A, DPH jb302@30: * 0xB5 - SUB A, DPL jb302@30: * 0xB6 - SUB A, #data8 jb302@30: * 0xB7 - SUB A, @DPTR */ jb302@28: void jb302@28: SUB(void) { jb302@30: if (NNN < 6) { jb302@31: if ((A - get_reg(NNN)) < 0){ jb302@34: set_flag(S, 1); jb302@31: } jb302@31: else { jb302@34: set_flag(S, 0); jb302@31: } jb302@30: A = A - get_reg(NNN); jb302@30: set_zp(A); jb302@30: } jb302@30: else { jb302@30: switch (NNN) { jb302@30: jb302@30: case 6: jb302@31: tmpb = fetch(); jb302@31: if ((A - tmpb) < 0) { jb302@34: set_flag(S, 1); jb302@31: } jb302@31: else { jb302@34: set_flag(S, 0); jb302@31: } jb302@31: A = A - tmpb; jb302@30: set_zp(A); jb302@30: break; jb302@30: jb302@30: case 7: jb302@30: set_wide(TMP, get_wide(DPTR)); jb302@31: if ((A - mem[TMP]) < 0) { jb302@34: set_flag(S, 1); jb302@31: } jb302@31: else { jb302@34: set_flag(S, 0); jb302@31: } jb302@30: A = A - mem[TMP]; jb302@30: set_zp(A); jb302@30: break; jb302@30: } jb302@30: } jb302@28: } jb302@28: jb302@35: /* 0xB8 - SUBB A, R0 jb302@35: * 0xB9 - SUBB A, R1 jb302@35: * 0xBA - SUBB A, R2 jb302@35: * 0xBB - SUBB A, R3 jb302@35: * 0xBC - SUBB A, DPH jb302@35: * 0xBD - SUBB A, DPL jb302@35: * 0xBE - SUBB A, #data8 jb302@35: * 0xBF - SUBB A, @DPTR */ jb302@28: void jb302@28: SUBB(void) { jb302@35: if (NNN < 6) { jb302@35: if ((A - get_reg(NNN) - get_flag(C)) < 0){ jb302@35: set_flag(C, 1); jb302@35: } jb302@35: else { jb302@35: set_flag(C, 0); jb302@35: } jb302@35: A = A - get_reg(NNN) -get_flag(C); jb302@35: set_zp(A); jb302@35: } jb302@35: else { jb302@35: switch (NNN) { jb302@35: jb302@35: case 6: jb302@35: tmpb = fetch(); jb302@35: if ((A - tmpb - get_flag(C)) < 0) { jb302@35: set_flag(C, 1); jb302@35: } jb302@35: else { jb302@35: set_flag(C, 0); jb302@35: } jb302@35: A = A - tmpb - get_flag(C); jb302@35: set_zp(A); jb302@35: break; jb302@35: jb302@35: case 7: jb302@35: set_wide(TMP, get_wide(DPTR)); jb302@35: if ((A - mem[TMP] - get_flag(C)) < 0) { jb302@35: set_flag(C, 1); jb302@35: } jb302@35: else { jb302@35: set_flag(C, 0); jb302@35: } jb302@35: A = A - mem[TMP] - get_flag(C); jb302@35: set_zp(A); jb302@35: break; jb302@35: } jb302@35: } jb302@28: } jb302@28: jb302@28: void jb302@28: PJMP(void) { jb302@28: /* implement me */ jb302@28: } jb302@28: jb302@28: void jb302@28: PCALL(void) { jb302@28: /* implement me */ jb302@28: } jb302@28: jb302@28: /* 0xD0 - DJNZ R0, rel8 jb302@28: * 0xD1 - DJNZ R1, rel8 jb302@28: * 0xD2 - DJNZ R2, rel8 jb302@28: * 0xD3 - DJNZ R3, rel8 */ jb302@28: void jb302@28: DJNZ(void) { jb302@35: set_reg(NNN, get_reg(NNN) - 1); jb302@35: if (get_reg(NNN) == 0) { jb302@35: set_wide(PC, get_wide(PC) + (signed char)fetch() - 1); jb302@35: } jb302@35: else { jb302@35: inc_pc(1); jb302@35: } jb302@28: } jb302@28: jb302@35: /* 0xD4 - CJNE R0, #data, rel8 jb302@35: * 0xD5 - CJNE R1, #data, rel8 jb302@35: * 0xD6 - CJNE R2, #data, rel8 jb302@35: * 0xD7 - CJNE R3, #data, rel8 jb302@35: * 0xDF - CJNE A, #data8, rel8 */ jb302@28: void jb302@28: CJNE(void) { jb302@35: switch(IR) { jb302@35: jb302@35: case 0xDF: jb302@35: tmpb = fetch(); jb302@35: if (tmpb != A) { jb302@35: set_wide(PC, get_wide(PC) + (signed char)fetch() - 1); jb302@35: } jb302@35: else { jb302@35: inc_pc(1); jb302@35: } jb302@35: break; jb302@35: jb302@35: jb302@35: default: jb302@35: tmpb = fetch(); jb302@35: if (tmpb != get_reg(NNN - 4)) { jb302@35: set_wide(PC, get_wide(PC) + (signed char)fetch() - 1); jb302@35: } jb302@35: else { jb302@35: inc_pc(1); jb302@35: } jb302@35: break; jb302@35: } jb302@28: } jb302@28: jb302@28: /* 0xD8 - LJMP addr16 */ jb302@28: void jb302@28: LJMP(void) { jb302@35: set_wide(PC, fetch_wide()); jb302@28: } jb302@28: jb302@35: /* 0xD9 - LCALL addr16 */ jb302@28: void jb302@28: LCALL(void) { jb302@35: /* push PC to stack */ jb302@35: mem[get_wide(SP)] = get_reg(PCL); jb302@35: set_wide(SP, get_wide(SP) + 1); jb302@35: mem[get_wide(SP)] = get_reg(PCH); jb302@35: set_wide(SP, get_wide(SP) + 1); jb302@35: /* jmp */ jb302@35: set_wide(PC, fetch_wide()); jb302@28: } jb302@28: jb302@35: /* 0xDA - RET */ jb302@28: void jb302@28: RET(void) { jb302@35: /* get PC from stack */ jb302@35: set_wide(SP, get_wide(SP) - 1); jb302@35: tmpb = mem[get_wide(SP)]; /* PCH */ jb302@35: set_wide(SP, get_wide(SP) - 1); jb302@35: set_wide(PC, MWIDE(tmpb, mem[get_wide(SP)])); jb302@28: } jb302@28: jb302@28: void jb302@28: RETI(void) { jb302@28: /* implement me */ jb302@28: } jb302@28: jb302@28: /* 0xDC - SJMP rel8 */ jb302@28: void jb302@28: SJMP(void) { jb302@34: /* -1 because the fetch() increments the PC */ jb302@34: set_wide(PC, get_wide(PC) + (signed char)fetch() -1); jb302@28: } jb302@28: jb302@28: /* 0xDD - JMP @A+DPTR jb302@28: * 0xDE - JMP @DPTR */ jb302@28: void jb302@28: JMP(void) { jb302@34: switch(IR) { jb302@34: jb302@34: case 0xDD: jb302@34: set_wide(PC, A + get_wide(DPTR)); jb302@34: break; jb302@34: jb302@34: case 0xDE: jb302@34: set_wide(PC, get_wide(DPTR)); jb302@34: break; jb302@34: } jb302@28: } jb302@28: jb302@34: /* 0xE0 - JZ rel8 */ jb302@28: void jb302@34: JZ(void) { jb302@34: if (get_flag(Z) == 1) { jb302@34: set_wide(PC, get_wide(PC) + (signed char)fetch() -1); jb302@34: } jb302@34: /* skip rel8 if jump not needed */ jb302@34: else { jb302@34: inc_pc(1); jb302@34: } jb302@28: } jb302@28: jb302@34: /* 0xE1 - JNZ rel8 */ jb302@28: void jb302@28: JNZ(void) { jb302@34: if (get_flag(Z) == 0) { jb302@34: set_wide(PC, get_wide(PC) + (signed char)fetch() -1); jb302@34: } jb302@34: else { jb302@34: inc_pc(1); jb302@34: } jb302@28: } jb302@28: jb302@34: /* 0xE2 - JC rel8 */ jb302@28: void jb302@34: JC(void) { jb302@34: if (get_flag(C) == 1) { jb302@34: set_wide(PC, get_wide(PC) + (signed char)fetch() -1); jb302@34: } jb302@34: else { jb302@34: inc_pc(1); jb302@34: } jb302@28: } jb302@28: jb302@34: /* 0xE3 - JNC rel8 */ jb302@28: void jb302@34: JNC(void) { jb302@34: if (get_flag(C) == 0) { jb302@34: set_wide(PC, get_wide(PC) + (signed char)fetch() -1); jb302@34: } jb302@34: else { jb302@34: inc_pc(1); jb302@34: } jb302@28: } jb302@28: jb302@34: /* 0xE4 - JPO rel8 */ jb302@28: void jb302@34: JPO(void) { jb302@34: /* P = 1 when parity even */ jb302@34: if (get_flag(P) == 0) { jb302@34: set_wide(PC, get_wide(PC) + (signed char)fetch() -1); jb302@34: } jb302@34: else { jb302@34: inc_pc(1); jb302@34: } jb302@34: jb302@28: } jb302@28: jb302@34: /* 0xE5 - JPE rel8 */ jb302@28: void jb302@28: JPE(void) { jb302@34: if (get_flag(P) == 1) { jb302@34: set_wide(PC, get_wide(PC) + (signed char)fetch() -1); jb302@34: } jb302@34: else { jb302@34: inc_pc(1); jb302@34: } jb302@28: } jb302@28: jb302@34: /* 0xE6 - JS rel8 */ jb302@28: void jb302@34: JS(void) { jb302@34: if (get_flag(S) == 1) { jb302@34: set_wide(PC, get_wide(PC) + (signed char)fetch() -1); jb302@34: } jb302@34: else { jb302@34: inc_pc(1); jb302@34: } jb302@28: } jb302@28: jb302@34: /* 0xE7 - JNS rel8 */ jb302@28: void jb302@28: JNS(void) { jb302@34: if (get_flag(S) == 0) { jb302@34: set_wide(PC, get_wide(PC) + (signed char)fetch() -1); jb302@34: } jb302@34: else { jb302@34: inc_pc(1); jb302@34: } jb302@28: } jb302@28: jb302@35: /* 0xE8 - PUSH R0 jb302@35: * 0xE9 - PUSH R1 jb302@35: * 0xEA - PUSH R2 jb302@35: * 0xEB - PUSH R3 jb302@35: * 0xEC - PUSH DPH jb302@35: * 0xED - PUSH DPL jb302@35: * 0xEE - PUSH A jb302@35: * 0xEF - PUSH FLAGS */ jb302@28: void jb302@28: PUSH(void) { jb302@35: if (NNN < 6) { jb302@35: mem[get_wide(SP)] = get_reg(NNN); jb302@35: set_wide(SP, get_wide(SP) + 1); jb302@35: jb302@35: } jb302@35: else { jb302@35: switch(IR) { jb302@35: jb302@35: case 0xEE: jb302@35: mem[get_wide(SP)] = A; jb302@35: set_wide(SP, get_wide(SP) + 1); jb302@35: break; jb302@35: jb302@35: case 0xEF: jb302@35: mem[get_wide(SP)] = flags; jb302@35: set_wide(SP, get_wide(SP) + 1); jb302@35: break; jb302@35: jb302@35: default: jb302@35: break; jb302@35: } jb302@35: } jb302@28: } jb302@28: jb302@35: /* 0xF0 - POP R0 jb302@35: * 0xF1 - POP R1 jb302@35: * 0xF2 - POP R2 jb302@35: * 0xF3 - POP R3 jb302@35: * 0xF4 - POP DPH jb302@35: * 0xF5 - POP DPL jb302@35: * 0xF6 - POP A jb302@35: * 0xF7 - POP FLAGS */ jb302@28: void jb302@35: POP(void) { jb302@35: if (NNN < 6) { jb302@35: set_wide(SP, get_wide(SP) - 1); jb302@35: set_reg(NNN, mem[get_wide(SP)]); jb302@35: } jb302@35: else { jb302@35: switch(IR) { jb302@35: jb302@35: case 0xF6: jb302@35: set_wide(SP, get_wide(SP) - 1); jb302@35: A = mem[get_wide(SP)]; jb302@35: break; jb302@35: jb302@35: case 0xF7: jb302@35: set_wide(SP, get_wide(SP) - 1); jb302@35: flags = mem[get_wide(SP)]; jb302@35: break; jb302@35: jb302@35: default: jb302@35: break; jb302@35: } jb302@35: } jb302@28: } jb302@28: jb302@35: jb302@35: /* 0xF8 - MUL R0, R1 */ jb302@28: void jb302@35: MUL(void) { jb302@42: tmpw = regs[R0] * regs[R1]; jb302@42: regs[R0] = GHIGH(tmpw); jb302@42: regs[R1] = GLOW(tmpw); jb302@28: } jb302@28: jb302@35: /* 0xF9 - DIV R0, R1 */ jb302@28: void jb302@35: DIV(void) { jb302@42: tmpw = regs[R0] / regs[R1]; jb302@42: regs[R0] = GHIGH(tmpw); jb302@42: regs[R1] = GLOW(tmpw); jb302@28: } jb302@28: jb302@35: /* 0xFA - DA A */ jb302@28: void jb302@35: DA(void) { jb302@42: if (((A & 0xF) > 9) | get_flag(AC) == 1) { jb302@42: A = A + 6; jb302@42: } jb302@42: if (((A & 0xF0) > 9) | get_flag(C) == 1) { jb302@42: A = A + 0x60; jb302@42: } jb302@28: } jb302@28: jb302@35: /* 0xFC - IN port_addr */ jb302@28: void jb302@35: IN(void) { jb302@35: /* implement me */ jb302@28: } jb302@28: jb302@35: /* 0xFD - OUT port_addr */ jb302@28: void jb302@28: OUT(void) { jb302@35: /* implement me */ jb302@28: } jb302@28: jb302@35: /* 0xFE INT vect8 */ jb302@28: void jb302@35: INT(void) { jb302@35: /* implement me */ jb302@28: } jb302@28: jb302@28: /* 0xFF - HLT */ jb302@28: void jb302@28: HLT(void) { jb302@42: exit(0); jb302@28: }