From 17b1f5cf14ab3dbdaf54d25d22250bd4a56b8c4e Mon Sep 17 00:00:00 2001 From: timislearning Date: Thu, 29 Oct 2020 10:41:23 -0400 Subject: [PATCH 1/3] Day 1 --- .idea/.gitignore | 8 ++++ .idea/Computer-Architecture.iml | 15 +++++++ .../inspectionProfiles/profiles_settings.xml | 6 +++ .idea/misc.xml | 4 ++ .idea/modules.xml | 8 ++++ .idea/vcs.xml | 6 +++ ls8/README.md | 2 + ls8/cpu.py | 43 +++++++++++++++++-- 8 files changed, 88 insertions(+), 4 deletions(-) create mode 100644 .idea/.gitignore create mode 100644 .idea/Computer-Architecture.iml create mode 100644 .idea/inspectionProfiles/profiles_settings.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/vcs.xml diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 000000000..73f69e095 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml +# Editor-based HTTP Client requests +/httpRequests/ diff --git a/.idea/Computer-Architecture.iml b/.idea/Computer-Architecture.iml new file mode 100644 index 000000000..d0fafc9e1 --- /dev/null +++ b/.idea/Computer-Architecture.iml @@ -0,0 +1,15 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 000000000..105ce2da2 --- /dev/null +++ b/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 000000000..d1e22ecb8 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 000000000..c25953416 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 000000000..94a25f7f4 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/ls8/README.md b/ls8/README.md index d9170d968..215026839 100644 --- a/ls8/README.md +++ b/ls8/README.md @@ -60,6 +60,8 @@ but you'll have to implement those three above instructions first! ## Step 0: IMPORTANT: inventory what is here! * Make a list of files here. +1. cpu.py emulates a cpu of LS-8 Microcomputer +2. ls8.py - uses cpu to run a program * Write a short 3-10-word description of what each file does. * Note what has been implemented, and what hasn't. * Read this whole file. diff --git a/ls8/cpu.py b/ls8/cpu.py index 9a307496e..3150da4c3 100644 --- a/ls8/cpu.py +++ b/ls8/cpu.py @@ -7,11 +7,17 @@ class CPU: def __init__(self): """Construct a new CPU.""" - pass - + #pass + self.ram = [0] * 256 # 256 ram + self. pc = 0 #program counter + self.reg = [0] * 8 # 8 bit regester + self.mar = 0 #memory address register + self.mdr = 0 #memory data register + self.flag = 0 #flag register + + self.running = True def load(self): """Load a program into memory.""" - address = 0 # For now, we've just hardcoded a program: @@ -62,4 +68,33 @@ def trace(self): def run(self): """Run the CPU.""" - pass + LDI = 0b10000010 + PRN = 0b01000111 + HLT = 0b00000001 + while self.running: + ir = self.ram_read(self.pc) # these are info reg and program counter + operand_a = self.ram_read(self.pc + 1) + operand_b = self.ram_read(self.pc + 2) + + if ir == HLT: + self.running = False + self.pc += 1 + elif ir == PRN: + print(self.reg[operand_a]) + self.pc += 2 + elif ir == LDI: + self.reg[operand_a] = operand_b + self.pc += 3 + else: + self.running = False + print(f'O00F bad input: {ir}') + + + + def ram_read(self, mar): + return self.ram[mar] + + + def ram_write(self, mar, mdr): + self.ram[mar] = mdr + From 199c0320877c14fda98072f6bbb3c76ea1740cef Mon Sep 17 00:00:00 2001 From: timislearning Date: Wed, 4 Nov 2020 20:22:38 -0500 Subject: [PATCH 2/3] day 3 --- ls8/cpu.py | 150 ++++++++++++++++++++++++++++++++++++++--------------- ls8/ls8.py | 12 ++++- 2 files changed, 118 insertions(+), 44 deletions(-) diff --git a/ls8/cpu.py b/ls8/cpu.py index 3150da4c3..b526294df 100644 --- a/ls8/cpu.py +++ b/ls8/cpu.py @@ -1,6 +1,16 @@ """CPU functionality.""" import sys +import os.path +HLT = 0b00000001 +LDI = 0b10000010 +PRN = 0b01000111 +MUL = 0b10100010 +PUSH = 0b01000101 + +POP = 0b01000110 + + class CPU: """Main CPU class.""" @@ -8,33 +18,75 @@ class CPU: def __init__(self): """Construct a new CPU.""" #pass - self.ram = [0] * 256 # 256 ram + self.ram = [0] * 256 # 256 ram can only be as 0-355 self. pc = 0 #program counter self.reg = [0] * 8 # 8 bit regester - self.mar = 0 #memory address register - self.mdr = 0 #memory data register - self.flag = 0 #flag register - + self.mar = 0 #memory address register memory address to read or write + self.mdr = 0 #memory data register holds the value to write or read + self.flag = 0 #flag register hold flag status + self.halted = False self.running = True - def load(self): - """Load a program into memory.""" - address = 0 + # Initialize the Stack Pointer + # SPpoints at the value at the top of the stack (most recently pushed), or at address F4 ifempty. + self.reg[7] = 0xF4 # 244 # int('F4', 16) + self.ir = 0 + # Setup Branch Table + self.branchtable = {} + self.branchtable[HLT] = self.execute_HLT + self.branchtable[LDI] = self.execute_LDI + self.branchtable[PRN] = self.execute_PRN + self.branchtable[MUL] = self.execute_MUL + self.branchtable[PUSH] = self.execute_PUSH + self.branchtable[POP] = self.execute_POP + + # Property wrapper for SP (Stack Pointer) + + @property + def sp(self): + return self.reg[7] + + @sp.setter + def sp(self, a): + self.reg[7] = a & 0xFF + + def instruction_size(self): + return ((self.ir >> 6) & 0b11) + 1 + + def instruction_sets_pc(self): + return ((self.ir >> 4) & 0b0001) == 1 - # For now, we've just hardcoded a program: + def ram_read(self, mar): + if mar >= 0 and mar < len(self.ram): + return self.ram[mar] + else: + print(f"Error:{mar}") + return -1 + + def ram_write(self, mar, mdr): + if mar >= 0 and mar < len(self.ram): + self.ram[mar] = mdr & 0xFF + else: + print(f"Error:{mdr}") - program = [ - # From print8.ls8 - 0b10000010, # LDI R0,8 - 0b00000000, - 0b00001000, - 0b01000111, # PRN R0 - 0b00000000, - 0b00000001, # HLT - ] + def load(self, file_name): + """Load a program into memory.""" - for instruction in program: - self.ram[address] = instruction - address += 1 + address = 0 + + file_path = os.path.join(os.path.dirname(__file__), file_name) + try: + with open(file_path) as f: + for line in f: + num = line.split("#")[0].strip() # "10000010" + try: + instruction = int(num, 2) + self.ram[address] = instruction + address += 1 + except: + continue + except: + print(f'Could not find file named: {file_name}') + sys.exit(1) def alu(self, op, reg_a, reg_b): @@ -68,33 +120,47 @@ def trace(self): def run(self): """Run the CPU.""" - LDI = 0b10000010 - PRN = 0b01000111 - HLT = 0b00000001 - while self.running: - ir = self.ram_read(self.pc) # these are info reg and program counter + + + while not self.halted: + self.ir = self.ram_read(self.pc) # these are info reg and program counter operand_a = self.ram_read(self.pc + 1) operand_b = self.ram_read(self.pc + 2) - if ir == HLT: - self.running = False - self.pc += 1 - elif ir == PRN: - print(self.reg[operand_a]) - self.pc += 2 - elif ir == LDI: - self.reg[operand_a] = operand_b - self.pc += 3 - else: - self.running = False - print(f'O00F bad input: {ir}') + if not self.instruction_sets_pc(): + self.pc += self.instruction_size() + self.exexute_instruction(operand_a,operand_b) + def exexute_instruction(self, operand_a, operand_b): + if self.ir in self.branchtable: + self.branchtable[self.ir](operand_a, operand_b) + else: + print('Error') + sys.exit(1) - def ram_read(self, mar): - return self.ram[mar] + + def execute_HLT(self, a=None, b=None): + self.halted = True + + def execute_LDI(self, reg_num, val): + self.reg[reg_num] = val + + def execute_PRN(self, reg_num, b=None): + print(self.reg[reg_num]) + + def execute_MUL(self, reg_num, reg_num2): + self.reg[reg_num] *= self.reg[reg_num2] + + def execute_PUSH(self, reg_num, b=None): + self.sp -= 1 + self.mdr = self.reg[reg_num] + self.ram_write(self.sp, self.mdr) + + def execute_POP(self, dest_reg_num, b=None): + self.mdr = self.ram_read(self.sp) + self.reg[dest_reg_num] = self.mdr + self.sp += 1 - def ram_write(self, mar, mdr): - self.ram[mar] = mdr diff --git a/ls8/ls8.py b/ls8/ls8.py index 74128d36b..797b75d58 100755 --- a/ls8/ls8.py +++ b/ls8/ls8.py @@ -1,11 +1,19 @@ #!/usr/bin/env python3 """Main.""" - +argv_message = '' import sys from cpu import * +import sys +if len(sys.argv) != 2: + print(argv_message) + sys.exit(1) +else: + + file_name = sys.argv[1] + cpu = CPU() -cpu.load() +cpu.load(file_name) cpu.run() \ No newline at end of file From 00a0cdec91b37d72ea0734bb4129133153236bee Mon Sep 17 00:00:00 2001 From: timislearning Date: Thu, 5 Nov 2020 21:52:24 -0500 Subject: [PATCH 3/3] day 4 --- ls8/cpu.py | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/ls8/cpu.py b/ls8/cpu.py index b526294df..be7f0c3c9 100644 --- a/ls8/cpu.py +++ b/ls8/cpu.py @@ -6,10 +6,13 @@ LDI = 0b10000010 PRN = 0b01000111 MUL = 0b10100010 -PUSH = 0b01000101 +PUSH = 0b01000101 POP = 0b01000110 +CALL = 0b01010000 +RET = 0b00010001 +ADD = 0b10100000 class CPU: @@ -26,7 +29,7 @@ def __init__(self): self.flag = 0 #flag register hold flag status self.halted = False self.running = True - # Initialize the Stack Pointer + # SPpoints at the value at the top of the stack (most recently pushed), or at address F4 ifempty. self.reg[7] = 0xF4 # 244 # int('F4', 16) self.ir = 0 @@ -38,8 +41,11 @@ def __init__(self): self.branchtable[MUL] = self.execute_MUL self.branchtable[PUSH] = self.execute_PUSH self.branchtable[POP] = self.execute_POP + self.branchtable[CALL] = self.execute_CALL + self.branchtable[ADD] = self.execute_ADD + self.branchtable[RET] = self.excute_RET - # Property wrapper for SP (Stack Pointer) + # Property wrapper @property def sp(self): @@ -162,5 +168,16 @@ def execute_POP(self, dest_reg_num, b=None): self.reg[dest_reg_num] = self.mdr self.sp += 1 + def execute_CALL(self, dest_reg_num, b=None): + self.sp -=1 + self.ram_write(self.sp, self.pc + self.instruction_size()) + self.pc = self.reg[dest_reg_num] + + def excute_RET(self, a=None, b=None): + self.mdr = self.ram_read(self.sp) + self.pc = self.mdr + self.sp += 1 + def execute_ADD(self, reg_num, reg_num1): + self.reg[reg_num] += self.reg[reg_num1]