def test_create(self): MMU([ (0, 128, False, None) ]) MMU([ (0, 128, False, None), (128, 128, True, None) ])
def test_write_readonly(self): m = MMU([(0, 16, True), (16, 16), (32, 16, True)]) with self.assertRaises(ReadOnlyError): m.write(8, 1) m.write(20, 1) with self.assertRaises(ReadOnlyError): m.write(40, 1)
def test_nestest(self): path = os.path.join( os.path.dirname(os.path.realpath(__file__)), "files", "nestest_mod.nes" ) with open(path, "rb") as f: mmu = MMU([ (0x0000, 0x800), # RAM (0x2000, 0x8), # PPU (0x4000, 0x18), (0x8000, 0xc000, True, f, 0x3ff0) # ROM ]) c = CPU(mmu, 0xc000) c.r.s = 0xfd # Not sure why the stack starts here. while c.r.pc != 0xc66e: try: c.step() except Exception as e: print(c.r) print(traceback.format_exc()) raise e self.assertEqual(c.mmu.read(0x2), 0x00, hex(c.mmu.read(0x2))) self.assertEqual(c.mmu.read(0x3), 0x00, hex(c.mmu.read(0x3)))
def test_addBlock_overlapping(self): m = MMU([]) m.addBlock(128, 128) with self.assertRaises(MemoryRangeError): m.addBlock(0, 129) with self.assertRaises(MemoryRangeError): m.addBlock(255, 128)
def test_reset(self): m = MMU([(0, 16, True), (16, 16, False)]) m.blocks[0]['memory'][0] = 5 m.write(16, 10) m.reset() self.assertEqual(m.read(0), 5) self.assertEqual(m.read(16), 0)
def test_create_with_file(self): path = os.path.join(os.path.dirname(os.path.realpath(__file__)), "files", "test_load_file.bin") with open(path, "rb") as f: m = MMU([(0, 128, True, f)]) self.assertEqual(m.blocks[0]['memory'][0], 0xa9)
def test_create_with_list(self): m = MMU([ (0, 128, False, [1, 2, 3]) ]) self.assertEqual(m.blocks[0]['memory'][0], 1) self.assertEqual(m.blocks[0]['memory'][2], 3) self.assertEqual(m.blocks[0]['memory'][3], 0)
def init_cpu(mem, pc_value): mmu = MMU([(0x00, len(mem), False, mem) # readonly = False ]) c = CPU(mmu, pc_value) return c
def runBinary(self, pasfile, breakpointlabels, randoms, counters): # breakpointlabels is a list of labels to stop emulation on program counter hit # prepare binary file binfile = self.buildBinary(pasfile) binstart = int(self.config.get('params','binaryLocation'),16) memsize = int(self.config.get('params','memorySize'),16) # load into emulator memory with open(binfile, "rb") as filedata: self.m = MMU([ (0, binstart), (binstart, binstart + memsize, False, filedata) ]) # initialize cpu self.c = CPU(self.m, self.labels['START']) self.cmdCount = 0 # add user defined random registers if len(randoms) > 0: for item in randoms: self.randoms.append(item) # add user defined counters if len(counters) > 0: for item in counters: self.counters.append(item) # update randoms converting labels to direct addresses for value in self.randoms: if not isinstance(value, int): labelname = self.validateLabel(value.upper()) self.randoms.remove(value) self.randoms.append(self.labels[labelname]) # update counters converting labels to direct addresses for value in self.counters: if not isinstance(value, int): labelname = self.validateLabel(value.upper()) self.counters.remove(value) self.counters.append(self.labels[labelname]) # convert breakpoint labels into addresses self.breakpointadressess = [] if len(breakpointlabels) > 0: for blabel in breakpointlabels: labelname = self.validateLabel(blabel.upper()) self.breakpointadressess.append(self.labels[labelname]) # make sure all elements are unique self.randoms = list(set(self.randoms)) self.counters = list(set(self.counters)) self.breakpointadressess = list(set(self.breakpointadressess)) self.runEmu() return [self.c,self.m,self.labels]
def test_index_error(self): m = MMU([(0, 128)]) with self.assertRaises(IndexError): m.write(-1, 0) with self.assertRaises(IndexError): m.write(128, 0) with self.assertRaises(IndexError): m.read(-1) with self.assertRaises(IndexError): m.read(128)
def load_level(stage, prg_rom, chr_rom, sym_file, nes_palette): # Initialize the MMU / CPU mmu = MMU([(0x0, _WORKING_RAM_SIZE, False, []), (0x8000, 0x10000, True, list(prg_rom))]) cpu = CPU(mmu, 0x0) # Execute some preamble subroutines which set up variables used by the main subroutines. if isinstance(stage, tuple): world_num, area_num = stage mmu.write(sym_file['WORLDNUMBER'], world_num - 1) mmu.write(sym_file['AREANUMBER'], area_num - 1) _execute_subroutine(cpu, sym_file['LOADAREAPOINTER']) else: area_pointer = stage mmu.write(sym_file['AREAPOINTER'], area_pointer) mmu.write(sym_file['HALFWAYPAGE'], 0) mmu.write(sym_file['ALTENTRANCECONTROL'], 0) mmu.write(sym_file['PRIMARYHARDMODE'], 0) mmu.write(sym_file['OPERMODE_TASK'], 0) _execute_subroutine(cpu, sym_file['INITIALIZEAREA']) # Extract the palette. palette = _load_palette(mmu, sym_file, nes_palette) # Repeatedly extract meta-tile columns, until the level starts repeating. cols = [] for column_pos in range(1000): _execute_subroutine(cpu, sym_file['AREAPARSERCORE']) cols.append(_get_metatile_buffer(mmu, sym_file)) _execute_subroutine(cpu, sym_file['INCREMENTCOLUMNPOS']) if len(cols) >= 96 and cols[-48:] == cols[-96:-48]: cols = cols[:-80] break level = np.array(cols).T # Render a dict of metatiles. mtiles = { mtile: _render_metatile(mmu, chr_rom, mtile, palette) for mtile in set(level.flatten()) } return level, mtiles
def test_create_overlapping(self): with self.assertRaises(MemoryRangeError): MMU([(0, 129), (128, 128)])
def test_read(self): m = MMU([(0, 128)]) m.write(16, 5) m.write(64, 111) self.assertEqual(5, m.read(16)) self.assertEqual(111, m.read(64))
def test_create_empty(self): MMU([])
def test_write_multiple_blocks(self): m = MMU([(0, 128), (1024, 128)]) m.write(16, 25) self.assertEqual(m.blocks[0]['memory'][16], 25) m.write(1056, 55) self.assertEqual(m.blocks[1]['memory'][32], 55, m.blocks[1]['memory'])
def test_write(self): m = MMU([(0, 128)]) m.write(16, 25) self.assertEqual(m.blocks[0]['memory'][16], 25)
out = a.assemble(open(f)) # Put the input into an array input_path = '../input.txt' with open(input_path, 'rb') as f: input_bytes = [] b = f.read(1) while b: input_bytes.append(ord(b)) b = f.read(1) # Add another new line to terminate input_bytes += [10] # Initialize memory and the CPU m = MMU([ (0x00, 0x200), # Create RAM with 512 bytes (0x1000, 0x1000 + len(input_bytes), True, input_bytes), # Input bytes (0xC000, 0xFFFF, True, out ) # Create ROM starting at 0xC000 with your program. ]) c = CPU(m, 0xC000) while not c.r.getFlag('B'): # Run until we break c.step() # Print out the 3-byte answer as decimal print(m.read(0x10) + (m.read(0x11) << 8) + (m.read(0x12) << 16))
def _cpu(self, ram=(0, 0x200, False), rom=(0x1000, 0x100), romInit=None, pc=0x1000): return CPU(MMU([ram, rom + (True, romInit)]), pc)
def test_addBlock(self): m = MMU([]) m.addBlock(0, 128, False, None) m.addBlock(128, 128, True, None)