Mercurial > hg > ede
view emulator/iset.c @ 27:a542cd390efd
long overdue update
author | james <jb302@eecs.qmul.ac.uk> |
---|---|
date | Wed, 02 Apr 2014 14:11:50 +0100 |
parents | 256d24488e3f |
children |
line wrap: on
line source
/* iset.c * op functions */ #include <stdlib.h> #include "iset.h" #include "mem.h" /* useful macros */ #define BANK (registers.flags & 0x01) #define CARRY ((registers.flags & 0x08) >> 3) #define NNN (op & 0x07) #define MMM ((op & 0x38) >> 3) /* temp registers for various instructions */ /* 0x00 - NOP */ void NOP(void) { } /* 0x08 - SET C * 0x0A - SET BS * 0x0C - SET IE */ void SET(void) { switch (op) { case 0x08: registers.flags = registers.flags | 0x80; break; case 0x0A: registers.flags = registers.flags | 0x01; break; case 0x0C: registers.flags = registers.flags | 0x02; break; default: break; } } /* 0x09 - CLR C * 0x0B - CLR BS * 0x0D - CLR IE */ void CLR(void) { switch (op) { case 0x09: registers.flags = registers.flags & 0xF7; break; case 0x0B: registers.flags = registers.flags & 0xFE; break; case 0x0D: registers.flags = registers.flags & 0xFD; break; default: break; } } /* 0x0E - CPL C * 0x0F - CPL A */ void CPL(void) { switch (op) { case 0x0E: if (CARRY) { registers.flags = registers.flags | 0x80; } else { registers.flags = registers.flags & 0xF7; } break; case 0x0F: registers.A = ~registers.A; break; default: break; } } /* 0x10 - XCSD */ void XCSD(void) { tmpw = get_SP(); set_SP(get_DPTR()); set_DPTR(tmpw); } /* 0x11 - SFA */ void SFA(void) { registers.A = registers.flags; } /* 0x12 - LAF */ void LAF(void) { registers.flags = registers.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 (op & 0x40) { case 0x00: switch (op & 0xF8) { /* 0b00010XXX */ case 0x10: switch (NNN) { /* MOV DPTR, SP */ case 3: set_DPTR(get_SP()); break; /* MOV SP, DPTR */ case 4: set_SP(get_DPTR()); break; /* MOV A, #data8 */ case 5: PC++; registers.A = fetch(); break; /* MOV SP, #data16 */ case 6: PC++; set_SP(fetch_wide()); PC++; break; /* MOV DPTR, #data16 */ case 7: PC++; set_DPTR(fetch_wide()); PC++; break; default: break; } break; /* 0b00011XXX */ case 0x18: switch (NNN) { /* MOV A, addr16 */ case 0: PC++; registers.A = memory[fetch_wide()]; PC++; break; /* MOV addr16, A */ case 1: PC++; memory[fetch_wide()] = registers.A; PC++; break; /* MOV A, @A+DPTR */ case 2: registers.A = memory[registers.A + get_DPTR()]; break; /* MOV A, @A+PC */ case 3: registers.A = memory[registers.A + PC]; break; /* MOV A, @addr16 */ case 4: PC++; registers.A = memory[memory[fetch_wide()]]; PC++; break; /* MOV @addr16, A */ case 5: PC++; memory[memory[fetch_wide()]] = registers.A; PC++; break; /* MOV A, @DPTR */ case 6: registers.A = memory[get_DPTR()]; break; /* MOV @DPTR, A */ case 7: memory[get_DPTR()] = registers.A; break; default: break; } break; /* 0b00100nnn */ case 0x20: memory[get_DPTR()] = get_R(NNN, BANK); break; /* 0b00101nnn */ case 0x28: /* store immediate data in op */ PC++; set_R(NNN, BANK, fetch()); break; /* 0b00110nnn */ case 0x30: set_R(NNN, BANK, registers.A); break; /* 0b00111nnn */ case 0x38: registers.A = get_R(NNN, BANK); break; default: break; } break; /* 0b01mmmnnn */ case 0x40: /* if mmm == nnn: MOV Rm, @DPTR */ if (MMM == NNN) { set_R(NNN, BANK, memory[get_DPTR()]); } /* else: MOV Rm, Rn */ else { set_R(MMM, BANK, get_R(NNN, BANK)); } break; default: break; } } void ANL(void) { /* 0x80 - ANL A, R0 * 0x81 - ANL A, R1 * 0x82 - ANL A, R2 * 0x83 - ANL A, R3 * 0x84 - ANL A, DPH * 0x85 - ANL A, DPL */ if (NNN <= 5) { registers.A = registers.A & get_R(NNN, BANK); } else { switch (NNN) { /* 0x86 - ANL A, #data8 */ case 6: PC++; registers.A = registers.A & fetch(); break; /* 0x87 - ANL A, @DPTR */ case 7: registers.A = registers.A & memory[get_DPTR()]; default: break; } } } void ORL(void) { /* 0x88 - ORL A, R0 * 0x89 - ORL A, R1 * 0x8A - ORL A, R2 * 0x8B - ORL A, R3 * 0x8C - ORL A, DPH * 0x8D - ORL A, DPL */ if (NNN <= 5) { registers.A = registers.A | get_R(NNN, BANK); } else { switch (NNN) { /* 0x8E - ORL A, #data8 */ case 6: PC++; registers.A = registers.A | fetch(); break; /* 0x8F - ORL A, @DPTR */ case 7: registers.A = registers.A | memory[get_DPTR()]; default: break; } } } void XRL(void) { /* 0x90 - XRL A, R0 * 0x91 - XRL A, R1 * 0x92 - XRL A, R2 * 0x93 - XRL A, R3 * 0x94 - XRL A, DPH * 0x95 - XRL A, DPL */ if (NNN <= 5) { registers.A = registers.A ^ get_R(NNN, BANK); } else { switch (NNN) { /* 0x96 - XRL A, #data8 */ case 6: PC++; registers.A = registers.A ^ fetch(); break; /* 0x97 - XRL A, @DPTR */ case 7: registers.A = registers.A ^ memory[get_DPTR()]; default: break; } } } /* 0x98 - RL A */ void RL(void) { registers.A = (registers.A << 1) | (registers.A >> 7); } /* 0x99 - RLC A */ void RLC(void) { /* implement me */ } /* 0x9A - RR A */ void RR(void) { registers.A = (registers.A >> 1) | (registers.A << 7); } /* 0x9B - RRC A */ void RRC(void) { /* implement me */ } /* 0x9C - INC DPTR * 0x9E - INC A */ void INC(void) { switch (op) { case 0x9C: tmpw = get_DPTR(); set_DPTR(tmpw + 1); break; case 0x9E: registers.A++; break; default: break; } } /* 0x9D - DEC DPTR * 0x9F - DEC A */ void DEC(void) { switch (op) { case 0x9D: tmpw = get_DPTR(); set_DPTR(tmpw - 1); break; case 0x9F: registers.A--; break; default: break; } } void ADD(void) { /* 0xA0 - ADD A, R0 * 0xA1 - ADD A, R1 * 0xA2 - ADD A, R2 * 0xA3 - ADD A, R3 * 0xA4 - ADD A, DPH * 0xA5 - ADD A, DPL */ if (NNN <= 5) { registers.A = registers.A + get_R(NNN, BANK); } else { switch (NNN) { /* 0xA6 - ADD A, #data8 */ case 6: PC++; registers.A = registers.A + fetch(); break; /* 0xA7 - ADD A, @DPTR */ case 7: registers.A = registers.A + memory[get_DPTR()]; default: break; } } } void ADDC(void) { /* implement me */ } void SUB(void) { /* 0xB0 - SUB A, R0 * 0xB1 - SUB A, R1 * 0xB2 - SUB A, R2 * 0xB3 - SUB A, R3 * 0xB4 - SUB A, DPH * 0xB5 - SUB A, DPL */ if (NNN <= 5) { registers.A = registers.A - get_R(NNN, BANK); } else { switch (NNN) { /* 0xB6 - SUB A, #data8 */ case 6: PC++; registers.A = registers.A - fetch(); break; /* 0xB7 - SUB A, @DPTR */ case 7: registers.A = registers.A - memory[get_DPTR()]; default: 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) { /* decrement reg */ tmpb = get_R(op & 0x03, BANK); tmpb--; set_R(op & 0x03, BANK, tmpb); /* jump if not zero */ PC++; if (tmpb != 0) { tmpb = fetch(); PC = PC + (signed char)tmpb - 1; } } void CJNE(void) { /* fetch data */ PC++; tmpb = fetch(); PC++; /* 0xD4 - CJNE R0, data8, rel8 * 0xD5 - CJNE R1, data8, rel8 * 0xD6 - CJNE R2, data8, rel8 * 0xD7 - CJNE R3, data8, rel8 */ if ((op & 0x0F) <= 7) { /* jump if not equal to reg */ if (tmpb != get_R(op & 0x03, BANK)) { tmpb = fetch(); PC = PC + (signed char)tmpb -1; } } /* 0xDF - CJNE A, data8, rel8 */ else if ((op & 0x0F) == 0x0F) { /* jump if not equal to A */ if (tmpb != registers.A) { tmpb = fetch(); PC = PC + (signed char)tmpb -1; } } } /* 0xD8 - LJMP addr16 */ void LJMP(void) { PC++; PC = fetch_wide() - 1; } void LCALL(void) { /* implement me */ } void RET(void) { /* implement me */ } void RETI(void) { /* implement me */ } /* 0xDC - SJMP rel8 */ void SJMP(void) { PC++; tmpb = fetch(); PC = PC + (signed char)tmpb - 1; } /* 0xDD - JMP @A+DPTR * 0xDE - JMP @DPTR */ void JMP(void) { switch (op) { case 0xDD: PC = registers.A + get_DPTR() - 1; break; case 0xDE: PC = get_DPTR() - 1; break; default: break; } } 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) { exit(0); }