mirror of
https://github.com/TomHarte/CLK.git
synced 2026-04-21 02:17:08 +00:00
Add all absolute-indexed oddities.
This commit is contained in:
@@ -140,9 +140,7 @@ struct Traits {
|
||||
] sortedArrayUsingSelector:@selector(compare:)];
|
||||
for(NSString *file in files) {
|
||||
if(
|
||||
[file isEqualToString:@"93.json"] || // SHA
|
||||
[file isEqualToString:@"9c.json"] || // SHY
|
||||
[file isEqualToString:@"9b.json"] // SHS
|
||||
[file isEqualToString:@"93.json"] // SHA
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -86,9 +86,8 @@ enum class AccessProgram {
|
||||
JMPAbsolute, JMPAbsoluteIndirect,
|
||||
|
||||
// Irregular unintended, undocumented and unreliable.
|
||||
SHAIndirectIndexed,
|
||||
SHASHXAbsoluteY,
|
||||
SHS, SHY,
|
||||
SHxIndirectIndexed,
|
||||
SHxAbsoluteXY,
|
||||
|
||||
// Terminal.
|
||||
JAM,
|
||||
@@ -283,7 +282,7 @@ struct Decoder<model, std::enable_if_t<is_6502(model)>> {
|
||||
case 0x33: return {IndirectIndexedModify, Operation::RLA};
|
||||
case 0x53: return {IndirectIndexedModify, Operation::LSE};
|
||||
case 0x73: return {IndirectIndexedModify, Operation::RRA};
|
||||
case 0x93: return {SHAIndirectIndexed, Operation::SHA};
|
||||
case 0x93: return {SHxIndirectIndexed, Operation::SHA};
|
||||
case 0xb3: return {IndirectIndexedRead, Operation::LAX};
|
||||
case 0xd3: return {IndirectIndexedModify, Operation::DCP};
|
||||
case 0xf3: return {IndirectIndexedModify, Operation::INS};
|
||||
@@ -355,7 +354,7 @@ struct Decoder<model, std::enable_if_t<is_6502(model)>> {
|
||||
case 0x3b: return {AbsoluteYModify, Operation::RLA};
|
||||
case 0x5b: return {AbsoluteYModify, Operation::LSE};
|
||||
case 0x7b: return {AbsoluteYModify, Operation::RRA};
|
||||
case 0x9b: return {SHS, Operation::SHS};
|
||||
case 0x9b: return {SHxAbsoluteXY, Operation::SHS};
|
||||
case 0xbb: return {AbsoluteYRead, Operation::LAS};
|
||||
case 0xdb: return {AbsoluteYModify, Operation::DCP};
|
||||
case 0xfb: return {AbsoluteYModify, Operation::INS};
|
||||
@@ -364,7 +363,7 @@ struct Decoder<model, std::enable_if_t<is_6502(model)>> {
|
||||
case 0x3c: return {AbsoluteXRead, Operation::NOP};
|
||||
case 0x5c: return {AbsoluteXRead, Operation::NOP};
|
||||
case 0x7c: return {AbsoluteXRead, Operation::NOP};
|
||||
case 0x9c: return {SHY, Operation::SHY};
|
||||
case 0x9c: return {SHxAbsoluteXY, Operation::SHY};
|
||||
case 0xbc: return {AbsoluteXRead, Operation::LDY};
|
||||
case 0xdc: return {AbsoluteXRead, Operation::NOP};
|
||||
case 0xfc: return {AbsoluteXRead, Operation::NOP};
|
||||
@@ -382,7 +381,7 @@ struct Decoder<model, std::enable_if_t<is_6502(model)>> {
|
||||
case 0x3e: return {AbsoluteXModify, Operation::ROL};
|
||||
case 0x5e: return {AbsoluteXModify, Operation::LSR};
|
||||
case 0x7e: return {AbsoluteXModify, Operation::ROR};
|
||||
case 0x9e: return {SHASHXAbsoluteY, Operation::SHX};
|
||||
case 0x9e: return {SHxAbsoluteXY, Operation::SHX};
|
||||
case 0xbe: return {AbsoluteYRead, Operation::LDX};
|
||||
case 0xde: return {AbsoluteXModify, Operation::DEC};
|
||||
case 0xfe: return {AbsoluteXModify, Operation::INC};
|
||||
@@ -391,7 +390,7 @@ struct Decoder<model, std::enable_if_t<is_6502(model)>> {
|
||||
case 0x3f: return {AbsoluteXModify, Operation::RLA};
|
||||
case 0x5f: return {AbsoluteXModify, Operation::LSE};
|
||||
case 0x7f: return {AbsoluteXModify, Operation::RRA};
|
||||
case 0x9f: return {SHASHXAbsoluteY, Operation::SHA};
|
||||
case 0x9f: return {SHxAbsoluteXY, Operation::SHA};
|
||||
case 0xbf: return {AbsoluteYRead, Operation::LAX};
|
||||
case 0xdf: return {AbsoluteXModify, Operation::DCP};
|
||||
case 0xff: return {AbsoluteXModify, Operation::INS};
|
||||
|
||||
@@ -62,7 +62,38 @@ void Processor<model, Traits>::run_for(const Cycles cycles) {
|
||||
auto ®isters = Storage::registers_;
|
||||
uint8_t throwaway = 0;
|
||||
|
||||
const auto sha = [&] {
|
||||
if(Storage::did_adjust_top_) {
|
||||
Storage::address_.halves.high = Storage::operand_ =
|
||||
registers.a & registers.x & Storage::address_.halves.high;
|
||||
} else {
|
||||
Storage::operand_ = registers.a & registers.x & (Storage::address_.halves.high + 1);
|
||||
}
|
||||
};
|
||||
const auto shx = [&] {
|
||||
if(Storage::did_adjust_top_) {
|
||||
Storage::address_.halves.high = Storage::operand_ = registers.x & Storage::address_.halves.high;
|
||||
} else {
|
||||
Storage::operand_ = registers.x & (Storage::address_.halves.high + 1);
|
||||
}
|
||||
};
|
||||
const auto shy = [&] {
|
||||
if(Storage::did_adjust_top_) {
|
||||
Storage::address_.halves.high = Storage::operand_ = registers.y & Storage::address_.halves.high;
|
||||
} else {
|
||||
Storage::operand_ = registers.y & (Storage::address_.halves.high + 1);
|
||||
}
|
||||
};
|
||||
const auto shs = [&] {
|
||||
registers.s = registers.a & registers.x;
|
||||
if(Storage::did_adjust_top_) {
|
||||
Storage::address_.halves.high = Storage::operand_ = registers.s & Storage::address_.halves.high;
|
||||
} else {
|
||||
Storage::operand_ = registers.s & (Storage::address_.halves.high + 1);
|
||||
}
|
||||
};
|
||||
const auto check_interrupt = [] {
|
||||
// TODO.
|
||||
};
|
||||
const auto perform_operation = [&] {
|
||||
CPU::MOS6502Mk2::perform<model>(
|
||||
@@ -571,7 +602,7 @@ void Processor<model, Traits>::run_for(const Cycles cycles) {
|
||||
|
||||
// MARK: - Potentially-faulty addressing of SHA/SHX/SHY/SHS.
|
||||
|
||||
case access_program(SHASHXAbsoluteY):
|
||||
case access_program(SHxAbsoluteXY):
|
||||
++registers.pc.full;
|
||||
|
||||
Storage::address_.halves.low = Storage::operand_;
|
||||
@@ -579,26 +610,19 @@ void Processor<model, Traits>::run_for(const Cycles cycles) {
|
||||
++registers.pc.full;
|
||||
|
||||
Storage::operand_ = Storage::address_.halves.high;
|
||||
Storage::address_.full += registers.y;
|
||||
Storage::address_.full += (Storage::decoded_.operation == Operation::SHY) ? registers.x : registers.y;
|
||||
Storage::did_adjust_top_ = Storage::address_.halves.high != Storage::operand_;
|
||||
|
||||
std::swap(Storage::address_.halves.high, Storage::operand_);
|
||||
access(BusOperation::Read, Literal(Storage::address_.full), throwaway);
|
||||
std::swap(Storage::address_.halves.high, Storage::operand_);
|
||||
|
||||
if(Storage::decoded_.operation == Operation::SHA) {
|
||||
if(Storage::did_adjust_top_) {
|
||||
Storage::address_.halves.high = Storage::operand_ =
|
||||
registers.a & registers.x & Storage::address_.halves.high;
|
||||
} else {
|
||||
Storage::operand_ = registers.a & registers.x & (Storage::address_.halves.high + 1);
|
||||
}
|
||||
} else {
|
||||
if(Storage::did_adjust_top_) {
|
||||
Storage::address_.halves.high = Storage::operand_ = registers.x & Storage::address_.halves.high;
|
||||
} else {
|
||||
Storage::operand_ = registers.x & (Storage::address_.halves.high + 1);
|
||||
}
|
||||
switch(Storage::decoded_.operation) {
|
||||
default: __builtin_unreachable();
|
||||
case Operation::SHA: sha(); break;
|
||||
case Operation::SHX: shx(); break;
|
||||
case Operation::SHY: shy(); break;
|
||||
case Operation::SHS: shs(); break;
|
||||
}
|
||||
|
||||
check_interrupt();
|
||||
|
||||
@@ -373,32 +373,6 @@ void perform(
|
||||
registers.flags.set_nz(registers.x);
|
||||
registers.flags.carry = ((difference >> 8)&1)^1;
|
||||
} break;
|
||||
|
||||
// MARK: - Oddball address dependencies.
|
||||
|
||||
case Operation::SHA:
|
||||
// if(address_.full != next_address_.full) {
|
||||
// address_.halves.high = operand_ = a_ & x_ & address_.halves.high;
|
||||
// } else {
|
||||
// operand_ = a_ & x_ & (address_.halves.high + 1);
|
||||
// }
|
||||
break;
|
||||
case Operation::SHY:
|
||||
// if(address_.full != next_address_.full) {
|
||||
// address_.halves.high = operand_ = y_ & address_.halves.high;
|
||||
// } else {
|
||||
// operand_ = y_ & (address_.halves.high + 1);
|
||||
// }
|
||||
break;
|
||||
case Operation::SHS:
|
||||
// if(address_.full != next_address_.full) {
|
||||
// s_ = a_ & x_;
|
||||
// address_.halves.high = operand_ = s_ & address_.halves.high;
|
||||
// } else {
|
||||
// s_ = a_ & x_;
|
||||
// operand_ = s_ & (address_.halves.high + 1);
|
||||
// }
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user