# CSPT13 Computer Architecture II ## Guided Project Pt. 1 ``` """CPU functionality.""" import sys HLT = 0b00000001 LDI = 0b10000010 PRN = 0b01000111 class CPU: """Main CPU class.""" def __init__(self): """Construct a new CPU.""" self.registers = [0] * 8 self.registers[7] = 0xF4 self.pc = 0 self.ram = [0] * 256 self.halted = False def load(self): """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 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") def trace(self): """ Handy function to print out the CPU state. You might want to call this from run() if you need help debugging. """ print(f"TRACE: %02X | %02X %02X %02X |" % ( self.pc, #self.fl, #self.ie, self.ram_read(self.pc), self.ram_read(self.pc + 1), self.ram_read(self.pc + 2) ), end='') for i in range(8): print(" %02X" % self.reg[i], end='') print() def ram_read(self, address): return self.ram[address] def ram_write(self, value, address): self.ram[address] = value def run(self): """Run the CPU.""" while not self.halted: instruction_to_execute = self.ram_read(self.pc) operand_a = self.ram_read(self.pc + 1) operand_b = self.ram_read(self.pc + 2) self.execute_instruction(instruction_to_execute, operand_a, operand_b) def execute_instruction(self, instruction, operand_a, operand_b): if instruction == HLT: self.halted = True self.pc += 1 elif instruction == PRN: print(self.registers[operand_a]) self.pc += 2 elif instruction == LDI: self.registers[operand_a] = operand_b self.pc += 3 else: print("idk what to do.") pass ``` ## Parsing Operands from Instruction ``` # Meanings of the bits in the first byte of each instruction: `AABCDDDD` # * `AA` Number of operands for this opcode, 0-2 INSTRUCTION = 0b10000010 # >> 6 --> 0b100001 & 0b001100 --> 0b10 PC = 0 number_of_times_to_increment_pc = ((INSTRUCTION >> 6) & 0b11) + 1 PC += number_of_times_to_increment_pc ``` ## File I/O ``` import sys try: with open(sys.argv[1]) as my_file: for line in my_file: comment_split = line.split("#") maybe_binary_number = comment_split[0] try: x = int(maybe_binary_number, 2) print("{:08b}: {:d}".format(x, x)) except: print(f"failed to cast {maybe_binary_number} to an int") continue except FileNotFoundError: print("file not found...") ```