jb302@39: #include jb302@39: #include jb302@39: jb302@39: #define MAIN jb302@39: #include "mem.h" jb302@39: #include "iset.h" jb302@39: jb302@39: /* fill instruction table jb302@39: * MCS-51 - this needs to be stored in code memory */ jb302@39: jb302@39: FUNCTION_TABLE const code iset = { jb302@39: NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, jb302@39: SET, CLR, SET, CLR, SET, CLR, CPL, CPL, jb302@39: XCSD, SFA, LAF, MOV, MOV, MOV, MOV, MOV, jb302@39: MOV, MOV, MOV, MOV, MOV, MOV, MOV, MOV, jb302@39: MOV, MOV, MOV, MOV, MOV, MOV, MOV, MOV, jb302@39: MOV, MOV, MOV, MOV, MOV, MOV, MOV, MOV, jb302@39: MOV, MOV, MOV, MOV, MOV, MOV, MOV, MOV, jb302@39: MOV, MOV, MOV, MOV, MOV, MOV, MOV, MOV, jb302@39: MOV, MOV, MOV, MOV, MOV, MOV, MOV, MOV, jb302@39: MOV, MOV, MOV, MOV, MOV, MOV, MOV, MOV, jb302@39: MOV, MOV, MOV, MOV, MOV, MOV, MOV, MOV, jb302@39: MOV, MOV, MOV, MOV, MOV, MOV, MOV, MOV, jb302@39: MOV, MOV, MOV, MOV, MOV, MOV, MOV, MOV, jb302@39: MOV, MOV, MOV, MOV, MOV, MOV, MOV, MOV, jb302@39: MOV, MOV, MOV, MOV, MOV, MOV, MOV, MOV, jb302@39: MOV, MOV, MOV, MOV, MOV, MOV, MOV, MOV, jb302@39: ANL, ANL, ANL, ANL, ANL, ANL, ANL, ANL, jb302@39: ORL, ORL, ORL, ORL, ORL, ORL, ORL, ORL, jb302@39: XRL, XRL, XRL, XRL, XRL, XRL, XRL, XRL, jb302@39: RL, RLC, RR, RRC, INC, DEC, INC, DEC, jb302@39: ADD, ADD, ADD, ADD, ADD, ADD, ADD, ADD, jb302@39: ADDC, ADDC, ADDC, ADDC, ADDC, ADDC, ADDC, ADDC, jb302@39: SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, jb302@39: SUBB, SUBB, SUBB, SUBB, SUBB, SUBB, SUBB, SUBB, jb302@39: PJMP, PJMP, PJMP, PJMP, PJMP, PJMP, PJMP, PJMP, jb302@39: PCALL, PCALL, PCALL, PCALL, PCALL, PCALL, PCALL, PCALL, jb302@39: DJNZ, DJNZ, DJNZ, DJNZ, CJNE, CJNE, CJNE, CJNE, jb302@39: LJMP, LCALL, RET, RETI, SJMP, JMP, JMP, CJNE, jb302@39: JZ, JNZ, JC, JNC, JPO, JPE, JS, JNS, jb302@39: PUSH, PUSH, PUSH, PUSH, PUSH, PUSH, PUSH, PUSH, jb302@39: POP, POP, POP, POP, POP, POP, POP, POP, jb302@39: MUL, DIV, DA, NOP, IN, OUT, INT, HLT jb302@39: }; jb302@39: jb302@39: BYTE pause; /* becomes 1 when we hit a break point in run mode */ jb302@39: BYTE free_run; /* free run if not 0 */ jb302@39: BYTE pause; /* pause flag */ jb302@39: WIDE addrc; /* address counter */ jb302@39: BYTE args[4]; /* dbg args */ jb302@39: jb302@39: WIDE bp[8] = { 0xFFFF, jb302@39: 0xFFFF, jb302@39: 0xFFFF, jb302@39: 0xFFFF, jb302@39: 0xFFFF, jb302@39: 0xFFFF, jb302@39: 0xFFFF, jb302@39: 0xFFFF jb302@39: }; jb302@39: jb302@39: jb302@39: void jb302@39: snd(BYTE c) { jb302@39: putchar(c); jb302@39: } jb302@39: jb302@39: BYTE jb302@39: rcv(void) { jb302@39: return getchar(); jb302@39: } jb302@39: jb302@39: void jb302@39: step(void) { jb302@39: IR = fetch(); jb302@39: iset.ops[IR](); jb302@39: } jb302@39: jb302@39: void jb302@39: run(void) { jb302@39: while (pause != 1) { jb302@39: step(); jb302@39: for (addrc = 0; addrc < 8; addrc++) { jb302@39: if (bp[addrc] == get_wide(PC)) { jb302@39: pause = 1; jb302@39: } jb302@39: } jb302@39: } jb302@39: } jb302@39: jb302@39: void controller() { jb302@39: if (free_run == 0) { jb302@39: switch (rcv()) { jb302@39: jb302@39: /* step */ jb302@39: case 0x00: jb302@39: step(); jb302@39: break; jb302@39: jb302@39: /* run for length steps*/ jb302@39: case 0x01: jb302@39: run(); jb302@39: break; jb302@39: jb302@39: /* set reg */ jb302@39: case 0x02: jb302@39: args[0] = rcv(); /* reg */ jb302@39: args[1] = rcv(); /* val */ jb302@39: regs[args[0]] = args[1]; jb302@39: break; jb302@39: jb302@39: /* get reg */ jb302@39: case 0x03: jb302@39: args[0] = rcv(); /* reg */ jb302@39: snd(regs[args[0]]); jb302@39: break; jb302@39: jb302@39: /* set flag */ jb302@39: case 0x04: jb302@39: args[0] = rcv(); /* flag */ jb302@39: args[1] = rcv(); /* on? */ jb302@39: set_flag(args[0], args[1]); jb302@39: break; jb302@39: jb302@39: /* get flag */ jb302@39: case 0x05: jb302@39: args[0] = rcv(); /* flag */ jb302@39: snd(get_flag(args[0])); jb302@39: break; jb302@39: jb302@39: /* write mem block */ jb302@39: case 0x06: jb302@39: args[0] = rcv(); /* addr high */ jb302@39: args[1] = rcv(); /* addr low */ jb302@39: args[2] = rcv(); /* length high */ jb302@39: args[3] = rcv(); /* length low */ jb302@39: tmpw = MWIDE(args[0], args[1]); jb302@39: for (addrc = tmpw; addrc < tmpw + MWIDE(args[2], args[3]); addrc++) { jb302@39: if (addrc >= 0xFFFF) { jb302@39: break; jb302@39: } jb302@39: mem[addrc] = rcv(); jb302@39: } jb302@39: break; jb302@39: jb302@39: /* read mem block */ jb302@39: case 0x07: jb302@39: args[0] = rcv(); /* addr high */ jb302@39: args[1] = rcv(); /* addr low */ jb302@39: args[2] = rcv(); /* length high */ jb302@39: args[3] = rcv(); /* length low */ jb302@39: tmpw = MWIDE(args[0], args[1]); jb302@39: for (addrc = tmpw; addrc < tmpw + MWIDE(args[2], args[3]); addrc++) { jb302@39: if (addrc >= 0xFFFF) { jb302@39: break; jb302@39: } jb302@39: snd(mem[addrc]); jb302@39: } jb302@39: break; jb302@39: jb302@39: /* get A */ jb302@39: case 0x08: jb302@39: snd(A); jb302@39: break; jb302@39: jb302@39: /* get flags */ jb302@39: case 0x09: jb302@39: snd(flags); jb302@39: break; jb302@39: jb302@39: /* get instruction register */ jb302@39: case 0x0A: jb302@39: snd(IR); jb302@39: break; jb302@39: jb302@39: /* run for length */ jb302@39: case 0x0B: jb302@39: args[0] = rcv(); /* length high */ jb302@39: args[1] = rcv(); /* length low */ jb302@39: for (tmpw = 0 ; tmpw < MWIDE(args[0], args[1]) ; tmpw++) { jb302@39: step(); jb302@39: } jb302@39: break; jb302@39: jb302@39: case 0x0C: jb302@39: free_run = 1; jb302@39: break; jb302@39: jb302@39: /* set break point */ jb302@39: case 0x0D: jb302@39: args[0] = rcv(); /* bp index */ jb302@39: args[1] = rcv(); /* address high */ jb302@39: args[2] = rcv(); /* address low */ jb302@39: if (args[0] > 7) { jb302@39: break; jb302@39: } jb302@39: bp[args[0]] = MWIDE(args[1], args[2]); jb302@39: break; jb302@39: jb302@39: /* test cmd */ jb302@39: case 0x54: jb302@39: snd('A'); jb302@39: break; jb302@39: } jb302@39: } jb302@39: else { jb302@39: step(); jb302@39: } jb302@39: } jb302@39: jb302@39: void jb302@39: main(void) { jb302@39: /* serial set up jb302@39: * SCON - mode 1, 8-bit UART, enable rcvr jb302@39: * TMOD - timer 1, mode 2, 8-bit reload jb302@39: * TH1 - reload value for 1200 baud @ 12MHz jb302@39: * TR1 - timer 1 run jb302@39: * TI - set TI to send first char of UART */ jb302@39: /* dont go into free run on restart */ jb302@39: free_run = 0; jb302@39: SCON = 0x50; jb302@39: TMOD |= 0x20; jb302@39: TH1 = 0xE8; jb302@39: TR1 = 1; jb302@39: TI = 1; jb302@39: for (;;) { jb302@39: controller(); jb302@39: } jb302@39: } jb302@39: