works now--learned about extern
This commit is contained in:
parent
09d2db16d9
commit
42b2e0b84e
6 changed files with 52 additions and 38 deletions
16
README.md
16
README.md
|
@ -1,3 +1,17 @@
|
|||
# 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}
|
||||
```
|
||||
|
|
66
src/main.c
66
src/main.c
|
@ -12,6 +12,9 @@
|
|||
#include "ops.h"
|
||||
#include "traps.h"
|
||||
|
||||
u16 memory[MEMORY_MAX];
|
||||
u16 reg[R_COUNT];
|
||||
u16 running;
|
||||
|
||||
// Helper functions
|
||||
u16 sign_extend(u16 x, int bit_count) {
|
||||
|
@ -98,11 +101,13 @@ u16 mem_read(u16 address) {
|
|||
if (check_key()) {
|
||||
memory[MR_KBSR] = (1 << 15);
|
||||
memory[MR_KBDR] = getchar();
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
memory[MR_KBSR] = 0;
|
||||
}
|
||||
}
|
||||
return memory[address];
|
||||
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
|
@ -136,56 +141,49 @@ int main(int argc, char **argv) {
|
|||
op = instr >> 12;
|
||||
|
||||
switch (op) {
|
||||
case OP_BR:
|
||||
op_br(instr);
|
||||
break;
|
||||
case OP_ADD:
|
||||
op_add(instr);
|
||||
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:
|
||||
op_and(instr);
|
||||
break;
|
||||
case OP_LDR:
|
||||
op_ldr(instr);
|
||||
break;
|
||||
case OP_STR:
|
||||
op_str(instr);
|
||||
break;
|
||||
case OP_RTI:
|
||||
// unused
|
||||
abort();
|
||||
break;
|
||||
case OP_NOT:
|
||||
op_not(instr);
|
||||
break;
|
||||
case OP_LDI:
|
||||
op_ldr(instr);
|
||||
break;
|
||||
case OP_STI:
|
||||
op_sti(instr);
|
||||
case OP_BR:
|
||||
op_br(instr);
|
||||
break;
|
||||
case OP_JMP:
|
||||
op_jmp(instr);
|
||||
break;
|
||||
case OP_RES:
|
||||
// unused
|
||||
abort();
|
||||
case OP_JSR:
|
||||
op_jsr(instr);
|
||||
break;
|
||||
case OP_LD:
|
||||
op_ld(instr);
|
||||
break;
|
||||
case OP_LDI:
|
||||
op_ldi(instr);
|
||||
break;
|
||||
case OP_LDR:
|
||||
op_ldr(instr);
|
||||
break;
|
||||
case OP_LEA:
|
||||
op_lea(instr);
|
||||
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:
|
||||
reg[R_R7] = reg[R_PC];
|
||||
switch (instr & 0xFF) {
|
||||
switch (instr & 0xFF)
|
||||
{
|
||||
case TRAP_GETC:
|
||||
trap_getc();
|
||||
break;
|
||||
|
@ -206,10 +204,12 @@ int main(int argc, char **argv) {
|
|||
break;
|
||||
}
|
||||
break;
|
||||
case OP_RES:
|
||||
case OP_RTI:
|
||||
default:
|
||||
// invalid opcode
|
||||
abort();
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -39,9 +39,9 @@ enum {
|
|||
};
|
||||
|
||||
// Global variables
|
||||
static u16 memory[MEMORY_MAX];
|
||||
static u16 reg[R_COUNT];
|
||||
static u16 running;
|
||||
extern u16 memory[MEMORY_MAX];
|
||||
extern u16 reg[R_COUNT];
|
||||
extern u16 running;
|
||||
|
||||
u16 sign_extend(u16 x, int bit_count);
|
||||
void update_flags(u16 r);
|
||||
|
|
|
@ -28,7 +28,7 @@ void trap_in(void) {
|
|||
char c = getchar();
|
||||
putc(c, stdout);
|
||||
fflush(stdout);
|
||||
reg[R_R0] = (uint16_t)c;
|
||||
reg[R_R0] = (u16)c;
|
||||
update_flags(R_R0);
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue