1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-12-25 18:30:21 +00:00

Implemented a rudimentary way to test that instructions take as long as the FUSE tests think they should. Hence discovered that the (HL)-accessing BIT, RES and SET weren't. Corrected.

This commit is contained in:
Thomas Harte 2017-06-12 22:22:00 -04:00
parent e6e6e4e62b
commit aed2827e7b
6 changed files with 29 additions and 2 deletions

View File

@ -59,6 +59,7 @@ typedef NS_ENUM(NSInteger, CSTestMachineZ80Register) {
@property(nonatomic, readonly, nonnull) NSArray<CSTestMachineZ80BusOperationCapture *> *busOperationCaptures;
@property(nonatomic, readonly) BOOL isHalted;
@property(nonatomic, readonly) int completedCycles;
@property(nonatomic) BOOL nmiLine;
@property(nonatomic) BOOL irqLine;

View File

@ -149,6 +149,10 @@ static CPU::Z80::Register registerForRegister(CSTestMachineZ80Register reg) {
return _processor->get_halt_line() ? YES : NO;
}
- (int)completedCycles {
return _processor->get_length_of_completed_machine_cycles();
}
- (void)setNmiLine:(BOOL)nmiLine {
_nmiLine = nmiLine;
_processor->set_non_maskable_interrupt_line(nmiLine ? true : false);

View File

@ -194,6 +194,10 @@ class FUSETests: XCTestCase {
machine.runForNumber(ofCycles: Int32(targetState.tStates))
// Verify that exactly the right number of cycles was hit; this is a primitive cycle length tester.
let cyclesRun = machine.completedCycles
XCTAssert(cyclesRun == Int32(targetState.tStates), "Instruction length off; was \(machine.completedCycles) but should be \(targetState.tStates): \(name)")
let finalState = RegisterState(machine: machine)
// Compare processor state.

View File

@ -285,6 +285,13 @@ template <class T> class Processor {
Program(INDEX(), FETCHL(temp8_, INDEX_ADDR()), {MicroOp::op, &temp8_}), \
Program({MicroOp::op, &a_})
#define READ_OP_GROUP_D(op) \
Program({MicroOp::op, &bc_.bytes.high}), Program({MicroOp::op, &bc_.bytes.low}), \
Program({MicroOp::op, &de_.bytes.high}), Program({MicroOp::op, &de_.bytes.low}), \
Program({MicroOp::op, &index.bytes.high}), Program({MicroOp::op, &index.bytes.low}), \
Program(INDEX(), FETCHL(temp8_, INDEX_ADDR()), WAIT(1), {MicroOp::op, &temp8_}), \
Program({MicroOp::op, &a_})
#define RMW(x, op, ...) Program(INDEX(), FETCHL(x, INDEX_ADDR()), {MicroOp::op, &x}, WAIT(1), STOREL(x, INDEX_ADDR()))
#define RMWI(x, op, ...) Program(WAIT(2), FETCHL(x, INDEX_ADDR()), {MicroOp::op, &x}, WAIT(1), STOREL(x, INDEX_ADDR()))
@ -461,7 +468,7 @@ template <class T> class Processor {
/* 0x40 0x7f: BIT */
/* 0x80 0xcf: RES */
/* 0xd0 0xdf: SET */
CB_PAGE(MODIFY_OP_GROUP, READ_OP_GROUP)
CB_PAGE(MODIFY_OP_GROUP, READ_OP_GROUP_D)
};
InstructionTable offsets_cb_program_table = {
CB_PAGE(IX_MODIFY_OP_GROUP, IX_READ_OP_GROUP)

View File

@ -14,9 +14,10 @@ namespace {
class ConcreteAllRAMProcessor: public AllRAMProcessor, public Processor<ConcreteAllRAMProcessor> {
public:
ConcreteAllRAMProcessor() : AllRAMProcessor() {}
ConcreteAllRAMProcessor() : AllRAMProcessor(), completed_cycles(0) {}
inline int perform_machine_cycle(const MachineCycle &cycle) {
completed_cycles += cycle.length;
uint16_t address = cycle.address ? *cycle.address : 0x0000;
switch(cycle.operation) {
case BusOperation::ReadOpcode:
@ -88,6 +89,14 @@ class ConcreteAllRAMProcessor: public AllRAMProcessor, public Processor<Concrete
void set_non_maskable_interrupt_line(bool value) {
CPU::Z80::Processor<ConcreteAllRAMProcessor>::set_non_maskable_interrupt_line(value);
}
int get_length_of_completed_machine_cycles() {
return completed_cycles;
}
private:
int completed_cycles;
};
}

View File

@ -36,6 +36,8 @@ class AllRAMProcessor:
virtual void set_interrupt_line(bool value) = 0;
virtual void set_non_maskable_interrupt_line(bool value) = 0;
virtual int get_length_of_completed_machine_cycles() = 0;
protected:
MemoryAccessDelegate *delegate_;
AllRAMProcessor() : ::CPU::AllRAMProcessor(65536), delegate_(nullptr) {}