From f7f856d4381e8eae5fd31e095f3d7303ad3039ae Mon Sep 17 00:00:00 2001 From: sean-one Date: Mon, 4 Mar 2019 11:21:02 -0800 Subject: [PATCH 01/18] initial set up --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index e81f54cf..61e1d6ff 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,4 @@ + # Computer Architecture ## Project From 7b9fd6b8eefabc03d3de23e83b13d3c9ee65592c Mon Sep 17 00:00:00 2001 From: sean-one Date: Tue, 5 Mar 2019 12:49:03 -0800 Subject: [PATCH 02/18] finished cpu init --- README.md | 2 +- ls8/cpu.c | 11 +++++++++++ ls8/cpu.h | 3 +++ 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 61e1d6ff..5afa3e40 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ - + # Computer Architecture ## Project diff --git a/ls8/cpu.c b/ls8/cpu.c index bdb1f506..f0e57ee1 100644 --- a/ls8/cpu.c +++ b/ls8/cpu.c @@ -64,4 +64,15 @@ void cpu_run(struct cpu *cpu) void cpu_init(struct cpu *cpu) { // TODO: Initialize the PC and other special registers + // set r0-r6 to clear to 0 + for (int i = 0; i < 7; i++) { + cpu->reg[i] = 0; + } + // set r7 to 0xF4 + cpu->reg[7] = 0xF4; + // set PC to 0 | no flags yet + cpu->PC = 0; + // set ram to 0 + memset(cpu->ram, 0, sizeof cpu->ram); + } diff --git a/ls8/cpu.h b/ls8/cpu.h index 46e49c44..94438735 100644 --- a/ls8/cpu.h +++ b/ls8/cpu.h @@ -5,8 +5,11 @@ struct cpu { // TODO // PC + unsigned char PC; // registers (array) + unsigned char reg[8]; // ram (array) + unsigned char ram[256]; }; // ALU operations From ec65c56de8152e5c3df80368fd5df0ec701e2f7e Mon Sep 17 00:00:00 2001 From: sean-one Date: Tue, 5 Mar 2019 13:13:45 -0800 Subject: [PATCH 03/18] cpu ram read and write --- ls8/cpu.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/ls8/cpu.c b/ls8/cpu.c index f0e57ee1..96c94fff 100644 --- a/ls8/cpu.c +++ b/ls8/cpu.c @@ -26,6 +26,16 @@ void cpu_load(struct cpu *cpu) // TODO: Replace this with something less hard-coded } +// MAR - memory address register | where does is go +// MDR - memory data register | what it is +void cpu_ram_write(struct cpu *cpu, unsigned char mar, unsigned char mdr) { + cpu->ram[mar] = mdr; +} + +unsigned char cpu_ram_read(struct cpu *cpu, unsigned char mar) { + return cpu->ram[mar]; +} + /** * ALU */ From 0c6017acf3b1ead1a982c65dd3928d4f1edf37b9 Mon Sep 17 00:00:00 2001 From: sean-one Date: Tue, 5 Mar 2019 15:37:38 -0800 Subject: [PATCH 04/18] working on running --- ls8/cpu.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/ls8/cpu.c b/ls8/cpu.c index 96c94fff..8669d0cb 100644 --- a/ls8/cpu.c +++ b/ls8/cpu.c @@ -60,10 +60,18 @@ void cpu_run(struct cpu *cpu) while (running) { // TODO // 1. Get the value of the current instruction (in address PC). + unsigned char IR = cpu_ram_read(cpu, cpu->PC); // 2. Figure out how many operands this next instruction requires // 3. Get the appropriate value(s) of the operands following this instruction + unsigned char operand0 = cpu_ram_read(cpu, cpu->PC + 1); + unsigned char operand1 = cpu_ram_read(cpu, cpu->PC + 2); // 4. switch() over it to decide on a course of action. // 5. Do whatever the instruction should do according to the spec. + switch (IR) { + default: + // beej printed IR & cpu->PC + printf("unexpected command") + } // 6. Move the PC to the next instruction. } } From a59bbeef357e333adcd9c461d0e5fc75fd52febb Mon Sep 17 00:00:00 2001 From: sean-one Date: Tue, 5 Mar 2019 16:05:28 -0800 Subject: [PATCH 05/18] tested to see if build worked working on running --- ls8/cpu.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/ls8/cpu.c b/ls8/cpu.c index 8669d0cb..7797b6c7 100644 --- a/ls8/cpu.c +++ b/ls8/cpu.c @@ -1,3 +1,7 @@ +#include +#include +#include + #include "cpu.h" #define DATA_LEN 6 @@ -68,9 +72,12 @@ void cpu_run(struct cpu *cpu) // 4. switch() over it to decide on a course of action. // 5. Do whatever the instruction should do according to the spec. switch (IR) { + // BE SURE CASE IS SAVED AS BINARY LITERALS IN CPU.H FILE + case LDI: default: // beej printed IR & cpu->PC - printf("unexpected command") + printf("unexpected command\n"); + exit(1); } // 6. Move the PC to the next instruction. } From 3a63ed7eb951a988189a67c4404c12b551b97996 Mon Sep 17 00:00:00 2001 From: sean-one Date: Tue, 5 Mar 2019 19:48:41 -0800 Subject: [PATCH 06/18] hardcode print8 works --- ls8/cpu.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/ls8/cpu.c b/ls8/cpu.c index 7797b6c7..eb85a106 100644 --- a/ls8/cpu.c +++ b/ls8/cpu.c @@ -74,6 +74,17 @@ void cpu_run(struct cpu *cpu) switch (IR) { // BE SURE CASE IS SAVED AS BINARY LITERALS IN CPU.H FILE case LDI: + cpu->reg[operand0] = operand1; + cpu->PC += 3; + break; + case PRN: + printf("%d\n", cpu->reg[operand0]); + cpu->PC += 2; + break; + case HLT: + cpu->PC++; + return 0; + default: // beej printed IR & cpu->PC printf("unexpected command\n"); From 2962c840f38f899b85dd0e41ab200a39eb8a60b0 Mon Sep 17 00:00:00 2001 From: sean-one Date: Wed, 6 Mar 2019 00:03:48 -0800 Subject: [PATCH 07/18] prints from static opened file --- ls8/cpu.c | 37 ++++++++++++++++++++++++++++--------- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/ls8/cpu.c b/ls8/cpu.c index eb85a106..fb9fe645 100644 --- a/ls8/cpu.c +++ b/ls8/cpu.c @@ -11,15 +11,34 @@ */ void cpu_load(struct cpu *cpu) { - char data[DATA_LEN] = { - // From print8.ls8 - 0b10000010, // LDI R0,8 - 0b00000000, - 0b00001000, - 0b01000111, // PRN R0 - 0b00000000, - 0b00000001 // HLT - }; + // get the file | will get file path via argument later + // per guided demo + FILE *fp; + char line[1024]; + + char data[DATA_LEN]; + + fp = fopen("./examples/print8.ls8", "r"); + while (fgets(line, sizeof line, fp) != NULL) { + char *endpoint; + unsigned char value; + unsigned char data_index; + + value = strtoul(line, &endpoint, 2); + + if(endpoint == line) { + continue; + } + + else if (value) { + data[data_index] = value; + data_index++; + } + else { + data[data_index] = "0"; + data_index++; + } + } int address = 0; From 9843f0bc3042c9cddc297c7b75564d57e822a80b Mon Sep 17 00:00:00 2001 From: sean-one Date: Wed, 6 Mar 2019 11:44:26 -0800 Subject: [PATCH 08/18] updated dynamic file open --- ls8/cpu.c | 26 +++++++++----------------- ls8/cpu.h | 2 +- ls8/ls8.c | 8 ++++++-- 3 files changed, 16 insertions(+), 20 deletions(-) diff --git a/ls8/cpu.c b/ls8/cpu.c index fb9fe645..01471442 100644 --- a/ls8/cpu.c +++ b/ls8/cpu.c @@ -9,20 +9,23 @@ /** * Load the binary bytes from a .ls8 source file into a RAM array */ -void cpu_load(struct cpu *cpu) +void cpu_load(char *filename, struct cpu *cpu) { // get the file | will get file path via argument later // per guided demo FILE *fp; char line[1024]; - char data[DATA_LEN]; + int address = 0x00; + + if((fp = fopen(filename, "r")) == NULL) { + fprintf(stderr, "Unable to open file %s\n", filename); + exit(2); + } - fp = fopen("./examples/print8.ls8", "r"); while (fgets(line, sizeof line, fp) != NULL) { char *endpoint; unsigned char value; - unsigned char data_index; value = strtoul(line, &endpoint, 2); @@ -30,20 +33,9 @@ void cpu_load(struct cpu *cpu) continue; } - else if (value) { - data[data_index] = value; - data_index++; - } - else { - data[data_index] = "0"; - data_index++; - } - } - - int address = 0; + cpu->ram[address++] = value; - for (int i = 0; i < DATA_LEN; i++) { - cpu->ram[address++] = data[i]; + } // TODO: Replace this with something less hard-coded diff --git a/ls8/cpu.h b/ls8/cpu.h index 94438735..cb50ba73 100644 --- a/ls8/cpu.h +++ b/ls8/cpu.h @@ -30,7 +30,7 @@ enum alu_op { // Function declarations -extern void cpu_load(struct cpu *cpu); +extern void cpu_load(char *filename, struct cpu *cpu); extern void cpu_init(struct cpu *cpu); extern void cpu_run(struct cpu *cpu); diff --git a/ls8/ls8.c b/ls8/ls8.c index d24578ee..520ad696 100644 --- a/ls8/ls8.c +++ b/ls8/ls8.c @@ -4,12 +4,16 @@ /** * Main */ -int main(void) +int main(int argc, char **argv) { struct cpu cpu; + if (argc != 2) { + fprintf(stderr, "correct formatting: ls8 \n"); + return 1; + } cpu_init(&cpu); - cpu_load(&cpu); + cpu_load(argv[1], &cpu); cpu_run(&cpu); return 0; From 6c0fbe4fee81ffdb5c083a0eb4ee6cb04db74a56 Mon Sep 17 00:00:00 2001 From: sean-one Date: Wed, 6 Mar 2019 13:17:58 -0800 Subject: [PATCH 09/18] working on MUL next --- README.md | 20 ++++++++++---------- ls8/cpu.c | 1 - 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 5afa3e40..81cc1999 100644 --- a/README.md +++ b/README.md @@ -8,18 +8,18 @@ ## Task List: add this to the first comment of your Pull Request ### Day 1: Get `print8.ls8` running -- [ ] Inventory what is here -- [ ] Implement `struct cpu` in `cpu.h` -- [ ] Add RAM functions `cpu_ram_read` and `cpu_ram_write` -- [ ] Implement `cpu_init()` -- [ ] Implement the core of `cpu_run()` -- [ ] Implement the `HLT` instruction handler -- [ ] Add the `LDI` instruction -- [ ] Add the `PRN` instruction +- [x] Inventory what is here +- [x] Implement `struct cpu` in `cpu.h` +- [x] Add RAM functions `cpu_ram_read` and `cpu_ram_write` +- [x] Implement `cpu_init()` +- [x] Implement the core of `cpu_run()` +- [x] Implement the `HLT` instruction handler +- [x] Add the `LDI` instruction +- [x] Add the `PRN` instruction ### Day 2: Add the ability to load files dynamically, get `mult.ls8` and `stack.ls8` running -- [ ] Un-hardcode the machine code -- [ ] Implement the `cpu_load` function to load an `.ls8` file given the filename passed in as an argument +- [x] Un-hardcode the machine code +- [x] Implement the `cpu_load` function to load an `.ls8` file given the filename passed in as an argument - [ ] Implement a Multiply instruction and Print the result (run `mult8.ls8`) - [ ] Implement the System Stack and be able to run the `stack.ls8` program diff --git a/ls8/cpu.c b/ls8/cpu.c index 01471442..817f89f0 100644 --- a/ls8/cpu.c +++ b/ls8/cpu.c @@ -35,7 +35,6 @@ void cpu_load(char *filename, struct cpu *cpu) cpu->ram[address++] = value; - } // TODO: Replace this with something less hard-coded From 95de0b2531f61ce0669d34e30312818114b9db3c Mon Sep 17 00:00:00 2001 From: sean-one Date: Wed, 6 Mar 2019 15:10:54 -0800 Subject: [PATCH 10/18] mult finished --- ls8/cpu.c | 11 +++++++++++ ls8/cpu.h | 1 + 2 files changed, 12 insertions(+) diff --git a/ls8/cpu.c b/ls8/cpu.c index 817f89f0..419a96b0 100644 --- a/ls8/cpu.c +++ b/ls8/cpu.c @@ -55,8 +55,15 @@ unsigned char cpu_ram_read(struct cpu *cpu, unsigned char mar) { */ void alu(struct cpu *cpu, enum alu_op op, unsigned char regA, unsigned char regB) { + unsigned char *reg = cpu->reg; + + // assign operands to values + unsigned char valueA = reg[regA]; + unsigned char valueB = reg[regB]; + switch (op) { case ALU_MUL: + reg[regA] *= valueB; // TODO break; @@ -94,6 +101,10 @@ void cpu_run(struct cpu *cpu) case HLT: cpu->PC++; return 0; + case MUL: + alu(cpu, ALU_MUL, operand0, operand1); + cpu->PC += 3; + break; default: // beej printed IR & cpu->PC diff --git a/ls8/cpu.h b/ls8/cpu.h index cb50ba73..ac81ab2b 100644 --- a/ls8/cpu.h +++ b/ls8/cpu.h @@ -26,6 +26,7 @@ enum alu_op { #define LDI 0b10000010 #define HLT 0b00000001 #define PRN 0b01000111 +#define MUL 0b10100010 // TODO: more instructions here. These can be used in cpu_run(). // Function declarations From 3b2332632c0d815fcf5270724114240baff52457 Mon Sep 17 00:00:00 2001 From: sean-one Date: Wed, 6 Mar 2019 15:14:40 -0800 Subject: [PATCH 11/18] working on PUSH & POP --- README.md | 2 +- ls8/cpu.c | 4 ++++ ls8/cpu.h | 2 ++ 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 81cc1999..fea840b3 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ ### Day 2: Add the ability to load files dynamically, get `mult.ls8` and `stack.ls8` running - [x] Un-hardcode the machine code - [x] Implement the `cpu_load` function to load an `.ls8` file given the filename passed in as an argument -- [ ] Implement a Multiply instruction and Print the result (run `mult8.ls8`) +- [x] Implement a Multiply instruction and Print the result (run `mult8.ls8`) - [ ] Implement the System Stack and be able to run the `stack.ls8` program ### Day 3: Get `call.ls8` running diff --git a/ls8/cpu.c b/ls8/cpu.c index 419a96b0..b8415322 100644 --- a/ls8/cpu.c +++ b/ls8/cpu.c @@ -105,6 +105,10 @@ void cpu_run(struct cpu *cpu) alu(cpu, ALU_MUL, operand0, operand1); cpu->PC += 3; break; + case PUSH: + break; + case POP: + break; default: // beej printed IR & cpu->PC diff --git a/ls8/cpu.h b/ls8/cpu.h index ac81ab2b..e6a0c12a 100644 --- a/ls8/cpu.h +++ b/ls8/cpu.h @@ -27,6 +27,8 @@ enum alu_op { #define HLT 0b00000001 #define PRN 0b01000111 #define MUL 0b10100010 +#define PUSH 0b01000101 +#define POP 0b01000110 // TODO: more instructions here. These can be used in cpu_run(). // Function declarations From 59307f1279f8d395f361a9dcc11be664ee87cdbf Mon Sep 17 00:00:00 2001 From: sean-one Date: Wed, 6 Mar 2019 15:50:55 -0800 Subject: [PATCH 12/18] added push and pop functions --- ls8/cpu.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/ls8/cpu.c b/ls8/cpu.c index b8415322..5a59586c 100644 --- a/ls8/cpu.c +++ b/ls8/cpu.c @@ -71,6 +71,17 @@ void alu(struct cpu *cpu, enum alu_op op, unsigned char regA, unsigned char regB } } +void push_to_stack(struct cpu *cpu, int val) { + cpu->reg[7]--; + cpu->ram[cpu->reg[7]] = val; +} + +int pop_from_stack(struct cpu *cpu) { + int val = cpu->ram[cpu->reg[7]]; + cpu->reg[7]++; + return val; +} + /** * Run the CPU */ From 4c23ac24827000b675f837009e7a831e9b27f463 Mon Sep 17 00:00:00 2001 From: sean-one Date: Wed, 6 Mar 2019 18:33:07 -0800 Subject: [PATCH 13/18] finish stack function --- ls8/cpu.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/ls8/cpu.c b/ls8/cpu.c index 5a59586c..2bb7fab8 100644 --- a/ls8/cpu.c +++ b/ls8/cpu.c @@ -76,8 +76,8 @@ void push_to_stack(struct cpu *cpu, int val) { cpu->ram[cpu->reg[7]] = val; } -int pop_from_stack(struct cpu *cpu) { - int val = cpu->ram[cpu->reg[7]]; +unsigned char pop_from_stack(struct cpu *cpu) { + unsigned char val = cpu->ram[cpu->reg[7]]; cpu->reg[7]++; return val; } @@ -117,8 +117,12 @@ void cpu_run(struct cpu *cpu) cpu->PC += 3; break; case PUSH: + push_to_stack(cpu, cpu->reg[operand0]); + cpu->PC += 2; break; case POP: + pop_from_stack(cpu); + cpu->PC += 2; break; default: From d89af1f3162a41ca76be7a5f71ffd0004844bb0b Mon Sep 17 00:00:00 2001 From: sean-one Date: Thu, 7 Mar 2019 12:28:07 -0800 Subject: [PATCH 14/18] starting to work on calls --- README.md | 2 +- ls8/cpu.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index fea840b3..c10efa76 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ - [x] Un-hardcode the machine code - [x] Implement the `cpu_load` function to load an `.ls8` file given the filename passed in as an argument - [x] Implement a Multiply instruction and Print the result (run `mult8.ls8`) -- [ ] Implement the System Stack and be able to run the `stack.ls8` program +- [x] Implement the System Stack and be able to run the `stack.ls8` program ### Day 3: Get `call.ls8` running - [ ] Implement the CALL and RET instructions diff --git a/ls8/cpu.c b/ls8/cpu.c index 2bb7fab8..fb1f1b95 100644 --- a/ls8/cpu.c +++ b/ls8/cpu.c @@ -121,7 +121,7 @@ void cpu_run(struct cpu *cpu) cpu->PC += 2; break; case POP: - pop_from_stack(cpu); + cpu->reg[operand0] = pop_from_stack(cpu); cpu->PC += 2; break; From 37cfd9d7a7f9ee8ba8f4bdcce7110e74fdf65a16 Mon Sep 17 00:00:00 2001 From: sean-one Date: Thu, 7 Mar 2019 14:14:19 -0800 Subject: [PATCH 15/18] alu add finished --- ls8/cpu.c | 8 +++++++- ls8/cpu.h | 4 +++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/ls8/cpu.c b/ls8/cpu.c index fb1f1b95..7e1c0ec0 100644 --- a/ls8/cpu.c +++ b/ls8/cpu.c @@ -64,7 +64,9 @@ void alu(struct cpu *cpu, enum alu_op op, unsigned char regA, unsigned char regB switch (op) { case ALU_MUL: reg[regA] *= valueB; - // TODO + break; + case ALU_ADD: + reg[regA] += valueB; break; // TODO: implement more ALU ops @@ -116,6 +118,10 @@ void cpu_run(struct cpu *cpu) alu(cpu, ALU_MUL, operand0, operand1); cpu->PC += 3; break; + case ADD: + alu(cpu, ALU_ADD, operand0, operand1); + cpu->PC += 3; + break; case PUSH: push_to_stack(cpu, cpu->reg[operand0]); cpu->PC += 2; diff --git a/ls8/cpu.h b/ls8/cpu.h index e6a0c12a..301ce5eb 100644 --- a/ls8/cpu.h +++ b/ls8/cpu.h @@ -14,7 +14,8 @@ struct cpu { // ALU operations enum alu_op { - ALU_MUL + ALU_MUL, + ALU_ADD // Add more here }; @@ -27,6 +28,7 @@ enum alu_op { #define HLT 0b00000001 #define PRN 0b01000111 #define MUL 0b10100010 +#define ADD 0b10100000 #define PUSH 0b01000101 #define POP 0b01000110 // TODO: more instructions here. These can be used in cpu_run(). From 6c3a6c4081c310b6f1e3b4f92c6b25e4479504b8 Mon Sep 17 00:00:00 2001 From: sean-one Date: Thu, 7 Mar 2019 14:29:08 -0800 Subject: [PATCH 16/18] call.ls8 able to run --- ls8/cpu.c | 12 ++++++++++-- ls8/cpu.h | 3 +++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/ls8/cpu.c b/ls8/cpu.c index 7e1c0ec0..ad8677be 100644 --- a/ls8/cpu.c +++ b/ls8/cpu.c @@ -58,7 +58,7 @@ void alu(struct cpu *cpu, enum alu_op op, unsigned char regA, unsigned char regB unsigned char *reg = cpu->reg; // assign operands to values - unsigned char valueA = reg[regA]; + // unsigned char valueA = reg[regA]; // unused variable unsigned char valueB = reg[regB]; switch (op) { @@ -113,7 +113,8 @@ void cpu_run(struct cpu *cpu) break; case HLT: cpu->PC++; - return 0; + exit(1); + // return 0; case MUL: alu(cpu, ALU_MUL, operand0, operand1); cpu->PC += 3; @@ -130,6 +131,13 @@ void cpu_run(struct cpu *cpu) cpu->reg[operand0] = pop_from_stack(cpu); cpu->PC += 2; break; + case CALL: + push_to_stack(cpu, cpu->PC + 2); + cpu->PC = cpu->reg[operand0]; + break; + case RET: + cpu->PC = pop_from_stack(cpu); + break; default: // beej printed IR & cpu->PC diff --git a/ls8/cpu.h b/ls8/cpu.h index 301ce5eb..9a8aa81a 100644 --- a/ls8/cpu.h +++ b/ls8/cpu.h @@ -31,6 +31,9 @@ enum alu_op { #define ADD 0b10100000 #define PUSH 0b01000101 #define POP 0b01000110 +#define CALL 0b01010000 +#define RET 0b00010001 + // TODO: more instructions here. These can be used in cpu_run(). // Function declarations From 9a350223bd06c0aee8996b68eeefa87e933f7c62 Mon Sep 17 00:00:00 2001 From: sean-one Date: Fri, 8 Mar 2019 09:32:14 -0800 Subject: [PATCH 17/18] added sprint files --- README.md | 4 +- ls8/examples/sctest.ls8 | 86 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+), 2 deletions(-) create mode 100644 ls8/examples/sctest.ls8 diff --git a/README.md b/README.md index c10efa76..70b5a14d 100644 --- a/README.md +++ b/README.md @@ -24,8 +24,8 @@ - [x] Implement the System Stack and be able to run the `stack.ls8` program ### Day 3: Get `call.ls8` running -- [ ] Implement the CALL and RET instructions -- [ ] Implement Subroutine Calls and be able to run the `call.ls8` program +- [x] Implement the CALL and RET instructions +- [x] Implement Subroutine Calls and be able to run the `call.ls8` program ### Stretch - [ ] Add the timer interrupt to the LS-8 emulator diff --git a/ls8/examples/sctest.ls8 b/ls8/examples/sctest.ls8 new file mode 100644 index 00000000..8f86bba7 --- /dev/null +++ b/ls8/examples/sctest.ls8 @@ -0,0 +1,86 @@ +# Code to test the Sprint Challenge +# +# Expected output: +# 1 +# 4 +# 5 + +10000010 # LDI R0,10 +00000000 +00001010 +10000010 # LDI R1,20 +00000001 +00010100 +10000010 # LDI R2,TEST1 +00000010 +00010011 +10100111 # CMP R0,R1 +00000000 +00000001 +01010101 # JEQ R2 +00000010 +10000010 # LDI R3,1 +00000011 +00000001 +01000111 # PRN R3 +00000011 +# TEST1 (address 19): +10000010 # LDI R2,TEST2 +00000010 +00100000 +10100111 # CMP R0,R1 +00000000 +00000001 +01010110 # JNE R2 +00000010 +10000010 # LDI R3,2 +00000011 +00000010 +01000111 # PRN R3 +00000011 +# TEST2 (address 32): +10000010 # LDI R1,10 +00000001 +00001010 +10000010 # LDI R2,TEST3 +00000010 +00110000 +10100111 # CMP R0,R1 +00000000 +00000001 +01010101 # JEQ R2 +00000010 +10000010 # LDI R3,3 +00000011 +00000011 +01000111 # PRN R3 +00000011 +# TEST3 (address 48): +10000010 # LDI R2,TEST4 +00000010 +00111101 +10100111 # CMP R0,R1 +00000000 +00000001 +01010110 # JNE R2 +00000010 +10000010 # LDI R3,4 +00000011 +00000100 +01000111 # PRN R3 +00000011 +# TEST4 (address 61): +10000010 # LDI R3,5 +00000011 +00000101 +01000111 # PRN R3 +00000011 +10000010 # LDI R2,TEST5 +00000010 +01001001 +01010100 # JMP R2 +00000010 +01000111 # PRN R3 +00000011 +# TEST5 (address 73): +00000001 # HLT From 0a157e9e73787f11427be10a4409e592b087e624 Mon Sep 17 00:00:00 2001 From: sean-one Date: Fri, 8 Mar 2019 10:24:27 -0800 Subject: [PATCH 18/18] test file gets expected output | sprint mvp done --- ls8/cpu.c | 38 ++++++++++++++++++++++++++++++++++++-- ls8/cpu.h | 9 ++++++++- 2 files changed, 44 insertions(+), 3 deletions(-) diff --git a/ls8/cpu.c b/ls8/cpu.c index ad8677be..9b582a65 100644 --- a/ls8/cpu.c +++ b/ls8/cpu.c @@ -58,7 +58,7 @@ void alu(struct cpu *cpu, enum alu_op op, unsigned char regA, unsigned char regB unsigned char *reg = cpu->reg; // assign operands to values - // unsigned char valueA = reg[regA]; // unused variable + unsigned char valueA = reg[regA]; unsigned char valueB = reg[regB]; switch (op) { @@ -68,6 +68,18 @@ void alu(struct cpu *cpu, enum alu_op op, unsigned char regA, unsigned char regB case ALU_ADD: reg[regA] += valueB; break; + case ALU_CMP: + if (valueA == valueB) { + cpu->FL = 1; + // printf("even %d\n", cpu->FL); + } else if (valueA < valueB) { + cpu->FL = 2; + // printf("less %d\n", cpu->FL); + } else { + cpu->FL = 3; + // printf("greater %d\n", cpu->FL); + } + break; // TODO: implement more ALU ops } @@ -138,6 +150,27 @@ void cpu_run(struct cpu *cpu) case RET: cpu->PC = pop_from_stack(cpu); break; + case CMP: + alu(cpu, ALU_CMP, operand0, operand1); + cpu->PC += 3; + break; + case JMP: + cpu->PC = cpu->reg[operand0]; + break; + case JEQ: + if (cpu->FL == 1) { + cpu->PC = cpu->reg[operand0]; + } else { + cpu->PC += 2; + } + break; + case JNE: + if (cpu->FL != 1) { + cpu->PC = cpu->reg[operand0]; + } else { + cpu->PC += 2; + } + break; default: // beej printed IR & cpu->PC @@ -160,8 +193,9 @@ void cpu_init(struct cpu *cpu) } // set r7 to 0xF4 cpu->reg[7] = 0xF4; - // set PC to 0 | no flags yet + // set PC & flag to 0 cpu->PC = 0; + cpu->FL = 0; // set ram to 0 memset(cpu->ram, 0, sizeof cpu->ram); diff --git a/ls8/cpu.h b/ls8/cpu.h index 9a8aa81a..061bc248 100644 --- a/ls8/cpu.h +++ b/ls8/cpu.h @@ -10,12 +10,15 @@ struct cpu { unsigned char reg[8]; // ram (array) unsigned char ram[256]; + // create a flag + unsigned char FL; }; // ALU operations enum alu_op { ALU_MUL, - ALU_ADD + ALU_ADD, + ALU_CMP // Add more here }; @@ -33,6 +36,10 @@ enum alu_op { #define POP 0b01000110 #define CALL 0b01010000 #define RET 0b00010001 +#define CMP 0b10100111 +#define JMP 0b01010100 +#define JEQ 0b01010101 +#define JNE 0b01010110 // TODO: more instructions here. These can be used in cpu_run().