Example #1
0
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
Example #2
0
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
Example #3
0
        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())