From d8ed96f20a65e0269a2aa9887e8198dbee75dd84 Mon Sep 17 00:00:00 2001 From: Anthony Date: Wed, 2 Dec 2020 18:04:37 -0600 Subject: [PATCH 1/2] Initial commit --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 20c417457..110092f1e 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,4 @@ -# Computer Architecture - +# Computer Architecture..... ## Project * [Implement the LS-8 Emulator](ls8/) From 1eec70ba9a9fccd77207e7d5690164cc7c3fdee4 Mon Sep 17 00:00:00 2001 From: Anthony Date: Wed, 2 Dec 2020 22:27:58 -0600 Subject: [PATCH 2/2] Finished MVP Met --- README.md | 1 + ls8/cpu.py | 140 ++++++++++++++++++++++++++++++++++++++++++++--------- ls8/ls8.py | 3 +- 3 files changed, 119 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index 110092f1e..ae23eb511 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ # Computer Architecture..... +### https://github.com/LambdaSchool/Computer-Architecture/pull/245 ## Project * [Implement the LS-8 Emulator](ls8/) diff --git a/ls8/cpu.py b/ls8/cpu.py index 9a307496e..f367797e0 100644 --- a/ls8/cpu.py +++ b/ls8/cpu.py @@ -2,41 +2,69 @@ import sys +HLT = 0b00000001 +LDI = 0b10000010 +PRN = 0b01000111 +MULT = 0b10100010 +PUSH = 0b01000101 +POP = 0b01000110 +SP = 7 # stack pointer is reg7 +ADD = 0b10100000 +CALL = 0b01010000 +RET = 0b00010001 +CMP = 0b10100111 +JEQ = 0b01010101 +JMP = 0b01010100 +JNE = 0b01010110 + + class CPU: """Main CPU class.""" def __init__(self): """Construct a new CPU.""" - pass - - def load(self): - """Load a program into memory.""" - - address = 0 - # For now, we've just hardcoded a program: + self.pc = 0 + self.halted = False + self.ram = [0] * 256 + self.reg = [0] * 8 + self.reg[7] = 0xF4 # stack pointer + self.less = 0 + self.greater = 0 + self.equal = 0 - program = [ - # From print8.ls8 - 0b10000010, # LDI R0,8 - 0b00000000, - 0b00001000, - 0b01000111, # PRN R0 - 0b00000000, - 0b00000001, # HLT - ] + def ram_read(self, address): + return self.ram[address] - for instruction in program: - self.ram[address] = instruction - address += 1 + def ram_write(self, val, address): + self.ram[address] = val + def load(self): + """Load a program into memory.""" + address = 0 + with open(sys.argv[1]) as fp: + for line in fp: + comment_split = line.split("#") + num = comment_split[0].strip() + if num == "": + continue + value = int(num, 2) # set value to the number (of base 2) + self.ram_write(value, address) + address += 1 def alu(self, op, reg_a, reg_b): """ALU operations.""" - - if op == "ADD": + if op == "ADD": # add self.reg[reg_a] += self.reg[reg_b] - #elif op == "SUB": etc + elif op == "MULT": # multiply + self.reg[reg_a] *= self.reg[reg_b] + elif op == "CMP": # compare + if self.reg[reg_a] < self.reg[reg_b]: + self.less = 1 + elif self.reg[reg_a] > self.reg[reg_b]: + self.greater = 1 + elif self.reg[reg_a] == self.reg[reg_b]: + self.equal = 1 else: raise Exception("Unsupported ALU operation") @@ -62,4 +90,70 @@ def trace(self): def run(self): """Run the CPU.""" - pass + while not self.halted: + instruction = self.ram[self.pc] + operand_a = self.ram_read(self.pc + 1) + operand_b = self.ram_read(self.pc + 2) + self.execute_instruction(instruction, operand_a, operand_b) + + def execute_instruction(self, instruction, operand_a, operand_b): + if instruction is LDI: + self.reg[operand_a] = operand_b + self.pc += 3 + + elif instruction is PRN: + print(self.reg[operand_a]) + self.pc += 2 + + elif instruction is ADD: + self.alu("ADD", operand_a, operand_b) + self.pc += 3 + + elif instruction is MULT: + self.alu("MULT", operand_a, operand_b) + self.pc += 3 + + elif instruction is CMP: + self.alu("CMP", operand_a, operand_b) + self.pc += 3 + + elif instruction is POP: + self.reg[operand_a] = self.ram[self.reg[SP]] + self.reg[SP] += 1 + self.pc += 2 + + elif instruction is PUSH: + self.reg[SP] -= 1 + self.ram[self.reg[SP]] = self.reg[operand_a] + self.pc += 2 + + elif instruction is CALL: + self.reg[self.reg[SP]] -= 1 + self.ram[self.reg[SP]] = self.pc + 2 + self.pc = self.reg[operand_a] + + elif instruction is RET: + self.pc = self.ram[self.reg[SP]] + self.reg[self.reg[SP]] += 1 + + elif instruction is JMP: + self.pc = self.reg[operand_a] + + elif instruction is JEQ: + if self.equal == 1: + self.pc = self.reg[operand_a] + else: + self.pc += 2 + + elif instruction is JNE: + if self.equal == 0: + self.pc = self.reg[operand_a] + else: + self.pc += 2 + + elif instruction is HLT: + self.halted = True + + else: + print("Idk this instruction, exiting.") + sys.exit(1) diff --git a/ls8/ls8.py b/ls8/ls8.py index 74128d36b..7554af839 100755 --- a/ls8/ls8.py +++ b/ls8/ls8.py @@ -1,11 +1,10 @@ #!/usr/bin/env python3 """Main.""" - import sys from cpu import * cpu = CPU() cpu.load() -cpu.run() \ No newline at end of file +cpu.run()