From 6e582412883b045ba9a66705a69e3f80ec53eef6 Mon Sep 17 00:00:00 2001 From: n loewen Date: Mon, 3 Mar 2025 19:52:12 +0000 Subject: [PATCH] Implement remaining instructions + basic 5x5 display printout --- src/cpu.py | 185 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 185 insertions(+) create mode 100644 src/cpu.py diff --git a/src/cpu.py b/src/cpu.py new file mode 100644 index 0000000..7da5078 --- /dev/null +++ b/src/cpu.py @@ -0,0 +1,185 @@ +import sys + +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('mem 254', self.memory[254]) + # print(self.memory) + + def start(self): + self.running = True + + def print_screen(self): + for i in range(5): + for j in range(5): + # print(f"{i}-{j}", end=" ") + # print(self.memory[(i*5)+j], end=" ") + memory_index = (i * 5) + j + if self.memory[memory_index] > 0: + print("#", end=" ") + else: + print("_", end=" ") + print() + + def step(self): + if self.IP >= 256: + self.IP = 0 + print("IP:", 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 + print("instr:", self.instruction['opcode'], self.instruction['operand']) + print("mnem:", self.nums2mnems[self.instruction['opcode']]) + self.nums2mnems[self.instruction['opcode']](self, self.instruction['operand']) + print("acc:", self.acc) + print("running:", self.running) + print() + self.print_screen() + print() + if not self.running: + sys.exit() + + def hlt(self, operand): + self.running = False + + def nop(self, operand): + pass + + def lda_lit(self, operand): + self.acc = operand + + def lda_mem(self, operand): + self.acc = memory[operand] + + def sta_lit(self, operand): + memory[operand] = self.acc + + def sta_mem(self, operand): + memory[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 = memory[operand] + + def ske(self, operand): + if self.flags['Eq']: + 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, + 1: nop, + 2: lda_lit, + 3: sta_lit, + 4: add_lit, + 5: sub_lit, + 6: jmp_lit, + 7: ske, + 8: skz, + 9: skn, + 10: skc, + 11: cst, + 12: ccl, + 16: hlt, + 17: nop, + 18: lda_mem, + 19: sta_mem, + 20: add_mem, + 21: sub_mem, + 22: jmp_mem, + 23: ske, + 24: skz, + 25: skn, + 26: skc, + 27: cst, + 28: ccl, + } + +cpu = CPU() + +prog = '04 FF 04 01 14 01 00 00' +program_bytes = bytes.fromhex(prog) +# Add jmp at addr 254: +program_with_jump = program_bytes + bytearray(254 - len(program_bytes)) + bytes.fromhex('06 00') +cpu.load_memory(program_with_jump) + +cpu.print_screen() + +cpu.start() +cpu.step() +cpu.step() +cpu.step() +cpu.step() +cpu.step()