mirror of
https://github.com/TomHarte/CLK.git
synced 2024-12-24 12:30:17 +00:00
Added the concept of a trap handler to the all-RAM processor and exposed it via the test Z80 classes.
This commit is contained in:
parent
eae1f78221
commit
62b432c046
@ -13,6 +13,12 @@ typedef NS_ENUM(NSInteger, CSTestMachineZ80Register) {
|
||||
CSTestMachineZ80RegisterStackPointer,
|
||||
};
|
||||
|
||||
@class CSTestMachineZ80;
|
||||
|
||||
@interface CSTestMachineTrapHandler
|
||||
- (void)testMachine:(CSTestMachineZ80 *)testMachine didTrapAtAddress:(uint16_t)address;
|
||||
@end
|
||||
|
||||
@interface CSTestMachineZ80 : NSObject
|
||||
|
||||
- (void)setData:(NSData *)data atAddress:(uint16_t)startAddress;
|
||||
@ -21,4 +27,7 @@ typedef NS_ENUM(NSInteger, CSTestMachineZ80Register) {
|
||||
- (void)setValue:(uint16_t)value forRegister:(CSTestMachineZ80Register)reg;
|
||||
- (uint16_t)valueForRegister:(CSTestMachineZ80Register)reg;
|
||||
|
||||
@property(nonatomic, weak) id<CSTestMachineTrapHandler> trapHandler;
|
||||
- (void)addTrapAddress:(uint16_t)trapAddress;
|
||||
|
||||
@end
|
||||
|
@ -9,6 +9,26 @@
|
||||
#import "TestMachineZ80.h"
|
||||
#include "Z80AllRAM.hpp"
|
||||
|
||||
@interface CSTestMachineZ80 ()
|
||||
- (void)testMachineDidTrapAtAddress:(uint16_t)address;
|
||||
@end
|
||||
|
||||
#pragma mark - C++ trap handler
|
||||
|
||||
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_;
|
||||
};
|
||||
|
||||
#pragma mark - Register enum map
|
||||
|
||||
static CPU::Z80::Register registerForRegister(CSTestMachineZ80Register reg) {
|
||||
switch (reg) {
|
||||
case CSTestMachineZ80RegisterProgramCounter: return CPU::Z80::Register::ProgramCounter;
|
||||
@ -16,8 +36,25 @@ static CPU::Z80::Register registerForRegister(CSTestMachineZ80Register reg) {
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Test class
|
||||
|
||||
@implementation CSTestMachineZ80 {
|
||||
CPU::Z80::AllRAMProcessor _processor;
|
||||
MachineTrapHandler *_cppTrapHandler;
|
||||
}
|
||||
|
||||
#pragma mark - Lifecycle
|
||||
|
||||
- (instancetype)init {
|
||||
if(self = [super init]) {
|
||||
_cppTrapHandler = new MachineTrapHandler(self);
|
||||
_processor.set_trap_handler(_cppTrapHandler);
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
delete _cppTrapHandler;
|
||||
}
|
||||
|
||||
#pragma mark - Accessors
|
||||
@ -38,4 +75,12 @@ static CPU::Z80::Register registerForRegister(CSTestMachineZ80Register reg) {
|
||||
return _processor.get_value_of_register(registerForRegister(reg));
|
||||
}
|
||||
|
||||
- (void)addTrapAddress:(uint16_t)trapAddress {
|
||||
_processor.add_trap_address(trapAddress);
|
||||
}
|
||||
|
||||
- (void)testMachineDidTrapAtAddress:(uint16_t)address {
|
||||
[self.trapHandler testMachine:self didTrapAtAddress:address];
|
||||
}
|
||||
|
||||
@end
|
||||
|
@ -22,3 +22,17 @@ void AllRAMProcessor::set_data_at_address(uint16_t startAddress, size_t length,
|
||||
uint32_t AllRAMProcessor::get_timestamp() {
|
||||
return timestamp_;
|
||||
}
|
||||
|
||||
void AllRAMProcessor::check_address_for_trap(uint16_t address) {
|
||||
if(trap_addresses_.find(address) != trap_addresses_.end()) {
|
||||
trap_handler_->processor_did_trap(*this, address);
|
||||
}
|
||||
}
|
||||
|
||||
void AllRAMProcessor::set_trap_handler(TrapHandler *trap_handler) {
|
||||
trap_handler_ = trap_handler;
|
||||
}
|
||||
|
||||
void AllRAMProcessor::add_trap_address(uint16_t address) {
|
||||
trap_addresses_.insert(address);
|
||||
}
|
||||
|
@ -10,6 +10,7 @@
|
||||
#define AllRAMProcessor_hpp
|
||||
|
||||
#include <cstdint>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
namespace CPU {
|
||||
@ -20,9 +21,22 @@ class AllRAMProcessor {
|
||||
uint32_t get_timestamp();
|
||||
void set_data_at_address(uint16_t startAddress, size_t length, const uint8_t *data);
|
||||
|
||||
class TrapHandler {
|
||||
public:
|
||||
virtual void processor_did_trap(AllRAMProcessor &, uint16_t address) = 0;
|
||||
};
|
||||
void set_trap_handler(TrapHandler *trap_handler);
|
||||
void add_trap_address(uint16_t address);
|
||||
|
||||
protected:
|
||||
std::vector<uint8_t> memory_;
|
||||
uint32_t timestamp_;
|
||||
|
||||
void check_address_for_trap(uint16_t address);
|
||||
|
||||
private:
|
||||
std::set<uint16_t> trap_addresses_;
|
||||
TrapHandler *trap_handler_;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -16,6 +16,7 @@ AllRAMProcessor::AllRAMProcessor() : ::CPU::AllRAMProcessor(65536) {}
|
||||
int AllRAMProcessor::perform_machine_cycle(const MachineCycle *cycle) {
|
||||
switch(cycle->operation) {
|
||||
case BusOperation::ReadOpcode:
|
||||
check_address_for_trap(*cycle->address);
|
||||
case BusOperation::Read:
|
||||
printf("r %04x\n", *cycle->address);
|
||||
*cycle->value = memory_[*cycle->address];
|
||||
|
Loading…
Reference in New Issue
Block a user