Esempio n. 1
0
    def __init__(self, cols=NUM_COLUMNS):

        logging.getLogger('MC6809').disabled = True

        fn = os.path.join(os.path.dirname(__file__), 'coco_raaka_tu.bin')
        with open(fn, 'rb') as f:
            self.binary = f.read()
        self.binary = list(b'\x00' * 0x600 + self.binary)

        CFG_DICT = {
            "verbosity": None,
            "trace": None,
        }

        class Config(BaseConfig):
            RAM_START = 0x0000
            RAM_END = 0x7FFF
            ROM_START = 0x8000
            ROM_END = 0xFFFF

        cfg = Config(CFG_DICT)

        # Memory management -- defer everything to our read/write functions
        #
        memory = Memory(cfg)
        memory.add_read_byte_callback(self.read_memory, 0, 0xFFFF)
        memory.add_write_byte_callback(self.write_memory, 0, 0xFFFF)

        # Start of program is 0x600
        #
        self.cpu = CPU(memory, cfg)
        self.still_running = False

        self.buffer = ''
        self.cols = cols
Esempio n. 2
0
    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
Esempio n. 3
0
class BaseCPUTestCase(BaseTestCase):
    UNITTEST_CFG_DICT = {
        "verbosity": None,
        "display_cycle": False,
        "trace": None,
        "bus_socket_host": None,
        "bus_socket_port": None,
        "ram": None,
        "rom": None,
        "max_ops": None,
        "use_bus": False,
    }

    def setUp(self):
        cfg = TestCfg(self.UNITTEST_CFG_DICT)
        memory = Memory(cfg)
        self.cpu = CPU(memory, cfg)
        memory.cpu = self.cpu  # FIXME
        self.cpu.cc.set(0x00)

    def cpu_test_run(self, start, end, mem):
        for cell in mem:
            self.assertLess(-1, cell, "$%x < 0" % cell)
            self.assertGreater(0x100, cell, "$%x > 0xff" % cell)
        log.debug("memory load at $%x: %s", start,
                  ", ".join(["$%x" % i for i in mem]))
        self.cpu.memory.load(start, mem)
        if end is None:
            end = start + len(mem)
        self.cpu.test_run(start, end)

    cpu_test_run.__test__ = False  # Exclude from nose

    def cpu_test_run2(self, start, count, mem):
        for cell in mem:
            self.assertLess(-1, cell, "$%x < 0" % cell)
            self.assertGreater(0x100, cell, "$%x > 0xff" % cell)
        self.cpu.memory.load(start, mem)
        self.cpu.test_run2(start, count)

    cpu_test_run2.__test__ = False  # Exclude from nose

    def assertMemory(self, start, mem):
        for index, should_byte in enumerate(mem):
            address = start + index
            is_byte = self.cpu.memory.read_byte(address)

            msg = "$%02x is not $%02x at address $%04x (index: %i)" % (
                is_byte, should_byte, address, index)
            self.assertEqual(is_byte, should_byte, msg)
Esempio n. 4
0
class BaseCPUTestCase(BaseTestCase):
    UNITTEST_CFG_DICT = {
        "verbosity":None,
        "display_cycle":False,
        "trace":None,
        "bus_socket_host":None,
        "bus_socket_port":None,
        "ram":None,
        "rom":None,
        "max_ops":None,
        "use_bus":False,
    }
    def setUp(self):
        cfg = TestCfg(self.UNITTEST_CFG_DICT)
        memory = Memory(cfg)
        self.cpu = CPU(memory, cfg)
        memory.cpu = self.cpu # FIXME
        self.cpu.cc.set(0x00)

    def cpu_test_run(self, start, end, mem):
        for cell in mem:
            self.assertLess(-1, cell, "$%x < 0" % cell)
            self.assertGreater(0x100, cell, "$%x > 0xff" % cell)
        log.debug("memory load at $%x: %s", start,
            ", ".join(["$%x" % i for i in mem])
        )
        self.cpu.memory.load(start, mem)
        if end is None:
            end = start + len(mem)
        self.cpu.test_run(start, end)
    cpu_test_run.__test__=False # Exclude from nose

    def cpu_test_run2(self, start, count, mem):
        for cell in mem:
            self.assertLess(-1, cell, "$%x < 0" % cell)
            self.assertGreater(0x100, cell, "$%x > 0xff" % cell)
        self.cpu.memory.load(start, mem)
        self.cpu.test_run2(start, count)
    cpu_test_run2.__test__=False # Exclude from nose

    def assertMemory(self, start, mem):
        for index, should_byte in enumerate(mem):
            address = start + index
            is_byte = self.cpu.memory.read_byte(address)

            msg = "$%02x is not $%02x at address $%04x (index: %i)" % (
                is_byte, should_byte, address, index
            )
            self.assertEqual(is_byte, should_byte, msg)
Esempio n. 5
0
    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
Esempio n. 6
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
Esempio n. 7
0
                InstructionClass = PrepagedInstructions

            instrution_class = InstructionClass(self.cpu, instr_func)
            func = getattr(instrution_class, func_name)

            self.opcode_dict[op_code] = (op_code_data["cycles"], func)


if __name__ == "__main__":
    from MC6809.components.cpu6809 import CPU
    from MC6809.tests.test_base import BaseCPUTestCase
    from dragonpy.Dragon32.config import Dragon32Cfg
    from MC6809.components.memory import Memory

    cmd_args = BaseCPUTestCase.UNITTEST_CFG_DICT
    cfg = Dragon32Cfg(cmd_args)
    memory = Memory(cfg)
    cpu = CPU(memory, cfg)

    for op_code, data in sorted(cpu.opcode_dict.items()):
        cycles, func = data
        if op_code > 0xff:
            op_code = "$%04x" % op_code
        else:
            op_code = "  $%02x" % op_code

        print("Op %s - cycles: %2i - func: %s" %
              (op_code, cycles, func.__name__))

    print(" --- END --- ")
Esempio n. 8
0
 def setUp(self):
     cfg = TestCfg(self.UNITTEST_CFG_DICT)
     memory = Memory(cfg)
     self.cpu = CPU(memory, cfg)
     memory.cpu = self.cpu  # FIXME
     self.cpu.cc.set(0x00)
Esempio n. 9
0
 def __init__(self):
     cfg = Config(CFG_DICT)
     memory = Memory(cfg)
     self.cpu = CPU(memory, cfg)
Esempio n. 10
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
Esempio n. 11
0
 def setUp(self):
     cfg = TestCfg(self.UNITTEST_CFG_DICT)
     memory = Memory(cfg)
     self.cpu = CPU(memory, cfg)
Esempio n. 12
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())
Esempio n. 13
0
 def __init__(self):
     cfg = Config(CFG_DICT)
     memory = Memory(cfg)
     self.cpu = CPU(memory, cfg)
Esempio n. 14
0
class MC6809Example(object):
    def __init__(self):
        cfg = Config(CFG_DICT)
        memory = Memory(cfg)
        self.cpu = CPU(memory, cfg)

    def cpu_test_run(self, start, end, mem):
        assert isinstance(mem, bytearray), "given mem is not a bytearray!"

        print("memory load at $%x: %s", start,
            ", ".join(["$%x" % i for i in mem])
        )
        self.cpu.memory.load(start, mem)
        if end is None:
            end = start + len(mem)
        self.cpu.test_run(start, end)

    def crc32(self, data):
        """
        Calculate a ZIP 32-bit CRC from data in memory.
        Origin code by Johann E. Klasek, j AT klasek at
        """
        data_address = 0x1000 # position of the test data
        self.cpu.memory.load(data_address, data)  # write test data into RAM
        self.cpu.index_x.set(data_address + len(data)) # end address
        addr_hi, addr_lo = divmod(data_address, 0x100) # start address

        self.cpu_test_run(start=0x0100, end=None, mem=bytearray([
            #                              0100|           .ORG  $100
            0x10, 0xCE, 0x40, 0x00, #      0100|           LDS   #$4000
            #                              0104|    CRCHH: EQU   $ED
            #                              0104|    CRCHL: EQU   $B8
            #                              0104|    CRCLH: EQU   $83
            #                              0104|    CRCLL: EQU   $20
            #                              0104| CRCINITH: EQU   $FFFF
            #                              0104| CRCINITL: EQU   $FFFF
            #                              0104|                            ; CRC 32 bit in DP (4 bytes)
            #                              0104|      CRC: EQU   $80
            0xCE, addr_hi, addr_lo, #      0104|           LDU   #....      ; start address in u
            0x34, 0x10, #                  010C|           PSHS  x          ; end address +1 to TOS
            0xCC, 0xFF, 0xFF, #            010E|           LDD   #CRCINITL
            0xDD, 0x82, #                  0111|           STD   crc+2
            0x8E, 0xFF, 0xFF, #            0113|           LDX   #CRCINITH
            0x9F, 0x80, #                  0116|           STX   crc
            #                              0118|                            ; d/x contains the CRC
            #                              0118|       BL:
            0xE8, 0xC0, #                  0118|           EORB  ,u+        ; XOR with lowest byte
            0x10, 0x8E, 0x00, 0x08, #      011A|           LDY   #8         ; bit counter
            #                              011E|       RL:
            0x1E, 0x01, #                  011E|           EXG   d,x
            #                              0120|      RL1:
            0x44, #                        0120|           LSRA             ; shift CRC right, beginning with high word
            0x56, #                        0121|           RORB
            0x1E, 0x01, #                  0122|           EXG   d,x
            0x46, #                        0124|           RORA             ; low word
            0x56, #                        0125|           RORB
            0x24, 0x12, #                  0126|           BCC   cl
            #                              0128|                            ; CRC=CRC XOR polynomic
            0x88, 0x83, #                  0128|           EORA  #CRCLH     ; apply CRC polynomic low word
            0xC8, 0x20, #                  012A|           EORB  #CRCLL
            0x1E, 0x01, #                  012C|           EXG   d,x
            0x88, 0xED, #                  012E|           EORA  #CRCHH     ; apply CRC polynomic high word
            0xC8, 0xB8, #                  0130|           EORB  #CRCHL
            0x31, 0x3F, #                  0132|           LEAY  -1,y       ; bit count down
            0x26, 0xEA, #                  0134|           BNE   rl1
            0x1E, 0x01, #                  0136|           EXG   d,x        ; CRC: restore correct order
            0x27, 0x04, #                  0138|           BEQ   el         ; leave bit loop
            #                              013A|       CL:
            0x31, 0x3F, #                  013A|           LEAY  -1,y       ; bit count down
            0x26, 0xE0, #                  013C|           BNE   rl         ; bit loop
            #                              013E|       EL:
            0x11, 0xA3, 0xE4, #            013E|           CMPU  ,s         ; end address reached?
            0x26, 0xD5, #                  0141|           BNE   bl         ; byte loop
            0xDD, 0x82, #                  0143|           STD   crc+2      ; CRC low word
            0x9F, 0x80, #                  0145|           STX   crc        ; CRC high word
        ]))
        d = self.cpu.accu_d.get()
        x = self.cpu.index_x.get()
        crc32 = x * 0x10000 + d
        return crc32 ^ 0xFFFFFFFF

    def compare_crc32(self, data):

        if sys.version_info > (3,):
            data = bytes(data, encoding="ASCII")

        print("Compare CRC32 with: %r" % data)

        print("\nCreate CRC32 with binascii:")
        start_time = time.time()
        excpected_crc32 = binascii.crc32(data) & 0xffffffff
        duration = time.time() - start_time
        print("\tbinascii crc32..: $%X calculated in %.6fsec" % (excpected_crc32, duration))

        print("\nCreate CRC32 with Emulated 6809 CPU:")
        start_time = time.time()
        crc32_value = self.crc32(data)
        duration = time.time() - start_time
        print("\tMC6809 crc32..: $%X calculated in %.2fsec" % (crc32_value, duration))
        print()
        if crc32_value==excpected_crc32:
            print(" *** CRC32 values from 6809 and binascii are the same, ok.\n")
            return True
        else:
            print(" *** ERROR: CRC32 are different!\n")
            return False
Esempio n. 15
0
 def setUp(self):
     cfg = TestCfg(self.UNITTEST_CFG_DICT)
     memory = Memory(cfg)
     self.cpu = CPU(memory, cfg)
     memory.cpu = self.cpu # FIXME
     self.cpu.cc.set(0x00)
Esempio n. 16
0
class CoCoRaakaTu:

    GAME_NAME = 'coco_raaka_tu'

    NUM_COLUMNS = 32

    @staticmethod
    def print_banner():
        print('Raaka-Tu - 1982 for the TRS-80 Color Computer')
        print(
            'See the disassembly: http://computerarcheology.com/CoCo/RaakaTu/')
        print(
            'Everything you need to know: http://www.figmentfly.com/raakatu/raakatu.html'
        )

    def __init__(self, cols=NUM_COLUMNS):

        logging.getLogger('MC6809').disabled = True

        fn = os.path.join(os.path.dirname(__file__), 'coco_raaka_tu.bin')
        with open(fn, 'rb') as f:
            self.binary = f.read()
        self.binary = list(b'\x00' * 0x600 + self.binary)

        CFG_DICT = {
            "verbosity": None,
            "trace": None,
        }

        class Config(BaseConfig):
            RAM_START = 0x0000
            RAM_END = 0x7FFF
            ROM_START = 0x8000
            ROM_END = 0xFFFF

        cfg = Config(CFG_DICT)

        # Memory management -- defer everything to our read/write functions
        #
        memory = Memory(cfg)
        memory.add_read_byte_callback(self.read_memory, 0, 0xFFFF)
        memory.add_write_byte_callback(self.write_memory, 0, 0xFFFF)

        # Start of program is 0x600
        #
        self.cpu = CPU(memory, cfg)
        self.still_running = False

        self.buffer = ''
        self.cols = cols

    def print_char(self, c):
        if c == '\r' or c == '\n':
            self.print_flush()
        else:
            self.buffer = self.buffer + c

    def print_flush(self):
        while True:

            self.buffer = self.buffer.strip()

            if len(self.buffer) <= self.cols:
                print(self.buffer)
                self.buffer = ''
                return

            if self.buffer[self.cols] == ' ':
                print(self.buffer[0:self.cols])
                self.buffer = self.buffer[self.cols:]
            else:
                i = self.buffer[0:self.cols].rfind(' ')
                if i < 0:
                    i = self.cols
                print(self.buffer[:i])
                self.buffer = self.buffer[i:]

    def show_error_message(self):
        '''Instead of flashing in place
        '''

        s = ''
        for y in range(32):
            c = self.binary[0x5E0 + y]
            if c < 32 or c > 127 or c == 96:
                c = 32
            s = s + chr(c)
        print(s.strip())

    def simulate_coco_input(self):
        '''Get input from the user and poke it into COCO screen memory    
        '''

        for y in range(32):
            self.binary[0x5E0 + y] = 96

        user_input = input('> ')
        user_input = user_input.strip().upper()
        p = 0x5E0  # Start of the bottom row
        for c in user_input:
            c = ord(c)
            if c == 32:
                self.binary[p] = 96
                p += 1
            elif c >= 65 and c <= 90:
                self.binary[p] = c
                p += 1
            if p >= 0x5FF:
                break

        #for p in range(0x5E0,0x5E0+32):
        #    print(self.binary[p])

    def simulate_coco_print(self, s):
        '''Print a character
        '''

        #print('##',s)

        self.print_char(s)

    def read_memory(self, _cycles, frm, addr):

        # This is the "print character routine. We point it to C000 then handle the
        # print by intercepting the routine at C000.
        #
        if addr == 0xA002:
            return 0xC0
        if addr == 0xA003:
            return 0x00
        if addr == 0xC000:
            self.simulate_coco_print(chr(self.cpu.accu_a.value))
            return 0x39

        # The wait-for-key calls this routine to roll the random number. Since we
        # are eating that spin-wait, we'll provide random numbers here.
        #
        if addr == 0x12A8:
            self.binary[0x1338] = random.randint(0, 255)
            self.cpu.accu_a.set(random.randint(0, 255))
            return 0x39

        # This bypasses the built in 32-column management. We'll handle word-breaks in
        # the print routine, which allows for any size console.
        #
        if addr == 0x89:
            return 0

        # This is where the error message is flashed. Instead, we'll just print the error.
        #
        if addr == 0x9A5:
            self.show_error_message()
        if addr == 0x9BB:
            return 0x21  # BRN to avoid a loop of flashes

        # This is where the game gets a line of input from the user.
        #
        if addr == 0xACC or addr == 0xA63:
            self.simulate_coco_input()
            return 0x39

        # This is the infinite loop when the player does a QUIT.
        # We'll abort the running program
        #
        if addr == 0x10B5:
            self.still_running = False
            return 0x20

        # This is in RAM.
        #
        if addr <= 0x3F17:
            # print('.. '+hex(addr)+' @'+hex(frm)+' <'+hex(self.binary[addr]))
            return self.binary[addr]

        raise Exception('## UNHANDLED READ from=' + hex(frm) +
                        ' destination=' + hex(addr))

    def write_memory(self, _cycles, frm, addr, value):

        # This is RAM.
        #
        if addr <= 0x3F17:
            self.binary[addr] = value
            return

        raise Exception('## UNHANDLED WRITE from' + hex(frm) +
                        ' destination=' + hex(addr) + ' value=' + hex(value))

    def run_forever(self):

        self.cpu.program_counter.set(0x600)
        self.still_running = True
        while self.still_running:
            self.cpu.run()
Esempio n. 17
0
class MC6809Example(object):
    def __init__(self):
        cfg = Config(CFG_DICT)
        memory = Memory(cfg)
        self.cpu = CPU(memory, cfg)

    def cpu_test_run(self, start, end, mem):
        assert isinstance(mem, bytearray), "given mem is not a bytearray!"

        print("memory load at $%x: %s", start,
              ", ".join(["$%x" % i for i in mem]))
        self.cpu.memory.load(start, mem)
        if end is None:
            end = start + len(mem)
        self.cpu.test_run(start, end)

    def crc32(self, data):
        """
        Calculate a ZIP 32-bit CRC from data in memory.
        Origin code by Johann E. Klasek, j AT klasek at
        """
        data_address = 0x1000  # position of the test data
        self.cpu.memory.load(data_address, data)  # write test data into RAM
        self.cpu.index_x.set(data_address + len(data))  # end address
        addr_hi, addr_lo = divmod(data_address, 0x100)  # start address

        self.cpu_test_run(
            start=0x0100,
            end=None,
            mem=bytearray([
                #                              0100|           .ORG  $100
                0x10,
                0xCE,
                0x40,
                0x00,  #      0100|           LDS   #$4000
                #                              0104|    CRCHH: EQU   $ED
                #                              0104|    CRCHL: EQU   $B8
                #                              0104|    CRCLH: EQU   $83
                #                              0104|    CRCLL: EQU   $20
                #                              0104| CRCINITH: EQU   $FFFF
                #                              0104| CRCINITL: EQU   $FFFF
                #                              0104|                            ; CRC 32 bit in DP (4 bytes)
                #                              0104|      CRC: EQU   $80
                0xCE,
                addr_hi,
                addr_lo,  #      0104|           LDU   #....      ; start address in u
                0x34,
                0x10,  #                  010C|           PSHS  x          ; end address +1 to TOS
                0xCC,
                0xFF,
                0xFF,  #            010E|           LDD   #CRCINITL
                0xDD,
                0x82,  #                  0111|           STD   crc+2
                0x8E,
                0xFF,
                0xFF,  #            0113|           LDX   #CRCINITH
                0x9F,
                0x80,  #                  0116|           STX   crc
                #                              0118|                            ; d/x contains the CRC
                #                              0118|       BL:
                0xE8,
                0xC0,  #                  0118|           EORB  ,u+        ; XOR with lowest byte
                0x10,
                0x8E,
                0x00,
                0x08,  #      011A|           LDY   #8         ; bit counter
                #                              011E|       RL:
                0x1E,
                0x01,  #                  011E|           EXG   d,x
                #                              0120|      RL1:
                0x44,  #                        0120|           LSRA             ; shift CRC right, beginning with high word
                0x56,  #                        0121|           RORB
                0x1E,
                0x01,  #                  0122|           EXG   d,x
                0x46,  #                        0124|           RORA             ; low word
                0x56,  #                        0125|           RORB
                0x24,
                0x12,  #                  0126|           BCC   cl
                #                              0128|                            ; CRC=CRC XOR polynomic
                0x88,
                0x83,  #                  0128|           EORA  #CRCLH     ; apply CRC polynomic low word
                0xC8,
                0x20,  #                  012A|           EORB  #CRCLL
                0x1E,
                0x01,  #                  012C|           EXG   d,x
                0x88,
                0xED,  #                  012E|           EORA  #CRCHH     ; apply CRC polynomic high word
                0xC8,
                0xB8,  #                  0130|           EORB  #CRCHL
                0x31,
                0x3F,  #                  0132|           LEAY  -1,y       ; bit count down
                0x26,
                0xEA,  #                  0134|           BNE   rl1
                0x1E,
                0x01,  #                  0136|           EXG   d,x        ; CRC: restore correct order
                0x27,
                0x04,  #                  0138|           BEQ   el         ; leave bit loop
                #                              013A|       CL:
                0x31,
                0x3F,  #                  013A|           LEAY  -1,y       ; bit count down
                0x26,
                0xE0,  #                  013C|           BNE   rl         ; bit loop
                #                              013E|       EL:
                0x11,
                0xA3,
                0xE4,  #            013E|           CMPU  ,s         ; end address reached?
                0x26,
                0xD5,  #                  0141|           BNE   bl         ; byte loop
                0xDD,
                0x82,  #                  0143|           STD   crc+2      ; CRC low word
                0x9F,
                0x80,  #                  0145|           STX   crc        ; CRC high word
            ]))
        d = self.cpu.accu_d.get()
        x = self.cpu.index_x.get()
        crc32 = x * 0x10000 + d
        return crc32 ^ 0xFFFFFFFF

    def compare_crc32(self, data):

        if sys.version_info > (3, ):
            data = bytes(data, encoding="ASCII")

        print("Compare CRC32 with: %r" % data)

        print("\nCreate CRC32 with binascii:")
        start_time = time.time()
        excpected_crc32 = binascii.crc32(data) & 0xffffffff
        duration = time.time() - start_time
        print("\tbinascii crc32..: $%X calculated in %.6fsec" %
              (excpected_crc32, duration))

        print("\nCreate CRC32 with Emulated 6809 CPU:")
        start_time = time.time()
        crc32_value = self.crc32(data)
        duration = time.time() - start_time
        print("\tMC6809 crc32..: $%X calculated in %.2fsec" %
              (crc32_value, duration))
        print()
        if crc32_value == excpected_crc32:
            print(
                " *** CRC32 values from 6809 and binascii are the same, ok.\n")
            return True
        else:
            print(" *** ERROR: CRC32 are different!\n")
            return False
Esempio n. 18
0
 def setUp(self):
     cfg = TestCfg(self.UNITTEST_CFG_DICT)
     memory = Memory(cfg)
     self.cpu = CPU(memory, cfg)