From 96c03b90f894012d19c7028865eb807318209892 Mon Sep 17 00:00:00 2001 From: Riley-Brown Date: Mon, 4 Mar 2019 18:18:14 -0500 Subject: [PATCH 01/16] added struct for cpu --- ls8/cpu.h | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/ls8/cpu.h b/ls8/cpu.h index 46e49c44..7587db62 100644 --- a/ls8/cpu.h +++ b/ls8/cpu.h @@ -2,17 +2,22 @@ #define _CPU_H_ // Holds all information about the CPU -struct cpu { +struct cpu +{ // TODO // PC + unsigned int pc; // registers (array) + unsigned char reg[8]; // ram (array) + unsigned char ram[256]; }; // ALU operations -enum alu_op { - ALU_MUL - // Add more here +enum alu_op +{ + ALU_MUL + // Add more here }; // Instructions @@ -20,9 +25,9 @@ enum alu_op { // These use binary literals. If these aren't available with your compiler, hex // literals should be used. -#define LDI 0b10000010 -#define HLT 0b00000001 -#define PRN 0b01000111 +#define LDI 0b10000010 +#define HLT 0b00000001 +#define PRN 0b01000111 // TODO: more instructions here. These can be used in cpu_run(). // Function declarations From bc5eecfe28794cd48ca7acaa3bedfb56f1744d06 Mon Sep 17 00:00:00 2001 From: Riley-Brown Date: Tue, 5 Mar 2019 16:12:31 -0500 Subject: [PATCH 02/16] updated cpu init --- ls8/cpu.c | 37 +++++++++++++++++++++++-------------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/ls8/cpu.c b/ls8/cpu.c index bdb1f506..a13e8637 100644 --- a/ls8/cpu.c +++ b/ls8/cpu.c @@ -8,18 +8,19 @@ 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 + // From print8.ls8 + 0b10000010, // LDI R0,8 + 0b00000000, + 0b00001000, + 0b01000111, // PRN R0 + 0b00000000, + 0b00000001 // HLT }; int address = 0; - for (int i = 0; i < DATA_LEN; i++) { + for (int i = 0; i < DATA_LEN; i++) + { cpu->ram[address++] = data[i]; } @@ -31,10 +32,11 @@ void cpu_load(struct cpu *cpu) */ void alu(struct cpu *cpu, enum alu_op op, unsigned char regA, unsigned char regB) { - switch (op) { - case ALU_MUL: - // TODO - break; + switch (op) + { + case ALU_MUL: + // TODO + break; // TODO: implement more ALU ops } @@ -47,7 +49,8 @@ void cpu_run(struct cpu *cpu) { int running = 1; // True until we get a HLT instruction - while (running) { + while (running) + { // TODO // 1. Get the value of the current instruction (in address PC). // 2. Figure out how many operands this next instruction requires @@ -64,4 +67,10 @@ void cpu_run(struct cpu *cpu) void cpu_init(struct cpu *cpu) { // TODO: Initialize the PC and other special registers -} + for (int i = 0; i <= 6; i++) + { + cpu->reg[i] = 0; + } + + cpu->reg[7] = 0; + cpu->pc = 0; From 706acbd3cfd58c4dcd3fb2a068b8507e7661d6fb Mon Sep 17 00:00:00 2001 From: Riley-Brown Date: Tue, 5 Mar 2019 16:39:53 -0500 Subject: [PATCH 03/16] added memset in cpu init to set ram to 0 --- ls8/cpu.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ls8/cpu.c b/ls8/cpu.c index a13e8637..a9a468eb 100644 --- a/ls8/cpu.c +++ b/ls8/cpu.c @@ -74,3 +74,7 @@ void cpu_init(struct cpu *cpu) cpu->reg[7] = 0; cpu->pc = 0; + + // set everything in ram to 0 + memset(cpu->ram, 0, sizeof cpu->ram); +} \ No newline at end of file From 61700d8cd69d6dc1f1b1800b04d2ee6a4e246595 Mon Sep 17 00:00:00 2001 From: Riley-Brown Date: Tue, 5 Mar 2019 17:09:58 -0500 Subject: [PATCH 04/16] added cpu_ram_read function --- ls8/cpu.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/ls8/cpu.c b/ls8/cpu.c index a9a468eb..96779d13 100644 --- a/ls8/cpu.c +++ b/ls8/cpu.c @@ -61,6 +61,12 @@ void cpu_run(struct cpu *cpu) } } +// ram functions +unsigned char cpu_ram_read(struct cpu *cpu, unsigned char index) +{ + return cpu->ram[index]; +} + /** * Initialize a CPU struct */ From 465b69a9d08c381440f8eb7755bb7dd13cff06d8 Mon Sep 17 00:00:00 2001 From: Riley-Brown Date: Tue, 5 Mar 2019 18:28:41 -0500 Subject: [PATCH 05/16] added ram write function and started on cpu run --- ls8/cpu.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/ls8/cpu.c b/ls8/cpu.c index 96779d13..1f4ae78f 100644 --- a/ls8/cpu.c +++ b/ls8/cpu.c @@ -53,6 +53,7 @@ void cpu_run(struct cpu *cpu) { // TODO // 1. Get the value of the current instruction (in address PC). + cpu->ram[running]; // 2. Figure out how many operands this next instruction requires // 3. Get the appropriate value(s) of the operands following this instruction // 4. switch() over it to decide on a course of action. @@ -67,6 +68,11 @@ unsigned char cpu_ram_read(struct cpu *cpu, unsigned char index) return cpu->ram[index]; } +void cpu_ram_write(struct cpu *cpu, unsigned mar, unsigned char mdr) +{ + cpu->ram[mar] = mdr; +} + /** * Initialize a CPU struct */ From 7e7407d785e7dd0a6a55cea232f4c284c2e55b1c Mon Sep 17 00:00:00 2001 From: Riley-Brown Date: Tue, 5 Mar 2019 19:07:49 -0500 Subject: [PATCH 06/16] updated cpu_run step one --- ls8/cpu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ls8/cpu.c b/ls8/cpu.c index 1f4ae78f..85176794 100644 --- a/ls8/cpu.c +++ b/ls8/cpu.c @@ -53,7 +53,7 @@ void cpu_run(struct cpu *cpu) { // TODO // 1. Get the value of the current instruction (in address PC). - cpu->ram[running]; + 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 // 4. switch() over it to decide on a course of action. From 1ac3c9ab48ffad3d1a1ec86f84caa573ec806331 Mon Sep 17 00:00:00 2001 From: Riley-Brown Date: Tue, 5 Mar 2019 19:18:30 -0500 Subject: [PATCH 07/16] added operands for next cpu instructions --- ls8/cpu.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ls8/cpu.c b/ls8/cpu.c index 85176794..a1f04a45 100644 --- a/ls8/cpu.c +++ b/ls8/cpu.c @@ -55,7 +55,10 @@ void cpu_run(struct cpu *cpu) // 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 operandA = cpu_ram_read(cpu, cpu->pc + 1); + unsigned char operandB = 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. // 6. Move the PC to the next instruction. From a380da84c89a57ba77a17205e595f6c9b74c2b3d Mon Sep 17 00:00:00 2001 From: Riley-Brown Date: Wed, 6 Mar 2019 14:05:54 -0500 Subject: [PATCH 08/16] updated cpu run --- ls8/cpu.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/ls8/cpu.c b/ls8/cpu.c index a1f04a45..d3d84812 100644 --- a/ls8/cpu.c +++ b/ls8/cpu.c @@ -55,11 +55,29 @@ void cpu_run(struct cpu *cpu) // 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 + //IR gives you the current instuction + //reading from the bitwise right shift will give you the number of operands: + unsigned char operandA = 0; + unsigned char operandB = 0; + unsigned int numOp = IR >> 6; // 3. Get the appropriate value(s) of the operands following this instruction - unsigned char operandA = cpu_ram_read(cpu, cpu->pc + 1); - unsigned char operandB = cpu_ram_read(cpu, cpu->pc + 2); + if (numOp == 2) + { + unsigned char operandA = cpu_ram_read(cpu, (cpu->pc + 1) & 0xff); + unsigned char operandB = cpu_ram_read(cpu, (cpu->pc + 2) & 0xff); + } // 4. switch() over it to decide on a course of action. + switch (IR) + { + case LDI: + // change the value of reg @ operanA to operandB; + cpu->reg[operandA] = operandB; + break; + + default: + break; + } // 5. Do whatever the instruction should do according to the spec. // 6. Move the PC to the next instruction. } From 6f576e274f5fc0c696342e70784bba4a3826484e Mon Sep 17 00:00:00 2001 From: Riley-Brown Date: Wed, 6 Mar 2019 16:02:28 -0500 Subject: [PATCH 09/16] added cases for cpu_run switch statement --- ls8/cpu.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/ls8/cpu.c b/ls8/cpu.c index d3d84812..7b79562f 100644 --- a/ls8/cpu.c +++ b/ls8/cpu.c @@ -74,8 +74,14 @@ void cpu_run(struct cpu *cpu) // change the value of reg @ operanA to operandB; cpu->reg[operandA] = operandB; break; - + case PRN: + printf("%d\n", cou - reg[operandA]); + break; + case HLT: + running = 0; + break; default: + printf("Error"); break; } // 5. Do whatever the instruction should do according to the spec. From 7b10c83d83632fb4020dbcb4666d441e81cf8bdb Mon Sep 17 00:00:00 2001 From: Riley-Brown Date: Wed, 6 Mar 2019 16:06:20 -0500 Subject: [PATCH 10/16] fixed spelling error for PRN switch case --- ls8/cpu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ls8/cpu.c b/ls8/cpu.c index 7b79562f..a27439c2 100644 --- a/ls8/cpu.c +++ b/ls8/cpu.c @@ -75,7 +75,7 @@ void cpu_run(struct cpu *cpu) cpu->reg[operandA] = operandB; break; case PRN: - printf("%d\n", cou - reg[operandA]); + printf("%d\n", cpu->reg[operandA]); break; case HLT: running = 0; From 2776a158155614c6010035ecdb68dca99707d6eb Mon Sep 17 00:00:00 2001 From: Riley-Brown Date: Wed, 6 Mar 2019 16:11:12 -0500 Subject: [PATCH 11/16] added print for LDI and PRN case --- ls8/cpu.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ls8/cpu.c b/ls8/cpu.c index a27439c2..05cb72d5 100644 --- a/ls8/cpu.c +++ b/ls8/cpu.c @@ -72,12 +72,15 @@ void cpu_run(struct cpu *cpu) { case LDI: // change the value of reg @ operanA to operandB; + printf("%d\n", cpu->reg[operandB]); cpu->reg[operandA] = operandB; + printf("%d\n", cpu->reg[operandB]); break; case PRN: printf("%d\n", cpu->reg[operandA]); break; case HLT: + running = 0; break; default: From bf50f25502050136b6ec4db5940148c072435edb Mon Sep 17 00:00:00 2001 From: Riley-Brown Date: Wed, 6 Mar 2019 17:33:10 -0500 Subject: [PATCH 12/16] updated switch case to get next bytes in memory --- ls8/cpu.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ls8/cpu.c b/ls8/cpu.c index 05cb72d5..93670279 100644 --- a/ls8/cpu.c +++ b/ls8/cpu.c @@ -74,13 +74,14 @@ void cpu_run(struct cpu *cpu) // change the value of reg @ operanA to operandB; printf("%d\n", cpu->reg[operandB]); cpu->reg[operandA] = operandB; + cpu->pc += 2; printf("%d\n", cpu->reg[operandB]); break; case PRN: + cpu->pc += 2; printf("%d\n", cpu->reg[operandA]); break; case HLT: - running = 0; break; default: From bb11573235a0e6ff826c8f4412207c14668a26a9 Mon Sep 17 00:00:00 2001 From: Riley-Brown Date: Wed, 6 Mar 2019 19:10:09 -0500 Subject: [PATCH 13/16] Updated hardcoded values in cpu_load function --- ls8/cpu.c | 48 +++++++++++++++++++++++++++++++----------------- 1 file changed, 31 insertions(+), 17 deletions(-) diff --git a/ls8/cpu.c b/ls8/cpu.c index 93670279..16cf1560 100644 --- a/ls8/cpu.c +++ b/ls8/cpu.c @@ -1,30 +1,44 @@ #include "cpu.h" +#include +#include +#include #define DATA_LEN 6 /** * Load the binary bytes from a .ls8 source file into a RAM array */ -void cpu_load(struct cpu *cpu) +void cpu_load(struct cpu *cpu, char *file) { - char data[DATA_LEN] = { - // From print8.ls8 - 0b10000010, // LDI R0,8 - 0b00000000, - 0b00001000, - 0b01000111, // PRN R0 - 0b00000000, - 0b00000001 // HLT - }; - - int address = 0; - - for (int i = 0; i < DATA_LEN; i++) - { - cpu->ram[address++] = data[i]; - } + // char data[DATA_LEN] = { + // // From print8.ls8 + // 0b10000010, // LDI R0,8 + // 0b00000000, + // 0b00001000, + // 0b01000111, // PRN R0 + // 0b00000000, + // 0b00000001 // HLT + // }; + + // int address = 0; + + // for (int i = 0; i < DATA_LEN; i++) + // { + // cpu->ram[address++] = data[i]; + // } // TODO: Replace this with something less hard-coded + FILE *fptr; + char line[1024]; + char data = 0; + fptr = fopen(file, "r"); + + while (fgets(line, sizeof(line), fptr) != NULL) + { + unsigned char endpoint; + endpoint = strtoul(line, NULL, 2); + cpu_ram_write(cpu, data++, endpoint); + } } /** From 616622093d4eba7f4e7cccb36b335dc5a5fd8b86 Mon Sep 17 00:00:00 2001 From: Riley-Brown Date: Wed, 6 Mar 2019 19:13:26 -0500 Subject: [PATCH 14/16] Added fclose in cpu_load function --- ls8/cpu.c | 1 + 1 file changed, 1 insertion(+) diff --git a/ls8/cpu.c b/ls8/cpu.c index 16cf1560..95689561 100644 --- a/ls8/cpu.c +++ b/ls8/cpu.c @@ -39,6 +39,7 @@ void cpu_load(struct cpu *cpu, char *file) endpoint = strtoul(line, NULL, 2); cpu_ram_write(cpu, data++, endpoint); } + fclose(fptr); } /** From 34b20a6d9d665ead47faee575ae32dc81cf101be Mon Sep 17 00:00:00 2001 From: Riley-Brown Date: Thu, 7 Mar 2019 16:40:55 -0500 Subject: [PATCH 15/16] fixed bug in .h file --- ls8/cpu.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ls8/cpu.h b/ls8/cpu.h index 7587db62..4c4dd0ea 100644 --- a/ls8/cpu.h +++ b/ls8/cpu.h @@ -32,7 +32,7 @@ enum alu_op // Function declarations -extern void cpu_load(struct cpu *cpu); +extern void cpu_load(struct cpu *cpu, char *file); extern void cpu_init(struct cpu *cpu); extern void cpu_run(struct cpu *cpu); From 969e68eec74056eeb5d1615a44abd8ae9eb3c247 Mon Sep 17 00:00:00 2001 From: Riley-Brown Date: Thu, 7 Mar 2019 17:27:15 -0500 Subject: [PATCH 16/16] Added agrs in ls8.c file --- ls8/ls8.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/ls8/ls8.c b/ls8/ls8.c index d24578ee..309f44cd 100644 --- a/ls8/ls8.c +++ b/ls8/ls8.c @@ -4,12 +4,17 @@ /** * Main */ -int main(void) +int main(int argc, char **argv) { struct cpu cpu; + if (argc != 2) + { + printf("Error"); + return 1; + } cpu_init(&cpu); - cpu_load(&cpu); + cpu_load(&cpu, argv[1]); cpu_run(&cpu); return 0;