diff --git a/OSBindings/Mac/Clock SignalTests/Bridges/TestMachineZ80.mm b/OSBindings/Mac/Clock SignalTests/Bridges/TestMachineZ80.mm index 22cb7e87c..2ba157c6f 100644 --- a/OSBindings/Mac/Clock SignalTests/Bridges/TestMachineZ80.mm +++ b/OSBindings/Mac/Clock SignalTests/Bridges/TestMachineZ80.mm @@ -119,6 +119,7 @@ static CPU::Z80::Register registerForRegister(CSTestMachineZ80Register reg) { - (instancetype)init { if(self = [super init]) { _processor = CPU::Z80::AllRAMProcessor::Processor(); + _processor.reset_power_on(); _cppTrapHandler = new MachineTrapHandler(self); _busOperationHandler = new BusOperationHandler(self); _busOperationCaptures = [[NSMutableArray alloc] init]; diff --git a/Processors/Z80/Z80.hpp b/Processors/Z80/Z80.hpp index 97ef7562b..ecaddc7ea 100644 --- a/Processors/Z80/Z80.hpp +++ b/Processors/Z80/Z80.hpp @@ -657,7 +657,8 @@ template class Processor: public MicroOpScheduler { iff2_(false), number_of_cycles_(0), request_status_(Interrupt::PowerOn), - last_request_status_(Interrupt::PowerOn) { + last_request_status_(Interrupt::PowerOn), + irq_line_(false) { set_flags(0xff); assemble_base_page(base_page_, hl_, false, cb_page_); @@ -676,6 +677,12 @@ template class Processor: public MicroOpScheduler { assemble_fetch_decode_execute(fdcb_page_, 3); assemble_fetch_decode_execute(ddcb_page_, 3); + + MicroOp reset_program[] = Program(WAIT(3), {MicroOp::Reset}); + reset_program_.resize(3); + reset_program_[0] = reset_program[0]; + reset_program_[1] = reset_program[1]; + reset_program_[2] = reset_program[2]; } /*! @@ -1415,6 +1422,19 @@ template class Processor: public MicroOpScheduler { halt_mask_ = 0x00; break; +#pragma mark - Interrupt handling + + case MicroOp::Reset: + // TODO +// iff1_ = iff2_ = false; +// interrupt_mode_ = 0; +// pc_.full = 0; +// sp_.full = 0xffff; +// a_ = 0xff; +// set_flags(0xff); +// i_ = r_ = 0; + break; + #pragma mark - Internal bookkeeping case MicroOp::SetInstructionPage: @@ -1643,6 +1663,15 @@ template class Processor: public MicroOpScheduler { else request_status_ &= ~Interrupt::Reset; } + /*! + This emulation automatically sets itself up in power-on state at creation, which has the effect of triggering a + reset at the first opportunity. Use @c reset_power_on to disable that behaviour. + */ + inline void reset_power_on() { + request_status_ &= ~Interrupt::PowerOn; + last_request_status_ &= ~Interrupt::PowerOn; + } + /*! For receivers of perform_machine_cycle only. Temporarily rejects the current machine cycle, causing time to be rewinded to its beginning.