diff --git a/ls8/cpu.py b/ls8/cpu.py index 9a307496e..233e68dae 100644 --- a/ls8/cpu.py +++ b/ls8/cpu.py @@ -1,44 +1,81 @@ """CPU functionality.""" - +# import sys +#instruction set: +HLT = 0b00000001 +LDI = 0b10000010 +PRN = 0b01000111 +MUL = 0b10100010 +PUSH = 0b01000101 +POP = 0b01000110 +CALL = 0b01010000 +RET = 0b00010001 +CMP = 0b10100111 +JMP = 0b01010100 +JEQ = 0b01010101 +JNE = 0b01010110 + +# flags +L = 0b100 +G = 0b10 +E = 0b1 + class CPU: """Main CPU class.""" def __init__(self): - """Construct a new CPU.""" - pass + self.reg = [0] * 8 + self.ram = [0] * 256 + self.pc = 0 + self.sp = 0 #set it to the first one in the stack? + self.fl = 0 - def load(self): - """Load a program into memory.""" + self.reg[self.sp] = 0xf4 - address = 0 +#originally this part is `hardcoded` and needs the parser instead + + def load(self, filename): + """Load a program into memory.""" + try: + address = 0 #constant ram address + with open(filename) as f: + for line in f: + comment_split = line.split("#") + num = comment_split[0].strip() + if num == '': + continue - # For now, we've just hardcoded a program: + self.ram[address] = int(num, 2) + address += 1 - program = [ - # From print8.ls8 - 0b10000010, # LDI R0,8 - 0b00000000, - 0b00001000, - 0b01000111, # PRN R0 - 0b00000000, - 0b00000001, # HLT - ] + except FileNotFoundError: + print("file not found") + sys.exit(2) - for instruction in program: - self.ram[address] = instruction - address += 1 + + def ram_read(self, address): + return self.ram[address] + def ram_write(self, newvalue, address): + self.ram[address] = newvalue 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 - else: - raise Exception("Unsupported ALU operation") + self.pc += 3 + elif op == "MUL": + self.reg[reg_a] *= self.reg[reg_b] + self.pc += 3 + print() + elif op == "CMP": + if self.reg[reg_a] == self.reg[reg_b]: + self.fl = 1 + else: + self.fl = 0 + self.pc += 3 def trace(self): """ @@ -61,5 +98,81 @@ def trace(self): print() def run(self): - """Run the CPU.""" - pass + running = True + while running: + instruction = self.ram[self.pc] + operand_a = self.ram[self.pc + 1] + operand_b = self.ram[self.pc + 2] +# LDI + if instruction == LDI: + reg_index = operand_a + num = operand_b + self.reg[reg_index] = num + self.pc += 3 +# PRN + elif instruction == PRN: + reg_index = operand_a + num = self.reg[reg_index] + print(num) + self.pc += 2 +#MUL + elif instruction == MUL: + self.alu("MUL", operand_a, operand_b) +#PUSH + elif instruction == PUSH: + reg_index = operand_a + val = self.reg[reg_index] + + self.reg[self.sp] -= 1 + + self.ram[self.reg[self.sp]] = val + self.pc += 2 +#POP + elif instruction == POP: + reg_index = operand_a + + self.reg[reg_index] = self.ram[self.reg[self.sp]] + + self.reg[self.sp] += 1 + self.pc += 2 +# HLT + elif instruction == HLT: + running = False + sys.exit(0) +# CALL + elif instruction == CALL: + address_to_return_to = self.pc + 2 + self.reg[self.pc] -= 1 + self.ram[self.reg[self.sp]] = address_to_return_to + reg_index = operand_a + address_to_call = self.reg[reg_index] + self.pc = address_to_call +# RET + elif instruction == RET: + self.pc = self.ram[self.reg[self.sp]] + self.reg[self.sp] + 1 +# CMP + elif instruction == CMP: + # if self.reg[self.ram_read(operand_a)] == self.reg[self.ram_read(operand_b)]: + # self.reg[self.fl] = self.ref[self.fl] | (1<<0) + # else: self.reg[self.fl] + self.alu("CMP", operand_a, operand_b) +#JMP + elif instruction == JMP: + self.pc = self.reg[operand_a] +#JEP + elif instruction == JEQ: + if self.fl & E: + self.pc = self.reg[operand_a] + else: + self.pc += 2 +#JNE + elif instruction == JNE: + if not self.fl & E: + self.pc = self.reg[operand_a] + else: + self.pc += 2 + + else: + print("WRONG WAY") + sys.exit(1) \ No newline at end of file diff --git a/ls8/ls8.py b/ls8/ls8.py index 74128d36b..83855dcae 100755 --- a/ls8/ls8.py +++ b/ls8/ls8.py @@ -5,7 +5,13 @@ import sys from cpu import * +if len(sys.argv) != 2: + print("Usage: python3 fileio.py ") + sys.exit(1) + +filename = sys.argv[1] + cpu = CPU() -cpu.load() +cpu.load(filename) cpu.run() \ No newline at end of file