diff --git a/ls8/cpu.py b/ls8/cpu.py index 9a307496e..d6d338406 100644 --- a/ls8/cpu.py +++ b/ls8/cpu.py @@ -6,37 +6,146 @@ class CPU: """Main CPU class.""" def __init__(self): - """Construct a new CPU.""" - pass - - def load(self): + self.ram = [0] * 256 + self.reg = [0] * 8 + self.pc = 0 + self.running = False + self.sp = 7 #our stack pointer starts at the top of a 0-7 index + self.fl = 0b00000000 # all flags set to false on initialization + self.reg[self.sp] = 0xf4 # initialize stack pointer to RAM address f4 + + def call_stack(self, func): + branch_table = { + 0b10000010: self.LDI, + 0b01000111: self.PRN, + 0b10100010: self.MULT, + 0b01100101: self.INC, + 0b01100110: self.DEC, + 0b01000101: self.PUSH, + 0b01000110: self.POP, + 0b00000001: self.HLT, + 0b01010000: self.CALL, + 0b00010001: self.RET + } + if func in branch_table: + branch_table[func]() + else: + print('invalid function') + sys.exit(1) + + def LDI(self): + reg_num = self.ram_read(self.pc+1) + value = self.ram_read(self.pc+2) + self.reg[reg_num] = value + self.pc += 3 + # num_operands = (ir & 0b11000000) >> 6 + # num_to_move = num_operands +1 + # self.pc += num_to_move + + def PRN(self): + reg_num = self.ram_read(self.pc+1) + print(self.reg[reg_num]) + self.pc += 2 + + def HLT(self): + self.running = False + self.pc += 1 + + def MULT(self): + self.alu('MULT', self.pc+1, self.pc+2) + self.pc += 3 + + def DEC(self): + self.alu('DEC', self.pc+1, None) + + def INC(self): + self.alu('INC', self.pc+1, None) + + def PUSH(self, value =None): + #decrement SP + self.sp -= 1 + if not value: + value = self.reg[self.ram_read(self.pc + 1)] + #get next value + # reg_num = self.ram[self.pc + 1] + # value = self.reg[reg_num] + #store it + # self.ram[self.sp] = value + self.ram_write(value, self.reg[self.sp]) + self.pc += 2 + # new way + # self.reg[self.sp] -= 1 + # if not value: + # value = self.reg[self.ram_read(self.pc + 1)] + # self.ram_write(value, self.reg[self.sp]) + # self.pc += 2 + + + def POP(self): + # print('pop') + value = self.ram[self.sp] + #go to next in ram + self.reg[self.ram[self.pc + 1]] = value + #increment sp + self.sp +=1 + self.pc += 2 + + def ram_read(self, MAR): + return self.ram[MAR] + + def ram_write(self, MDR, MAR): + self.ram[MAR] = MDR + + def load(self, file_path): """Load a program into memory.""" - + file_path = sys.argv[1] + program = open(f"{file_path}", "r") address = 0 - - # For now, we've just hardcoded a program: - - program = [ - # From print8.ls8 - 0b10000010, # LDI R0,8 - 0b00000000, - 0b00001000, - 0b01000111, # PRN R0 - 0b00000000, - 0b00000001, # HLT - ] - - for instruction in program: - self.ram[address] = instruction - address += 1 - + for line in program: + if line[0] == "0" or line[0] == "1": + command = line.split("#", 1)[0] + self.ram[address] = int(command, 2) + address += 1 + + def CALL(self): + # self.reg[self.sp] -= 1 + # self.ram_write(self.reg[self.sp], self.pc + 1) + # self.pc += 2 + # self.trace() + # version 2 + new_pc = self.reg[self.ram_read(self.pc + 1)] + self.PUSH(self.pc + 2) + self.pc = new_pc + + + + def RET(self): + self.pc = self.ram_read(self.reg[self.sp]) + self.reg[self.sp] += 1 + # trace() def alu(self, op, reg_a, reg_b): """ALU operations.""" if op == "ADD": - self.reg[reg_a] += self.reg[reg_b] - #elif op == "SUB": etc + self.reg[self.pc+1] += self.reg[self.pc+2] + + elif op == "SUB": + self.reg[self.ram[reg_a]] -= self.reg[self.ram[reg_b]] + + elif op == "CMP": + if self.reg[self.ram[reg_a]] < self.reg[self.ram[reg_b]]: + self.fl = 0b00000100 + elif self.reg[self.ram[reg_a]] > self.reg[self.ram[reg_b]]: + self.fl = 0b00000010 + elif self.reg[self.ram[reg_a]] == self.reg[self.ram[reg_b]]: + self.fl = 0b00000001 + else: + self.fl = 0b00000000 + + elif op == "MULT": + self.reg[self.ram[reg_a]] *= self.reg[self.ram[reg_b]] + else: raise Exception("Unsupported ALU operation") @@ -62,4 +171,7 @@ def trace(self): def run(self): """Run the CPU.""" - pass + self.running = True + while self.running: + ir = self.ram[self.pc] + self.call_stack(ir) \ No newline at end of file diff --git a/ls8/ls8.py b/ls8/ls8.py index 74128d36b..3e8b40627 100755 --- a/ls8/ls8.py +++ b/ls8/ls8.py @@ -3,9 +3,14 @@ """Main.""" import sys -from cpu import * +# from cpu import * +# from cpu2 import * +from cpu3 import * cpu = CPU() -cpu.load() -cpu.run() \ No newline at end of file +if len(sys.argv) > 1: + cpu.load(sys.argv[1]) + cpu.run() +else: + print("please add a program to run") \ No newline at end of file