From 79be45dd22b393cdda6ed5919e4a9c95968499f3 Mon Sep 17 00:00:00 2001 From: Simone Ballard Date: Mon, 12 Apr 2021 21:19:28 -0600 Subject: [PATCH 01/10] initial look around --- ls8/cpu.py | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/ls8/cpu.py b/ls8/cpu.py index 9a307496e..c0373d28d 100644 --- a/ls8/cpu.py +++ b/ls8/cpu.py @@ -1,13 +1,14 @@ """CPU functionality.""" - +# import sys class CPU: """Main CPU class.""" def __init__(self): - """Construct a new CPU.""" - pass + self.registers = [0] * 8 + self.somethingelse = [0] * 256 + self.pc = 0 def load(self): """Load a program into memory.""" @@ -30,6 +31,15 @@ def load(self): self.ram[address] = instruction address += 1 + def ram_read(self, address): + for value in address: + self.ram[address.value] = value + return value + + def ram_write(newvalue, address): + for value in address: + value.replace(value, newvalue) + return value def alu(self, op, reg_a, reg_b): """ALU operations.""" @@ -61,5 +71,8 @@ def trace(self): print() def run(self): + running = True """Run the CPU.""" - pass + IR = self.ram[pc] + operand_a = self.ram[pc + 1] + operand_b = self.ram[pc + 2] \ No newline at end of file From 552ae6bdff55fbcd5b06d8fe023aa416c8a64de7 Mon Sep 17 00:00:00 2001 From: Simone Ballard Date: Mon, 12 Apr 2021 22:25:55 -0600 Subject: [PATCH 02/10] what I have so far w/o additional notes --- ls8/cpu.py | 47 +++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 41 insertions(+), 6 deletions(-) diff --git a/ls8/cpu.py b/ls8/cpu.py index c0373d28d..c650d9be7 100644 --- a/ls8/cpu.py +++ b/ls8/cpu.py @@ -2,13 +2,20 @@ # import sys +#instruction set: +HLT = 0 +LDI = 0, 8 +PRN = 0 + class CPU: """Main CPU class.""" def __init__(self): self.registers = [0] * 8 - self.somethingelse = [0] * 256 + self.ram = [0] * 256 self.pc = 0 +#not really sure where to put this + running = True def load(self): """Load a program into memory.""" @@ -70,9 +77,37 @@ def trace(self): print() - def run(self): - running = True - """Run the CPU.""" - IR = self.ram[pc] +#From the spec: +#When the LS-8 is booted, the following steps occur: + +#R0-R6 are cleared to 0. +#R7 is set to 0xF4. +#PC and FL registers are cleared to 0. +#RAM is cleared to 0. +#Subsequently, the program can be loaded into RAM starting at address 0x00. + + def run(self, pc): + instruction = self.ram[pc] operand_a = self.ram[pc + 1] - operand_b = self.ram[pc + 2] \ No newline at end of file + operand_b = self.ram[pc + 2] +#potential structure for LDI + if instruction == LDI: + reg_index = operand_a + num = operand_b + num = int(self.registers[reg_index]) + print(num) + pc += 3 +#potential structure for PRN + elif instruction == PRN: + reg_index = operand_a + num = self.registers[reg_index] + print(num) + pc += 2 +#potential structure for HLT + elif instruction == HLT: + running = False + sys.exit(0) + + else: + print("WRONG WAY") + sys.exit(1) \ No newline at end of file From 481a7d428fc141842239a23413ecb4c28eccea4d Mon Sep 17 00:00:00 2001 From: Simone Ballard Date: Wed, 14 Apr 2021 16:14:35 -0600 Subject: [PATCH 03/10] added file loader --- ls8/cpu.py | 110 ++++++++++++++++++++++++++--------------------------- 1 file changed, 53 insertions(+), 57 deletions(-) diff --git a/ls8/cpu.py b/ls8/cpu.py index c650d9be7..cd5ecaf80 100644 --- a/ls8/cpu.py +++ b/ls8/cpu.py @@ -3,9 +3,9 @@ import sys #instruction set: -HLT = 0 -LDI = 0, 8 -PRN = 0 +HLT = 0b00000001 +LDI = 0b10000010 +PRN = 0b01000111 class CPU: """Main CPU class.""" @@ -14,39 +14,34 @@ def __init__(self): self.registers = [0] * 8 self.ram = [0] * 256 self.pc = 0 -#not really sure where to put this - running = True + +#originally this part is `hardcoded` and needs the parser instead - def load(self): + def load(self, filename): """Load a program into memory.""" - - 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 - + 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 + + ram[address] = int(num) + address += 1 + + except FileNotFoundError: + print("file not found") + sys.exit(2) + + load(filename) + def ram_read(self, address): - for value in address: - self.ram[address.value] = value - return value + return self.ram[address] - def ram_write(newvalue, address): - for value in address: - value.replace(value, newvalue) - return value + def ram_write(self, newvalue, address): + self.ram[address] = newvalue def alu(self, op, reg_a, reg_b): """ALU operations.""" @@ -86,28 +81,29 @@ def trace(self): #RAM is cleared to 0. #Subsequently, the program can be loaded into RAM starting at address 0x00. - def run(self, pc): - instruction = self.ram[pc] - operand_a = self.ram[pc + 1] - operand_b = self.ram[pc + 2] -#potential structure for LDI - if instruction == LDI: - reg_index = operand_a - num = operand_b - num = int(self.registers[reg_index]) - print(num) - pc += 3 -#potential structure for PRN - elif instruction == PRN: - reg_index = operand_a - num = self.registers[reg_index] - print(num) - pc += 2 -#potential structure for HLT - elif instruction == HLT: - running = False - sys.exit(0) - - else: - print("WRONG WAY") - sys.exit(1) \ No newline at end of file + def run(self): + 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.registers[reg_index] = num + self.pc += 3 +# PRN + elif instruction == PRN: + reg_index = operand_a + num = self.registers[reg_index] + print(num) + self.pc += 2 +# HLT + elif instruction == HLT: + running = False + sys.exit(0) + + else: + print("WRONG WAY") + sys.exit(1) \ No newline at end of file From 17ab9a8f6f4436c8f0d5a4b53431ee3ffda76a91 Mon Sep 17 00:00:00 2001 From: Simone Ballard Date: Wed, 14 Apr 2021 17:01:14 -0600 Subject: [PATCH 04/10] MUL added --- ls8/cpu.py | 38 +++++++++++++++++++++++--------------- ls8/ls8.py | 15 ++++++++++++++- 2 files changed, 37 insertions(+), 16 deletions(-) diff --git a/ls8/cpu.py b/ls8/cpu.py index cd5ecaf80..66eb431cb 100644 --- a/ls8/cpu.py +++ b/ls8/cpu.py @@ -6,6 +6,7 @@ HLT = 0b00000001 LDI = 0b10000010 PRN = 0b01000111 +MUL = 0b10100010 class CPU: """Main CPU class.""" @@ -14,22 +15,22 @@ def __init__(self): self.registers = [0] * 8 self.ram = [0] * 256 self.pc = 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 - - ram[address] = int(num) - address += 1 + 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 + + ram[address] = int(num) + address += 1 except FileNotFoundError: print("file not found") @@ -48,9 +49,11 @@ def alu(self, op, reg_a, reg_b): 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() def trace(self): """ @@ -99,6 +102,11 @@ def run(self): num = self.registers[reg_index] print(num) self.pc += 2 +#MUL + elif instruction == MUL: + reg_index = operand_a + reg_index = operand_b + alu("MUL", self.reg_a, self.reg_b) # HLT elif instruction == HLT: running = False diff --git a/ls8/ls8.py b/ls8/ls8.py index 74128d36b..3acd2633c 100755 --- a/ls8/ls8.py +++ b/ls8/ls8.py @@ -5,7 +5,20 @@ import sys from cpu import * +if len(sys.argv) != 2: + print("Usage: python3 fileio.py ") + sys.exit(1) + +try: + with open(sys.argv[1]) as f: + for line in f: + print(int(line)) + +except FileNotFoundError: + print("file not found") + sys.exit(2) + cpu = CPU() -cpu.load() +cpu.load(filename) cpu.run() \ No newline at end of file From 5b03de18c00aaaa3695b8833326278c7bc67cba1 Mon Sep 17 00:00:00 2001 From: Simone Ballard Date: Thu, 15 Apr 2021 14:50:48 -0600 Subject: [PATCH 05/10] push and pop added --- ls8/cpu.py | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/ls8/cpu.py b/ls8/cpu.py index 66eb431cb..e28aad7a2 100644 --- a/ls8/cpu.py +++ b/ls8/cpu.py @@ -7,6 +7,8 @@ LDI = 0b10000010 PRN = 0b01000111 MUL = 0b10100010 +PUSH = 8 +POP = 10 class CPU: """Main CPU class.""" @@ -15,6 +17,9 @@ def __init__(self): self.registers = [0] * 8 self.ram = [0] * 256 self.pc = 0 + self.sp = 0 #set it to the first one in the stack? + + self.registers[self.sp] = 0xf4 #originally this part is `hardcoded` and needs the parser instead @@ -29,7 +34,7 @@ def load(self, filename): if num == '': continue - ram[address] = int(num) + self.ram[address] = int(num) address += 1 except FileNotFoundError: @@ -106,7 +111,24 @@ def run(self): elif instruction == MUL: reg_index = operand_a reg_index = operand_b - alu("MUL", self.reg_a, self.reg_b) + self.alu("MUL", self.reg_a, self.reg_b) +#PUSH + elif instruction == PUSH: + reg_index = self.ram[self.pc + 1] + val = self.registers[reg_index] + + self.registers[self.sp] -= 1 + + self.ram[self.registers[self.sp]] = val + self.pc += 2 +#POP + elif instruction == POP: + reg_index = self.ram[self.pc + 1] + + self.registers[reg_index] = self.ram[self.registers[self.sp]] + + self.registers[self.sp] += 1 + self.pc += 2 # HLT elif instruction == HLT: running = False From 266fda20f5031cbf2ac0b3510602fc047af8c423 Mon Sep 17 00:00:00 2001 From: Simone Ballard Date: Thu, 15 Apr 2021 18:02:42 -0600 Subject: [PATCH 06/10] Call and RET added --- ls8/cpu.py | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/ls8/cpu.py b/ls8/cpu.py index e28aad7a2..37a1ad2b5 100644 --- a/ls8/cpu.py +++ b/ls8/cpu.py @@ -9,6 +9,8 @@ MUL = 0b10100010 PUSH = 8 POP = 10 +CALL = 11 +RET = 12 class CPU: """Main CPU class.""" @@ -114,7 +116,7 @@ def run(self): self.alu("MUL", self.reg_a, self.reg_b) #PUSH elif instruction == PUSH: - reg_index = self.ram[self.pc + 1] + reg_index = operand_a val = self.registers[reg_index] self.registers[self.sp] -= 1 @@ -123,7 +125,7 @@ def run(self): self.pc += 2 #POP elif instruction == POP: - reg_index = self.ram[self.pc + 1] + reg_index = operand_a self.registers[reg_index] = self.ram[self.registers[self.sp]] @@ -133,6 +135,18 @@ def run(self): elif instruction == HLT: running = False sys.exit(0) +# CALL + elif instruction == CALL: + address_to_return_to = self.pc + 2 + self.registers[self.pc] -= 1 + self.ram[self.registers[self.sp]] = address_to_return_to + reg_index = operand_a + address_to_call = self.registers[reg_index] + self.pc = address_to_call + + elif instruction == RET: + self.pc = self.ram[self.registers[self.sp]] + self.registers[self.sp] + 1 else: print("WRONG WAY") From a38c6109660afb11eb7627469ee4c20aadcfa661 Mon Sep 17 00:00:00 2001 From: Simone Ballard Date: Thu, 15 Apr 2021 20:34:18 -0600 Subject: [PATCH 07/10] instruction binary added --- ls8/cpu.py | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/ls8/cpu.py b/ls8/cpu.py index 37a1ad2b5..19981a9fc 100644 --- a/ls8/cpu.py +++ b/ls8/cpu.py @@ -7,10 +7,10 @@ LDI = 0b10000010 PRN = 0b01000111 MUL = 0b10100010 -PUSH = 8 -POP = 10 -CALL = 11 -RET = 12 +PUSH = 0b01000101 +POP = 0b01000110 +CALL = 0b01010000 +RET = 0b00010001 class CPU: """Main CPU class.""" @@ -82,15 +82,6 @@ def trace(self): print() -#From the spec: -#When the LS-8 is booted, the following steps occur: - -#R0-R6 are cleared to 0. -#R7 is set to 0xF4. -#PC and FL registers are cleared to 0. -#RAM is cleared to 0. -#Subsequently, the program can be loaded into RAM starting at address 0x00. - def run(self): running = True while running: From 05cfa840e07485792dc89d18a0e13989bfc7873b Mon Sep 17 00:00:00 2001 From: Simone Ballard Date: Fri, 16 Apr 2021 12:22:49 -0600 Subject: [PATCH 08/10] just started --- ls8/cpu.py | 43 +++++++++++++++++++++++-------------------- ls8/ls8.py | 9 +-------- 2 files changed, 24 insertions(+), 28 deletions(-) diff --git a/ls8/cpu.py b/ls8/cpu.py index 19981a9fc..c040847dd 100644 --- a/ls8/cpu.py +++ b/ls8/cpu.py @@ -11,17 +11,22 @@ POP = 0b01000110 CALL = 0b01010000 RET = 0b00010001 +CMP = 0b10100111 +JMP = 0b01010100 +JEQ = 0b01010101 +JNE = 0b01010110 class CPU: """Main CPU class.""" def __init__(self): - self.registers = [0] * 8 + 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 - self.registers[self.sp] = 0xf4 + self.reg[self.sp] = 0xf4 #originally this part is `hardcoded` and needs the parser instead @@ -36,14 +41,13 @@ def load(self, filename): if num == '': continue - self.ram[address] = int(num) + self.ram[address] = int(num, 2) address += 1 except FileNotFoundError: print("file not found") sys.exit(2) - load(filename) def ram_read(self, address): return self.ram[address] @@ -92,35 +96,33 @@ def run(self): if instruction == LDI: reg_index = operand_a num = operand_b - self.registers[reg_index] = num + self.reg[reg_index] = num self.pc += 3 # PRN elif instruction == PRN: reg_index = operand_a - num = self.registers[reg_index] + num = self.reg[reg_index] print(num) self.pc += 2 #MUL elif instruction == MUL: - reg_index = operand_a - reg_index = operand_b - self.alu("MUL", self.reg_a, self.reg_b) + self.alu("MUL", operand_a, operand_b) #PUSH elif instruction == PUSH: reg_index = operand_a - val = self.registers[reg_index] + val = self.reg[reg_index] - self.registers[self.sp] -= 1 + self.reg[self.sp] -= 1 - self.ram[self.registers[self.sp]] = val + self.ram[self.reg[self.sp]] = val self.pc += 2 #POP elif instruction == POP: reg_index = operand_a - self.registers[reg_index] = self.ram[self.registers[self.sp]] + self.reg[reg_index] = self.ram[self.reg[self.sp]] - self.registers[self.sp] += 1 + self.reg[self.sp] += 1 self.pc += 2 # HLT elif instruction == HLT: @@ -129,15 +131,16 @@ def run(self): # CALL elif instruction == CALL: address_to_return_to = self.pc + 2 - self.registers[self.pc] -= 1 - self.ram[self.registers[self.sp]] = address_to_return_to + self.reg[self.pc] -= 1 + self.ram[self.reg[self.sp]] = address_to_return_to reg_index = operand_a - address_to_call = self.registers[reg_index] + address_to_call = self.reg[reg_index] self.pc = address_to_call - +# RET elif instruction == RET: - self.pc = self.ram[self.registers[self.sp]] - self.registers[self.sp] + 1 + self.pc = self.ram[self.reg[self.sp]] + self.reg[self.sp] + 1 +# else: print("WRONG WAY") diff --git a/ls8/ls8.py b/ls8/ls8.py index 3acd2633c..83855dcae 100755 --- a/ls8/ls8.py +++ b/ls8/ls8.py @@ -9,14 +9,7 @@ print("Usage: python3 fileio.py ") sys.exit(1) -try: - with open(sys.argv[1]) as f: - for line in f: - print(int(line)) - -except FileNotFoundError: - print("file not found") - sys.exit(2) +filename = sys.argv[1] cpu = CPU() From d40df88a9b97cae413c3e760696fff39f5bf5a3f Mon Sep 17 00:00:00 2001 From: Simone Ballard Date: Fri, 16 Apr 2021 14:40:05 -0600 Subject: [PATCH 09/10] updated --- ls8/cpu.py | 35 +++++++++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/ls8/cpu.py b/ls8/cpu.py index c040847dd..73c15fa56 100644 --- a/ls8/cpu.py +++ b/ls8/cpu.py @@ -16,6 +16,11 @@ JEQ = 0b01010101 JNE = 0b01010110 +# flags +L = 0b100 +G = 0b10 +E = 0b1 + class CPU: """Main CPU class.""" @@ -24,7 +29,7 @@ def __init__(self): self.ram = [0] * 256 self.pc = 0 self.sp = 0 #set it to the first one in the stack? - self.fl = 0 + self.fl = self.reg self.reg[self.sp] = 0xf4 @@ -65,6 +70,12 @@ def alu(self, op, reg_a, reg_b): 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): """ @@ -140,7 +151,27 @@ def run(self): 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") From b0a77a11def413630f004b4232c1903e70b40197 Mon Sep 17 00:00:00 2001 From: Simone Ballard Date: Fri, 16 Apr 2021 14:42:28 -0600 Subject: [PATCH 10/10] MVP --- ls8/cpu.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ls8/cpu.py b/ls8/cpu.py index 73c15fa56..233e68dae 100644 --- a/ls8/cpu.py +++ b/ls8/cpu.py @@ -29,7 +29,7 @@ def __init__(self): self.ram = [0] * 256 self.pc = 0 self.sp = 0 #set it to the first one in the stack? - self.fl = self.reg + self.fl = 0 self.reg[self.sp] = 0xf4