aboutsummaryrefslogtreecommitdiff
path: root/vm.c
diff options
context:
space:
mode:
authorJuan J. Martinez <jjm@usebox.net>2023-05-01 21:44:35 +0100
committerJuan J. Martinez <jjm@usebox.net>2023-05-01 21:44:35 +0100
commitef84fb6fcb45a86fce97acda58606a76a937a1da (patch)
treea3e049b858724837cc9ce0106e30c9e1c028ddc6 /vm.c
parentc081dfe226c6e92865cbb97d8e9a2ef86d8c6acb (diff)
downloadtr8vm-ef84fb6fcb45a86fce97acda58606a76a937a1da.tar.gz
tr8vm-ef84fb6fcb45a86fce97acda58606a76a937a1da.zip
Added the VM player using SDL
- Wired basic functionality (fram-buffer, frame interrupt) - Bug fixes in the assembler
Diffstat (limited to 'vm.c')
-rw-r--r--vm.c94
1 files changed, 61 insertions, 33 deletions
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);
}