1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-11-29 12:50:28 +00:00

Advances to IO.

This commit is contained in:
Thomas Harte 2021-04-12 21:41:20 -04:00
parent b42780173a
commit 06f1e64177

View File

@ -16,6 +16,7 @@ static constexpr uint16_t initial_pc = 0x0000;
static constexpr uint16_t initial_ir = 0xe000;
static constexpr uint16_t initial_bc_de_hl = 0xabcd;
static constexpr uint16_t initial_ix_iy = 0x3412;
static constexpr uint16_t initial_sp = 0x6800;
struct CapturingZ80: public CPU::Z80::BusHandler {
@ -29,6 +30,13 @@ struct CapturingZ80: public CPU::Z80::BusHandler {
run_for(3);
bus_records_.clear();
// Set the flags so that if this is a conditional operation, it'll succeed.
if((*code.begin())&0x8) {
z80_.set_value_of_register(CPU::Z80::Register::Flags, 0xff);
} else {
z80_.set_value_of_register(CPU::Z80::Register::Flags, 0x00);
}
// Set the refresh address to the EE page and set A to 0x80.
z80_.set_value_of_register(CPU::Z80::Register::I, 0xe0);
z80_.set_value_of_register(CPU::Z80::Register::A, 0x80);
@ -41,6 +49,9 @@ struct CapturingZ80: public CPU::Z80::BusHandler {
// Set IX and IY.
z80_.set_value_of_register(CPU::Z80::Register::IX, initial_ix_iy);
z80_.set_value_of_register(CPU::Z80::Register::IY, initial_ix_iy);
// Set SP.
z80_.set_value_of_register(CPU::Z80::Register::StackPointer, initial_sp);
}
void run_for(int cycles) {
@ -910,4 +921,214 @@ struct ContentionCheck {
} z80:z80];
}
}
- (void)testPOPddRET {
for(uint8_t opcode : {
// POP dd
0xc1, 0xd1, 0xe1, 0xf1,
// RET
0xc9,
}) {
const std::initializer_list<uint8_t> opcodes = {opcode};
CapturingZ80 z80(opcodes);
z80.run_for(10);
[self validate48Contention:{
{initial_pc, 4},
{initial_sp, 3},
{initial_sp+1, 3},
} z80:z80];
[self validatePlus3Contention:{
{initial_pc, 4},
{initial_sp, 3},
{initial_sp+1, 3},
} z80:z80];
}
}
- (void)testRETIN {
for(const auto &sequence : std::vector<std::vector<uint8_t>>{
// RETN
{0xed, 0x45}, {0xed, 0x55}, {0xed, 0x5d},
{0xed, 0x65}, {0xed, 0x6d}, {0xed, 0x75}, {0xed, 0x7d},
{0xed, 0x4d}, // RETI
}) {
CapturingZ80 z80(sequence);
z80.run_for(14);
[self validate48Contention:{
{initial_pc, 4},
{initial_pc+1, 4},
{initial_sp, 3},
{initial_sp+1, 3},
} z80:z80];
[self validatePlus3Contention:{
{initial_pc, 4},
{initial_pc+1, 4},
{initial_sp, 3},
{initial_sp+1, 3},
} z80:z80];
}
}
- (void)testRETcc {
for(uint8_t opcode : {
0xc0, 0xc8, 0xd0, 0xd8,
0xe0, 0xe8, 0xf0, 0xf8,
}) {
const std::initializer_list<uint8_t> opcodes = {opcode};
CapturingZ80 z80(opcodes);
z80.run_for(11);
[self validate48Contention:{
{initial_pc, 4},
{initial_ir, 1},
{initial_sp, 3},
{initial_sp+1, 3},
} z80:z80];
[self validatePlus3Contention:{
{initial_pc, 5},
{initial_sp, 3},
{initial_sp+1, 3},
} z80:z80];
}
}
- (void)testPUSHRST {
for(uint8_t opcode : {
// PUSH dd
0xc5, 0xd5, 0xe5, 0xf5,
// RST x
0xc7, 0xcf, 0xd7, 0xdf, 0xe7, 0xef, 0xf7, 0xff,
}) {
const std::initializer_list<uint8_t> opcodes = {opcode};
CapturingZ80 z80(opcodes);
z80.run_for(11);
[self validate48Contention:{
{initial_pc, 4},
{initial_ir, 1},
{initial_sp-1, 3},
{initial_sp-2, 3},
} z80:z80];
[self validatePlus3Contention:{
{initial_pc, 5},
{initial_sp-1, 3},
{initial_sp-2, 3},
} z80:z80];
}
}
- (void)testCALL {
for(const auto &sequence : std::vector<std::vector<uint8_t>>{
// CALL cc
{0xc4, 0x00, 0x00}, {0xcc, 0x00, 0x00},
{0xd4, 0x00, 0x00}, {0xdc, 0x00, 0x00},
{0xe4, 0x00, 0x00}, {0xec, 0x00, 0x00},
{0xf4, 0x00, 0x00}, {0xfc, 0x00, 0x00},
{0xcd, 0x00, 0x00}, // CALL
}) {
CapturingZ80 z80(sequence);
z80.run_for(17);
[self validate48Contention:{
{initial_pc, 4},
{initial_pc+1, 3},
{initial_pc+2, 3},
{initial_pc+2, 1},
{initial_sp-1, 3},
{initial_sp-2, 3},
} z80:z80];
[self validatePlus3Contention:{
{initial_pc, 4},
{initial_pc+1, 3},
{initial_pc+2, 4},
{initial_sp-1, 3},
{initial_sp-2, 3},
} z80:z80];
}
}
- (void)testJR {
for(const auto &sequence : std::vector<std::vector<uint8_t>>{
// JR cc
{0x20, 0x00}, {0x28, 0x00},
{0x30, 0x00}, {0x38, 0x00},
{0x18, 0x00}, // JR
}) {
CapturingZ80 z80(sequence);
z80.run_for(12);
[self validate48Contention:{
{initial_pc, 4},
{initial_pc+1, 3},
{initial_pc+1, 1},
{initial_pc+1, 1},
{initial_pc+1, 1},
{initial_pc+1, 1},
{initial_pc+1, 1},
} z80:z80];
[self validatePlus3Contention:{
{initial_pc, 4},
{initial_pc+1, 8},
} z80:z80];
}
}
- (void)testDJNZ {
for(const auto &sequence : std::vector<std::vector<uint8_t>>{
{0x10, 0x00}
}) {
CapturingZ80 z80(sequence);
z80.run_for(13);
[self validate48Contention:{
{initial_pc, 4},
{initial_ir, 1},
{initial_pc+1, 3},
{initial_pc+1, 1},
{initial_pc+1, 1},
{initial_pc+1, 1},
{initial_pc+1, 1},
{initial_pc+1, 1},
} z80:z80];
[self validatePlus3Contention:{
{initial_pc, 5},
{initial_pc+1, 8},
} z80:z80];
}
}
- (void)testRLDRRD {
for(const auto &sequence : std::vector<std::vector<uint8_t>>{
{0xed, 0x6f}, // RLD
{0xed, 0x67}, // RRD
}) {
CapturingZ80 z80(sequence);
z80.run_for(18);
[self validate48Contention:{
{initial_pc, 4},
{initial_pc+1, 4},
{initial_bc_de_hl, 3},
{initial_bc_de_hl, 1},
{initial_bc_de_hl, 1},
{initial_bc_de_hl, 1},
{initial_bc_de_hl, 1},
{initial_bc_de_hl, 3},
} z80:z80];
[self validatePlus3Contention:{
{initial_pc, 4},
{initial_pc+1, 4},
{initial_bc_de_hl, 7},
{initial_bc_de_hl, 3},
} z80:z80];
}
}
@end