mirror of
https://github.com/TomHarte/CLK.git
synced 2024-10-07 21:57:46 +00:00
Adds an IN/OUT test.
This commit is contained in:
parent
06f1e64177
commit
8a3bfb8672
@ -131,6 +131,7 @@ struct CapturingZ80: public CPU::Z80::BusHandler {
|
|||||||
struct ContentionCheck {
|
struct ContentionCheck {
|
||||||
uint16_t address;
|
uint16_t address;
|
||||||
int length;
|
int length;
|
||||||
|
bool is_io = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
- (void)compareExpectedContentions:(const std::initializer_list<ContentionCheck> &)contentions found:(const std::vector<ContentionCheck> &)found label:(const char *)label {
|
- (void)compareExpectedContentions:(const std::initializer_list<ContentionCheck> &)contentions found:(const std::vector<ContentionCheck> &)found label:(const char *)label {
|
||||||
@ -142,6 +143,7 @@ struct ContentionCheck {
|
|||||||
while(contention != contentions.end() && found_contention != found.end()) {
|
while(contention != contentions.end() && found_contention != found.end()) {
|
||||||
XCTAssertEqual(contention->address, found_contention->address, "[%s] mismatched address at step %zu; expected %04x but found %04x", label, contention - contentions.begin(), contention->address, found_contention->address);
|
XCTAssertEqual(contention->address, found_contention->address, "[%s] mismatched address at step %zu; expected %04x but found %04x", label, contention - contentions.begin(), contention->address, found_contention->address);
|
||||||
XCTAssertEqual(contention->length, found_contention->length, "[%s] mismatched length at step %zu; expected %d but found %d", label, contention - contentions.begin(), contention->length, found_contention->length);
|
XCTAssertEqual(contention->length, found_contention->length, "[%s] mismatched length at step %zu; expected %d but found %d", label, contention - contentions.begin(), contention->length, found_contention->length);
|
||||||
|
XCTAssertEqual(contention->is_io, found_contention->is_io, "[%s] mismatched IO flag at step %zu; expected %d but found %d", label, contention - contentions.begin(), contention->is_io, found_contention->is_io);
|
||||||
|
|
||||||
if(contention->address != found_contention->address || contention->length != found_contention->length) {
|
if(contention->address != found_contention->address || contention->length != found_contention->length) {
|
||||||
break;
|
break;
|
||||||
@ -164,26 +166,32 @@ struct ContentionCheck {
|
|||||||
|
|
||||||
int count = 0;
|
int count = 0;
|
||||||
uint16_t address = bus_records.front().address;
|
uint16_t address = bus_records.front().address;
|
||||||
|
bool is_io = false;
|
||||||
|
|
||||||
for(size_t c = 0; c < bus_records.size(); c++) {
|
for(size_t c = 0; c < bus_records.size(); c++) {
|
||||||
++count;
|
++count;
|
||||||
|
|
||||||
if(
|
if(
|
||||||
c && // i.e. not at front.
|
c && // i.e. not at front.
|
||||||
!bus_records[c].mreq // i.e. beginning of a new contention.
|
!bus_records[c].mreq && // i.e. beginning of a new contention.
|
||||||
|
!bus_records[c].ioreq // i.e. not during an IO cycle.
|
||||||
) {
|
) {
|
||||||
found_contentions.emplace_back();
|
found_contentions.emplace_back();
|
||||||
found_contentions.back().address = address;
|
found_contentions.back().address = address;
|
||||||
found_contentions.back().length = count - 1;
|
found_contentions.back().length = count - 1;
|
||||||
|
found_contentions.back().is_io = is_io;
|
||||||
|
|
||||||
count = 1;
|
count = 1;
|
||||||
address = bus_records[c].address;
|
address = bus_records[c].address;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
is_io = bus_records[c].ioreq;
|
||||||
}
|
}
|
||||||
|
|
||||||
found_contentions.emplace_back();
|
found_contentions.emplace_back();
|
||||||
found_contentions.back().address = address;
|
found_contentions.back().address = address;
|
||||||
found_contentions.back().length = count;
|
found_contentions.back().length = count;
|
||||||
|
found_contentions.back().is_io = is_io;
|
||||||
|
|
||||||
[self compareExpectedContentions:contentions found:found_contentions label:"48kb"];
|
[self compareExpectedContentions:contentions found:found_contentions label:"48kb"];
|
||||||
}
|
}
|
||||||
@ -199,27 +207,35 @@ struct ContentionCheck {
|
|||||||
|
|
||||||
int count = 0;
|
int count = 0;
|
||||||
uint16_t address = bus_records.front().address;
|
uint16_t address = bus_records.front().address;
|
||||||
|
bool is_io = false;
|
||||||
|
|
||||||
for(size_t c = 0; c < bus_records.size(); c += 2) {
|
for(size_t c = 0; c < bus_records.size(); c += 2) {
|
||||||
++count;
|
++count;
|
||||||
|
|
||||||
const bool is_leading_edge = !bus_records[c].mreq && bus_records[c+1].mreq && !bus_records[c].refresh;
|
// The IOREQ test below is a little inauthentic; it's included to match the published Spectrum
|
||||||
|
// tables, even though the +3 doesn't contend IO.
|
||||||
|
const bool is_mreq_leading_edge = !bus_records[c].mreq && bus_records[c+1].mreq && !bus_records[c].refresh;
|
||||||
|
const bool is_ioreq_leading_edge = c < bus_records.size() - 2 && !bus_records[c].ioreq && bus_records[c+2].ioreq;
|
||||||
if(
|
if(
|
||||||
c && // i.e. not at front.
|
c && // i.e. not at front.
|
||||||
is_leading_edge // i.e. beginning of a new contention.
|
(is_mreq_leading_edge || is_ioreq_leading_edge) // i.e. beginning of a new contention.
|
||||||
) {
|
) {
|
||||||
found_contentions.emplace_back();
|
found_contentions.emplace_back();
|
||||||
found_contentions.back().address = address;
|
found_contentions.back().address = address;
|
||||||
found_contentions.back().length = count - 1;
|
found_contentions.back().length = count - 1;
|
||||||
|
found_contentions.back().is_io = is_io;
|
||||||
|
|
||||||
count = 1;
|
count = 1;
|
||||||
address = bus_records[c].address;
|
address = bus_records[c].address;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
is_io = bus_records[c].ioreq;
|
||||||
}
|
}
|
||||||
|
|
||||||
found_contentions.emplace_back();
|
found_contentions.emplace_back();
|
||||||
found_contentions.back().address = address;
|
found_contentions.back().address = address;
|
||||||
found_contentions.back().length = count;
|
found_contentions.back().length = count;
|
||||||
|
found_contentions.back().is_io = is_io;
|
||||||
|
|
||||||
[self compareExpectedContentions:contentions found:found_contentions label:"+3"];
|
[self compareExpectedContentions:contentions found:found_contentions label:"+3"];
|
||||||
}
|
}
|
||||||
@ -1131,4 +1147,25 @@ struct ContentionCheck {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)testINOUTA {
|
||||||
|
for(const auto &sequence : std::vector<std::vector<uint8_t>>{
|
||||||
|
{0xdb, 0xef}, // IN A, (n)
|
||||||
|
{0xd3, 0xef}, // OUT (n), A
|
||||||
|
}) {
|
||||||
|
CapturingZ80 z80(sequence);
|
||||||
|
z80.run_for(11);
|
||||||
|
|
||||||
|
[self validate48Contention:{
|
||||||
|
{initial_pc, 4},
|
||||||
|
{initial_pc+1, 3},
|
||||||
|
{0x80ef, 4, true},
|
||||||
|
} z80:z80];
|
||||||
|
[self validatePlus3Contention:{
|
||||||
|
{initial_pc, 4},
|
||||||
|
{initial_pc+1, 3},
|
||||||
|
{0x80ef, 4, true},
|
||||||
|
} z80:z80];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
Loading…
Reference in New Issue
Block a user