From ef84fb6fcb45a86fce97acda58606a76a937a1da Mon Sep 17 00:00:00 2001 From: "Juan J. Martinez" Date: Mon, 1 May 2023 21:44:35 +0100 Subject: Added the VM player using SDL - Wired basic functionality (fram-buffer, frame interrupt) - Bug fixes in the assembler --- vm.c | 94 ++++++++++++++++++++++++++++++++++++++++++++------------------------ 1 file changed, 61 insertions(+), 33 deletions(-) (limited to 'vm.c') diff --git a/vm.c b/vm.c index b9785ef..7d91eb8 100644 --- a/vm.c +++ b/vm.c @@ -81,7 +81,7 @@ static void dump(Tr8 *vm) fprintf(stderr, " PC 0x%04x: ", vm->pc); for (i = 0; i < 16 && i + vm->pc < UINT16_MAX + 1; i++) - fprintf(stderr, "0x%02x ", vm->ram[vm->pc + i]); + fprintf(stderr, "0x%02x ", vm->read_m(vm->pc + i)); fprintf(stderr, "\n"); fprintf(stderr, " SP 0x%04x: ", vm->sp); @@ -90,7 +90,7 @@ static void dump(Tr8 *vm) else { for (i = 0; i < 16 && i + vm->sp < UINT16_MAX + 1; i++) - fprintf(stderr, "0x%02x ", vm->ram[vm->sp + i]); + fprintf(stderr, "0x%02x ", vm->read_m(vm->sp + i)); } fprintf(stderr, "\n"); @@ -113,11 +113,27 @@ static void dump(Tr8 *vm) fprintf(stderr, "****\n"); } -void tr8_init(Tr8 *vm, uint8_t *ram) +void tr8_init(Tr8 *vm, void (*write_m)(uint16_t, uint8_t), uint8_t (*read_m)(uint16_t)) { memset(vm, 0, sizeof(Tr8)); + vm->write_m = write_m; + vm->read_m = read_m; vm->f = IF; - vm->ram = ram; +} + +uint8_t tr8_frame_int(Tr8 *vm) +{ + if (vm->f & IF) + return 1; + + vm->write_m(--vm->sp, vm->pc & 0xff); + vm->write_m(--vm->sp, vm->pc >> 8); + vm->write_m(--vm->sp, vm->f); + vm->pc = vm->read_m(FRAME_INT_VECT) | (vm->read_m(FRAME_INT_VECT + 1) << 8); + vm->f = IF; + vm->intr = 1; + + return tr8_eval(vm); } uint8_t tr8_eval(Tr8 *vm) @@ -129,7 +145,7 @@ uint8_t tr8_eval(Tr8 *vm) for (;;) { /* each instruction is 16-bit */ - instr = vm->ram[vm->pc] | (vm->ram[vm->pc + 1] << 8); + instr = vm->read_m(vm->pc) | (vm->read_m(vm->pc + 1) << 8); vm->pc += 2; /* if the branch flag is set, we skip this instruction */ @@ -157,12 +173,12 @@ uint8_t tr8_eval(Tr8 *vm) { if (vm->f & IF) { - fprintf(stderr, "*HALT*\n"); + fprintf(stderr, "*HALT with IF*\n"); vm->pc -= 2; dump(vm); - return 1; + return 0; } - return 0; + return 1; } /* PORT r1, r3 */ vm->regs[R1(instr)] = port(vm->regs[R1(instr)], vm->regs[R3(instr)]); @@ -172,16 +188,21 @@ uint8_t tr8_eval(Tr8 *vm) if (FHL(instr)) { /* IRET */ - vm->pc = vm->ram[vm->sp + 1] | (vm->ram[vm->sp] << 8); + vm->f = vm->read_m(vm->sp++); + vm->pc = vm->read_m(vm->sp + 1) | (vm->read_m(vm->sp) << 8); vm->sp += 2; - vm->f |= (~IF); + if (vm->intr) + { + vm->intr = 0; + return 1; + } } else { if (FL(instr)) { /* RET */ - vm->pc = vm->ram[vm->sp + 1] | (vm->ram[vm->sp] << 8); + vm->pc = vm->read_m(vm->sp + 1) | (vm->read_m(vm->sp) << 8); vm->sp += 2; } } @@ -202,10 +223,10 @@ uint8_t tr8_eval(Tr8 *vm) case 2: if (FL(instr)) /* LD [r1:r2], r3 */ - vm->ram[ADDR(vm->regs[R1(instr)], vm->regs[R2(instr)])] = vm->regs[R3(instr)]; + vm->write_m(ADDR(vm->regs[R1(instr)], vm->regs[R2(instr)]), vm->regs[R3(instr)]); else /* LD r3, [r1:r2] */ - vm->regs[R3(instr)] = vm->ram[ADDR(vm->regs[R1(instr)], vm->regs[R2(instr)])]; + vm->regs[R3(instr)] = vm->read_m(ADDR(vm->regs[R1(instr)], vm->regs[R2(instr)])); break; case 3: @@ -213,10 +234,10 @@ uint8_t tr8_eval(Tr8 *vm) { if (FHL(instr)) /* PUSH F */ - vm->ram[--vm->sp] = vm->f; + vm->write_m(--vm->sp, vm->f); else /* POP F */ - vm->f = vm->ram[vm->sp++]; + vm->f = vm->read_m(vm->sp++); } else { @@ -231,10 +252,10 @@ uint8_t tr8_eval(Tr8 *vm) { if (FHL(instr)) /* PUSH r1 */ - vm->ram[--vm->sp] = vm->regs[R1(instr)]; + vm->write_m(--vm->sp, vm->regs[R1(instr)]); else /* POP r1 */ - vm->regs[R1(instr)] = vm->ram[vm->sp++]; + vm->regs[R1(instr)] = vm->read_m(vm->sp++); } } break; @@ -338,12 +359,12 @@ uint8_t tr8_eval(Tr8 *vm) { if (FHH(instr)) /* JMP [vm->pc] */ - vm->pc = vm->ram[vm->pc] | (vm->ram[vm->pc + 1] << 8); + vm->pc = vm->read_m(vm->pc) | (vm->read_m(vm->pc + 1) << 8); else { /* JMP [r1:r3] */ uint8_t addr = ADDR(vm->regs[R1(instr)], vm->regs[R3(instr)]); - vm->pc = vm->ram[addr] | (vm->ram[addr + 1] << 8); + vm->pc = vm->read_m(addr) | (vm->read_m(addr + 1) << 8); } } else @@ -351,19 +372,19 @@ uint8_t tr8_eval(Tr8 *vm) if (FHH(instr)) { /* CALL [vm->pc] */ - vm->ram[--vm->sp] = (vm->pc + 2) & 0xff; - vm->ram[--vm->sp] = (vm->pc + 2) >> 8; - vm->pc = vm->ram[vm->pc] | (vm->ram[vm->pc + 1] << 8); + vm->write_m(--vm->sp, (vm->pc + 2) & 0xff); + vm->write_m(--vm->sp, (vm->pc + 2) >> 8); + vm->pc = vm->read_m(vm->pc) | (vm->read_m(vm->pc + 1) << 8); } else { /* CALL [r1:r3] */ uint16_t addr = ADDR(vm->regs[R1(instr)], vm->regs[R3(instr)]); - vm->ram[--vm->sp] = vm->pc & 0xff; - vm->ram[--vm->sp] = vm->pc >> 8; + vm->write_m(--vm->sp, vm->pc & 0xff); + vm->write_m(--vm->sp, vm->pc >> 8); - vm->pc = vm->ram[addr] | (vm->ram[addr + 1] << 8); + vm->pc = vm->read_m(addr) | (vm->read_m(addr + 1) << 8); } } break; @@ -401,18 +422,18 @@ uint8_t tr8_eval(Tr8 *vm) vm->f |= IF; else /* CIF */ - /* TODO: not in an interrupt */ - vm->f &= (~IF); + if (!vm->intr) + vm->f &= (~IF); } break; case 12: if (FHH(instr)) /* LD [SP + imm], r1 */ - vm->ram[vm->sp + IMM(instr)] = vm->regs[R1(instr)]; + vm->write_m(vm->sp + IMM(instr), vm->regs[R1(instr)]); else /* LD r1, [SP + imm] */ - vm->regs[R1(instr)] = vm->ram[vm->sp + IMM(instr)]; + vm->regs[R1(instr)] = vm->read_m(vm->sp + IMM(instr)); break; case 13: @@ -443,16 +464,23 @@ uint8_t tr8_eval(Tr8 *vm) } if (vm->icnt == INSTR_PER_FRAME) - { - dump(vm); return 1; - } } } #ifdef DO_MAIN uint8_t ram[UINT16_MAX + 1] = { 0 }; +void write_m(uint16_t addr, uint8_t b) +{ + ram[addr] = b; +} + +uint8_t read_m(uint16_t addr) +{ + return ram[addr]; +} + int main(int argc, char *argv[]) { FILE *fd; @@ -489,7 +517,7 @@ int main(int argc, char *argv[]) } fclose(fd); - tr8_init(&vm, ram); + tr8_init(&vm, write_m, read_m); return tr8_eval(&vm); } -- cgit v1.2.3