Skip to content
91 changes: 77 additions & 14 deletions ls8/cpu.c
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
#include <string.h>
#include <stdlib.h>
#include <stdio.h> //need for printf

#include "cpu.h"

#define DATA_LEN 6
Expand All @@ -7,22 +11,37 @@
*/
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
};

int address = 0;

for (int i = 0; i < DATA_LEN; i++) {
cpu->ram[address++] = data[i];
//open file
FILE *fptr = fopen("", "r")

//read line by line until returns null, ignore blank lines and comments
while(fgets() != NULL)
{

}

//save data into ram, have to convert binary strings to int values to store in ram with strtoul


fclose(fptr);

//original hard code we're refactoring
// 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
}

Expand All @@ -40,6 +59,17 @@ void alu(struct cpu *cpu, enum alu_op op, unsigned char regA, unsigned char regB
}
}

unsigned char cpu_ram_read(struct cpu *cpu, unsigned char mar)
{
return cpu->ram[mar];
}

//mar is index in ram so set to new value
void cpu_ram_write(struct cpu *cpu, unsigned char mar, unsigned char mdr)
{
cpu->ram[mar] = mdr;
}

/**
* Run the CPU
*/
Expand All @@ -50,10 +80,34 @@ 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 operandA = cpu_ram_read(cpu, cpu->pc+1);
unsigned char operandB = cpu_ram_read(cpu, cpu->pc+2);
printf("TRACE: %0X2: %0X2 %0X2 %0X2 \n", cpu->pc, IR, operandA, operandB);
// 4. switch() over it to decide on a course of action.
// 5. Do whatever the instruction should do according to the spec.
switch(IR)
{
case LDI:
//sets value in given register to value specified
cpu->reg[operandA] = operandB;
//increment by 3 since 3 arguments (CP+2)
cpu->pc += 3;
break;
case PRN:
//print out numerically in given register
printf("%d\n", cpu->reg[operandA]);
cpu->pc += 2;
break;
case HLT: //why is this needed when have break ?
running = 0; //set running to false
break;
default: //program stops if gets instruction it doesnt know
printf("unexpected instruction: 0x%0X2 at 0x%0X2 \n", IR, cpu->pc);
exit(1);
}
// 6. Move the PC to the next instruction.
}
}
Expand All @@ -64,4 +118,13 @@ void cpu_run(struct cpu *cpu)
void cpu_init(struct cpu *cpu)
{
// TODO: Initialize the PC and other special registers
cpu->pc = 0;
memset(cpu->reg, 0, sizeof(unsigned char)*8); //just use size of cpu reg?
memset(cpu->ram, 0, sizeof(unsigned char)*256);
}
// When the LS-8 is booted, the following steps occur:

// * `R0`-`R6` are cleared to `0`.
// * `R7` is set to `0xF4`.
// * `PC` and `FL` registers are cleared to `0`.
// * RAM is cleared to `0`.
8 changes: 6 additions & 2 deletions ls8/cpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,16 @@
#define _CPU_H_

// Holds all information about the CPU
struct cpu {
typedef struct cpu {
// TODO
// PC
unsigned char pc;
unsigned char fl;
// registers (array)
unsigned char reg[8];
// ram (array)
};
unsigned char ram[256];
} cpu;

// ALU operations
enum alu_op {
Expand Down
8 changes: 6 additions & 2 deletions ls8/ls8.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
/**
* Main
*/
int main(void)
//the way this is set up shows us the order that this should be built out
int main(int argc, char *argv[]) //changed from void for command line processing. arg count and array of strings that hold indiv args.
{
struct cpu cpu;

Expand All @@ -13,4 +14,7 @@ int main(void)
cpu_run(&cpu);

return 0;
}
}

//argv[0] == "./ls8"
//argv[1] == "examples/mult.ls8"