class Machine(object): def __init__(self, cfg, periphery_class, display_callback, user_input_queue): self.cfg = cfg self.machine_api = cfg.machine_api self.periphery_class = periphery_class # "write into Display RAM" for render them in DragonTextDisplayCanvas(): self.display_callback = display_callback # Queue to send keyboard inputs to CPU Thread: self.user_input_queue = user_input_queue memory = Memory(self.cfg) self.cpu = CPU(memory, self.cfg) memory.cpu = self.cpu # FIXME try: self.periphery = self.periphery_class(self.cfg, self.cpu, memory, self.display_callback, self.user_input_queue) except TypeError as err: raise TypeError("%s - class: %s" % (err, self.periphery_class.__name__)) self.cpu_init_state = self.cpu.get_state() # Used for hard reset # from dragonpy.tests.test_base import print_cpu_state_data # print_cpu_state_data(self.cpu_init_state) self.cpu.reset() self.max_ops = self.cfg.cfg_dict["max_ops"] self.op_count = 0 def get_basic_program(self): program_start = self.cpu.memory.read_word( self.machine_api.PROGRAM_START_ADDR) variables_start = self.cpu.memory.read_word( self.machine_api.VARIABLES_START_ADDR) array_start = self.cpu.memory.read_word( self.machine_api.ARRAY_START_ADDR) free_space_start = self.cpu.memory.read_word( self.machine_api.FREE_SPACE_START_ADDR) program_end = variables_start - 1 variables_end = array_start - 1 array_end = free_space_start - 1 log.critical("programm code: $%04x-$%04x", program_start, program_end) log.critical("variables....: $%04x-$%04x", variables_start, variables_end) log.critical("array........: $%04x-$%04x", array_start, array_end) dump = [ value for addr, value in self.cpu.memory.iter_bytes( program_start, program_end) ] log.critical("Dump: %s", repr(dump)) log_program_dump(dump) listing = self.machine_api.program_dump2ascii_lines( dump, program_start) log.critical("Listing in ASCII:\n%s", "\n".join(listing)) return listing def inject_basic_program(self, ascii_listing): """ save the given ASCII BASIC program listing into the emulator RAM. """ program_start = self.cpu.memory.read_word( self.machine_api.PROGRAM_START_ADDR) tokens = self.machine_api.ascii_listing2program_dump(ascii_listing) self.cpu.memory.load(program_start, tokens) log.critical("BASIC program injected into Memory.") # Update the BASIC addresses: program_end = program_start + len(tokens) self.cpu.memory.write_word(self.machine_api.VARIABLES_START_ADDR, program_end) self.cpu.memory.write_word(self.machine_api.ARRAY_START_ADDR, program_end) self.cpu.memory.write_word(self.machine_api.FREE_SPACE_START_ADDR, program_end) log.critical("BASIC addresses updated.") def hard_reset(self): self.periphery.reset() # from dragonpy.tests.test_base import print_cpu_state_data # print_cpu_state_data(self.cpu_init_state) self.cpu.set_state(self.cpu_init_state) # print_cpu_state_data(self.cpu.get_state()) self.cpu.reset() def quit(self): self.cpu.running = False
class Machine(object): def __init__(self, cfg, periphery_class, display_callback, user_input_queue): self.cfg = cfg self.machine_api = cfg.machine_api self.periphery_class = periphery_class # "write into Display RAM" for render them in DragonTextDisplayCanvas(): self.display_callback = display_callback # Queue to send keyboard inputs to CPU Thread: self.user_input_queue = user_input_queue memory = Memory(self.cfg) self.cpu = CPU(memory, self.cfg) memory.cpu = self.cpu # FIXME try: self.periphery = self.periphery_class( self.cfg, self.cpu, memory, self.display_callback, self.user_input_queue ) except TypeError as err: raise TypeError("%s - class: %s" % (err, self.periphery_class.__name__)) self.cpu_init_state = self.cpu.get_state() # Used for hard reset # from dragonpy.tests.test_base import print_cpu_state_data # print_cpu_state_data(self.cpu_init_state) self.cpu.reset() self.max_ops = self.cfg.cfg_dict["max_ops"] self.op_count = 0 def get_basic_program(self): program_start = self.cpu.memory.read_word(self.machine_api.PROGRAM_START_ADDR) variables_start = self.cpu.memory.read_word(self.machine_api.VARIABLES_START_ADDR) array_start = self.cpu.memory.read_word(self.machine_api.ARRAY_START_ADDR) free_space_start = self.cpu.memory.read_word(self.machine_api.FREE_SPACE_START_ADDR) program_end = variables_start - 1 variables_end = array_start - 1 array_end = free_space_start - 1 log.critical("programm code: $%04x-$%04x", program_start, program_end) log.critical("variables....: $%04x-$%04x", variables_start, variables_end) log.critical("array........: $%04x-$%04x", array_start, array_end) dump = [ value for addr, value in self.cpu.memory.iter_bytes(program_start, program_end) ] log.critical("Dump: %s", repr(dump)) log_program_dump(dump) listing = self.machine_api.program_dump2ascii_lines(dump, program_start) log.critical("Listing in ASCII:\n%s", "\n".join(listing)) return listing def inject_basic_program(self, ascii_listing): """ save the given ASCII BASIC program listing into the emulator RAM. """ program_start = self.cpu.memory.read_word( self.machine_api.PROGRAM_START_ADDR ) tokens = self.machine_api.ascii_listing2program_dump(ascii_listing) self.cpu.memory.load(program_start, tokens) log.critical("BASIC program injected into Memory.") # Update the BASIC addresses: program_end = program_start + len(tokens) self.cpu.memory.write_word(self.machine_api.VARIABLES_START_ADDR, program_end) self.cpu.memory.write_word(self.machine_api.ARRAY_START_ADDR, program_end) self.cpu.memory.write_word(self.machine_api.FREE_SPACE_START_ADDR, program_end) log.critical("BASIC addresses updated.") def hard_reset(self): self.periphery.reset() # from dragonpy.tests.test_base import print_cpu_state_data # print_cpu_state_data(self.cpu_init_state) self.cpu.set_state(self.cpu_init_state) # print_cpu_state_data(self.cpu.get_state()) self.cpu.reset() def quit(self): self.cpu.running = False
return 0 else: print('Code at {:04X} read {:02X}'.format(b, addr)) memory = Memory(cfg) # The CoCo ROM will "accidentally" write to FFFF. Just ignore that as the hardware does. memory.add_write_byte_callback(lambda a, b, c, d: 0, 0xFFFF, 0xFFFF) memory.add_write_byte_callback(write_PIA, 0xFF00, 0xFFF0) memory.add_read_byte_callback(read_PIA, 0xFF00, 0xFFF0) with open('bas12.rom', 'rb') as f: basic_rom = f.read() memory.load(0xA000, basic_rom) memory.load(0xFFF0, basic_rom[-16:]) with open('extbas11.rom', 'rb') as f: ext_rom = f.read() memory.load(0x8000, ext_rom) cpu = CPU(memory, cfg) cpu.reset() print(cpu.program_counter) #print(memory.read_byte(0xFFFF )) while True: cpu.run() cpu.irq() print(cpu.get_state())