Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 82 additions & 13 deletions ls8/cpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -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];
}

Expand All @@ -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
}
Expand All @@ -43,25 +45,92 @@ void alu(struct cpu *cpu, enum alu_op op, unsigned char regA, unsigned char regB
/**
* Run the CPU
*/

void push_to_stack(struct cpu *cpu, int val)
{
cpu->reg[7]--;
cpu->ram[cpu->reg[7]] = val;
}
unsigned char cpu_pop(struct cpu *cpu)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now you need to add PUSH and POP instructions to your switch statement.

{
unsigned char val = cpu_ram_read(cpu, cpu->reg[7]);
cpu->reg[7]++;
return val;
}

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).
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;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome job with this! Now you need to use it.


// 3. Get the appropriate value(s) of the operands following this instruction
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;
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:
printf("Error");
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can make this error more verbose with the program counter and instruction code for better debugging.

break;
}
// 5. Do whatever the instruction should do according to the spec.
// 6. Move the PC to the next instruction.
}
}

// ram functions
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
*/
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;

// set everything in ram to 0
memset(cpu->ram, 0, sizeof cpu->ram);
}
21 changes: 13 additions & 8 deletions ls8/cpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,32 @@
#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

// 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
Expand All @@ -31,4 +36,4 @@ extern void cpu_load(struct cpu *cpu);
extern void cpu_init(struct cpu *cpu);
extern void cpu_run(struct cpu *cpu);

#endif
#endif