1
0
mirror of https://github.com/TomHarte/CLK.git synced 2026-04-26 03:29:40 +00:00

Add absolute-indexed addressing.

This commit is contained in:
Thomas Harte
2025-10-22 17:18:54 -04:00
parent 69122cdec4
commit 02e74ca1f4
2 changed files with 142 additions and 7 deletions
+6 -7
View File
@@ -55,7 +55,6 @@ enum class AccessProgram {
AbsoluteXRead,
AbsoluteXModify,
AbsoluteXWrite,
AbsoluteXNOP,
AbsoluteYRead,
AbsoluteYModify,
@@ -354,14 +353,14 @@ struct Decoder<model, std::enable_if_t<is_6502(model)>> {
case 0xdb: return {AbsoluteYModify, Operation::DCP};
case 0xfb: return {AbsoluteYModify, Operation::INS};
case 0x1c: return {AbsoluteXNOP, Operation::NOP};
case 0x3c: return {AbsoluteXNOP, Operation::NOP};
case 0x5c: return {AbsoluteXNOP, Operation::NOP};
case 0x7c: return {AbsoluteXNOP, Operation::NOP};
case 0x1c: return {AbsoluteXRead, Operation::NOP};
case 0x3c: return {AbsoluteXRead, Operation::NOP};
case 0x5c: return {AbsoluteXRead, Operation::NOP};
case 0x7c: return {AbsoluteXRead, Operation::NOP};
case 0x9c: return {AbsoluteXWrite, Operation::SHY};
case 0xbc: return {AbsoluteXRead, Operation::LDY};
case 0xdc: return {AbsoluteXNOP, Operation::NOP};
case 0xfc: return {AbsoluteXNOP, Operation::NOP};
case 0xdc: return {AbsoluteXRead, Operation::NOP};
case 0xfc: return {AbsoluteXRead, Operation::NOP};
case 0x1d: return {AbsoluteXRead, Operation::ORA};
case 0x3d: return {AbsoluteXRead, Operation::AND};
+136
View File
@@ -301,6 +301,142 @@ void Processor<model, Traits>::run_for(const Cycles cycles) {
goto fetch_decode;
// MARK: - Absolute indexed.
case access_program(AbsoluteXRead):
++registers.pc.full;
Storage::address_.halves.low = Storage::operand_;
access(BusOperation::Read, Literal(registers.pc.full), Storage::address_.halves.high);
++registers.pc.full;
Storage::operand_ = Storage::address_.halves.high;
Storage::address_.full += registers.x;
if(Storage::operand_ == Storage::address_.halves.high) {
goto skip_absolute_x_read_bonus_cycle;
}
std::swap(Storage::address_.halves.high, Storage::operand_);
access(BusOperation::Read, Literal(Storage::address_.full), throwaway);
std::swap(Storage::address_.halves.high, Storage::operand_);
skip_absolute_x_read_bonus_cycle:
check_interrupt();
access(BusOperation::Read, Literal(Storage::address_.full), Storage::operand_);
perform_operation();
goto fetch_decode;
case access_program(AbsoluteYRead):
++registers.pc.full;
Storage::address_.halves.low = Storage::operand_;
access(BusOperation::Read, Literal(registers.pc.full), Storage::address_.halves.high);
++registers.pc.full;
Storage::operand_ = Storage::address_.halves.high;
Storage::address_.full += registers.y;
if(Storage::operand_ == Storage::address_.halves.high) {
goto skip_absolute_y_read_bonus_cycle;
}
std::swap(Storage::address_.halves.high, Storage::operand_);
access(BusOperation::Read, Literal(Storage::address_.full), throwaway);
std::swap(Storage::address_.halves.high, Storage::operand_);
skip_absolute_y_read_bonus_cycle:
check_interrupt();
access(BusOperation::Read, Literal(Storage::address_.full), Storage::operand_);
perform_operation();
goto fetch_decode;
case access_program(AbsoluteXWrite):
++registers.pc.full;
Storage::address_.halves.low = Storage::operand_;
access(BusOperation::Read, Literal(registers.pc.full), Storage::address_.halves.high);
++registers.pc.full;
Storage::operand_ = Storage::address_.halves.high;
Storage::address_.full += registers.x;
std::swap(Storage::address_.halves.high, Storage::operand_);
access(BusOperation::Read, Literal(Storage::address_.full), throwaway);
std::swap(Storage::address_.halves.high, Storage::operand_);
check_interrupt();
perform_operation();
access(BusOperation::Write, Literal(Storage::address_.full), Storage::operand_);
goto fetch_decode;
case access_program(AbsoluteYWrite):
++registers.pc.full;
Storage::address_.halves.low = Storage::operand_;
access(BusOperation::Read, Literal(registers.pc.full), Storage::address_.halves.high);
++registers.pc.full;
Storage::operand_ = Storage::address_.halves.high;
Storage::address_.full += registers.y;
std::swap(Storage::address_.halves.high, Storage::operand_);
access(BusOperation::Read, Literal(Storage::address_.full), throwaway);
std::swap(Storage::address_.halves.high, Storage::operand_);
check_interrupt();
perform_operation();
access(BusOperation::Write, Literal(Storage::address_.full), Storage::operand_);
goto fetch_decode;
case access_program(AbsoluteXModify):
++registers.pc.full;
Storage::address_.halves.low = Storage::operand_;
access(BusOperation::Read, Literal(registers.pc.full), Storage::address_.halves.high);
++registers.pc.full;
Storage::operand_ = Storage::address_.halves.high;
Storage::address_.full += registers.x;
std::swap(Storage::address_.halves.high, Storage::operand_);
access(BusOperation::Read, Literal(Storage::address_.full), throwaway);
std::swap(Storage::address_.halves.high, Storage::operand_);
access(BusOperation::Read, Literal(Storage::address_.full), Storage::operand_);
access(BusOperation::Write, Literal(Storage::address_.full), Storage::operand_);
check_interrupt();
perform_operation();
access(BusOperation::Write, Literal(Storage::address_.full), Storage::operand_);
goto fetch_decode;
case access_program(AbsoluteYModify):
++registers.pc.full;
Storage::address_.halves.low = Storage::operand_;
access(BusOperation::Read, Literal(registers.pc.full), Storage::address_.halves.high);
++registers.pc.full;
Storage::operand_ = Storage::address_.halves.high;
Storage::address_.full += registers.y;
std::swap(Storage::address_.halves.high, Storage::operand_);
access(BusOperation::Read, Literal(Storage::address_.full), throwaway);
std::swap(Storage::address_.halves.high, Storage::operand_);
access(BusOperation::Read, Literal(Storage::address_.full), Storage::operand_);
access(BusOperation::Write, Literal(Storage::address_.full), Storage::operand_);
check_interrupt();
perform_operation();
access(BusOperation::Write, Literal(Storage::address_.full), Storage::operand_);
goto fetch_decode;
// MARK: - Stack.
case access_program(Pull):