works now--learned about extern

This commit is contained in:
Noah Swerhun 2023-08-18 18:50:20 -05:00
parent 09d2db16d9
commit 42b2e0b84e
6 changed files with 52 additions and 38 deletions

View file

@ -1,3 +1,17 @@
# lc3-vm # lc3-vm
Virtual machine based on the LC-3 architecture. Virtual machine based on the LC-3 architecture.
Inspired from this tutorial: https://www.jmeiners.com/lc3-vm/
Sample programs are included in the `samples/` directory.
**Build:**
```
make
```
**Run:**
```
./target/bin/lc3 samples/{sample program here}
```

View file

@ -12,6 +12,9 @@
#include "ops.h" #include "ops.h"
#include "traps.h" #include "traps.h"
u16 memory[MEMORY_MAX];
u16 reg[R_COUNT];
u16 running;
// Helper functions // Helper functions
u16 sign_extend(u16 x, int bit_count) { u16 sign_extend(u16 x, int bit_count) {
@ -98,11 +101,13 @@ u16 mem_read(u16 address) {
if (check_key()) { if (check_key()) {
memory[MR_KBSR] = (1 << 15); memory[MR_KBSR] = (1 << 15);
memory[MR_KBDR] = getchar(); memory[MR_KBDR] = getchar();
} else { }
else {
memory[MR_KBSR] = 0; memory[MR_KBSR] = 0;
} }
} }
return memory[address]; return memory[address];
} }
int main(int argc, char **argv) { int main(int argc, char **argv) {
@ -136,56 +141,49 @@ int main(int argc, char **argv) {
op = instr >> 12; op = instr >> 12;
switch (op) { switch (op) {
case OP_BR:
op_br(instr);
break;
case OP_ADD: case OP_ADD:
op_add(instr); op_add(instr);
break; break;
case OP_LD:
op_ld(instr);
break;
case OP_ST:
op_st(instr);
break;
case OP_JSR:
op_jsr(instr);
break;
case OP_AND: case OP_AND:
op_and(instr); op_and(instr);
break; break;
case OP_LDR:
op_ldr(instr);
break;
case OP_STR:
op_str(instr);
break;
case OP_RTI:
// unused
abort();
break;
case OP_NOT: case OP_NOT:
op_not(instr); op_not(instr);
break; break;
case OP_LDI: case OP_BR:
op_ldr(instr); op_br(instr);
break;
case OP_STI:
op_sti(instr);
break; break;
case OP_JMP: case OP_JMP:
op_jmp(instr); op_jmp(instr);
break; break;
case OP_RES: case OP_JSR:
// unused op_jsr(instr);
abort(); break;
case OP_LD:
op_ld(instr);
break;
case OP_LDI:
op_ldi(instr);
break;
case OP_LDR:
op_ldr(instr);
break; break;
case OP_LEA: case OP_LEA:
op_lea(instr); op_lea(instr);
break; break;
case OP_ST:
op_st(instr);
break;
case OP_STI:
op_sti(instr);
break;
case OP_STR:
op_str(instr);
break;
case OP_TRAP: case OP_TRAP:
reg[R_R7] = reg[R_PC]; reg[R_R7] = reg[R_PC];
switch (instr & 0xFF) { switch (instr & 0xFF)
{
case TRAP_GETC: case TRAP_GETC:
trap_getc(); trap_getc();
break; break;
@ -206,10 +204,12 @@ int main(int argc, char **argv) {
break; break;
} }
break; break;
case OP_RES:
case OP_RTI:
default: default:
// invalid opcode
abort(); abort();
break; break;
} }
} }

View file

@ -39,9 +39,9 @@ enum {
}; };
// Global variables // Global variables
static u16 memory[MEMORY_MAX]; extern u16 memory[MEMORY_MAX];
static u16 reg[R_COUNT]; extern u16 reg[R_COUNT];
static u16 running; extern u16 running;
u16 sign_extend(u16 x, int bit_count); u16 sign_extend(u16 x, int bit_count);
void update_flags(u16 r); void update_flags(u16 r);

View file

@ -28,7 +28,7 @@ void trap_in(void) {
char c = getchar(); char c = getchar();
putc(c, stdout); putc(c, stdout);
fflush(stdout); fflush(stdout);
reg[R_R0] = (uint16_t)c; reg[R_R0] = (u16)c;
update_flags(R_R0); update_flags(R_R0);
} }