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:
parent
e6e6e4e62b
commit
aed2827e7b
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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.
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -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) {}
|
||||
|
Loading…
Reference in New Issue
Block a user