mirror of
https://github.com/TomHarte/CLK.git
synced 2024-11-26 08:49:37 +00:00
Shifts size-limiting of X and Y to transitions and mutations, away from reads.
Primarily to remove potential bug-causing complexity — this is easier to debug. But let's see.
This commit is contained in:
parent
e3147b6b45
commit
d3c7253981
@ -392,6 +392,9 @@ class ConcreteMachine:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(operation == CPU::WDC65816::BusOperation::ReadOpcode && address == 0x00fa56) {
|
||||||
|
printf("?");
|
||||||
|
}
|
||||||
// log |= (address >= 0xffa6d9) && (address < 0xffa6ec);
|
// log |= (address >= 0xffa6d9) && (address < 0xffa6ec);
|
||||||
if(log) {
|
if(log) {
|
||||||
printf("%06x %s %02x", address, isReadOperation(operation) ? "->" : "<-", *value);
|
printf("%06x %s %02x", address, isReadOperation(operation) ? "->" : "<-", *value);
|
||||||
@ -405,7 +408,8 @@ class ConcreteMachine:
|
|||||||
m65816_.get_value_of_register(CPU::WDC65816::Register::Flags),
|
m65816_.get_value_of_register(CPU::WDC65816::Register::Flags),
|
||||||
m65816_.get_value_of_register(CPU::WDC65816::Register::DataBank),
|
m65816_.get_value_of_register(CPU::WDC65816::Register::DataBank),
|
||||||
m65816_.get_value_of_register(CPU::WDC65816::Register::ProgramBank),
|
m65816_.get_value_of_register(CPU::WDC65816::Register::ProgramBank),
|
||||||
m65816_.get_value_of_register(CPU::WDC65816::Register::Direct)
|
m65816_.get_value_of_register(CPU::WDC65816::Register::Direct
|
||||||
|
)
|
||||||
);
|
);
|
||||||
} else printf("\n");
|
} else printf("\n");
|
||||||
}
|
}
|
||||||
|
@ -275,6 +275,8 @@ class MemoryMap {
|
|||||||
e0_region.read = language_state.read ? ram : rom;
|
e0_region.read = language_state.read ? ram : rom;
|
||||||
e0_region.write = language_state.write ? nullptr : ram;
|
e0_region.write = language_state.write ? nullptr : ram;
|
||||||
|
|
||||||
|
if(!bank_base) printf("eo region read: %d!\n", language_state.read);
|
||||||
|
|
||||||
// Assert assumptions made above re: memory layout.
|
// Assert assumptions made above re: memory layout.
|
||||||
assert(region_map[bank_base | 0xd0] + 1 == region_map[bank_base | 0xe0]);
|
assert(region_map[bank_base | 0xd0] + 1 == region_map[bank_base | 0xe0]);
|
||||||
assert(region_map[bank_base | 0xe0] == region_map[bank_base | 0xff]);
|
assert(region_map[bank_base | 0xe0] == region_map[bank_base | 0xff]);
|
||||||
@ -290,6 +292,7 @@ class MemoryMap {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if(inhibit_banks0001) {
|
if(inhibit_banks0001) {
|
||||||
|
printf("Language card: disabled!\n");
|
||||||
set_no_card(0x0000);
|
set_no_card(0x0000);
|
||||||
set_no_card(0x0100);
|
set_no_card(0x0100);
|
||||||
} else {
|
} else {
|
||||||
|
@ -17,8 +17,8 @@ uint16_t ProcessorBase::get_value_of_register(Register r) const {
|
|||||||
case Register::StackPointer: return registers_.s.full & (registers_.emulation_flag ? 0xff : 0xffff);
|
case Register::StackPointer: return registers_.s.full & (registers_.emulation_flag ? 0xff : 0xffff);
|
||||||
case Register::Flags: return get_flags();
|
case Register::Flags: return get_flags();
|
||||||
case Register::A: return registers_.a.full;
|
case Register::A: return registers_.a.full;
|
||||||
case Register::X: return registers_.x.full & registers_.x_masks[1];
|
case Register::X: return registers_.x.full;
|
||||||
case Register::Y: return registers_.y.full & registers_.x_masks[1];
|
case Register::Y: return registers_.y.full;
|
||||||
case Register::EmulationFlag: return registers_.emulation_flag;
|
case Register::EmulationFlag: return registers_.emulation_flag;
|
||||||
case Register::DataBank: return registers_.data_bank >> 16;
|
case Register::DataBank: return registers_.data_bank >> 16;
|
||||||
case Register::ProgramBank: return registers_.program_bank >> 16;
|
case Register::ProgramBank: return registers_.program_bank >> 16;
|
||||||
@ -33,8 +33,8 @@ void ProcessorBase::set_value_of_register(Register r, uint16_t value) {
|
|||||||
case Register::StackPointer: registers_.s.full = value; break;
|
case Register::StackPointer: registers_.s.full = value; break;
|
||||||
case Register::Flags: set_flags(uint8_t(value)); break;
|
case Register::Flags: set_flags(uint8_t(value)); break;
|
||||||
case Register::A: registers_.a.full = value; break;
|
case Register::A: registers_.a.full = value; break;
|
||||||
case Register::X: registers_.x.full = value; break;
|
case Register::X: registers_.x.full = value & registers_.x_mask; break;
|
||||||
case Register::Y: registers_.y.full = value; break;
|
case Register::Y: registers_.y.full = value & registers_.x_mask; break;
|
||||||
case Register::EmulationFlag: set_emulation_mode(value); break;
|
case Register::EmulationFlag: set_emulation_mode(value); break;
|
||||||
case Register::DataBank: registers_.data_bank = uint32_t(value & 0xff) << 16; break;
|
case Register::DataBank: registers_.data_bank = uint32_t(value & 0xff) << 16; break;
|
||||||
case Register::ProgramBank: registers_.program_bank = uint32_t(value &0xff) << 16; break;
|
case Register::ProgramBank: registers_.program_bank = uint32_t(value &0xff) << 16; break;
|
||||||
|
@ -19,8 +19,6 @@ template <typename BusHandler, bool uses_ready_line> void Processor<BusHandler,
|
|||||||
#define m_flag() registers_.mx_flags[0]
|
#define m_flag() registers_.mx_flags[0]
|
||||||
#define x_flag() registers_.mx_flags[1]
|
#define x_flag() registers_.mx_flags[1]
|
||||||
|
|
||||||
#define x() (registers_.x.full & registers_.x_masks[1])
|
|
||||||
#define y() (registers_.y.full & registers_.x_masks[1])
|
|
||||||
#define stack_address() ((registers_.s.full & registers_.e_masks[1]) | (0x0100 & registers_.e_masks[0]))
|
#define stack_address() ((registers_.s.full & registers_.e_masks[1]) | (0x0100 & registers_.e_masks[0]))
|
||||||
|
|
||||||
Cycles number_of_cycles = cycles + cycles_left_to_run_;
|
Cycles number_of_cycles = cycles + cycles_left_to_run_;
|
||||||
@ -143,15 +141,15 @@ template <typename BusHandler, bool uses_ready_line> void Processor<BusHandler,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case CycleFetchBlockX:
|
case CycleFetchBlockX:
|
||||||
read(((instruction_buffer_.value & 0xff00) << 8) | x(), data_buffer_.any_byte());
|
read(((instruction_buffer_.value & 0xff00) << 8) | registers_.x.full, data_buffer_.any_byte());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CycleFetchBlockY:
|
case CycleFetchBlockY:
|
||||||
perform_bus(((instruction_buffer_.value & 0xff00) << 8) | y(), &bus_throwaway_, MOS6502Esque::InternalOperationRead);
|
perform_bus(((instruction_buffer_.value & 0xff00) << 8) | registers_.y.full, &bus_throwaway_, MOS6502Esque::InternalOperationRead);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CycleStoreBlockY:
|
case CycleStoreBlockY:
|
||||||
write(((instruction_buffer_.value & 0xff00) << 8) | y(), data_buffer_.any_byte());
|
write(((instruction_buffer_.value & 0xff00) << 8) | registers_.y.full, data_buffer_.any_byte());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
#undef increment_data_address
|
#undef increment_data_address
|
||||||
@ -266,18 +264,18 @@ template <typename BusHandler, bool uses_ready_line> void Processor<BusHandler,
|
|||||||
|
|
||||||
// Used for JMP and JSR (absolute, x).
|
// Used for JMP and JSR (absolute, x).
|
||||||
case OperationConstructAbsoluteIndexedIndirect:
|
case OperationConstructAbsoluteIndexedIndirect:
|
||||||
data_address_ = registers_.program_bank + ((instruction_buffer_.value + x()) & 0xffff);
|
data_address_ = registers_.program_bank + ((instruction_buffer_.value + registers_.x.full) & 0xffff);
|
||||||
data_address_increment_mask_ = 0x00'ff'ff;
|
data_address_increment_mask_ = 0x00'ff'ff;
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case OperationConstructAbsoluteLongX:
|
case OperationConstructAbsoluteLongX:
|
||||||
data_address_ = instruction_buffer_.value + x();
|
data_address_ = instruction_buffer_.value + registers_.x.full;
|
||||||
data_address_increment_mask_ = 0xff'ff'ff;
|
data_address_increment_mask_ = 0xff'ff'ff;
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case OperationConstructAbsoluteXRead:
|
case OperationConstructAbsoluteXRead:
|
||||||
case OperationConstructAbsoluteX:
|
case OperationConstructAbsoluteX:
|
||||||
data_address_ = instruction_buffer_.value + x() + registers_.data_bank;
|
data_address_ = instruction_buffer_.value + registers_.x.full + registers_.data_bank;
|
||||||
incorrect_data_address_ = (data_address_ & 0xff) | (instruction_buffer_.value & 0xff00) + registers_.data_bank;
|
incorrect_data_address_ = (data_address_ & 0xff) | (instruction_buffer_.value & 0xff00) + registers_.data_bank;
|
||||||
|
|
||||||
// If the incorrect address isn't actually incorrect, skip its usage.
|
// If the incorrect address isn't actually incorrect, skip its usage.
|
||||||
@ -289,7 +287,7 @@ template <typename BusHandler, bool uses_ready_line> void Processor<BusHandler,
|
|||||||
|
|
||||||
case OperationConstructAbsoluteYRead:
|
case OperationConstructAbsoluteYRead:
|
||||||
case OperationConstructAbsoluteY:
|
case OperationConstructAbsoluteY:
|
||||||
data_address_ = instruction_buffer_.value + y() + registers_.data_bank;
|
data_address_ = instruction_buffer_.value + registers_.y.full + registers_.data_bank;
|
||||||
incorrect_data_address_ = (data_address_ & 0xff) + (instruction_buffer_.value & 0xff00) + registers_.data_bank;
|
incorrect_data_address_ = (data_address_ & 0xff) + (instruction_buffer_.value & 0xff00) + registers_.data_bank;
|
||||||
|
|
||||||
// If the incorrect address isn't actually incorrect, skip its usage.
|
// If the incorrect address isn't actually incorrect, skip its usage.
|
||||||
@ -326,7 +324,7 @@ template <typename BusHandler, bool uses_ready_line> void Processor<BusHandler,
|
|||||||
|
|
||||||
case OperationConstructDirectIndexedIndirect:
|
case OperationConstructDirectIndexedIndirect:
|
||||||
data_address_ = registers_.data_bank + (
|
data_address_ = registers_.data_bank + (
|
||||||
((registers_.direct + x() + instruction_buffer_.value) & registers_.e_masks[1]) +
|
((registers_.direct + registers_.x.full + instruction_buffer_.value) & registers_.e_masks[1]) +
|
||||||
(registers_.direct & registers_.e_masks[0])
|
(registers_.direct & registers_.e_masks[0])
|
||||||
) & 0xffff;
|
) & 0xffff;
|
||||||
data_address_increment_mask_ = 0x00'ff'ff;
|
data_address_increment_mask_ = 0x00'ff'ff;
|
||||||
@ -337,7 +335,7 @@ template <typename BusHandler, bool uses_ready_line> void Processor<BusHandler,
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
case OperationConstructDirectIndirectIndexedLong:
|
case OperationConstructDirectIndirectIndexedLong:
|
||||||
data_address_ = y() + data_buffer_.value;
|
data_address_ = registers_.y.full + data_buffer_.value;
|
||||||
data_address_increment_mask_ = 0xff'ff'ff;
|
data_address_increment_mask_ = 0xff'ff'ff;
|
||||||
data_buffer_.clear();
|
data_buffer_.clear();
|
||||||
continue;
|
continue;
|
||||||
@ -353,7 +351,7 @@ template <typename BusHandler, bool uses_ready_line> void Processor<BusHandler,
|
|||||||
case OperationConstructDirectX:
|
case OperationConstructDirectX:
|
||||||
data_address_ = (
|
data_address_ = (
|
||||||
(registers_.direct & registers_.e_masks[0]) +
|
(registers_.direct & registers_.e_masks[0]) +
|
||||||
((instruction_buffer_.value + registers_.direct + x()) & registers_.e_masks[1])
|
((instruction_buffer_.value + registers_.direct + registers_.x.full) & registers_.e_masks[1])
|
||||||
) & 0xffff;
|
) & 0xffff;
|
||||||
data_address_increment_mask_ = 0x00'ff'ff;
|
data_address_increment_mask_ = 0x00'ff'ff;
|
||||||
|
|
||||||
@ -366,7 +364,7 @@ template <typename BusHandler, bool uses_ready_line> void Processor<BusHandler,
|
|||||||
case OperationConstructDirectY:
|
case OperationConstructDirectY:
|
||||||
data_address_ = (
|
data_address_ = (
|
||||||
(registers_.direct & registers_.e_masks[0]) +
|
(registers_.direct & registers_.e_masks[0]) +
|
||||||
((instruction_buffer_.value + registers_.direct + y()) & registers_.e_masks[1])
|
((instruction_buffer_.value + registers_.direct + registers_.y.full) & registers_.e_masks[1])
|
||||||
) & 0xffff;
|
) & 0xffff;
|
||||||
data_address_increment_mask_ = 0x00'ff'ff;
|
data_address_increment_mask_ = 0x00'ff'ff;
|
||||||
|
|
||||||
@ -382,7 +380,7 @@ template <typename BusHandler, bool uses_ready_line> void Processor<BusHandler,
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
case OperationConstructStackRelativeIndexedIndirect:
|
case OperationConstructStackRelativeIndexedIndirect:
|
||||||
data_address_ = registers_.data_bank + data_buffer_.value + y();
|
data_address_ = registers_.data_bank + data_buffer_.value + registers_.y.full;
|
||||||
data_address_increment_mask_ = 0xff'ff'ff;
|
data_address_increment_mask_ = 0xff'ff'ff;
|
||||||
data_buffer_.clear();
|
data_buffer_.clear();
|
||||||
continue;
|
continue;
|
||||||
@ -458,11 +456,8 @@ template <typename BusHandler, bool uses_ready_line> void Processor<BusHandler,
|
|||||||
// Performance.
|
// Performance.
|
||||||
//
|
//
|
||||||
|
|
||||||
#define LD(dest, src, masks) dest.full = (dest.full & masks[0]) | (src & masks[1])
|
#define LDA(src) registers_.a.full = (registers_.a.full & registers_.m_masks[0]) | (src & registers_.m_masks[1])
|
||||||
#define m_top() (instruction_buffer_.value >> registers_.m_shift) & 0xff
|
#define LDXY(dest, src) dest = (src) & registers_.x_mask
|
||||||
#define x_top() (registers_.x.full >> registers_.x_shift) & 0xff
|
|
||||||
#define y_top() (registers_.y.full >> registers_.x_shift) & 0xff
|
|
||||||
#define a_top() (registers_.a.full >> registers_.m_shift) & 0xff
|
|
||||||
|
|
||||||
case OperationPerform:
|
case OperationPerform:
|
||||||
switch(active_instruction_->operation) {
|
switch(active_instruction_->operation) {
|
||||||
@ -472,17 +467,17 @@ template <typename BusHandler, bool uses_ready_line> void Processor<BusHandler,
|
|||||||
//
|
//
|
||||||
|
|
||||||
case LDA:
|
case LDA:
|
||||||
LD(registers_.a, data_buffer_.value, registers_.m_masks);
|
LDA(data_buffer_.value);
|
||||||
registers_.flags.set_nz(registers_.a.full, registers_.m_shift);
|
registers_.flags.set_nz(registers_.a.full, registers_.m_shift);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LDX:
|
case LDX:
|
||||||
LD(registers_.x, data_buffer_.value, registers_.x_masks);
|
LDXY(registers_.x, data_buffer_.value);
|
||||||
registers_.flags.set_nz(registers_.x.full, registers_.x_shift);
|
registers_.flags.set_nz(registers_.x.full, registers_.x_shift);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LDY:
|
case LDY:
|
||||||
LD(registers_.y, data_buffer_.value, registers_.x_masks);
|
LDXY(registers_.y, data_buffer_.value);
|
||||||
registers_.flags.set_nz(registers_.y.full, registers_.x_shift);
|
registers_.flags.set_nz(registers_.y.full, registers_.x_shift);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -511,12 +506,12 @@ template <typename BusHandler, bool uses_ready_line> void Processor<BusHandler,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case STX:
|
case STX:
|
||||||
data_buffer_.value = registers_.x.full & registers_.x_masks[1];
|
data_buffer_.value = registers_.x.full;
|
||||||
data_buffer_.size = 2 - x_flag();
|
data_buffer_.size = 2 - x_flag();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case STY:
|
case STY:
|
||||||
data_buffer_.value = registers_.y.full & registers_.x_masks[1];
|
data_buffer_.value = registers_.y.full;
|
||||||
data_buffer_.size = 2 - x_flag();
|
data_buffer_.size = 2 - x_flag();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -554,41 +549,41 @@ template <typename BusHandler, bool uses_ready_line> void Processor<BusHandler,
|
|||||||
// (and make reasonable guesses as to the N flag).
|
// (and make reasonable guesses as to the N flag).
|
||||||
|
|
||||||
case TXS:
|
case TXS:
|
||||||
registers_.s = registers_.x.full & registers_.x_masks[1];
|
registers_.s = registers_.x.full;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TSX:
|
case TSX:
|
||||||
LD(registers_.x, registers_.s.full, registers_.x_masks);
|
LDXY(registers_.x, registers_.s.full);
|
||||||
registers_.flags.set_nz(registers_.x.full, registers_.x_shift);
|
registers_.flags.set_nz(registers_.x.full, registers_.x_shift);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TXY:
|
case TXY:
|
||||||
LD(registers_.y, registers_.x.full, registers_.x_masks);
|
LDXY(registers_.y, registers_.x.full);
|
||||||
registers_.flags.set_nz(registers_.y.full, registers_.x_shift);
|
registers_.flags.set_nz(registers_.y.full, registers_.x_shift);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TYX:
|
case TYX:
|
||||||
LD(registers_.x, registers_.y.full, registers_.x_masks);
|
LDXY(registers_.x, registers_.y.full);
|
||||||
registers_.flags.set_nz(registers_.x.full, registers_.x_shift);
|
registers_.flags.set_nz(registers_.x.full, registers_.x_shift);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TAX:
|
case TAX:
|
||||||
LD(registers_.x, registers_.a.full, registers_.x_masks);
|
LDXY(registers_.x, registers_.a.full);
|
||||||
registers_.flags.set_nz(registers_.x.full, registers_.x_shift);
|
registers_.flags.set_nz(registers_.x.full, registers_.x_shift);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TAY:
|
case TAY:
|
||||||
LD(registers_.y, registers_.a.full, registers_.x_masks);
|
LDXY(registers_.y, registers_.a.full);
|
||||||
registers_.flags.set_nz(registers_.y.full, registers_.x_shift);
|
registers_.flags.set_nz(registers_.y.full, registers_.x_shift);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TXA:
|
case TXA:
|
||||||
LD(registers_.a, registers_.x.full, registers_.m_masks);
|
LDA(registers_.x.full);
|
||||||
registers_.flags.set_nz(registers_.a.full, registers_.m_shift);
|
registers_.flags.set_nz(registers_.a.full, registers_.m_shift);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TYA:
|
case TYA:
|
||||||
LD(registers_.a, registers_.y.full, registers_.m_masks);
|
LDA(registers_.y.full);
|
||||||
registers_.flags.set_nz(registers_.a.full, registers_.m_shift);
|
registers_.flags.set_nz(registers_.a.full, registers_.m_shift);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -670,16 +665,16 @@ template <typename BusHandler, bool uses_ready_line> void Processor<BusHandler,
|
|||||||
|
|
||||||
case MVP:
|
case MVP:
|
||||||
registers_.data_bank = (instruction_buffer_.value & 0xff) << 16;
|
registers_.data_bank = (instruction_buffer_.value & 0xff) << 16;
|
||||||
--registers_.x.full;
|
LDXY(registers_.x.full, registers_.x.full - 1);
|
||||||
--registers_.y.full;
|
LDXY(registers_.y.full, registers_.y.full - 1);
|
||||||
if(registers_.a.full) registers_.pc -= 3;
|
if(registers_.a.full) registers_.pc -= 3;
|
||||||
--registers_.a.full;
|
--registers_.a.full;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MVN:
|
case MVN:
|
||||||
registers_.data_bank = (instruction_buffer_.value & 0xff) << 16;
|
registers_.data_bank = (instruction_buffer_.value & 0xff) << 16;
|
||||||
++registers_.x.full;
|
LDXY(registers_.x.full, registers_.x.full + 1);
|
||||||
++registers_.y.full;
|
LDXY(registers_.y.full, registers_.y.full + 1);
|
||||||
if(registers_.a.full) registers_.pc -= 3;
|
if(registers_.a.full) registers_.pc -= 3;
|
||||||
--registers_.a.full;
|
--registers_.a.full;
|
||||||
break;
|
break;
|
||||||
@ -725,29 +720,25 @@ template <typename BusHandler, bool uses_ready_line> void Processor<BusHandler,
|
|||||||
registers_.flags.set_nz(uint16_t(data_buffer_.value), registers_.m_shift);
|
registers_.flags.set_nz(uint16_t(data_buffer_.value), registers_.m_shift);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case INX: {
|
case INX:
|
||||||
const uint16_t x_inc = registers_.x.full + 1;
|
LDXY(registers_.x.full, registers_.x.full + 1);
|
||||||
LD(registers_.x, x_inc, registers_.x_masks);
|
|
||||||
registers_.flags.set_nz(registers_.x.full, registers_.x_shift);
|
registers_.flags.set_nz(registers_.x.full, registers_.x_shift);
|
||||||
} break;
|
break;
|
||||||
|
|
||||||
case DEX: {
|
case DEX:
|
||||||
const uint16_t x_dec = registers_.x.full - 1;
|
LDXY(registers_.x.full, registers_.x.full - 1);
|
||||||
LD(registers_.x, x_dec, registers_.x_masks);
|
|
||||||
registers_.flags.set_nz(registers_.x.full, registers_.x_shift);
|
registers_.flags.set_nz(registers_.x.full, registers_.x_shift);
|
||||||
} break;
|
break;
|
||||||
|
|
||||||
case INY: {
|
case INY:
|
||||||
const uint16_t y_inc = registers_.y.full + 1;
|
LDXY(registers_.y.full, registers_.y.full + 1);
|
||||||
LD(registers_.y, y_inc, registers_.x_masks);
|
|
||||||
registers_.flags.set_nz(registers_.y.full, registers_.x_shift);
|
registers_.flags.set_nz(registers_.y.full, registers_.x_shift);
|
||||||
} break;
|
break;
|
||||||
|
|
||||||
case DEY: {
|
case DEY:
|
||||||
const uint16_t y_dec = registers_.y.full - 1;
|
LDXY(registers_.y.full, registers_.y.full - 1);
|
||||||
LD(registers_.y, y_dec, registers_.x_masks);
|
|
||||||
registers_.flags.set_nz(registers_.y.full, registers_.x_shift);
|
registers_.flags.set_nz(registers_.y.full, registers_.x_shift);
|
||||||
} break;
|
break;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Bitwise operations.
|
// Bitwise operations.
|
||||||
@ -853,15 +844,15 @@ template <typename BusHandler, bool uses_ready_line> void Processor<BusHandler,
|
|||||||
// Arithmetic.
|
// Arithmetic.
|
||||||
//
|
//
|
||||||
|
|
||||||
#define cp(v, shift, masks) {\
|
#define cp(v, shift, mask) {\
|
||||||
const uint32_t temp32 = (v.full & masks[1]) - (data_buffer_.value & masks[1]); \
|
const uint32_t temp32 = (v.full & mask) - (data_buffer_.value & mask); \
|
||||||
registers_.flags.set_nz(uint16_t(temp32), shift); \
|
registers_.flags.set_nz(uint16_t(temp32), shift); \
|
||||||
registers_.flags.carry = ((~temp32) >> (8 + shift))&1; \
|
registers_.flags.carry = ((~temp32) >> (8 + shift))&1; \
|
||||||
}
|
}
|
||||||
|
|
||||||
case CMP: cp(registers_.a, registers_.m_shift, registers_.m_masks); break;
|
case CMP: cp(registers_.a, registers_.m_shift, registers_.m_masks[1]); break;
|
||||||
case CPX: cp(registers_.x, registers_.x_shift, registers_.x_masks); break;
|
case CPX: cp(registers_.x, registers_.x_shift, registers_.x_mask); break;
|
||||||
case CPY: cp(registers_.y, registers_.x_shift, registers_.x_masks); break;
|
case CPY: cp(registers_.y, registers_.x_shift, registers_.x_mask); break;
|
||||||
|
|
||||||
#undef cp
|
#undef cp
|
||||||
|
|
||||||
@ -895,7 +886,7 @@ template <typename BusHandler, bool uses_ready_line> void Processor<BusHandler,
|
|||||||
registers_.flags.overflow = (( (decimal_result ^ registers_.a.full) & (~decimal_result ^ data_buffer_.value) ) >> (1 + registers_.m_shift))&0x40;
|
registers_.flags.overflow = (( (decimal_result ^ registers_.a.full) & (~decimal_result ^ data_buffer_.value) ) >> (1 + registers_.m_shift))&0x40;
|
||||||
registers_.flags.set_nz(uint16_t(result), registers_.m_shift);
|
registers_.flags.set_nz(uint16_t(result), registers_.m_shift);
|
||||||
registers_.flags.carry = ((borrow >> 16)&1)^1;
|
registers_.flags.carry = ((borrow >> 16)&1)^1;
|
||||||
LD(registers_.a, result, registers_.m_masks);
|
LDA(result);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -932,7 +923,7 @@ template <typename BusHandler, bool uses_ready_line> void Processor<BusHandler,
|
|||||||
|
|
||||||
registers_.flags.set_nz(uint16_t(result), registers_.m_shift);
|
registers_.flags.set_nz(uint16_t(result), registers_.m_shift);
|
||||||
registers_.flags.carry = (result >> (8 + registers_.m_shift))&1;
|
registers_.flags.carry = (result >> (8 + registers_.m_shift))&1;
|
||||||
LD(registers_.a, result, registers_.m_masks);
|
LDA(result);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -950,12 +941,6 @@ template <typename BusHandler, bool uses_ready_line> void Processor<BusHandler,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef LD
|
|
||||||
#undef m_top
|
|
||||||
#undef x_top
|
|
||||||
#undef y_top
|
|
||||||
#undef a_top
|
|
||||||
|
|
||||||
// Store a selection as to the exceptions, if any, that would be honoured after this cycle if the
|
// Store a selection as to the exceptions, if any, that would be honoured after this cycle if the
|
||||||
// next thing is a MoveToNextProgram.
|
// next thing is a MoveToNextProgram.
|
||||||
selected_exceptions_ = pending_exceptions_ & (registers_.flags.inverse_interrupt | PowerOn | Reset | NMI);
|
selected_exceptions_ = pending_exceptions_ & (registers_.flags.inverse_interrupt | PowerOn | Reset | NMI);
|
||||||
@ -963,6 +948,8 @@ template <typename BusHandler, bool uses_ready_line> void Processor<BusHandler,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#undef LDA
|
||||||
|
#undef LDXY
|
||||||
#undef read
|
#undef read
|
||||||
#undef write
|
#undef write
|
||||||
#undef bus_operation
|
#undef bus_operation
|
||||||
|
@ -1109,16 +1109,10 @@ void ProcessorStorage::set_emulation_mode(bool enabled) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ProcessorStorage::set_m_x_flags(bool m, bool x) {
|
void ProcessorStorage::set_m_x_flags(bool m, bool x) {
|
||||||
// Reset the top byte of x and y if _exiting_ 8-bit mode.
|
registers_.x_mask = x ? 0x00ff : 0xffff;
|
||||||
// TODO: rationalise this sort of logic, both here and
|
|
||||||
// with regards to the stack pointer.
|
|
||||||
if(!x && registers_.mx_flags[1]) {
|
|
||||||
registers_.x.halves.high = registers_.y.halves.high = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
registers_.x_masks[0] = x ? 0xff00 : 0x0000;
|
|
||||||
registers_.x_masks[1] = x ? 0x00ff : 0xffff;
|
|
||||||
registers_.x_shift = x ? 0 : 8;
|
registers_.x_shift = x ? 0 : 8;
|
||||||
|
registers_.x.full &= registers_.x_mask;
|
||||||
|
registers_.y.full &= registers_.x_mask;
|
||||||
|
|
||||||
registers_.m_masks[0] = m ? 0xff00 : 0x0000;
|
registers_.m_masks[0] = m ? 0xff00 : 0x0000;
|
||||||
registers_.m_masks[1] = m ? 0x00ff : 0xffff;
|
registers_.m_masks[1] = m ? 0x00ff : 0xffff;
|
||||||
|
@ -269,9 +269,9 @@ struct ProcessorStorage {
|
|||||||
|
|
||||||
// Flags aplenty.
|
// Flags aplenty.
|
||||||
MOS6502Esque::LazyFlags flags;
|
MOS6502Esque::LazyFlags flags;
|
||||||
uint8_t mx_flags[2] = {1, 1}; // [0] = m; [1] = x. In both cases either `0` or `1`; `1` => 8-bit.
|
uint8_t mx_flags[2] = {1, 1}; // [0] = m; [1] = x. In both cases either `0` or `1`; `1` => 8-bit.
|
||||||
uint16_t m_masks[2] = {0xff00, 0x00ff}; // [0] = src mask; [1] = dst mask.
|
uint16_t m_masks[2] = {0xff00, 0x00ff}; // [0] = src mask; [1] = dst mask.
|
||||||
uint16_t x_masks[2] = {0xff00, 0x00ff}; // [0] = src mask; [1] = dst mask.
|
uint16_t x_mask = 0x00ff; // Just a mask representing the current size of the index registers.
|
||||||
uint16_t e_masks[2] = {0xff00, 0x00ff};
|
uint16_t e_masks[2] = {0xff00, 0x00ff};
|
||||||
int m_shift = 0;
|
int m_shift = 0;
|
||||||
int x_shift = 0;
|
int x_shift = 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user