#!/usr/bin/python3 # =================================================================== # my 6502 simulator # a start at a first cut # ------------------------------------------------------------------- # # My memory layout is not a real one. A real memory layout is # more complicated (Google 6502 memory layout). # # This is just to test my CPU implementation and a few selected # instructions. # # ---- my test memory layout # # 0 255 256 511 512 4095 # +--------+ +--------+ +---------------------------------+ # | zero | | stack | | program and data | # | page | | | | | # +--------+ +--------+ +---------------------------------+ # # Decimal Hex # 0 0x00 # 255 0xFF # 256 0x0100 # 511 0x01FF # 512 0x0200 # 4095 0x0FFF # 4096 0x1000 # # ---- registers and status register bits # # PC programm counter word (2 bytes) # SP stack pointer byte # A accmulator register byte # X X rergister byte # Y Y register byte # P status register byte # N bit (negative flag) # V bit (overflow flag) # B bit (break command flag) # D bit (decimal mode flag) # I bit (IRQ disable flag) # Z bit (zero flag) # C bit (carry flag) # # =================================================================== import sys MAX_MEM = 1024 * 4 mem = bytearray(MAX_MEM) # memory (4096 bytes) # ------------------------------------------------------------------- # ---- CPU # ------------------------------------------------------------------- class CPU: def __init__(self): self.reset() def reset(self): self.PC = 0x0200 # my program counter self.SP = 0xFF # my stack pointer self.A = 0x00 # accmulator register self.X = 0x00 # X register self.Y = 0x00 # Y register self.N = 0 # negative flag self.V = 0 # overflow flag self.B = 0 # break command flag self.D = 0 # decimal mode flag self.I = 0 # IRQ disable flag self.Z = 0 # zero flag self.C = 0 # carry flag def getN(self): return self.N def setN(self,x): if not verify_bit_value(x): sys.exit() self.N = x def statusN(self): if self.N: return True return False def getV(self): return self.V def setV(self,x): if not verify_bit_value(x): sys.exit() self.V = x def statusV(self): if self.V: return True return False def getB(self): return self.B def setB(self,x): if not verify_bit_value(x): sys.exit() self.B = x def statusB(self): if self.B: return True return False def getD(self): return self.D def setD(self,x): if not verify_bit_value(x): sys.exit() self.D = x def statusD(self): if self.B: return True return False def getI(self): return self.PI def setI(self,x): if not verify_bit_value(x): sys.exit() self.I = x def statusI(self): if self.B: return True return False def getZ(self): return self.Z def setZ(self,x): if not verify_bit_value(x): sys.exit() self.Z = x def statusZ(self): if self.B: return True return False def getC(self): return self.C def setC(self,x): if not verify_bit_value(x): sys.exit() self.C = x def statusC(self): if self.B: return True return False def resetP(self): self.N = 0 # negative flag self.V = 0 # overflow flag self.B = 0 # break command flag self.D = 0 # decimal mode flag self.I = 0 # IRQ disable flag self.Z = 0 # zero flag self.C = 0 # carry flag def getA(self): return self.A def setC(self,x): if not verify_byte_value(x): sys.exit() self.A = x def getX(self): return self.X def setC(self,x): if not verify_byte_value(x): sys.exit() self.X = x def getY(self): return self.Y def setC(self,x): if not verify_byte_value(x): sys.exit() self.Y = x def getPC(self): return self.PC def setPC(self,x): if not verify_word_value(x): sys.exit() self.PC = x def getSP(self): return self.SP def setSP(self,x): if not verify_word_value(x): sys.exit() self.SP = x def displayRegisters(self,title=None): print('-- CPU Registers ---------------------') if title: print(f'-- {title}') print(f'PC = {hex(self.PC):7} ({self.PC})') print(f'SP = {hex(self.SP):7} ({self.SP})') print(f'A = {hex(self.A):7} ({self.A})') print(f'X = {hex(self.X):7} ({self.X})') print(f'Y = {hex(self.Y):7} ({self.Y})') ##print(f'P.N = {self.N}') print(f'P.N = {self.statusN()}') ##print(f'P.V = {self.V}') print(f'P.V = {self.statusV()}') ##print(f'P.B = {self.B}') print(f'P.B = {self.statusB()}') ##print(f'P.D = {self.D}') print(f'P.D = {self.statusD()}') ##print(f'P.I = {self.I}') print(f'P.I = {self.statusI()}') ##print(f'P.Z = {self.Z}') print(f'P.Z = {self.statusZ()}') ##print(f'P.C = {self.C}') print(f'P.C = {self.statusC()}') print('--------------------------------------') def execute(mem): pass # ------------------------------------------------------------------- # ---- support functions # ------------------------------------------------------------------- def verify_bit_value(v): if v != 0 and v != 1: print(f'Illegal bit value ({v})') return False return True def verify_byte_value(v): if v < 0 or v > 255: print(f'Illegal byte value ({v})') return False return True def verify_word_value(v): if v < 0 and v > 65535: print(f'Illegal word value ({v})') return False return True def is_float(s): try: n = float(s) return (True,n) except: return (False,0.0) def is_int(s): try: n = int(s) return (True,n) except: return (False,0) def is_a_number(s): x,n = is_int(s) if x: return True x,n = is_float(s) if x: return True return False def init_memory(): mem = bytearray(MAX_MEM) # ------------------------------------------------------------------- # main # ------------------------------------------------------------------- if __name__ == '__main__': print() print('my 6502 CPU simulator') print() cpu = CPU() cpu.displayRegisters()