def get_ea_relative(self):
     addr, x = self.read_pc_byte()
     x = signed8(x)
     ea = self.program_counter.value + x
     #        log.debug("\tget_ea_relative(): ea = $%x + %i = $%x \t| %s",
     #            self.program_counter, x, ea,
     #            self.cfg.mem_info.get_shortest(ea)
     #        )
     return ea
    def test_HNZVC_8(self):
        for i in range(280):
            self.cpu.set_cc(0x00)
            r = i + 1  # e.g. ADDA 1 loop
            self.cpu.update_HNZVC_8(a=i, b=1, r=r)
            # print r, self.cpu.get_cc_info()

            # test half carry
            if r % 16 == 0:
                self.assertEqual(self.cpu.H, 1)
            else:
                self.assertEqual(self.cpu.H, 0)

            # test negative
            if 128 <= r <= 255:
                self.assertEqual(self.cpu.N, 1)
            else:
                self.assertEqual(self.cpu.N, 0)

            # test zero
            if signed8(r) == 0:
                self.assertEqual(self.cpu.Z, 1)
            else:
                self.assertEqual(self.cpu.Z, 0)

            # test overflow
            if r == 128 or r > 256:
                self.assertEqual(self.cpu.V, 1)
            else:
                self.assertEqual(self.cpu.V, 0)

            # test carry
            if r > 255:
                self.assertEqual(self.cpu.C, 1)
            else:
                self.assertEqual(self.cpu.C, 0)

            # Test that CC registers doesn't reset automaticly
            self.cpu.set_cc(0xff)
            r = i + 1  # e.g. ADDA 1 loop
            self.cpu.update_HNZVC_8(a=i, b=1, r=r)
            # print "+++", r, self.cpu.get_cc_info()
            self.assertEqualHex(self.cpu.get_cc_value(), 0xff)
    def test_HNZVC_8(self):
        for i in range(280):
            self.cpu.set_cc(0x00)
            r = i + 1 # e.g. ADDA 1 loop
            self.cpu.update_HNZVC_8(a=i, b=1, r=r)
            # print r, self.cpu.get_cc_info()

            # test half carry
            if r % 16 == 0:
                self.assertEqual(self.cpu.H, 1)
            else:
                self.assertEqual(self.cpu.H, 0)

            # test negative
            if 128 <= r <= 255:
                self.assertEqual(self.cpu.N, 1)
            else:
                self.assertEqual(self.cpu.N, 0)

            # test zero
            if signed8(r) == 0:
                self.assertEqual(self.cpu.Z, 1)
            else:
                self.assertEqual(self.cpu.Z, 0)

            # test overflow
            if r == 128 or r > 256:
                self.assertEqual(self.cpu.V, 1)
            else:
                self.assertEqual(self.cpu.V, 0)

            # test carry
            if r > 255:
                self.assertEqual(self.cpu.C, 1)
            else:
                self.assertEqual(self.cpu.C, 0)

            # Test that CC registers doesn't reset automaticly
            self.cpu.set_cc(0xff)
            r = i + 1 # e.g. ADDA 1 loop
            self.cpu.update_HNZVC_8(a=i, b=1, r=r)
            # print "+++", r, self.cpu.get_cc_info()
            self.assertEqualHex(self.cpu.get_cc_value(), 0xff)
    def get_ea_indexed(self):
        """
        Calculate the address for all indexed addressing modes
        """
        addr, postbyte = self.read_pc_byte()
        #        log.debug("\tget_ea_indexed(): postbyte: $%02x (%s) from $%04x",
        #             postbyte, byte2bit_string(postbyte), addr
        #         )

        rr = (postbyte >> 5) & 3
        try:
            register_str = self.INDEX_POSTBYTE2STR[rr]
        except KeyError:
            raise RuntimeError("Register $%x doesn't exists! (postbyte: $%x)" %
                               (rr, postbyte))

        register_obj = self.register_str2object[register_str]
        register_value = register_obj.value
        #        log.debug("\t%02x == register %s: value $%x",
        #             rr, register_obj.name, register_value
        #         )

        if not is_bit_set(postbyte, bit=7):  # bit 7 == 0
            # EA = n, R - use 5-bit offset from post-byte
            offset = signed5(postbyte & 0x1f)
            ea = register_value + offset
            #             log.debug(
            #                 "\tget_ea_indexed(): bit 7 == 0: reg.value: $%04x -> ea=$%04x + $%02x = $%04x",
            #                 register_value, register_value, offset, ea
            #             )
            return ea

        addr_mode = postbyte & 0x0f
        self.cycles += 1
        offset = None
        # TODO: Optimized this, maybe use a dict mapping...
        if addr_mode == 0x0:
            #             log.debug("\t0000 0x0 | ,R+ | increment by 1")
            ea = register_value
            register_obj.increment(1)
        elif addr_mode == 0x1:
            #             log.debug("\t0001 0x1 | ,R++ | increment by 2")
            ea = register_value
            register_obj.increment(2)
            self.cycles += 1
        elif addr_mode == 0x2:
            #             log.debug("\t0010 0x2 | ,R- | decrement by 1")
            register_obj.decrement(1)
            ea = register_obj.value
        elif addr_mode == 0x3:
            #             log.debug("\t0011 0x3 | ,R-- | decrement by 2")
            register_obj.decrement(2)
            ea = register_obj.value
            self.cycles += 1
        elif addr_mode == 0x4:
            #             log.debug("\t0100 0x4 | ,R | No offset")
            ea = register_value
        elif addr_mode == 0x5:
            #             log.debug("\t0101 0x5 | B, R | B register offset")
            offset = signed8(self.accu_b.value)
        elif addr_mode == 0x6:
            #             log.debug("\t0110 0x6 | A, R | A register offset")
            offset = signed8(self.accu_a.value)
        elif addr_mode == 0x8:
            #             log.debug("\t1000 0x8 | n, R | 8 bit offset")
            offset = signed8(self.read_pc_byte()[1])
        elif addr_mode == 0x9:
            #             log.debug("\t1001 0x9 | n, R | 16 bit offset")
            offset = signed16(self.read_pc_word()[1])
            self.cycles += 1
        elif addr_mode == 0xa:
            #             log.debug("\t1010 0xa | illegal, set ea=0")
            ea = 0
        elif addr_mode == 0xb:
            #             log.debug("\t1011 0xb | D, R | D register offset")
            # D - 16 bit concatenated reg. (A + B)
            offset = signed16(self.accu_d.value)  # FIXME: signed16() ok?
            self.cycles += 1
        elif addr_mode == 0xc:
            #             log.debug("\t1100 0xc | n, PCR | 8 bit offset from program counter")
            __, value = self.read_pc_byte()
            value_signed = signed8(value)
            ea = self.program_counter.value + value_signed
#             log.debug("\tea = pc($%x) + $%x = $%x (dez.: %i + %i = %i)",
#                 self.program_counter, value_signed, ea,
#                 self.program_counter, value_signed, ea,
#             )
        elif addr_mode == 0xd:
            #             log.debug("\t1101 0xd | n, PCR | 16 bit offset from program counter")
            __, value = self.read_pc_word()
            value_signed = signed16(value)
            ea = self.program_counter.value + value_signed
            self.cycles += 1
#             log.debug("\tea = pc($%x) + $%x = $%x (dez.: %i + %i = %i)",
#                 self.program_counter, value_signed, ea,
#                 self.program_counter, value_signed, ea,
#             )
        elif addr_mode == 0xe:
            #             log.error("\tget_ea_indexed(): illegal address mode, use 0xffff")
            ea = 0xffff  # illegal
        elif addr_mode == 0xf:
            #             log.debug("\t1111 0xf | [n] | 16 bit address - extended indirect")
            __, ea = self.read_pc_word()
        else:
            raise RuntimeError("Illegal indexed addressing mode: $%x" %
                               addr_mode)

        if offset is not None:
            ea = register_value + offset
#             log.debug("\t$%x + $%x = $%x (dez: %i + %i = %i)",
#                 register_value, offset, ea,
#                 register_value, offset, ea
#             )

        ea = ea & 0xffff

        if is_bit_set(postbyte, bit=4):  # bit 4 is 1 -> Indirect
            #             log.debug("\tIndirect addressing: get new ea from $%x", ea)
            ea = self.memory.read_word(ea)
#             log.debug("\tIndirect addressing: new ea is $%x", ea)

#        log.debug("\tget_ea_indexed(): return ea=$%x", ea)
        return ea