Mercurial > hg > ede
view emu/iset.c @ 30:c0c2e99b6bb0
fixed negative rel8 address bug in assembler
author | james <jb302@eecs.qmul.ac.uk> |
---|---|
date | Tue, 15 Apr 2014 12:21:22 +0100 |
parents | 83e80c2c489c |
children | 7a35e6ae1c36 |
line wrap: on
line source
/* iset.c * IR functions */ #include <stdlib.h> #include "iset.h" #include "mem.h" /* useful macros */ #define NNN (IR & 0x07) #define MMM ((IR & 0x38) >> 3) /* 0x00 - NOP */ void NOP(void) { } /* 0x08 - SET C * 0x0A - SET BS * 0x0C - SET IE */ void SET(void) { switch (IR) { case 0x08: set_flag(C, 0x01); break; case 0x0A: set_flag(BS, 0x01); break; case 0x0C: set_flag(IE, 0x01); break; default: break; } } /* 0x09 - CLR C * 0x0B - CLR BS * 0x0D - CLR IE */ void CLR(void) { switch (IR) { case 0x09: set_flag(C, 0x00); break; case 0x0B: set_flag(BS, 0x00); break; case 0x0D: set_flag(IE, 0x00); break; default: break; } } /* 0x0E - CPL C * 0x0F - CPL A */ void CPL(void) { switch (IR) { case 0x0E: if (get_flag(C) == 0) { set_flag(C, 0x01); } else { set_flag(C, 0x00); } case 0x0F: A = ~A; break; default: break; } } /* 0x10 - XCSD */ void XCSD(void) { tmpw = get_wide(SP); set_wide(SP, get_wide(DPTR)); set_wide(DPTR, tmpw); } /* 0x11 - SFA */ void SFA(void) { A = flags; } /* 0x12 - LAF */ void LAF(void) { flags = A; } /* 0b00010XXX - special MOVs * 0b00011XXX - direct, indirect and indexed MOVs * 0b00100nnn - register-indirect MOVs - MOV @DPTR, Rn * 0b00101nnn - immediate movs - MOV Rn, #data8 * 0b00110nnn - MOV Rn, A * 0b00111nnn - MOV A, Rn * 0b01mmmnnn - 64 register move instructions * * this is a mess */ void MOV(void) { switch (IR & 0x40) { case 0x00: switch (IR & 0xF8) { /* 0b00010XXX - special MOVs*/ case 0x10: switch (NNN) { /* MOV DPTR, SP */ case 3: set_wide(DPTR, get_wide(SP)); break; /* MOV SP, DPTR */ case 4: set_wide(SP, get_wide(DPTR)); break; /* MOV A, #data8 */ case 5: A = fetch(); break; /* MOV SP, #data16 */ case 6: set_wide(SP, fetch_wide()); break; /* MOV DPTR, #data16 */ case 7: set_wide(DPTR, fetch_wide()); break; default: break; } break; /* 0b00011XXX - direct, indirect and indexed MOVs*/ case 0x18: switch (NNN) { /* MOV A, addr16 */ case 0: set_wide(TMP, fetch_wide()); A = mem[get_wide(TMP)]; break; /* MOV addr16, A */ case 1: set_wide(TMP, fetch_wide()); mem[get_wide(TMP)] = A; break; /* MOV A, @A+DPTR */ case 2: set_wide(TMP, A + get_wide(DPTR)); A = mem[get_wide(TMP)]; break; /* MOV A, @A+PC */ case 3: set_wide(TMP, A + get_wide(PC)); A = mem[TMP]; break; /* MOV A, @addr16 */ case 4: set_wide(TMP, fetch_wide()); A = mem[mem[get_wide(TMP)]]; break; /* MOV @addr16, A */ case 5: set_wide(TMP, fetch_wide()); mem[mem[get_wide(TMP)]] = A; break; /* MOV A, @DPTR */ case 6: set_wide(TMP, get_wide(DPTR)); A = mem[get_wide(TMP)]; break; /* MOV @DPTR, A */ case 7: set_wide(TMP, get_wide(DPTR)); mem[get_wide(TMP)] = A; break; default: break; } break; /* 0b00100nnn - MOV @DPTR, Rn*/ case 0x20: set_wide(TMP, get_wide(DPTR)); mem[get_wide(TMP)] = get_reg(NNN); break; /* 0b00101nnn - immediate movs - MOV Rn, #data8*/ case 0x28: set_reg(NNN, fetch()); break; /* 0b00110nnn - MOV Rn, A */ case 0x30: set_reg(NNN, A); break; /* 0b00111nnn MOV A, Rn */ case 0x38: A = get_reg(NNN); break; default: break; } break;; /* 0b01mmmnnn MOV Rm Rn * if m == n: MOV Rm, @DPTR */ case 0x40: if (NNN == MMM) { set_wide(TMP, get_wide(DPTR)); set_reg(NNN, mem[get_wide(TMP)]); } else { set_reg(MMM, get_reg(NNN)); } break; default: break; } } /* 0x80 - ANL A, R0 * 0x81 - ANL A, R1 * 0x82 - ANL A, R2 * 0x83 - ANL A, R3 * 0x84 - ANL A, DPH * 0x85 - ANL A, DPL * 0x86 - ANL A, #data8 * 0x87 - ANL A, @DPTR */ void ANL(void) { if (NNN < 6) { A = A & get_reg(NNN); } else { switch (NNN) { case 6: A = A & fetch(); break; case 7: set_wide(TMP, get_wide(DPTR)); A = A & mem[TMP]; break; } } set_zp(A); } /* 0x88 - ORL A, R0 * 0x89 - ORL A, R1 * 0x8A - ORL A, R2 * 0x8B - ORL A, R3 * 0x8C - ORL A, DPH * 0x8D - ORL A, DPL * 0x8E - ORL A, #data8 * 0x8F - ORL A, @DPTR */ void ORL(void) { if (NNN < 6) { A = A | get_reg(NNN); } else { switch (NNN) { case 6: A = A | fetch(); break; case 7: set_wide(TMP, get_wide(DPTR)); A = A | mem[TMP]; break; } } set_zp(A); } /* 0x90 - XRL A, R0 * 0x91 - XRL A, R1 * 0x92 - XRL A, R2 * 0x93 - XRL A, R3 * 0x94 - XRL A, DPH * 0x95 - XRL A, DPL * 0x96 - XRL A, #data8 * 0x97 - XRL A, @DPTR */ void XRL(void) { if (NNN < 6) { A = A ^ get_reg(NNN); } else { switch (NNN) { case 6: A = A ^ fetch(); break; case 7: set_wide(TMP, get_wide(DPTR)); A = A ^ mem[TMP]; break; } } set_zp(A); } /* 0x98 - RL A */ void RL(void) { A = (A << 1) | (A >> 7); } /* 0x99 - RLC A */ void RLC(void) { tmpb = A; A = (A << 1) | get_flag(C); set_flag(C, tmpb >> 7); } /* 0x9A - RR A */ void RR(void) { A = (A >> 1) | (A << 7); } /* 0x9B - RRC A */ void RRC(void) { tmpb = A; A = (A >> 1) | (get_flag(C) << 7); set_flag(C, tmpb & 0x01); } /* 0x9C - INC DPTR * 0x9E - INC A */ void INC(void) { switch (IR) { case 0x9C: tmpw = get_wide(DPTR); if ((tmpw + 1) > 0xFFFF) { set_flag(OV, 1); } set_wide(DPTR, tmpw + 1); set_zp(DPL); set_zp(DPH); break; case 0x9E: if ((A + 1) > 0xFF) { set_flag(OV, 1); } A++; set_zp(A); } } /* 0x9D - DEC DPTR * 0x9F - DEC A */ void DEC(void) { switch (IR) { case 0x9D: tmpw = get_wide(DPTR); if ((tmpw - 1) < 0) { set_flag(OV, 1); } set_wide(DPTR, tmpw - 1); set_zp(DPL); set_zp(DPH); case 0x9F: if ((A - 1) < 0) { set_flag(OV, 1); } A--; set_zp(A); } } /* 0xA0 - ADD A, R0 * 0xA1 - ADD A, R1 * 0xA2 - ADD A, R2 * 0xA3 - ADD A, R3 * 0xA4 - ADD A, DPH * 0xA5 - ADD A, DPL * 0xA6 - ADD A, #data8 * 0xA7 - ADD A, @DPTR */ void ADD(void) { if (NNN < 6) { if ((A + get_reg(NNN)) > 0xFF){ } A = A + get_reg(NNN); set_zp(A); } else { switch (NNN) { case 6: A = A + fetch(); set_zp(A); break; case 7: set_wide(TMP, get_wide(DPTR)); A = A + mem[TMP]; set_zp(A); break; } } } void ADDC(void) { /* implement me */ } /* 0xB0 - SUB A, R0 * 0xB1 - SUB A, R1 * 0xB2 - SUB A, R2 * 0xB3 - SUB A, R3 * 0xB4 - SUB A, DPH * 0xB5 - SUB A, DPL * 0xB6 - SUB A, #data8 * 0xB7 - SUB A, @DPTR */ void SUB(void) { if (NNN < 6) { A = A - get_reg(NNN); set_zp(A); } else { switch (NNN) { case 6: A = A - fetch(); set_zp(A); break; case 7: set_wide(TMP, get_wide(DPTR)); A = A - mem[TMP]; set_zp(A); break; } } } void SUBB(void) { /* implement me */ } void PJMP(void) { /* implement me */ } void PCALL(void) { /* implement me */ } /* 0xD0 - DJNZ R0, rel8 * 0xD1 - DJNZ R1, rel8 * 0xD2 - DJNZ R2, rel8 * 0xD3 - DJNZ R3, rel8 */ void DJNZ(void) { } void CJNE(void) { } /* 0xD8 - LJMP addr16 */ void LJMP(void) { } void LCALL(void) { /* implement me */ } void RET(void) { /* implement me */ } void RETI(void) { /* implement me */ } /* 0xDC - SJMP rel8 */ void SJMP(void) { set_wide(PC, get_wide(PC) + (signed char)fetch()); } /* 0xDD - JMP @A+DPTR * 0xDE - JMP @DPTR */ void JMP(void) { } void JZ(void) { } void JNZ(void) { } void JC(void) { } void JNC(void) { } void JPO(void) { } void JPE(void) { } void JS(void) { } void JNS(void) { } void PUSH(void) { } void POP(void) { } void MUL(void) { } void DIV(void) { } void DA(void) { } void IN(void) { } void OUT(void) { } void INT(void) { } /* 0xFF - HLT */ void HLT(void) { }