1
0
mirror of https://github.com/TomHarte/CLK.git synced 2025-01-11 08:30:55 +00:00

Corrected conditional call timing, and its test.

This commit is contained in:
Thomas Harte 2017-06-20 20:57:23 -04:00
parent 25aba16ef8
commit 27ac342928
2 changed files with 25 additions and 12 deletions

View File

@ -1000,9 +1000,9 @@ class Z80MachineCycleTests: XCTestCase {
func testCALLcc() {
test(
program: [
0x37, // SCF
0xd4, // CALL NC
0xdc, // CALL C
0x37, // SCF
0xd4, 0x00, 0x80, // CALL NC
0xdc, 0x00, 0x80 // CALL C
],
busCycles: [
MachineCycle(operation: .readOpcode, length: 4),

View File

@ -273,6 +273,7 @@ template <class T> class Processor {
InstructionPage() : r_step(1), is_indexed(false) {}
};
std::vector<MicroOp> conditional_call_untaken_program_;
std::vector<MicroOp> reset_program_;
std::vector<MicroOp> irq_program_[3];
std::vector<MicroOp> nmi_program_;
@ -314,7 +315,7 @@ template <class T> class Processor {
#define NOP Sequence(BusOp(Refresh(2)))
#define JP(cc) StdInstr(Read16Inc(pc_, temp16_), {MicroOp::cc}, {MicroOp::Move16, &temp16_.full, &pc_.full})
#define CALL(cc) StdInstr(Read16Inc(pc_, temp16_), {MicroOp::cc}, Push(pc_), {MicroOp::Move16, &temp16_.full, &pc_.full}) // WAIT(1),
#define CALL(cc) StdInstr(ReadInc(pc_, temp16_.bytes.low), {MicroOp::cc, conditional_call_untaken_program_.data()}, Read4Inc(pc_, temp16_.bytes.high), Push(pc_), {MicroOp::Move16, &temp16_.full, &pc_.full})
#define RET(cc) Instr(3, {MicroOp::cc}, Pop(memptr_), {MicroOp::Move16, &memptr_.full, &pc_.full})
#define JR(cc) StdInstr(ReadInc(pc_, temp8_), {MicroOp::cc}, InternalOperation(5), {MicroOp::CalculateIndexAddress, &pc_.full}, {MicroOp::Move16, &memptr_.full, &pc_.full})
#define RST() Instr(3, {MicroOp::CalculateRSTDestination}, Push(pc_), {MicroOp::Move16, &memptr_.full, &pc_.full})
@ -735,6 +736,9 @@ template <class T> class Processor {
scheduled_program_counter_(nullptr) {
set_flags(0xff);
MicroOp conditional_call_untaken_program[] = Sequence(ReadInc(pc_, temp16_.bytes.high));
copy_program(conditional_call_untaken_program, conditional_call_untaken_program_);
assemble_base_page(base_page_, hl_, false, cb_page_);
assemble_base_page(dd_page_, ix_, true, ddcb_page_);
assemble_base_page(fd_page_, iy_, true, fdcb_page_);
@ -1190,14 +1194,23 @@ template <class T> class Processor {
#pragma mark - Conditionals
case MicroOp::TestNZ: if(!zero_result_) { advance_operation(); } break;
case MicroOp::TestZ: if(zero_result_) { advance_operation(); } break;
case MicroOp::TestNC: if(carry_result_ & Flag::Carry) { advance_operation(); } break;
case MicroOp::TestC: if(!(carry_result_ & Flag::Carry)) { advance_operation(); } break;
case MicroOp::TestPO: if(parity_overflow_result_ & Flag::Parity) { advance_operation(); } break;
case MicroOp::TestPE: if(!(parity_overflow_result_ & Flag::Parity)) { advance_operation(); } break;
case MicroOp::TestP: if(sign_result_ & Flag::Sign) { advance_operation(); } break;
case MicroOp::TestM: if(!(sign_result_ & Flag::Sign)) { advance_operation(); } break;
#define decline_conditional() \
if(operation->source) { \
scheduled_program_counter_ = (MicroOp *)operation->source; \
} else { \
advance_operation(); \
}
case MicroOp::TestNZ: if(!zero_result_) { decline_conditional(); } break;
case MicroOp::TestZ: if(zero_result_) { decline_conditional(); } break;
case MicroOp::TestNC: if(carry_result_ & Flag::Carry) { decline_conditional(); } break;
case MicroOp::TestC: if(!(carry_result_ & Flag::Carry)) { decline_conditional(); } break;
case MicroOp::TestPO: if(parity_overflow_result_ & Flag::Parity) { decline_conditional(); } break;
case MicroOp::TestPE: if(!(parity_overflow_result_ & Flag::Parity)) { decline_conditional(); } break;
case MicroOp::TestP: if(sign_result_ & Flag::Sign) { decline_conditional(); } break;
case MicroOp::TestM: if(!(sign_result_ & Flag::Sign)) { decline_conditional(); } break;
#undef decline_conditional
#pragma mark - Exchange