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
|
# 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 "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;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue