From 6e22b7e15ebbe6afdc49b745a4812d5238d4de3d Mon Sep 17 00:00:00 2001 From: Mike Sinnema Date: Mon, 20 Jul 2020 12:53:14 -0700 Subject: [PATCH 1/5] initial commit --- ls8/cpu.py | 126 +++++++++++++++++++++++++++++++++++++++++++---------- ls8/ls8.py | 2 +- 2 files changed, 103 insertions(+), 25 deletions(-) diff --git a/ls8/cpu.py b/ls8/cpu.py index 9a307496e..363739a57 100644 --- a/ls8/cpu.py +++ b/ls8/cpu.py @@ -6,37 +6,112 @@ 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 + + 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 + } + if func in branch_table: + branch_table[func]() + else: + print('invalid function') + sys.exit(1) + + def LDI(self): # num_operands = (ir & 0b11000000) >> 6 + 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): + # print('push') + #decrement SP + self.sp -=1 + #get next value + reg_num = self.ram[self.pc + 1] + value = self.reg[reg_num] + #store it + self.ram[self.sp] = value + 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, index): + return self.ram[index] + + def ram_write(self, index, value): + self.ram[index] = value + + def load(self, f): """Load a program into memory.""" - + file_path = f + 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 + +# +# while open(filename) as f: +# for address, line in enumerate(f): +# line = line.split("#") +# try: +# v = int(line[0], 2) +# except ValueError: +# continue +# memory[address] = v 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 == "MULT": + self.reg[self.ram[reg_a]] *= self.reg[self.ram[reg_b]] else: raise Exception("Unsupported ALU operation") @@ -62,4 +137,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..d66bc9d2a 100755 --- a/ls8/ls8.py +++ b/ls8/ls8.py @@ -7,5 +7,5 @@ cpu = CPU() -cpu.load() +cpu.load("examples/stack.ls8") cpu.run() \ No newline at end of file From 13e98cbe0e369a60797ae280f2535dae8dd2e047 Mon Sep 17 00:00:00 2001 From: Mike Sinnema Date: Mon, 20 Jul 2020 14:03:50 -0700 Subject: [PATCH 2/5] mult.ls8 working --- ls8/cpu.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/ls8/cpu.py b/ls8/cpu.py index 363739a57..53fc5de5e 100644 --- a/ls8/cpu.py +++ b/ls8/cpu.py @@ -11,6 +11,8 @@ def __init__(self): 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[7] = 0xf4 # initialize stack pointer to RAM address f4 def call_stack(self, func): branch_table = { @@ -83,9 +85,9 @@ def ram_read(self, index): def ram_write(self, index, value): self.ram[index] = value - def load(self, f): + def load(self, file_path): """Load a program into memory.""" - file_path = f + file_path = sys.argv[1] program = open(f"{file_path}", "r") address = 0 for line in program: From 4d58cd5383fc556913f3088aa58b52af782ef1fa Mon Sep 17 00:00:00 2001 From: Mike Sinnema Date: Tue, 21 Jul 2020 15:47:49 -0700 Subject: [PATCH 3/5] print8, mult, stack working -- index error in call --- ls8/cpu.py | 43 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 36 insertions(+), 7 deletions(-) diff --git a/ls8/cpu.py b/ls8/cpu.py index 53fc5de5e..f8768ad8f 100644 --- a/ls8/cpu.py +++ b/ls8/cpu.py @@ -23,7 +23,9 @@ def call_stack(self, func): 0b01100110: self.DEC, 0b01000101: self.PUSH, 0b01000110: self.POP, - 0b00000001: self.HLT + 0b00000001: self.HLT, + 0b01010000: self.CALL, + 0b00010001: self.RET } if func in branch_table: branch_table[func]() @@ -31,7 +33,7 @@ def call_stack(self, func): print('invalid function') sys.exit(1) - def LDI(self): # num_operands = (ir & 0b11000000) >> 6 + def LDI(self): reg_num = self.ram_read(self.pc+1) value = self.ram_read(self.pc+2) self.reg[reg_num] = value @@ -60,7 +62,6 @@ def INC(self): self.alu('INC', self.pc+1, None) def PUSH(self): - # print('push') #decrement SP self.sp -=1 #get next value @@ -79,11 +80,11 @@ def POP(self): self.sp +=1 self.pc += 2 - def ram_read(self, index): - return self.ram[index] + def ram_read(self, MAR): + return self.ram[MAR] - def ram_write(self, index, value): - self.ram[index] = value + def ram_write(self, MDR, MAR): + self.ram[MAR] = MDR def load(self, file_path): """Load a program into memory.""" @@ -96,6 +97,19 @@ def load(self, file_path): self.ram[address] = int(command, 2) address += 1 + def CALL(self): + ret_add = self.pc + 2 + self.reg[self.sp] -= 1 + # self.PUSH(self.pc+2) + self.ram[self.reg[self.sp]] = ret_add + reg_num = self.ram[self.pc +1] + # self.pc = ret_add + dest_add = self.reg[reg_num] + + def RET(self): + self.pc = self.reg[self.ram_read(self.pc + 1)] + self.reg[self.sp] += 1 + # # while open(filename) as f: # for address, line in enumerate(f): @@ -112,8 +126,23 @@ def alu(self, op, reg_a, reg_b): if op == "ADD": self.reg[self.pc+1] += self.reg[self.pc+2] + # self.pc += 3 + elif op == "SUB": + self.reg[self.ram[reg_a]] -= self.reg[self.ram[reg_b]] + # self.pc += 3 + 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 + # self.pc += 3 elif op == "MULT": self.reg[self.ram[reg_a]] *= self.reg[self.ram[reg_b]] + # self.pc += 3 else: raise Exception("Unsupported ALU operation") From fa91d3d8bca446b22f6fc11e86689b02094fbfc7 Mon Sep 17 00:00:00 2001 From: Mike Sinnema Date: Wed, 22 Jul 2020 15:14:30 -0700 Subject: [PATCH 4/5] still working on call and return --- ls8/cpu.py | 67 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 35 insertions(+), 32 deletions(-) diff --git a/ls8/cpu.py b/ls8/cpu.py index f8768ad8f..d6d338406 100644 --- a/ls8/cpu.py +++ b/ls8/cpu.py @@ -12,12 +12,12 @@ def __init__(self): 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[7] = 0xf4 # initialize stack pointer to RAM address f4 + 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, + 0b01000111: self.PRN, 0b10100010: self.MULT, 0b01100101: self.INC, 0b01100110: self.DEC, @@ -61,15 +61,25 @@ def DEC(self): def INC(self): self.alu('INC', self.pc+1, None) - def PUSH(self): + def PUSH(self, value =None): #decrement SP - self.sp -=1 + 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] + # reg_num = self.ram[self.pc + 1] + # value = self.reg[reg_num] #store it - self.ram[self.sp] = value + # 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') @@ -98,38 +108,31 @@ def load(self, file_path): address += 1 def CALL(self): - ret_add = self.pc + 2 - self.reg[self.sp] -= 1 - # self.PUSH(self.pc+2) - self.ram[self.reg[self.sp]] = ret_add - reg_num = self.ram[self.pc +1] - # self.pc = ret_add - dest_add = self.reg[reg_num] - + # 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.reg[self.ram_read(self.pc + 1)] + self.pc = self.ram_read(self.reg[self.sp]) self.reg[self.sp] += 1 - -# -# while open(filename) as f: -# for address, line in enumerate(f): -# line = line.split("#") -# try: -# v = int(line[0], 2) -# except ValueError: -# continue -# memory[address] = v - + # trace() def alu(self, op, reg_a, reg_b): """ALU operations.""" if op == "ADD": self.reg[self.pc+1] += self.reg[self.pc+2] - # self.pc += 3 + elif op == "SUB": self.reg[self.ram[reg_a]] -= self.reg[self.ram[reg_b]] - # self.pc += 3 + elif op == "CMP": if self.reg[self.ram[reg_a]] < self.reg[self.ram[reg_b]]: self.fl = 0b00000100 @@ -139,10 +142,10 @@ def alu(self, op, reg_a, reg_b): self.fl = 0b00000001 else: self.fl = 0b00000000 - # self.pc += 3 + elif op == "MULT": self.reg[self.ram[reg_a]] *= self.reg[self.ram[reg_b]] - # self.pc += 3 + else: raise Exception("Unsupported ALU operation") @@ -171,4 +174,4 @@ def run(self): self.running = True while self.running: ir = self.ram[self.pc] - self.call_stack(ir) \ No newline at end of file + self.call_stack(ir) \ No newline at end of file From 7dbc569a54a981782cf3ed652a759c62edb51f86 Mon Sep 17 00:00:00 2001 From: Mike Sinnema Date: Wed, 22 Jul 2020 20:19:03 -0700 Subject: [PATCH 5/5] started on cpu refactor --- ls8/ls8.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/ls8/ls8.py b/ls8/ls8.py index d66bc9d2a..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("examples/stack.ls8") -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