mirror of
https://github.com/TomHarte/CLK.git
synced 2024-09-30 07:55:01 +00:00
Attempted to bring a common hierarchy to the Z80 and 6502 test machines, particularly with a view to eliminating the special-case Jam stuff on the 6502.
This commit is contained in:
parent
0b2a3f18bc
commit
fd6623b5a5
@ -9,6 +9,7 @@
|
|||||||
/* Begin PBXBuildFile section */
|
/* Begin PBXBuildFile section */
|
||||||
4B049CDD1DA3C82F00322067 /* BCDTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B049CDC1DA3C82F00322067 /* BCDTest.swift */; };
|
4B049CDD1DA3C82F00322067 /* BCDTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B049CDC1DA3C82F00322067 /* BCDTest.swift */; };
|
||||||
4B08A2751EE35D56008B7065 /* Z80InterruptTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B08A2741EE35D56008B7065 /* Z80InterruptTests.swift */; };
|
4B08A2751EE35D56008B7065 /* Z80InterruptTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B08A2741EE35D56008B7065 /* Z80InterruptTests.swift */; };
|
||||||
|
4B08A2781EE39306008B7065 /* TestMachine.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4B08A2771EE39306008B7065 /* TestMachine.mm */; };
|
||||||
4B0BE4281D3481E700D5256B /* DigitalPhaseLockedLoop.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B0BE4261D3481E700D5256B /* DigitalPhaseLockedLoop.cpp */; };
|
4B0BE4281D3481E700D5256B /* DigitalPhaseLockedLoop.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B0BE4261D3481E700D5256B /* DigitalPhaseLockedLoop.cpp */; };
|
||||||
4B0CCC451C62D0B3001CAC5F /* CRT.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B0CCC421C62D0B3001CAC5F /* CRT.cpp */; };
|
4B0CCC451C62D0B3001CAC5F /* CRT.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B0CCC421C62D0B3001CAC5F /* CRT.cpp */; };
|
||||||
4B121F951E05E66800BFDA12 /* PCMPatchedTrackTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4B121F941E05E66800BFDA12 /* PCMPatchedTrackTests.mm */; };
|
4B121F951E05E66800BFDA12 /* PCMPatchedTrackTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4B121F941E05E66800BFDA12 /* PCMPatchedTrackTests.mm */; };
|
||||||
@ -444,6 +445,9 @@
|
|||||||
4B046DC31CFE651500E9E45E /* CRTMachine.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = CRTMachine.hpp; sourceTree = "<group>"; };
|
4B046DC31CFE651500E9E45E /* CRTMachine.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = CRTMachine.hpp; sourceTree = "<group>"; };
|
||||||
4B049CDC1DA3C82F00322067 /* BCDTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BCDTest.swift; sourceTree = "<group>"; };
|
4B049CDC1DA3C82F00322067 /* BCDTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BCDTest.swift; sourceTree = "<group>"; };
|
||||||
4B08A2741EE35D56008B7065 /* Z80InterruptTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Z80InterruptTests.swift; sourceTree = "<group>"; };
|
4B08A2741EE35D56008B7065 /* Z80InterruptTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Z80InterruptTests.swift; sourceTree = "<group>"; };
|
||||||
|
4B08A2761EE39306008B7065 /* TestMachine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TestMachine.h; sourceTree = "<group>"; };
|
||||||
|
4B08A2771EE39306008B7065 /* TestMachine.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = TestMachine.mm; sourceTree = "<group>"; };
|
||||||
|
4B08A2791EE3957B008B7065 /* TestMachine+ForSubclassEyesOnly.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "TestMachine+ForSubclassEyesOnly.h"; sourceTree = "<group>"; };
|
||||||
4B0B6E121C9DBD5D00FFB60D /* CRTConstants.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = CRTConstants.hpp; sourceTree = "<group>"; };
|
4B0B6E121C9DBD5D00FFB60D /* CRTConstants.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = CRTConstants.hpp; sourceTree = "<group>"; };
|
||||||
4B0BE4261D3481E700D5256B /* DigitalPhaseLockedLoop.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DigitalPhaseLockedLoop.cpp; sourceTree = "<group>"; };
|
4B0BE4261D3481E700D5256B /* DigitalPhaseLockedLoop.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DigitalPhaseLockedLoop.cpp; sourceTree = "<group>"; };
|
||||||
4B0BE4271D3481E700D5256B /* DigitalPhaseLockedLoop.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = DigitalPhaseLockedLoop.hpp; sourceTree = "<group>"; };
|
4B0BE4271D3481E700D5256B /* DigitalPhaseLockedLoop.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = DigitalPhaseLockedLoop.hpp; sourceTree = "<group>"; };
|
||||||
@ -1198,12 +1202,15 @@
|
|||||||
4BEF6AA81D35CE9E00E73575 /* DigitalPhaseLockedLoopBridge.h */,
|
4BEF6AA81D35CE9E00E73575 /* DigitalPhaseLockedLoopBridge.h */,
|
||||||
4B3BA0C81D318B44005DD7A7 /* MOS6522Bridge.h */,
|
4B3BA0C81D318B44005DD7A7 /* MOS6522Bridge.h */,
|
||||||
4B3BA0CA1D318B44005DD7A7 /* MOS6532Bridge.h */,
|
4B3BA0CA1D318B44005DD7A7 /* MOS6532Bridge.h */,
|
||||||
|
4B08A2761EE39306008B7065 /* TestMachine.h */,
|
||||||
|
4B08A2791EE3957B008B7065 /* TestMachine+ForSubclassEyesOnly.h */,
|
||||||
4B3BA0CC1D318B44005DD7A7 /* TestMachine6502.h */,
|
4B3BA0CC1D318B44005DD7A7 /* TestMachine6502.h */,
|
||||||
4BFCA1251ECBE33200AC40C1 /* TestMachineZ80.h */,
|
4BFCA1251ECBE33200AC40C1 /* TestMachineZ80.h */,
|
||||||
4B3BA0C61D318B44005DD7A7 /* C1540Bridge.mm */,
|
4B3BA0C61D318B44005DD7A7 /* C1540Bridge.mm */,
|
||||||
4BEF6AA91D35CE9E00E73575 /* DigitalPhaseLockedLoopBridge.mm */,
|
4BEF6AA91D35CE9E00E73575 /* DigitalPhaseLockedLoopBridge.mm */,
|
||||||
4B3BA0C91D318B44005DD7A7 /* MOS6522Bridge.mm */,
|
4B3BA0C91D318B44005DD7A7 /* MOS6522Bridge.mm */,
|
||||||
4B3BA0CB1D318B44005DD7A7 /* MOS6532Bridge.mm */,
|
4B3BA0CB1D318B44005DD7A7 /* MOS6532Bridge.mm */,
|
||||||
|
4B08A2771EE39306008B7065 /* TestMachine.mm */,
|
||||||
4B3BA0CD1D318B44005DD7A7 /* TestMachine6502.mm */,
|
4B3BA0CD1D318B44005DD7A7 /* TestMachine6502.mm */,
|
||||||
4BFCA1261ECBE33200AC40C1 /* TestMachineZ80.mm */,
|
4BFCA1261ECBE33200AC40C1 /* TestMachineZ80.mm */,
|
||||||
);
|
);
|
||||||
@ -2623,6 +2630,7 @@
|
|||||||
4BD4A8D01E077FD20020D856 /* PCMTrackTests.mm in Sources */,
|
4BD4A8D01E077FD20020D856 /* PCMTrackTests.mm in Sources */,
|
||||||
4B049CDD1DA3C82F00322067 /* BCDTest.swift in Sources */,
|
4B049CDD1DA3C82F00322067 /* BCDTest.swift in Sources */,
|
||||||
4B1D08061E0F7A1100763741 /* TimeTests.mm in Sources */,
|
4B1D08061E0F7A1100763741 /* TimeTests.mm in Sources */,
|
||||||
|
4B08A2781EE39306008B7065 /* TestMachine.mm in Sources */,
|
||||||
4BFCA1271ECBE33200AC40C1 /* TestMachineZ80.mm in Sources */,
|
4BFCA1271ECBE33200AC40C1 /* TestMachineZ80.mm in Sources */,
|
||||||
4B121F951E05E66800BFDA12 /* PCMPatchedTrackTests.mm in Sources */,
|
4B121F951E05E66800BFDA12 /* PCMPatchedTrackTests.mm in Sources */,
|
||||||
);
|
);
|
||||||
|
@ -0,0 +1,14 @@
|
|||||||
|
//
|
||||||
|
// TestMachine+ForSubclassEyesOnly.h
|
||||||
|
// Clock Signal
|
||||||
|
//
|
||||||
|
// Created by Thomas Harte on 03/06/2017.
|
||||||
|
// Copyright © 2017 Thomas Harte. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "TestMachine.h"
|
||||||
|
#include "AllRAMProcessor.hpp"
|
||||||
|
|
||||||
|
@interface CSTestMachine (ForSubclassEyesOnly)
|
||||||
|
- (CPU::AllRAMProcessor *)processor;
|
||||||
|
@end
|
22
OSBindings/Mac/Clock SignalTests/Bridges/TestMachine.h
Normal file
22
OSBindings/Mac/Clock SignalTests/Bridges/TestMachine.h
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
//
|
||||||
|
// TestMachine.h
|
||||||
|
// Clock Signal
|
||||||
|
//
|
||||||
|
// Created by Thomas Harte on 03/06/2017.
|
||||||
|
// Copyright © 2017 Thomas Harte. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
|
@class CSTestMachine;
|
||||||
|
|
||||||
|
@protocol CSTestMachineTrapHandler
|
||||||
|
- (void)testMachine:(nonnull CSTestMachine *)testMachine didTrapAtAddress:(uint16_t)address;
|
||||||
|
@end
|
||||||
|
|
||||||
|
@interface CSTestMachine : NSObject
|
||||||
|
|
||||||
|
@property(nonatomic, weak, nullable) id<CSTestMachineTrapHandler> trapHandler;
|
||||||
|
- (void)addTrapAddress:(uint16_t)trapAddress;
|
||||||
|
|
||||||
|
@end
|
57
OSBindings/Mac/Clock SignalTests/Bridges/TestMachine.mm
Normal file
57
OSBindings/Mac/Clock SignalTests/Bridges/TestMachine.mm
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
//
|
||||||
|
// TestMachine.m
|
||||||
|
// Clock Signal
|
||||||
|
//
|
||||||
|
// Created by Thomas Harte on 03/06/2017.
|
||||||
|
// Copyright © 2017 Thomas Harte. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "TestMachine.h"
|
||||||
|
#import "TestMachine+ForSubclassEyesOnly.h"
|
||||||
|
#include "AllRAMProcessor.hpp"
|
||||||
|
|
||||||
|
@interface CSTestMachine ()
|
||||||
|
- (void)testMachineDidTrapAtAddress:(uint16_t)address;
|
||||||
|
@end
|
||||||
|
|
||||||
|
#pragma mark - C++ delegate handlers
|
||||||
|
|
||||||
|
class MachineTrapHandler: public CPU::AllRAMProcessor::TrapHandler {
|
||||||
|
public:
|
||||||
|
MachineTrapHandler(CSTestMachine *targetMachine) : target_(targetMachine) {}
|
||||||
|
|
||||||
|
void processor_did_trap(CPU::AllRAMProcessor &, uint16_t address) {
|
||||||
|
[target_ testMachineDidTrapAtAddress:address];
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
CSTestMachine *target_;
|
||||||
|
};
|
||||||
|
|
||||||
|
#pragma mark - The test machine
|
||||||
|
|
||||||
|
@implementation CSTestMachine {
|
||||||
|
MachineTrapHandler *_cppTrapHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (instancetype)init {
|
||||||
|
if(self = [super init]) {
|
||||||
|
_cppTrapHandler = new MachineTrapHandler(self);
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)dealloc {
|
||||||
|
delete _cppTrapHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)addTrapAddress:(uint16_t)trapAddress {
|
||||||
|
self.processor->set_trap_handler(_cppTrapHandler);
|
||||||
|
self.processor->add_trap_address(trapAddress);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)testMachineDidTrapAtAddress:(uint16_t)address {
|
||||||
|
[self.trapHandler testMachine:self didTrapAtAddress:address];
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
@ -7,6 +7,7 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#import <Foundation/Foundation.h>
|
#import <Foundation/Foundation.h>
|
||||||
|
#import "TestMachine.h"
|
||||||
|
|
||||||
typedef NS_ENUM(NSInteger, CSTestMachine6502Register) {
|
typedef NS_ENUM(NSInteger, CSTestMachine6502Register) {
|
||||||
CSTestMachine6502RegisterLastOperationAddress,
|
CSTestMachine6502RegisterLastOperationAddress,
|
||||||
@ -25,7 +26,7 @@ extern const uint8_t CSTestMachine6502JamOpcode;
|
|||||||
- (void)testMachine:(CSTestMachine6502 *)machine didJamAtAddress:(uint16_t)address;
|
- (void)testMachine:(CSTestMachine6502 *)machine didJamAtAddress:(uint16_t)address;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@interface CSTestMachine6502 : NSObject
|
@interface CSTestMachine6502 : CSTestMachine
|
||||||
|
|
||||||
- (void)setData:(NSData *)data atAddress:(uint16_t)startAddress;
|
- (void)setData:(NSData *)data atAddress:(uint16_t)startAddress;
|
||||||
- (void)runForNumberOfCycles:(int)cycles;
|
- (void)runForNumberOfCycles:(int)cycles;
|
||||||
|
@ -9,22 +9,23 @@
|
|||||||
#import "TestMachine6502.h"
|
#import "TestMachine6502.h"
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "6502AllRAM.hpp"
|
#include "6502AllRAM.hpp"
|
||||||
|
#import "TestMachine+ForSubclassEyesOnly.h"
|
||||||
|
|
||||||
const uint8_t CSTestMachine6502JamOpcode = CPU::MOS6502::JamOpcode;
|
const uint8_t CSTestMachine6502JamOpcode = CPU::MOS6502::JamOpcode;
|
||||||
|
|
||||||
#pragma mark - C++ jam handler
|
#pragma mark - C++ jam handler
|
||||||
|
|
||||||
class MachineJamHandler: public CPU::MOS6502::AllRAMProcessor::JamHandler {
|
//class MachineJamHandler: public CPU::MOS6502::AllRAMProcessor::JamHandler {
|
||||||
public:
|
// public:
|
||||||
MachineJamHandler(CSTestMachine6502 *targetMachine) : _targetMachine(targetMachine) {}
|
// MachineJamHandler(CSTestMachine6502 *targetMachine) : _targetMachine(targetMachine) {}
|
||||||
|
//
|
||||||
void processor_did_jam(CPU::MOS6502::AllRAMProcessor::Processor *processor, uint16_t address) override {
|
// void processor_did_jam(CPU::MOS6502::AllRAMProcessor::Processor *processor, uint16_t address) override {
|
||||||
[_targetMachine.jamHandler testMachine:_targetMachine didJamAtAddress:address];
|
// [_targetMachine.jamHandler testMachine:_targetMachine didJamAtAddress:address];
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
private:
|
// private:
|
||||||
CSTestMachine6502 *_targetMachine;
|
// CSTestMachine6502 *_targetMachine;
|
||||||
};
|
//};
|
||||||
|
|
||||||
#pragma mark - Register enum map
|
#pragma mark - Register enum map
|
||||||
|
|
||||||
@ -43,8 +44,8 @@ static CPU::MOS6502::Register registerForRegister(CSTestMachine6502Register reg)
|
|||||||
#pragma mark - Test class
|
#pragma mark - Test class
|
||||||
|
|
||||||
@implementation CSTestMachine6502 {
|
@implementation CSTestMachine6502 {
|
||||||
CPU::MOS6502::AllRAMProcessor _processor;
|
CPU::MOS6502::AllRAMProcessor *_processor;
|
||||||
MachineJamHandler *_cppJamHandler;
|
// MachineJamHandler *_cppJamHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma mark - Lifecycle
|
#pragma mark - Lifecycle
|
||||||
@ -53,67 +54,70 @@ static CPU::MOS6502::Register registerForRegister(CSTestMachine6502Register reg)
|
|||||||
self = [super init];
|
self = [super init];
|
||||||
|
|
||||||
if(self) {
|
if(self) {
|
||||||
_cppJamHandler = new MachineJamHandler(self);
|
_processor = CPU::MOS6502::AllRAMProcessor::Processor();
|
||||||
_processor.set_jam_handler(_cppJamHandler);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)dealloc {
|
- (void)dealloc {
|
||||||
delete _cppJamHandler;
|
delete _processor;
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma mark - Accessors
|
#pragma mark - Accessors
|
||||||
|
|
||||||
- (uint8_t)valueForAddress:(uint16_t)address {
|
- (uint8_t)valueForAddress:(uint16_t)address {
|
||||||
uint8_t value;
|
uint8_t value;
|
||||||
_processor.perform_bus_operation(CPU::MOS6502::BusOperation::Read, address, &value);
|
_processor->get_data_at_address(address, 1, &value);
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setValue:(uint8_t)value forAddress:(uint16_t)address {
|
- (void)setValue:(uint8_t)value forAddress:(uint16_t)address {
|
||||||
_processor.perform_bus_operation(CPU::MOS6502::BusOperation::Write, address, &value);
|
_processor->set_data_at_address(address, 1, &value);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setValue:(uint16_t)value forRegister:(CSTestMachine6502Register)reg {
|
- (void)setValue:(uint16_t)value forRegister:(CSTestMachine6502Register)reg {
|
||||||
_processor.set_value_of_register(registerForRegister(reg), value);
|
_processor->set_value_of_register(registerForRegister(reg), value);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (uint16_t)valueForRegister:(CSTestMachine6502Register)reg {
|
- (uint16_t)valueForRegister:(CSTestMachine6502Register)reg {
|
||||||
return _processor.get_value_of_register(registerForRegister(reg));
|
return _processor->get_value_of_register(registerForRegister(reg));
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setData:(NSData *)data atAddress:(uint16_t)startAddress {
|
- (void)setData:(NSData *)data atAddress:(uint16_t)startAddress {
|
||||||
_processor.set_data_at_address(startAddress, data.length, (const uint8_t *)data.bytes);
|
_processor->set_data_at_address(startAddress, data.length, (const uint8_t *)data.bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)isJammed {
|
- (BOOL)isJammed {
|
||||||
return _processor.is_jammed();
|
return _processor->is_jammed();
|
||||||
}
|
}
|
||||||
|
|
||||||
- (uint32_t)timestamp {
|
- (uint32_t)timestamp {
|
||||||
return _processor.get_timestamp();
|
return _processor->get_timestamp();
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setIrqLine:(BOOL)irqLine {
|
- (void)setIrqLine:(BOOL)irqLine {
|
||||||
_irqLine = irqLine;
|
_irqLine = irqLine;
|
||||||
_processor.set_irq_line(irqLine);
|
_processor->set_irq_line(irqLine);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setNmiLine:(BOOL)nmiLine {
|
- (void)setNmiLine:(BOOL)nmiLine {
|
||||||
_nmiLine = nmiLine;
|
_nmiLine = nmiLine;
|
||||||
_processor.set_nmi_line(nmiLine);
|
_processor->set_nmi_line(nmiLine);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (CPU::AllRAMProcessor *)processor {
|
||||||
|
return _processor;
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma mark - Actions
|
#pragma mark - Actions
|
||||||
|
|
||||||
- (void)returnFromSubroutine {
|
- (void)returnFromSubroutine {
|
||||||
_processor.return_from_subroutine();
|
_processor->return_from_subroutine();
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)runForNumberOfCycles:(int)cycles {
|
- (void)runForNumberOfCycles:(int)cycles {
|
||||||
_processor.run_for_cycles(cycles);
|
_processor->run_for_cycles(cycles);
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
@ -8,13 +8,10 @@
|
|||||||
|
|
||||||
#import <Foundation/Foundation.h>
|
#import <Foundation/Foundation.h>
|
||||||
#import <stdint.h>
|
#import <stdint.h>
|
||||||
|
#import "TestMachine.h"
|
||||||
|
|
||||||
@class CSTestMachineZ80;
|
@class CSTestMachineZ80;
|
||||||
|
|
||||||
@protocol CSTestMachineTrapHandler
|
|
||||||
- (void)testMachine:(nonnull CSTestMachineZ80 *)testMachine didTrapAtAddress:(uint16_t)address;
|
|
||||||
@end
|
|
||||||
|
|
||||||
typedef NS_ENUM(NSInteger, CSTestMachineZ80BusOperationCaptureOperation) {
|
typedef NS_ENUM(NSInteger, CSTestMachineZ80BusOperationCaptureOperation) {
|
||||||
CSTestMachineZ80BusOperationCaptureOperationRead,
|
CSTestMachineZ80BusOperationCaptureOperationRead,
|
||||||
CSTestMachineZ80BusOperationCaptureOperationWrite,
|
CSTestMachineZ80BusOperationCaptureOperationWrite,
|
||||||
@ -46,7 +43,7 @@ typedef NS_ENUM(NSInteger, CSTestMachineZ80Register) {
|
|||||||
CSTestMachineZ80RegisterIFF1, CSTestMachineZ80RegisterIFF2, CSTestMachineZ80RegisterIM
|
CSTestMachineZ80RegisterIFF1, CSTestMachineZ80RegisterIFF2, CSTestMachineZ80RegisterIM
|
||||||
};
|
};
|
||||||
|
|
||||||
@interface CSTestMachineZ80 : NSObject
|
@interface CSTestMachineZ80 : CSTestMachine
|
||||||
|
|
||||||
- (void)setData:(nonnull NSData *)data atAddress:(uint16_t)startAddress;
|
- (void)setData:(nonnull NSData *)data atAddress:(uint16_t)startAddress;
|
||||||
- (void)setValue:(uint8_t)value atAddress:(uint16_t)address;
|
- (void)setValue:(uint8_t)value atAddress:(uint16_t)address;
|
||||||
@ -58,9 +55,6 @@ typedef NS_ENUM(NSInteger, CSTestMachineZ80Register) {
|
|||||||
- (void)setValue:(uint16_t)value forRegister:(CSTestMachineZ80Register)reg;
|
- (void)setValue:(uint16_t)value forRegister:(CSTestMachineZ80Register)reg;
|
||||||
- (uint16_t)valueForRegister:(CSTestMachineZ80Register)reg;
|
- (uint16_t)valueForRegister:(CSTestMachineZ80Register)reg;
|
||||||
|
|
||||||
@property(nonatomic, weak, nullable) id<CSTestMachineTrapHandler> trapHandler;
|
|
||||||
- (void)addTrapAddress:(uint16_t)trapAddress;
|
|
||||||
|
|
||||||
@property(nonatomic, assign) BOOL captureBusActivity;
|
@property(nonatomic, assign) BOOL captureBusActivity;
|
||||||
@property(nonatomic, readonly, nonnull) NSArray<CSTestMachineZ80BusOperationCapture *> *busOperationCaptures;
|
@property(nonatomic, readonly, nonnull) NSArray<CSTestMachineZ80BusOperationCapture *> *busOperationCaptures;
|
||||||
|
|
||||||
|
@ -8,26 +8,14 @@
|
|||||||
|
|
||||||
#import "TestMachineZ80.h"
|
#import "TestMachineZ80.h"
|
||||||
#include "Z80AllRAM.hpp"
|
#include "Z80AllRAM.hpp"
|
||||||
|
#import "TestMachine+ForSubclassEyesOnly.h"
|
||||||
|
|
||||||
@interface CSTestMachineZ80 ()
|
@interface CSTestMachineZ80 ()
|
||||||
- (void)testMachineDidTrapAtAddress:(uint16_t)address;
|
|
||||||
- (void)testMachineDidPerformBusOperation:(CPU::Z80::BusOperation)operation address:(uint16_t)address value:(uint8_t)value timeStamp:(int)time_stamp;
|
- (void)testMachineDidPerformBusOperation:(CPU::Z80::BusOperation)operation address:(uint16_t)address value:(uint8_t)value timeStamp:(int)time_stamp;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
#pragma mark - C++ delegate handlers
|
#pragma mark - C++ delegate handlers
|
||||||
|
|
||||||
class MachineTrapHandler: public CPU::AllRAMProcessor::TrapHandler {
|
|
||||||
public:
|
|
||||||
MachineTrapHandler(CSTestMachineZ80 *targetMachine) : target_(targetMachine) {}
|
|
||||||
|
|
||||||
void processor_did_trap(CPU::AllRAMProcessor &, uint16_t address) {
|
|
||||||
[target_ testMachineDidTrapAtAddress:address];
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
CSTestMachineZ80 *target_;
|
|
||||||
};
|
|
||||||
|
|
||||||
class BusOperationHandler: public CPU::Z80::AllRAMProcessor::MemoryAccessDelegate {
|
class BusOperationHandler: public CPU::Z80::AllRAMProcessor::MemoryAccessDelegate {
|
||||||
public:
|
public:
|
||||||
BusOperationHandler(CSTestMachineZ80 *targetMachine) : target_(targetMachine) {}
|
BusOperationHandler(CSTestMachineZ80 *targetMachine) : target_(targetMachine) {}
|
||||||
@ -105,7 +93,6 @@ static CPU::Z80::Register registerForRegister(CSTestMachineZ80Register reg) {
|
|||||||
|
|
||||||
@implementation CSTestMachineZ80 {
|
@implementation CSTestMachineZ80 {
|
||||||
CPU::Z80::AllRAMProcessor *_processor;
|
CPU::Z80::AllRAMProcessor *_processor;
|
||||||
MachineTrapHandler *_cppTrapHandler;
|
|
||||||
BusOperationHandler *_busOperationHandler;
|
BusOperationHandler *_busOperationHandler;
|
||||||
|
|
||||||
NSMutableArray<CSTestMachineZ80BusOperationCapture *> *_busOperationCaptures;
|
NSMutableArray<CSTestMachineZ80BusOperationCapture *> *_busOperationCaptures;
|
||||||
@ -120,7 +107,6 @@ static CPU::Z80::Register registerForRegister(CSTestMachineZ80Register reg) {
|
|||||||
if(self = [super init]) {
|
if(self = [super init]) {
|
||||||
_processor = CPU::Z80::AllRAMProcessor::Processor();
|
_processor = CPU::Z80::AllRAMProcessor::Processor();
|
||||||
_processor->reset_power_on();
|
_processor->reset_power_on();
|
||||||
_cppTrapHandler = new MachineTrapHandler(self);
|
|
||||||
_busOperationHandler = new BusOperationHandler(self);
|
_busOperationHandler = new BusOperationHandler(self);
|
||||||
_busOperationCaptures = [[NSMutableArray alloc] init];
|
_busOperationCaptures = [[NSMutableArray alloc] init];
|
||||||
}
|
}
|
||||||
@ -128,7 +114,6 @@ static CPU::Z80::Register registerForRegister(CSTestMachineZ80Register reg) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (void)dealloc {
|
- (void)dealloc {
|
||||||
delete _cppTrapHandler;
|
|
||||||
delete _busOperationHandler;
|
delete _busOperationHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -160,15 +145,6 @@ static CPU::Z80::Register registerForRegister(CSTestMachineZ80Register reg) {
|
|||||||
return _processor->get_value_of_register(registerForRegister(reg));
|
return _processor->get_value_of_register(registerForRegister(reg));
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)addTrapAddress:(uint16_t)trapAddress {
|
|
||||||
_processor->set_trap_handler(_cppTrapHandler);
|
|
||||||
_processor->add_trap_address(trapAddress);
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)testMachineDidTrapAtAddress:(uint16_t)address {
|
|
||||||
[self.trapHandler testMachine:self didTrapAtAddress:address];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (BOOL)isHalted {
|
- (BOOL)isHalted {
|
||||||
return _processor->get_halt_line() ? YES : NO;
|
return _processor->get_halt_line() ? YES : NO;
|
||||||
}
|
}
|
||||||
@ -183,6 +159,10 @@ static CPU::Z80::Register registerForRegister(CSTestMachineZ80Register reg) {
|
|||||||
_processor->set_interrupt_line(irqLine ? true : false);
|
_processor->set_interrupt_line(irqLine ? true : false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (CPU::AllRAMProcessor *)processor {
|
||||||
|
return _processor;
|
||||||
|
}
|
||||||
|
|
||||||
#pragma mark - Z80-specific Runner
|
#pragma mark - Z80-specific Runner
|
||||||
|
|
||||||
- (void)runToNextInstruction {
|
- (void)runToNextInstruction {
|
||||||
|
@ -131,17 +131,18 @@ class ZexallTests: XCTestCase, CSTestMachineTrapHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func testMachine(_ testMachine: CSTestMachineZ80, didTrapAtAddress address: UInt16) {
|
func testMachine(_ testMachine: CSTestMachine, didTrapAtAddress address: UInt16) {
|
||||||
|
let testMachineZ80 = testMachine as! CSTestMachineZ80
|
||||||
switch address {
|
switch address {
|
||||||
case 0x0005:
|
case 0x0005:
|
||||||
let cRegister = testMachine.value(for: .C)
|
let cRegister = testMachineZ80.value(for: .C)
|
||||||
var textToAppend = ""
|
var textToAppend = ""
|
||||||
switch cRegister {
|
switch cRegister {
|
||||||
case 9:
|
case 9:
|
||||||
var address = testMachine.value(for: .DE)
|
var address = testMachineZ80.value(for: .DE)
|
||||||
var character: Character = " "
|
var character: Character = " "
|
||||||
while true {
|
while true {
|
||||||
character = Character(UnicodeScalar(testMachine.value(atAddress: address)))
|
character = Character(UnicodeScalar(testMachineZ80.value(atAddress: address)))
|
||||||
if character == "$" {
|
if character == "$" {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@ -149,7 +150,7 @@ class ZexallTests: XCTestCase, CSTestMachineTrapHandler {
|
|||||||
address = address + 1
|
address = address + 1
|
||||||
}
|
}
|
||||||
case 5:
|
case 5:
|
||||||
textToAppend = String(describing: UnicodeScalar(testMachine.value(for: .E)))
|
textToAppend = String(describing: UnicodeScalar(testMachineZ80.value(for: .E)))
|
||||||
case 0:
|
case 0:
|
||||||
done = true
|
done = true
|
||||||
default:
|
default:
|
||||||
|
@ -12,14 +12,20 @@
|
|||||||
|
|
||||||
using namespace CPU::MOS6502;
|
using namespace CPU::MOS6502;
|
||||||
|
|
||||||
AllRAMProcessor::AllRAMProcessor() : ::CPU::AllRAMProcessor(65536) {
|
namespace {
|
||||||
set_power_on(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
int AllRAMProcessor::perform_bus_operation(MOS6502::BusOperation operation, uint16_t address, uint8_t *value) {
|
class ConcreteAllRAMProcessor: public AllRAMProcessor, public Processor<ConcreteAllRAMProcessor> {
|
||||||
|
public:
|
||||||
|
ConcreteAllRAMProcessor() {
|
||||||
|
set_power_on(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
int perform_bus_operation(BusOperation operation, uint16_t address, uint8_t *value) {
|
||||||
timestamp_++;
|
timestamp_++;
|
||||||
|
|
||||||
// if(operation == MOS6502::BusOperation::ReadOpcode) printf("%04x\n", address);
|
if(operation == BusOperation::ReadOpcode) {
|
||||||
|
check_address_for_trap(address);
|
||||||
|
}
|
||||||
|
|
||||||
if(isReadOperation(operation)) {
|
if(isReadOperation(operation)) {
|
||||||
*value = memory_[address];
|
*value = memory_[address];
|
||||||
@ -28,4 +34,39 @@ int AllRAMProcessor::perform_bus_operation(MOS6502::BusOperation operation, uint
|
|||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void run_for_cycles(int number_of_cycles) {
|
||||||
|
Processor<ConcreteAllRAMProcessor>::run_for_cycles(number_of_cycles);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_jammed() {
|
||||||
|
return Processor<ConcreteAllRAMProcessor>::is_jammed();
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_irq_line(bool value) {
|
||||||
|
Processor<ConcreteAllRAMProcessor>::set_irq_line(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_nmi_line(bool value) {
|
||||||
|
Processor<ConcreteAllRAMProcessor>::set_nmi_line(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void return_from_subroutine() {
|
||||||
|
Processor<ConcreteAllRAMProcessor>::return_from_subroutine();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t get_value_of_register(Register r) {
|
||||||
|
return Processor<ConcreteAllRAMProcessor>::get_value_of_register(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_value_of_register(Register r, uint16_t value) {
|
||||||
|
Processor<ConcreteAllRAMProcessor>::set_value_of_register(r, value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
AllRAMProcessor *AllRAMProcessor::Processor() {
|
||||||
|
return new ConcreteAllRAMProcessor;
|
||||||
}
|
}
|
||||||
|
@ -16,13 +16,21 @@ namespace CPU {
|
|||||||
namespace MOS6502 {
|
namespace MOS6502 {
|
||||||
|
|
||||||
class AllRAMProcessor:
|
class AllRAMProcessor:
|
||||||
public ::CPU::AllRAMProcessor,
|
public ::CPU::AllRAMProcessor {
|
||||||
public Processor<AllRAMProcessor> {
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AllRAMProcessor();
|
static AllRAMProcessor *Processor();
|
||||||
|
|
||||||
int perform_bus_operation(MOS6502::BusOperation operation, uint16_t address, uint8_t *value);
|
virtual void run_for_cycles(int number_of_cycles) = 0;
|
||||||
|
virtual bool is_jammed() = 0;
|
||||||
|
virtual void set_irq_line(bool value) = 0;
|
||||||
|
virtual void set_nmi_line(bool value) = 0;
|
||||||
|
virtual void return_from_subroutine() = 0;
|
||||||
|
virtual uint16_t get_value_of_register(Register r) = 0;
|
||||||
|
virtual void set_value_of_register(Register r, uint16_t value) = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
AllRAMProcessor() : ::CPU::AllRAMProcessor(65536) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user