import time class CPU: def __init__(self): self.running = False self.IP = 254 self.acc = 0 self.flags = { 'C': False, 'Z': False, 'N': False, 'Eq': False } self.instruction = { 'opcode': False, 'operand': False } self.memory = False def load_memory(self, bytes): self.memory = bytes + bytearray(256 - len(bytes)) # print(self.memory) def start(self): self.running = True def step(self): if self.IP >= 255: # TODO CHECK self.IP = 0 print("IP:", toHex(self.IP)) self.instruction['opcode'] = self.memory[self.IP] self.IP = self.IP+1 self.instruction['operand'] = self.memory[self.IP] self.IP = self.IP+1 self.nums2mnems[self.instruction['opcode']](self, self.instruction['operand']) print("instr:", toHex(self.instruction['opcode']), toHex(self.instruction['operand'])) print("mnem:", self.nums2mnems[self.instruction['opcode']]) print("acc:", self.acc, "N:", self.flags['N']) print("running:", self.running) print() # self.print_screen() print("byte 26 (keyboard):", self.memory[26]) print() def hlt(self, operand): self.running = False def nop(self, operand): pass def lda_lit(self, operand): self.acc = operand self.flags['Z'] = True if self.acc == 0 else False self.flags['Eq'] = True if self.acc == operand else False self.flags['N'] = True if self.acc > 127 else False def lda_mem(self, operand): self.acc = self.memory[operand] self.flags['Z'] = True if self.acc == 0 else False self.flags['Eq'] = True if self.acc == operand else False self.flags['N'] = True if self.acc > 127 else False def sta_lit(self, operand): self.memory[operand] = self.acc def sta_mem(self, operand): self.memory[self.memory[operand]] = self.acc def add_lit(self, operand): self.acc = self.acc + operand if self.acc > 255: self.acc = self.acc % 256 self.flags['C'] = True else: self.flags['C'] = False self.flags['Z'] = True if self.acc == 0 else False self.flags['Eq'] = True if self.acc == operand else False self.flags['N'] = True if self.acc > 127 else False def add_mem(self, operand): self.acc = self.acc + self.memory[operand] if self.acc > 255: self.acc = self.acc % 256 self.flags['C'] = True else: self.flags['C'] = False self.flags['Z'] = True if self.acc == 0 else False self.flags['Eq'] = True if self.acc == operand else False self.flags['N'] = True if self.acc > 127 else False def sub_lit(self, operand): self.acc = self.acc - operand if self.acc < 0: self.acc = self.acc % 256 self.flags['C'] = True else: self.flags['C'] = False self.flags['Z'] = True if self.acc == 0 else False self.flags['Eq'] = True if self.acc == operand else False self.flags['N'] = True if self.acc > 127 else False def sub_mem(self, operand): self.acc = self.acc - self.memory[operand] if self.acc > 255: self.acc = self.acc % 256 self.flags['C'] = True else: self.flags['C'] = False self.flags['Z'] = True if self.acc == 0 else False self.flags['Eq'] = True if self.acc == operand else False self.flags['N'] = True if self.acc > 127 else False def jmp_lit(self, operand): self.IP = operand def jmp_mem(self, operand): self.IP = self.memory[operand] def ske(self, operand): # FIXME # if self.flags['Eq']: # self.IP += 2 if self.acc == operand: self.IP += 2 def skz(self, operand): if self.flags['Z']: self.IP += 2 def skn(self, operand): if self.flags['N']: self.IP += 2 def skc(self, operand): if self.flags['C']: self.IP += 2 def cst(self, operand): self.flags['C'] = True def ccl(self, operand): self.flags['C'] = False nums2mnems = { 0: hlt, # x0 1: nop, # x1 2: lda_lit, # 02 3: sta_lit, # 03 4: add_lit, # 04 5: sub_lit, # 05 6: jmp_lit, # 06 7: ske, # x7 8: skz, # x8 9: skn, # x9 10: skc, # A 11: cst, # B 12: ccl, # C 16: hlt, # 17: nop, # 18: lda_mem, # 12 19: sta_mem, # 13 20: add_mem, # 14 21: sub_mem, # 15 22: jmp_mem, # 16 23: ske, 24: skz, 25: skn, 26: skc, 27: cst, 28: ccl, }