def assertROL(self, src, dst, source_carry): src_bit_str = '{0:08b}'.format(src) dst_bit_str = '{0:08b}'.format(dst) print("%02x %s > ROLA > %02x %s -> %s" % (src, src_bit_str, dst, dst_bit_str, self.cpu.get_cc_info())) # Carry was cleared and moved into bit 0 excpeted_bits = "%s%s" % (src_bit_str[1:], source_carry) self.assertEqual(dst_bit_str, excpeted_bits) # test negative if dst >= 0x80: self.assertEqual(self.cpu.N, 1) else: self.assertEqual(self.cpu.N, 0) # test zero if dst == 0: self.assertEqual(self.cpu.Z, 1) else: self.assertEqual(self.cpu.Z, 0) # test overflow source_bit6 = is_bit_set(src, bit=6) source_bit7 = is_bit_set(src, bit=7) if source_bit6 == source_bit7: # V = bit 6 XOR bit 7 self.assertEqual(self.cpu.V, 0) else: self.assertEqual(self.cpu.V, 1) # test carry if 0x80 <= src <= 0xff: # if bit 7 was set self.assertEqual(self.cpu.C, 1) else: self.assertEqual(self.cpu.C, 0)
def assertROR(self, src, dst, source_carry): src_bit_str = '{0:08b}'.format(src) dst_bit_str = '{0:08b}'.format(dst) # print "%02x %s > RORA > %02x %s -> %s" % ( # src, src_bit_str, # dst, dst_bit_str, # self.cpu.get_cc_info() # ) # Carry was cleared and moved into bit 0 excpeted_bits = "%s%s" % (source_carry, src_bit_str[:-1]) self.assertEqual(dst_bit_str, excpeted_bits) # test negative if dst >= 0x80: self.assertEqual(self.cpu.N, 1) else: self.assertEqual(self.cpu.N, 0) # test zero if dst == 0: self.assertEqual(self.cpu.Z, 1) else: self.assertEqual(self.cpu.Z, 0) # test carry source_bit0 = is_bit_set(src, bit=0) if source_bit0: # if bit 0 was set self.assertEqual(self.cpu.C, 1) else: self.assertEqual(self.cpu.C, 0)
def assertROR(self, src, dst, source_carry): src_bit_str = '{0:08b}'.format(src) dst_bit_str = '{0:08b}'.format(dst) # print "%02x %s > RORA > %02x %s -> %s" % ( # src, src_bit_str, # dst, dst_bit_str, # self.cpu.cc.get_info # ) # Carry was cleared and moved into bit 0 excpeted_bits = "%s%s" % (source_carry, src_bit_str[:-1]) self.assertEqual(dst_bit_str, excpeted_bits) # test negative if dst >= 0x80: self.assertEqual(self.cpu.cc.N, 1) else: self.assertEqual(self.cpu.cc.N, 0) # test zero if dst == 0: self.assertEqual(self.cpu.cc.Z, 1) else: self.assertEqual(self.cpu.cc.Z, 0) # test carry source_bit0 = is_bit_set(src, bit=0) if source_bit0: # if bit 0 was set self.assertEqual(self.cpu.cc.C, 1) else: self.assertEqual(self.cpu.cc.C, 0)
def test_ASR_inherent(self): """ Shifts all bits of the operand one place to the right. Bit seven is held constant. Bit zero is shifted into the C (carry) bit. """ for src in range(0x100): self.cpu.accu_b.set(src) self.cpu.set_cc(0x00) # Set all CC flags self.cpu_test_run( start=0x1000, end=None, mem=[ 0x57, # ASRB/LSRB Inherent ]) dst = self.cpu.accu_b.value src_bit_str = '{0:08b}'.format(src) dst_bit_str = '{0:08b}'.format(dst) # print "%02x %s > ASRB > %02x %s -> %s" % ( # src, src_bit_str, # dst, dst_bit_str, # self.cpu.get_cc_info() # ) # Bit seven is held constant. if src_bit_str[0] == "1": excpeted_bits = "1%s" % src_bit_str[:-1] else: excpeted_bits = "0%s" % src_bit_str[:-1] # test ASRB/LSRB result self.assertEqual(dst_bit_str, excpeted_bits) # test negative if 128 <= dst <= 255: self.assertEqual(self.cpu.N, 1) else: self.assertEqual(self.cpu.N, 0) # test zero if dst == 0: self.assertEqual(self.cpu.Z, 1) else: self.assertEqual(self.cpu.Z, 0) # test overflow (is uneffected!) self.assertEqual(self.cpu.V, 0) # test carry source_bit0 = is_bit_set(src, bit=0) if source_bit0: self.assertEqual(self.cpu.C, 1) else: self.assertEqual(self.cpu.C, 0)
def test_ASR_inherent(self): """ Shifts all bits of the operand one place to the right. Bit seven is held constant. Bit zero is shifted into the C (carry) bit. """ for src in range(0x100): self.cpu.accu_b.set(src) self.cpu.cc.set(0x00) # Set all CC flags self.cpu_test_run(start=0x1000, end=None, mem=[ 0x57, # ASRB/LSRB Inherent ]) dst = self.cpu.accu_b.get() src_bit_str = '{0:08b}'.format(src) dst_bit_str = '{0:08b}'.format(dst) # print "%02x %s > ASRB > %02x %s -> %s" % ( # src, src_bit_str, # dst, dst_bit_str, # self.cpu.cc.get_info # ) # Bit seven is held constant. if src_bit_str[0] == "1": excpeted_bits = "1%s" % src_bit_str[:-1] else: excpeted_bits = "0%s" % src_bit_str[:-1] # test ASRB/LSRB result self.assertEqual(dst_bit_str, excpeted_bits) # test negative if 128 <= dst <= 255: self.assertEqual(self.cpu.cc.N, 1) else: self.assertEqual(self.cpu.cc.N, 0) # test zero if dst == 0: self.assertEqual(self.cpu.cc.Z, 1) else: self.assertEqual(self.cpu.cc.Z, 0) # test overflow (is uneffected!) self.assertEqual(self.cpu.cc.V, 0) # test carry source_bit0 = is_bit_set(src, bit=0) if source_bit0: self.assertEqual(self.cpu.cc.C, 1) else: self.assertEqual(self.cpu.cc.C, 0)
def assertROL(self, src, dst, source_carry): src_bit_str = '{0:08b}'.format(src) dst_bit_str = '{0:08b}'.format(dst) # print "%02x %s > ROLA > %02x %s -> %s" % ( # src, src_bit_str, # dst, dst_bit_str, # self.cpu.cc.get_info # ) # Carry was cleared and moved into bit 0 excpeted_bits = "%s%s" % (src_bit_str[1:], source_carry) self.assertEqual(dst_bit_str, excpeted_bits) # test negative if dst >= 0x80: self.assertEqual(self.cpu.cc.N, 1) else: self.assertEqual(self.cpu.cc.N, 0) # test zero if dst == 0: self.assertEqual(self.cpu.cc.Z, 1) else: self.assertEqual(self.cpu.cc.Z, 0) # test overflow source_bit6 = is_bit_set(src, bit=6) source_bit7 = is_bit_set(src, bit=7) if source_bit6 == source_bit7: # V = bit 6 XOR bit 7 self.assertEqual(self.cpu.cc.V, 0) else: self.assertEqual(self.cpu.cc.V, 1) # test carry if 0x80 <= src <= 0xff: # if bit 7 was set self.assertEqual(self.cpu.cc.C, 1) else: self.assertEqual(self.cpu.cc.C, 0)
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