1
0
mirror of https://github.com/TomHarte/CLK.git synced 2025-01-26 15:32:04 +00:00

Eliminates the 6502's specialised jam handler in favour of the generic trap handler, and simplifies the lookup costs of that as it's otherwise doubling execution costs.

This commit is contained in:
Thomas Harte 2017-06-03 21:54:42 -04:00
parent fd6623b5a5
commit b642d9f712
5 changed files with 23 additions and 43 deletions

View File

@ -9,7 +9,7 @@
import XCTest
import Foundation
class WolfgangLorenzTests: XCTestCase, CSTestMachine6502JamHandler {
class WolfgangLorenzTests: XCTestCase, CSTestMachineTrapHandler {
func testWolfgangLorenzStart() {
self.runWolfgangLorenzTest(" start")
@ -201,7 +201,7 @@ class WolfgangLorenzTests: XCTestCase, CSTestMachine6502JamHandler {
if let testData = try? Data(contentsOf: URL(fileURLWithPath: filename)) {
machine = CSTestMachine6502()
machine.jamHandler = self
machine.trapHandler = self
// machine.logActivity = true
output = ""
@ -225,11 +225,18 @@ class WolfgangLorenzTests: XCTestCase, CSTestMachine6502JamHandler {
] as [UInt8]), count: 19)
machine.setData( irqHandler, atAddress: 0xff48)
machine.setValue(CSTestMachine6502JamOpcode, forAddress:0xffd2) // print character
machine.addTrapAddress(0xffd2) // print character
machine.addTrapAddress(0xffe4) // scan keyboard
machine.addTrapAddress(0x8000) // exit
machine.addTrapAddress(0xa474) // exit
machine.setValue(0x60, forAddress:0xffd2) // 0x60 is RTS
machine.setValue(0x60, forAddress:0xffe4)
machine.setValue(0x60, forAddress:0x8000)
machine.setValue(0x60, forAddress:0xa474)
machine.setValue(CSTestMachine6502JamOpcode, forAddress:0xe16f) // load
machine.setValue(CSTestMachine6502JamOpcode, forAddress:0xffe4) // scan keyboard
machine.setValue(CSTestMachine6502JamOpcode, forAddress:0x8000) // exit
machine.setValue(CSTestMachine6502JamOpcode, forAddress:0xa474) // exit
machine.setValue(0x0801, for: CSTestMachine6502Register.programCounter)
machine.setValue(0xfd, for: CSTestMachine6502Register.stackPointer)
@ -296,19 +303,17 @@ class WolfgangLorenzTests: XCTestCase, CSTestMachine6502JamHandler {
return result
}
func testMachine(_ machine: CSTestMachine6502!, didJamAtAddress address: UInt16) {
func testMachine(_ testMachine: CSTestMachine, didTrapAtAddress address: UInt16) {
let testMachine6502 = testMachine as! CSTestMachine6502
switch address {
case 0xffd2:
machine.setValue(0x00, forAddress: 0x030c)
testMachine6502.setValue(0x00, forAddress: 0x030c)
let character = machine.value(for: CSTestMachine6502Register.A)
let character = testMachine6502.value(for: CSTestMachine6502Register.A)
output.append(Character(UnicodeScalar(character)!))
machine.returnFromSubroutine()
case 0xffe4:
machine.setValue(0x3, for:CSTestMachine6502Register.A)
machine.returnFromSubroutine()
testMachine6502.setValue(0x3, for:CSTestMachine6502Register.A)
case 0x8000, 0xa474:
NSException(name: NSExceptionName(rawValue: "Failed test"), reason: self.petsciiToString(output), userInfo: nil).raise()
@ -316,9 +321,6 @@ class WolfgangLorenzTests: XCTestCase, CSTestMachine6502JamHandler {
case 0x0000:
NSException(name: NSExceptionName(rawValue: "Failed test"), reason: "Execution hit 0000", userInfo: nil).raise()
case 0xe16f: // load next (which we consider to be success)
break;
default:
let hexAddress = String(format:"%04x", address)
NSException(name: NSExceptionName(rawValue: "Failed Test"), reason: "Processor jammed unexpectedly at \(hexAddress)", userInfo: nil).raise()

View File

@ -78,13 +78,6 @@ extern const uint8_t JamOpcode;
jammed state.
*/
template <class T> class Processor {
public:
class JamHandler {
public:
virtual void processor_did_jam(Processor *processor, uint16_t address) = 0;
};
private:
/*
@ -426,8 +419,6 @@ template <class T> class Processor {
}
bool is_jammed_;
JamHandler *jam_handler_;
int cycles_left_to_run_;
enum InterruptRequestFlags: uint8_t {
@ -511,7 +502,6 @@ template <class T> class Processor {
protected:
Processor() :
is_jammed_(false),
jam_handler_(nullptr),
cycles_left_to_run_(0),
ready_line_is_enabled_(false),
ready_is_active_(false),
@ -704,11 +694,6 @@ template <class T> class Processor {
is_jammed_ = true;
static const MicroOp jam[] = JAM;
scheduled_program_counter_ = jam;
if(jam_handler_) {
jam_handler_->processor_did_jam(this, pc_.full - 1);
checkSchedule(is_jammed_ = false;);
}
} continue;
#pragma mark - Bitwise
@ -1230,15 +1215,6 @@ template <class T> class Processor {
inline bool is_jammed() {
return is_jammed_;
}
/*!
Installs a jam handler. Jam handlers are notified if a running 6502 jams.
@param handler The class instance that will be this 6502's jam handler from now on.
*/
inline void set_jam_handler(JamHandler *handler) {
jam_handler_ = handler;
}
};
}

View File

@ -20,6 +20,7 @@ class AllRAMProcessor:
public:
static AllRAMProcessor *Processor();
virtual ~AllRAMProcessor() {}
virtual void run_for_cycles(int number_of_cycles) = 0;
virtual bool is_jammed() = 0;

View File

@ -12,6 +12,7 @@ using namespace CPU;
AllRAMProcessor::AllRAMProcessor(size_t memory_size) :
memory_(memory_size),
traps_(memory_size, false),
timestamp_(0) {}
void AllRAMProcessor::set_data_at_address(uint16_t startAddress, size_t length, const uint8_t *data) {
@ -33,5 +34,5 @@ void AllRAMProcessor::set_trap_handler(TrapHandler *trap_handler) {
}
void AllRAMProcessor::add_trap_address(uint16_t address) {
trap_addresses_.insert(address);
traps_[address] = true;
}

View File

@ -34,14 +34,14 @@ class AllRAMProcessor {
uint32_t timestamp_;
inline void check_address_for_trap(uint16_t address) {
if(trap_addresses_.find(address) != trap_addresses_.end()) {
if(traps_[address]) {
trap_handler_->processor_did_trap(*this, address);
}
}
private:
std::set<uint16_t> trap_addresses_;
TrapHandler *trap_handler_;
std::vector<bool> traps_;
};
}