示例#1
0
    def loadAssembly(self):
        # Enable/Disable actions
        self.actionLoad.setEnabled(False)
        self.actionRun.setEnabled(True)
        self.actionPause.setEnabled(True)
        self.actionStep.setEnabled(True)
        self.actionStop.setEnabled(True)
        editor = self.asmEdit
        editor.setReadOnly()

        assembly = editor.toPlainText()
        if not assembly:
            self.console.appendPlainText("Input Error.")
            self.restoreEditor()
            return
        self.assembler = Assembler(SEG_INIT)
        self.exe_file = self.assembler.compile(assembly)
        self.memory = Memory(MEMORY_SIZE, SEGMENT_SIZE)
        self.memory.load(self.exe_file)  # load code segment
        self.BIU = bus_interface_unit.bus_interface_unit(INSTRUCTION_QUEUE_SIZE, self.exe_file, self.memory)
        self.EU = execution_unit.execution_unit(self.BIU, True)
        self.cpu = CPU(self.BIU, self.EU, gui_mode=True)
        self.refreshModels()

        self.console.appendPlainText("Initial DS: " + hex(self.BIU.reg['DS']))
        self.console.appendPlainText("Initial CS: " + hex(self.BIU.reg['CS']))
        self.console.appendPlainText("Initial SS: " + hex(self.BIU.reg['SS']))
        self.console.appendPlainText("Initial ES: " + hex(self.BIU.reg['ES']))
        self.console.appendPlainText("Initial IP: " + hex(self.BIU.reg['IP']))
        self.console.appendPlainText("\nCPU initialized successfully.")
        self.console.appendPlainText("=" * 60 + '\n')
def test_write_Absolute():
    address_mode = Absolute
    cpu = CPU()
    memory = Memory(rom=[0x30, 0x01, 0xFF, 0x02, 0x0A, 0x05],
                    ram=list(map(lambda x: x % 256, range(Memory.ram_size()))))

    cpu.inc_cycle_by(-cpu.cycle)
    cpu.inc_pc_by(-cpu.pc + MemoryPositions.PRG_ROM_START.start)
    address = address_mode.fetch_address(cpu, memory)
    address_mode.write_to(cpu, memory, address, 50)
    assert address == 0x0130
    assert memory.ram[address] == 50
    assert cpu.cycle == 3

    cpu.inc_cycle_by(-cpu.cycle)
    address = address_mode.fetch_address(cpu, memory)
    address_mode.write_to(cpu, memory, address, 100)
    assert address == 0x02FF
    assert memory.ram[address] == 100
    assert cpu.cycle == 3

    cpu.inc_cycle_by(-cpu.cycle)
    address = address_mode.fetch_address(cpu, memory)
    address_mode.write_to(cpu, memory, address, 67)
    assert address == 0x050A
    assert memory.ram[address] == 67
    assert cpu.cycle == 3
def test_read_Absolute():
    address_mode = Absolute
    cpu = CPU()
    memory = Memory(rom=[0x32, 0x02, 0x7F, 0x01, 0xFF, 0x07],
                    ram=list(map(lambda x: x % 256, range(Memory.ram_size()))))

    cpu.inc_cycle_by(-cpu.cycle)
    cpu.inc_pc_by(-cpu.pc + MemoryPositions.PRG_ROM_START.start)
    address = address_mode.fetch_address(cpu, memory)
    value = address_mode.read_from(cpu, memory, address)
    assert address == 0x0232
    assert value == (0x0232 % 256)
    assert cpu.cycle == 3

    cpu.inc_cycle_by(-cpu.cycle)
    address = address_mode.fetch_address(cpu, memory)
    value = address_mode.read_from(cpu, memory, address)

    assert address == 0x017F
    assert value == (0x017F % 256)
    assert cpu.cycle == 3

    cpu.inc_cycle_by(-cpu.cycle)
    address = address_mode.fetch_address(cpu, memory)
    value = address_mode.read_from(cpu, memory, address)

    assert address == 0x07FF
    assert value == (0x07FF % 256)
    assert cpu.cycle == 3
示例#4
0
def test_TYA():
     cpu = CPU()
     memory = Memory()
     cpu.a = 1
     cpu.y = 2
     TYA = OpCodes.all[152]
     TYA.exec(cpu, memory)

     assert cpu.a == 2
     assert cpu.zero == False
     assert cpu.negative == False

     cpu.y = 0
     cpu.a = 1
     cpu.inc_cycle_by(-cpu.cycle)
     TYA.exec(cpu, memory)

     assert cpu.cycle == (TYA.cycles - 1)
     assert cpu.a == 0
     assert cpu.zero == True
     assert cpu.negative == False

     cpu.y = 0b10000001
     cpu.a = 1
     TYA.exec(cpu, memory)

     assert cpu.a == 0b10000001
     assert cpu.zero == False
     print(cpu.negative)
     assert cpu.negative == True
示例#5
0
def test_TAY():
     cpu = CPU()
     memory = Memory()
     cpu.y = 1
     cpu.a = 2
     TAY = OpCodes.all[168]
     TAY.exec(cpu, memory)

     assert cpu.y == 2
     assert cpu.zero == False
     assert cpu.negative == False

     cpu.a = 0
     cpu.y = 1
     cpu.inc_cycle_by(-cpu.cycle)
     TAY.exec(cpu, memory)

     assert cpu.cycle == (TAY.cycles - 1)
     assert cpu.y == 0
     assert cpu.zero == True
     assert cpu.negative == False

     cpu.a = 0b10000001
     cpu.y = 1
     TAY.exec(cpu, memory)

     assert cpu.y == 0b10000001
     assert cpu.zero == False
     print(cpu.negative)
     assert cpu.negative == True
def test_DEY_within_bounds():
    instruction = OpCodes.all[0x88]
    cpu = CPU()
    memory = Memory()
    cpu.inc_cycle_by(-cpu.cycle)
    cpu.y = 7
    instruction.exec(cpu, memory)

    assert cpu.cycle == (instruction.cycles - 1)
    assert cpu.y == 6
    assert cpu.zero == False
    assert cpu.negative == False
def test_read_IndirectY():
    address_mode = IndirectY
    cpu = CPU()
    memory = Memory(rom=[0x00, 0x02, 0x7F, 0x01, 0xFF, 0x07],
                    ram=list(map(lambda x: x % 256, range(Memory.ram_size()))))

    cpu.inc_cycle_by(-cpu.cycle)
    cpu.inc_pc_by(-cpu.pc + MemoryPositions.PRG_ROM_START.start)
    cpu.y = 4
    address = address_mode.fetch_address(cpu, memory)
    value = address_mode.read_from(cpu, memory, address)
    assert address == 0x0104
    assert value == address % 256

    cpu.inc_cycle_by(-cpu.cycle)
    cpu.y = 0xFF
    address = address_mode.fetch_address(cpu, memory)
    value = address_mode.read_from(cpu, memory, address)
    assert address == 0x0401
    assert value == address % 256
def test_write_IndirectY():
    address_mode = IndirectY
    cpu = CPU()
    memory = Memory(rom=[0x00, 0x02, 0x7F, 0x01, 0xFF, 0x07],
                    ram=list(map(lambda x: x % 256, range(Memory.ram_size()))))

    cpu.inc_cycle_by(-cpu.cycle)
    cpu.inc_pc_by(-cpu.pc + MemoryPositions.PRG_ROM_START.start)
    cpu.y = 4
    address = address_mode.fetch_address(cpu, memory)
    address_mode.write_to(cpu, memory, address, 9)
    assert address == 0x0104
    assert memory.ram[address] == 9

    cpu.inc_cycle_by(-cpu.cycle)
    cpu.y = 0xFF
    address = address_mode.fetch_address(cpu, memory)
    address_mode.write_to(cpu, memory, address, 50)
    assert address == 0x0401
    assert memory.ram[address] == 50
def test_read_IndirectX():
    address_mode = IndirectX
    cpu = CPU()
    memory = Memory(rom=[0x00, 0x02, 0x7F, 0x01, 0xFF, 0x07],
                    ram=list(map(lambda x: x % 256, range(Memory.ram_size()))))

    cpu.inc_cycle_by(-cpu.cycle)
    cpu.inc_pc_by(-cpu.pc + MemoryPositions.PRG_ROM_START.start)
    cpu.x = 4
    address = address_mode.fetch_address(cpu, memory)
    value = address_mode.read_from(cpu, memory, address)
    assert address == (((0x0504 + 1) % 256) << 8 | (0x0504 % 256))
    assert value == address % 256
    assert cpu.cycle == 5

    cpu.inc_cycle_by(-cpu.cycle)
    cpu.x = 0xFF
    address = address_mode.fetch_address(cpu, memory)
    value = address_mode.read_from(cpu, memory, address)
    assert address == (((0x0201 + 1) % 256) << 8 | (0x0201 % 256))
    assert value == address % 256
    assert cpu.cycle == 5
def test_Indirect():
    address_mode = Indirect
    cpu = CPU()
    memory = Memory(rom=[0x32, 0x02, 0x7F, 0x01, 0xFF, 0x07],
                    ram=list(map(lambda x: x % 256, range(Memory.ram_size()))))

    cpu.inc_cycle_by(-cpu.cycle)
    cpu.inc_pc_by(-cpu.pc + MemoryPositions.PRG_ROM_START.start)
    address = address_mode.fetch_address(cpu, memory)
    assert address == (((0x0232 + 1) % 256) << 8 | (0x0232 % 256))
    assert cpu.cycle == 4

    cpu.inc_cycle_by(-cpu.cycle)
    address = address_mode.fetch_address(cpu, memory)

    assert address == (((0x017F + 1) % 256) << 8 | (0x017F % 256))
    assert cpu.cycle == 4

    cpu.inc_cycle_by(-cpu.cycle)
    address = address_mode.fetch_address(cpu, memory)

    assert address == (((0x07FF + 1) % 256) << 8 | (0x07FF % 256))
    assert cpu.cycle == 4
示例#11
0
    def __init__(self, qApp=None):

        self.gui = uic.loadUi(_resource('mainwindow.ui'))
        # Assembly editor get focus on start
        self.asmEdit = self.gui.findChild(CodeEditor, "asmEdit")
        # Get console area
        self.console = self.gui.findChild(QPlainTextEdit, "txtConsole")

        self.assembler = Assembler(SEG_INIT)
        self.memory = Memory(MEMORY_SIZE, SEGMENT_SIZE)
        self.asmEdit.setPlainText(open(_resource('default.asm')).read())

        self.BIU = bus_interface_unit.bus_interface_unit(INSTRUCTION_QUEUE_SIZE, self.assembler, self.memory)
        self.EU = execution_unit.execution_unit(self.BIU, int_msg=True)
        self.cpu = CPU(self.BIU, self.EU, gui_mode=True)

        self.emitter = Emitter(self.emitStart)
        self.emitter.refresh.connect(self.refreshModels)
        self.setupEditorAndDiagram()
        self.setupSplitters()
        self.setupModels()
        self.setupTrees()
        self.setupActions()
        self.gui.showMaximized()
def test_DEY_negative():
    instruction = OpCodes.all[0x88]
    cpu = CPU()
    memory = Memory()
    cpu.inc_cycle_by(-cpu.cycle)
    cpu.y = 0
    instruction.exec(cpu, memory)

    assert cpu.cycle == (instruction.cycles - 1)
    assert cpu.y == 255
    assert cpu.zero == False
    assert cpu.negative == True

    cpu.inc_cycle_by(-cpu.cycle)
    cpu.y = -1
    instruction.exec(cpu, memory)

    assert cpu.cycle == (instruction.cycles - 1)
    assert cpu.y == 254
    assert cpu.zero == False
    assert cpu.negative == True
def test_DEX_zero():
    instruction = OpCodes.all[0xCA]
    cpu = CPU()
    memory = Memory()
    cpu.inc_cycle_by(-cpu.cycle)
    cpu.x = 1
    instruction.exec(cpu, memory)

    assert cpu.cycle == (instruction.cycles - 1)
    assert cpu.x == 0
    assert cpu.zero == True
    assert cpu.negative == False

    cpu.inc_cycle_by(-cpu.cycle)
    cpu.x = 257
    instruction.exec(cpu, memory)

    assert cpu.cycle == (instruction.cycles - 1)
    assert cpu.x == 0
    assert cpu.zero == True
    assert cpu.negative == False
示例#14
0
def main():
    help = '''
    Usage:
    python main.py ./tests/Requirement/bubble_sort.asm -i
    python main.py ./tests/Interrupt/show_date_time.asm -n
    注:-i表示打印中断信息,-n表示禁用debug。tests文件夹内含有大量测试用例
    可以参考文档,自行编写汇编语言程序来运行。
    '''

    DEBUG = True  # 是否单步运行
    INT_MSG = False  # 是否打印中断信息
    try:
        opts,args = getopt.getopt(sys.argv[2:],'-h-n-i',['help','nodebug','interrupt'])
        for opt_name,opt_value in opts:
            if opt_name in ('-h','--help'):
                print(help)
                exit()
            if opt_name in ('-n', '--nodebug'):
                DEBUG = False
            if opt_name in ('-i', '--interrupt'):
                INT_MSG = True
        with open(sys.argv[1], 'r', encoding='utf-8') as file:
            asm_code = file.read()
    except:
        print(help)
        sys.exit("Parameter incorrect")
   
    assembler = Assembler(SEG_INIT)
    exe_file = assembler.compile(asm_code)
    memory = Memory(MEMORY_SIZE, SEGMENT_SIZE)
    memory.load(exe_file) # load code segment

    BIU = bus_interface_unit.bus_interface_unit(INSTRUCTION_QUEUE_SIZE, exe_file, memory)
    EU = execution_unit.execution_unit(BIU, INT_MSG)
    cpu = CPU(BIU, EU, gui_mode=False)
    print("\nCPU initialized successfully.")
    print("=" * 80)

    while not cpu.check_done():
        cpu.iterate(debug=DEBUG)
    cpu.print_end_state()
示例#15
0
def emulate(file_path):
    nestest_log_format = args.nestest
    automation_mode = args.automation
    running = True
    file_contents = read_file(file_path)
    cartridge = Cartridge.from_bytes(file_contents)
    ppu = PPU(cartridge.chr_rom, mirroring=cartridge.header.flags_6&0b00000001)
    memory = Memory(cartridge.prg_rom,ppu=ppu)
    cpu = CPU(log_compatible_mode=nestest_log_format)
    ppu.setNMI(cpu,memory,NMI)

    reset_pos_low = memory.fetch(MemoryPositions.RESET.start)
    reset_pos_high = memory.fetch(MemoryPositions.RESET.end)
    reset_pos = MemoryPositions.PRG_ROM_START.wrap(
        AddressMode.get_16_bits_addr_from_high_low((reset_pos_high << 8) & HIGH_BITS_MASK, reset_pos_low & LOW_BITS_MASK))
    cpu.pc = reset_pos

    if nestest_log_format:
        # hack for Nintendulator nestest log comparison
        cpu.flags = 0x24
        cpu.inc_cycle_by(7)
    if automation_mode:
        cpu.pc = MemoryPositions.PRG_ROM_START.start

    i = 0
    line = 0

    while running:
        try:
            previous_state = CPUState(pc=cpu.pc, sp=cpu.sp, a=cpu.a, x=cpu.x, y=cpu.y, p=StatusRegisterFlags(int_value=cpu.flags), addr=cpu.addr, data=cpu.data,
                                      cycle=cpu.cycle, log_compatible_mode=nestest_log_format)
            if previous_state.pc == 0xC66E:
                # TODO: remove, this is a breakpoint for debugging
                aaaa = ""

            ppu.reloadControllers()#reloads controllers every tick

            i+=1
            if (i==114):

                ppu.scanLine(line)
                i=0
                line+=1
                if line==262:
                    line=0

            decoded = cpu.exec_in_cycle(fetch_and_decode_instruction, cpu, memory)  # fetching and decoding a instruction always take 1 cycle
            if decoded:
                decoded.exec(cpu, memory)
                if isinstance(decoded, BRK):
                    # abort program on BRK
                    running = False
                    print("Break")
                    break
                #print_debug_line(cpu, previous_state, decoded, nestest_log_format)
                cpu.clear_state_mem()
        except IndexError as e:
            # we've reached a program counter that is not within memory bounds
            print(e)
            running = False
        except KeyError as e:
            # print("Can't find instruction by code {}".format(e))
            cpu.inc_pc_by(1)
        except Exception as e:
            print(e)
            cpu.inc_pc_by(1)
示例#16
0
class MainWindow(object):
    def __init__(self, qApp=None):

        self.gui = uic.loadUi(_resource('mainwindow.ui'))
        # Assembly editor get focus on start
        self.asmEdit = self.gui.findChild(CodeEditor, "asmEdit")
        # Get console area
        self.console = self.gui.findChild(QPlainTextEdit, "txtConsole")

        self.assembler = Assembler(SEG_INIT)
        self.memory = Memory(MEMORY_SIZE, SEGMENT_SIZE)
        self.asmEdit.setPlainText(open(_resource('default.asm')).read())

        self.BIU = bus_interface_unit.bus_interface_unit(INSTRUCTION_QUEUE_SIZE, self.assembler, self.memory)
        self.EU = execution_unit.execution_unit(self.BIU, int_msg=True)
        self.cpu = CPU(self.BIU, self.EU, gui_mode=True)

        self.emitter = Emitter(self.emitStart)
        self.emitter.refresh.connect(self.refreshModels)
        self.setupEditorAndDiagram()
        self.setupSplitters()
        self.setupModels()
        self.setupTrees()
        self.setupActions()
        self.gui.showMaximized()

    def setupEditorAndDiagram(self):
        # self.asmEdit = QPlainTextEdit()
        self.asmEdit.setFocus()
        self.asmEdit.setStyleSheet("""QPlainTextEdit{
            font-family: 'Hack NF'; 
            font-weight: bold;
            font-size: 11pt;
            color: #ccc; 
            background-color: #282828;}""")
        self.highlight = AssemblyHighlighter(self.asmEdit.document())


    def setupSplitters(self):
        mainsplitter = self.gui.findChild(QSplitter, "mainsplitter")
        mainsplitter.setStretchFactor(0, 3)
        mainsplitter.setStretchFactor(1, 3)
        mainsplitter.setStretchFactor(2, 16)
        mainsplitter.setStretchFactor(3, 4)
        mainsplitter.setStretchFactor(4, 3)

        leftsplitter = self.gui.findChild(QSplitter, "leftsplitter")
        leftsplitter.setStretchFactor(0, 8)
        leftsplitter.setStretchFactor(1, 5)
        leftsplitter.setStretchFactor(2, 9)

        middlesplitter = self.gui.findChild(QSplitter, "middlesplitter")
        middlesplitter.setStretchFactor(0, 2)
        middlesplitter.setStretchFactor(1, 1)

    def setupModels(self):
        self.genRegsModel = RegistersModel(self.cpu.EU, (
                'AX', 'BX', 'CX', 'DX', 'SP', 'BP', 'SI', 'DI',
            ))
        self.specRegsModel = RegistersModel(self.cpu.BIU, (
                'DS', 'CS', 'SS', 'ES', 'IP',
            ))
        self.stateRegsModel = FlagModel(self.cpu.EU, (
                'CF', 'PF', 'AF', 'Z', 'S', 'O', 'TF', 'IF', 'DF',
            ))
        self.CodeSegModel = CodeSegModel(self.BIU, self.BIU.reg['IP'])
        self.StackSegModel = StackSegModel(self.BIU, self.EU.reg['SP'])
        self.DataSegModel = DataSegModel(self.BIU)

    def setupTrees(self):
        treeGenericRegs = self.gui.findChild(QTreeView, "treeGenericRegs")
        treeGenericRegs.setModel(self.genRegsModel)
        treeGenericRegs.expandAll()
        treeGenericRegs.resizeColumnToContents(0)
        treeGenericRegs.resizeColumnToContents(1)

        treeSpecificRegs = self.gui.findChild(QTreeView, "treeSpecificRegs")
        treeSpecificRegs.setModel(self.specRegsModel)
        treeSpecificRegs.expandAll()
        treeSpecificRegs.resizeColumnToContents(0)
        treeSpecificRegs.resizeColumnToContents(1)

        treeStateRegs = self.gui.findChild(QTreeView, "treeStateRegs")
        treeStateRegs.setModel(self.stateRegsModel)
        treeStateRegs.expandAll()
        treeStateRegs.resizeColumnToContents(0)
        treeStateRegs.resizeColumnToContents(1)

        # memory
        self.treeMemory = self.gui.findChild(QTreeView, "treeMemory")
        treeMemory = self.treeMemory
        treeMemory.setModel(self.CodeSegModel)
        treeMemory.resizeColumnToContents(0)
        treeMemory.resizeColumnToContents(1)

        self.treeMemory2 = self.gui.findChild(QTreeView, "treeMemory2")
        treeMemory2 = self.treeMemory2
        treeMemory2.setModel(self.StackSegModel)
        treeMemory2.resizeColumnToContents(0)
        treeMemory2.resizeColumnToContents(1)

        self.treeMemory3 = self.gui.findChild(QTreeView, "treeMemory3")
        treeMemory3 = self.treeMemory3
        treeMemory3.setModel(self.DataSegModel)
        treeMemory3.resizeColumnToContents(0)
        treeMemory3.resizeColumnToContents(1)

    def setupActions(self):
        self.actionNew = self.gui.findChild(QAction, "actionNew")
        self.actionNew.triggered.connect(self.newAction)

        self.actionOpen = self.gui.findChild(QAction, "actionOpen")
        self.actionOpen.triggered.connect(self.openAction)

        self.actionSave = self.gui.findChild(QAction, "actionSave")
        self.actionSave.triggered.connect(self.saveAction)

        self.actionLoad = self.gui.findChild(QAction, "actionLoad")
        self.actionLoad.triggered.connect(self.loadAssembly)

        self.actionRun = self.gui.findChild(QAction, "actionRun")
        self.actionRun.triggered.connect(self.runAction)

        self.actionPause = self.gui.findChild(QAction, "actionPause")
        self.actionPause.triggered.connect(self.pauseAction)
        
        self.actionStep = self.gui.findChild(QAction, "actionStep")
        self.actionStep.triggered.connect(self.nextInstruction)

        self.actionStop = self.gui.findChild(QAction, "actionStop")
        self.actionStop.triggered.connect(self.stopAction)

    def loadAssembly(self):
        # Enable/Disable actions
        self.actionLoad.setEnabled(False)
        self.actionRun.setEnabled(True)
        self.actionPause.setEnabled(True)
        self.actionStep.setEnabled(True)
        self.actionStop.setEnabled(True)
        editor = self.asmEdit
        editor.setReadOnly()

        assembly = editor.toPlainText()
        if not assembly:
            self.console.appendPlainText("Input Error.")
            self.restoreEditor()
            return
        self.assembler = Assembler(SEG_INIT)
        self.exe_file = self.assembler.compile(assembly)
        self.memory = Memory(MEMORY_SIZE, SEGMENT_SIZE)
        self.memory.load(self.exe_file)  # load code segment
        self.BIU = bus_interface_unit.bus_interface_unit(INSTRUCTION_QUEUE_SIZE, self.exe_file, self.memory)
        self.EU = execution_unit.execution_unit(self.BIU, True)
        self.cpu = CPU(self.BIU, self.EU, gui_mode=True)
        self.refreshModels()

        self.console.appendPlainText("Initial DS: " + hex(self.BIU.reg['DS']))
        self.console.appendPlainText("Initial CS: " + hex(self.BIU.reg['CS']))
        self.console.appendPlainText("Initial SS: " + hex(self.BIU.reg['SS']))
        self.console.appendPlainText("Initial ES: " + hex(self.BIU.reg['ES']))
        self.console.appendPlainText("Initial IP: " + hex(self.BIU.reg['IP']))
        self.console.appendPlainText("\nCPU initialized successfully.")
        self.console.appendPlainText("=" * 60 + '\n')
    
    def newAction(self):
        self.stopAction()
        self.asmEdit.setPlainText('\n'*30)
        self.restoreEditor()

    def saveAction(self):
        self.stopAction()
        filename = QFileDialog().getSaveFileName(self.gui, 'Save file', filter='*.asm', initialFilter='*.asm')[0]
        if os.path.exists(filename):
            with open(filename,'w') as f:
                text=self.asmEdit.toPlainText()
                f.write(text)

    def openAction(self):
        self.stopAction()
        filename = QFileDialog().getOpenFileName(self.gui, "Open File")[0]
        if os.path.exists(filename) and self.asmEdit.document().isModified():
            answer = QMessageBox.question(self.gui, "Modified Code",
                """<b>The current code is modified</b>
                   <p>What do you want to do?</p>
                """,
                QMessageBox.Discard | QMessageBox.Cancel,
                QMessageBox.Cancel)
            if answer == QMessageBox.Cancel:
                return
        if os.path.exists(filename):
            text = open(filename, encoding='utf-8').read()
            if len(text.split('\n')) < 30:
                text += '\n' * (30-len(text.split('\n')))
            self.asmEdit.setPlainText(text)
            self.restoreEditor()

    def emitStart(self, refresh):
        self.cpu.EU.interrupt = False
        while not self.cpu.check_done():
            self.cpu.iterate(debug=False)
            refresh.emit()
            time.sleep(0.1)
        print("Emit ended")
        self.actionRun.setEnabled(True)
        self.actionStep.setEnabled(True)
        self.cpu.print_end_state()
        refresh.emit()
        if self.cpu.EU.shutdown:
            self.cpu.EU.print("CPU Shutdown.")
            self.actionLoad.setEnabled(True)
            self.actionRun.setEnabled(False)
            self.actionPause.setEnabled(False)
            self.actionStep.setEnabled(False)
            self.actionStop.setEnabled(True)

    def runAction(self):
        print("run...")
        self.actionRun.setEnabled(False)
        self.actionStep.setEnabled(False)        
        self.emitter.start()

    def nextInstruction(self):
        print("step...")
        self.cpu.EU.interrupt = False
        if not self.cpu.check_done():
            self.cpu.iterate(debug=False)
            self.refreshModels()

        if self.cpu.EU.shutdown:
            self.cpu.print_end_state()
            self.restoreEditor()
        print("step end")

    def pauseAction(self):
        self.cpu.EU.interrupt = True
        self.actionRun.setEnabled(True)
        self.actionStep.setEnabled(True)

    def stopAction(self):
        self.pauseAction()
        self.restoreEditor()

    def restoreEditor(self):
        # Enable/Disable actions
        self.actionLoad.setEnabled(True)
        self.actionRun.setEnabled(False)
        self.actionPause.setEnabled(False)
        self.actionStep.setEnabled(False)
        self.actionStop.setEnabled(False)
        # Re-enable editor
        self.asmEdit.setReadOnly(False)
        self.asmEdit.setFocus()

    def refreshModels(self):
        self.console.moveCursor(self.console.textCursor().End)
        self.console.insertPlainText(self.cpu.EU.output)
        self.cpu.EU.output = ''
        self.setupModels()
        self.setupTrees()

    def show(self):
        self.gui.show()
示例#17
0
def test_read_AbsoluteX():
    address_mode = AbsoluteX
    cpu = CPU()
    memory = Memory(rom=[0x32, 0x02, 0x7F, 0x01, 0x00, 0x20], ram=list(map(lambda x: x % 256, range(Memory.ram_size()))))

    cpu.inc_cycle_by(-cpu.cycle)
    cpu.inc_pc_by(-cpu.pc + MemoryPositions.PRG_ROM_START.start)
    cpu.x = 0x0A
    address = address_mode.fetch_address(cpu, memory)
    value = address_mode.read_from(cpu, memory, address)
    assert address == 0x023C
    assert value == (0x023C % 256)

    cpu.inc_cycle_by(-cpu.cycle)
    cpu.x = 0xA1
    address = address_mode.fetch_address(cpu, memory)
    value = address_mode.read_from(cpu, memory, address)

    assert address == 0x0220
    assert value == (0x0220 % 256)

    cpu.inc_cycle_by(-cpu.cycle)
    cpu.x = 0x07
    address = address_mode.fetch_address(cpu, memory)
    value = address_mode.read_from(cpu, memory, address)

    assert address == 0x2007
示例#18
0
def test_Immediate():
    address_mode = Immediate
    cpu = CPU()
    memory = Memory(rom=[0x00])

    cpu.inc_cycle_by(-cpu.cycle)
    cpu.inc_pc_by(-cpu.pc)
    cpu.inc_pc_by(MemoryPositions.PRG_ROM_START.start)
    address = address_mode.fetch_address(cpu, memory)
    value = address_mode.read_from(cpu, memory, address)

    assert address == 0x00
    assert value == 0x00

    cpu.inc_cycle_by(-cpu.cycle)
    cpu.inc_pc_by(-cpu.pc)
    cpu.inc_pc_by(MemoryPositions.PRG_ROM_START.start)
    memory.rom[0] = 0x10
    address = address_mode.fetch_address(cpu, memory)
    value = address_mode.read_from(cpu, memory, address)

    assert address == 0x10
    assert value == 0x10

    cpu.inc_cycle_by(-cpu.cycle)
    cpu.inc_pc_by(-cpu.pc)
    cpu.inc_pc_by(MemoryPositions.PRG_ROM_START.start)
    memory.rom[0] = 0xFF
    address = address_mode.fetch_address(cpu, memory)
    value = address_mode.read_from(cpu, memory, address)

    assert address == 0xFF
    assert value == 0xFF
示例#19
0
def test_read_Accumulator():
    address_mode = Accumulator
    cpu = CPU()
    memory = Memory()

    cpu.inc_cycle_by(-cpu.cycle)
    address = address_mode.fetch_address(cpu, memory)
    address_mode.write_to(cpu, memory, address, 5)

    assert address is None
    assert cpu.a == 5

    cpu.inc_cycle_by(-cpu.cycle)
    cpu.inc_pc_by(-cpu.pc)
    cpu.inc_pc_by(MemoryPositions.PRG_ROM_START.start)
    cpu.a = 0x10
    address = address_mode.fetch_address(cpu, memory)
    address_mode.write_to(cpu, memory, address, 105)

    assert address is None
    assert cpu.a == 105

    cpu.inc_cycle_by(-cpu.cycle)
    cpu.inc_pc_by(-cpu.pc)
    cpu.inc_pc_by(MemoryPositions.PRG_ROM_START.start)
    cpu.a = 0xFF
    address = address_mode.fetch_address(cpu, memory)
    address_mode.write_to(cpu, memory, address, 255)

    assert address is None
    assert cpu.a == 255
示例#20
0
def test_write_AbsoluteX():
    address_mode = AbsoluteX
    cpu = CPU()
    memory = Memory(rom=[0x30, 0x01, 0xFF, 0x02, 0x0A, 0x05], ram=list(map(lambda x: x % 256, range(Memory.ram_size()))))

    cpu.inc_cycle_by(-cpu.cycle)
    cpu.inc_pc_by(-cpu.pc + MemoryPositions.PRG_ROM_START.start)
    cpu.x = 0x25
    address = address_mode.fetch_address(cpu, memory)
    address_mode.write_to(cpu, memory, address, 20)
    assert address == 0x0155
    assert memory.ram[address] == 20

    cpu.inc_cycle_by(-cpu.cycle)
    cpu.x = 0x30
    address = address_mode.fetch_address(cpu, memory)
    address_mode.write_to(cpu, memory, address, 100)
    assert address == 0x032F
    assert memory.ram[address] == 100

    cpu.inc_cycle_by(-cpu.cycle)
    cpu.x = 0x20
    address = address_mode.fetch_address(cpu, memory)
    address_mode.write_to(cpu, memory, address, 67)
    assert address == 0x052A
    assert memory.ram[address] == 67
示例#21
0
def test_read_Accumulator():
    address_mode = Accumulator
    cpu = CPU()
    memory = Memory()

    cpu.a = 0x00
    cpu.inc_cycle_by(-cpu.cycle)
    address = address_mode.fetch_address(cpu, memory)
    value = address_mode.read_from(cpu, memory, address)

    assert address is None
    assert value == 0x00

    cpu.inc_cycle_by(-cpu.cycle)
    cpu.inc_pc_by(-cpu.pc)
    cpu.inc_pc_by(MemoryPositions.PRG_ROM_START.start)
    cpu.a = 0x10
    address = address_mode.fetch_address(cpu, memory)
    value = address_mode.read_from(cpu, memory, address)

    assert address is None
    assert value == 0x10

    cpu.inc_cycle_by(-cpu.cycle)
    cpu.inc_pc_by(-cpu.pc)
    cpu.inc_pc_by(MemoryPositions.PRG_ROM_START.start)
    cpu.a = 0xFF
    address = address_mode.fetch_address(cpu, memory)
    value = address_mode.read_from(cpu, memory, address)

    assert address is None
    assert value == 0xFF
示例#22
0
def test_ROR_accumulator():
    instruction = OpCodes.all[0x6A]
    cpu = CPU()
    memory = Memory()
    cpu.inc_cycle_by(-cpu.cycle)
    cpu.a = 0b00000000
    cpu.carry = False
    instruction.exec(cpu, memory)

    assert cpu.cycle == (instruction.cycles - 1)
    assert cpu.a == 0b00000000
    assert cpu.zero == True
    assert cpu.carry == False
    assert cpu.negative == False

    cpu.inc_cycle_by(-cpu.cycle)
    cpu.a = 0b00000001
    cpu.carry = False
    instruction.exec(cpu, memory)

    assert cpu.cycle == (instruction.cycles - 1)
    assert cpu.a == 0b00000000
    assert cpu.zero == True
    assert cpu.carry == True
    assert cpu.negative == False

    cpu.inc_cycle_by(-cpu.cycle)
    cpu.a = 0b01000000
    cpu.carry = False
    instruction.exec(cpu, memory)

    assert cpu.cycle == (instruction.cycles - 1)
    assert cpu.a == 0b00100000
    assert cpu.zero == False
    assert cpu.carry == False
    assert cpu.negative == False

    cpu.inc_cycle_by(-cpu.cycle)
    cpu.a = 0b10000000
    cpu.carry = False
    instruction.exec(cpu, memory)

    assert cpu.cycle == (instruction.cycles - 1)
    assert cpu.a == 0b01000000
    assert cpu.zero == False
    assert cpu.carry == False
    assert cpu.negative == False

    cpu.inc_cycle_by(-cpu.cycle)
    cpu.a = 0b00000000
    cpu.carry = True
    instruction.exec(cpu, memory)

    assert cpu.cycle == (instruction.cycles - 1)
    assert cpu.a == 0b10000000
    assert cpu.zero == False
    assert cpu.carry == False
    assert cpu.negative == True

    cpu.inc_cycle_by(-cpu.cycle)
    cpu.a = 0b00000010
    cpu.carry = True
    instruction.exec(cpu, memory)

    assert cpu.cycle == (instruction.cycles - 1)
    assert cpu.a == 0b10000001
    assert cpu.zero == False
    assert cpu.carry == False
    assert cpu.negative == True

    cpu.inc_cycle_by(-cpu.cycle)
    cpu.a = 0b01000000
    cpu.carry = True
    instruction.exec(cpu, memory)

    assert cpu.cycle == (instruction.cycles - 1)
    assert cpu.a == 0b10100000
    assert cpu.zero == False
    assert cpu.carry == False
    assert cpu.negative == True

    cpu.inc_cycle_by(-cpu.cycle)
    cpu.a = 0b00000001
    cpu.carry = True
    instruction.exec(cpu, memory)

    assert cpu.cycle == (instruction.cycles - 1)
    assert cpu.a == 0b10000000
    assert cpu.zero == False
    assert cpu.carry == True
    assert cpu.negative == True
def test_read_ZeroPageX():
    address_mode = ZeroPageX
    cpu = CPU()
    memory = Memory(rom=list(range(256)), ram=list(reversed(range(256))))

    cpu.inc_cycle_by(-cpu.cycle)
    cpu.inc_pc_by(-cpu.pc + MemoryPositions.PRG_ROM_START.start)
    cpu.x = 1
    address = address_mode.fetch_address(cpu, memory)
    value = address_mode.read_from(cpu, memory, address)
    assert address == 1
    assert value == 254
    assert cpu.cycle == 3

    cpu.inc_cycle_by(-cpu.cycle)
    cpu.inc_pc_by(-cpu.pc + MemoryPositions.PRG_ROM_START.start + 20)
    cpu.x = 10
    address = address_mode.fetch_address(cpu, memory)
    value = address_mode.read_from(cpu, memory, address)

    assert address == 30
    assert value == 225
    assert cpu.cycle == 3

    cpu.inc_cycle_by(-cpu.cycle)
    cpu.inc_pc_by(-cpu.pc + MemoryPositions.PRG_ROM_START.start + 100)
    cpu.x = 5
    address = address_mode.fetch_address(cpu, memory)
    value = address_mode.read_from(cpu, memory, address)

    assert address == 105
    assert value == 150
    assert cpu.cycle == 3

    cpu.inc_cycle_by(-cpu.cycle)
    cpu.inc_pc_by(-cpu.pc + MemoryPositions.PRG_ROM_START.start + 255)
    cpu.x = 0
    address = address_mode.fetch_address(cpu, memory)
    value = address_mode.read_from(cpu, memory, address)

    assert address == 255
    assert value == 0
    assert cpu.cycle == 3

    cpu.inc_cycle_by(-cpu.cycle)
    cpu.inc_pc_by(-cpu.pc + MemoryPositions.PRG_ROM_START.start + 255)
    cpu.x = 5
    address = address_mode.fetch_address(cpu, memory)
    value = address_mode.read_from(cpu, memory, address)

    assert address == 4
    assert value == 251
    assert cpu.cycle == 3
def test_read_ZeroPage():
    address_mode = ZeroPage
    cpu = CPU()
    memory = Memory(rom=list(range(256)), ram=list(reversed(range(256))))

    cpu.inc_cycle_by(-cpu.cycle)
    cpu.inc_pc_by(-cpu.pc + MemoryPositions.PRG_ROM_START.start)
    address = address_mode.fetch_address(cpu, memory)
    value = address_mode.read_from(cpu, memory, address)
    assert address == 0
    assert value == 255

    cpu.inc_cycle_by(-cpu.cycle)
    cpu.inc_pc_by(-cpu.pc + MemoryPositions.PRG_ROM_START.start + 20)
    address = address_mode.fetch_address(cpu, memory)
    value = address_mode.read_from(cpu, memory, address)

    assert address == 20
    assert value == 235

    cpu.inc_cycle_by(-cpu.cycle)
    cpu.inc_pc_by(-cpu.pc + MemoryPositions.PRG_ROM_START.start + 100)
    address = address_mode.fetch_address(cpu, memory)
    value = address_mode.read_from(cpu, memory, address)

    assert address == 100
    assert value == 155

    cpu.inc_cycle_by(-cpu.cycle)
    cpu.inc_pc_by(-cpu.pc + MemoryPositions.PRG_ROM_START.start + 255)
    address = address_mode.fetch_address(cpu, memory)
    value = address_mode.read_from(cpu, memory, address)

    assert address == 255
    assert value == 0
def test_write_ZeroPage():
    address_mode = ZeroPage
    cpu = CPU()
    memory = Memory(rom=list(range(256)))

    cpu.inc_cycle_by(-cpu.cycle)
    cpu.inc_pc_by(-cpu.pc + MemoryPositions.PRG_ROM_START.start)
    address = address_mode.fetch_address(cpu, memory)
    address_mode.write_to(cpu, memory, address, 6)
    assert address == 0
    assert memory.ram[address] == 6

    cpu.inc_cycle_by(-cpu.cycle)
    cpu.inc_pc_by(-cpu.pc + MemoryPositions.PRG_ROM_START.start + 20)
    address = address_mode.fetch_address(cpu, memory)
    address_mode.write_to(cpu, memory, address, 105)

    assert address == 20
    assert memory.ram[address] == 105

    cpu.inc_cycle_by(-cpu.cycle)
    cpu.inc_pc_by(-cpu.pc + MemoryPositions.PRG_ROM_START.start + 100)
    address = address_mode.fetch_address(cpu, memory)
    address_mode.write_to(cpu, memory, address, 143)

    assert address == 100
    assert memory.ram[address] == 143

    cpu.inc_cycle_by(-cpu.cycle)
    cpu.inc_pc_by(-cpu.pc + MemoryPositions.PRG_ROM_START.start + 255)
    address = address_mode.fetch_address(cpu, memory)
    address_mode.write_to(cpu, memory, address, 255)

    assert address == 255
    assert memory.ram[address] == 255