From a6907044bd8571c7cecf53f0b358e2305653871a Mon Sep 17 00:00:00 2001 From: scawful Date: Sat, 11 May 2024 13:56:19 -0400 Subject: [PATCH] add experimental single-cycle step control to spc700 --- src/app/emu/audio/internal/instructions.cc | 18 ++++++++---- src/app/emu/audio/spc700.cc | 31 +++++++++++++++----- src/app/emu/audio/spc700.h | 33 ++++++++++++++-------- 3 files changed, 57 insertions(+), 25 deletions(-) diff --git a/src/app/emu/audio/internal/instructions.cc b/src/app/emu/audio/internal/instructions.cc index 13f19e03..ee207e9e 100644 --- a/src/app/emu/audio/internal/instructions.cc +++ b/src/app/emu/audio/internal/instructions.cc @@ -20,18 +20,24 @@ void Spc700::MOVY(uint16_t adr) { } void Spc700::MOVS(uint16_t adr) { - read(adr); - write(adr, A); + switch (bstep) { + case 0: read(adr); break; + case 1: write(adr, A); bstep = 0; break; + } } void Spc700::MOVSX(uint16_t adr) { - read(adr); - write(adr, X); + switch (bstep) { + case 0: read(adr); break; + case 1: write(adr, X); bstep = 0; break; + } } void Spc700::MOVSY(uint16_t adr) { - read(adr); - write(adr, Y); + switch (bstep) { + case 0: read(adr); break; + case 1: write(adr, Y); bstep = 0; break; + } } void Spc700::MOV(uint16_t adr) { diff --git a/src/app/emu/audio/spc700.cc b/src/app/emu/audio/spc700.cc index de970118..1c5dee06 100644 --- a/src/app/emu/audio/spc700.cc +++ b/src/app/emu/audio/spc700.cc @@ -22,6 +22,7 @@ void Spc700::Reset(bool hard) { SP = 0x00; PSW = ByteToFlags(0x00); } + step = 0; stopped_ = false; reset_wanted_ = true; } @@ -44,7 +45,14 @@ void Spc700::RunOpcode() { callbacks_.idle(true); return; } - ExecuteInstructions(ReadOpcode()); + if (step == 0) { + bstep = 0; + opcode = ReadOpcode(); + step = 1; + return; + } + ExecuteInstructions(opcode); + if (step == 1) step = 0; // reset step for non cycle-stepped opcodes. } void Spc700::ExecuteInstructions(uint8_t opcode) { @@ -814,7 +822,6 @@ void Spc700::ExecuteInstructions(uint8_t opcode) { A--; PSW.Z = (A == 0); PSW.N = (A & 0x80); - ; break; } case 0x9d: { // movxp imp @@ -843,7 +850,6 @@ void Spc700::ExecuteInstructions(uint8_t opcode) { A = yva & 0xff; PSW.Z = (A == 0); PSW.N = (A & 0x80); - ; break; } case 0x9f: { // xcn imp @@ -991,7 +997,6 @@ void Spc700::ExecuteInstructions(uint8_t opcode) { } PSW.Z = (A == 0); PSW.N = (A & 0x80); - ; break; } case 0xbf: { // mov ind+ @@ -1069,7 +1074,21 @@ void Spc700::ExecuteInstructions(uint8_t opcode) { break; } case 0xd0: { // bne rel - DoBranch(ReadOpcode(), !PSW.Z); + switch (step++) { + case 1: + dat = ReadOpcode(); + if (PSW.Z) step = 0; + break; + case 2: + callbacks_.idle(false); + break; + case 3: + callbacks_.idle(false); + PC += (int8_t)dat; + step = 0; + break; + } + // DoBranch(ReadOpcode(), !PSW.Z); break; } case 0xd4: { // movs dpx @@ -1276,8 +1295,6 @@ void Spc700::ExecuteInstructions(uint8_t opcode) { throw std::runtime_error("Unknown SPC opcode: " + std::to_string(opcode)); break; } - - //LogInstruction(initialPC, opcode); } void Spc700::LogInstruction(uint16_t initial_pc, uint8_t opcode) { diff --git a/src/app/emu/audio/spc700.h b/src/app/emu/audio/spc700.h index cb9b02ac..07128599 100644 --- a/src/app/emu/audio/spc700.h +++ b/src/app/emu/audio/spc700.h @@ -76,6 +76,15 @@ class Spc700 { bool stopped_; bool reset_wanted_; + // single-cycle + uint8_t opcode; + uint32_t step = 0; + uint32_t bstep; + uint16_t adr; + uint16_t adr1; + uint8_t dat; + uint16_t dat16; + uint8_t param; const uint8_t ipl_rom_[64]{ 0xCD, 0xEF, 0xBD, 0xE8, 0x00, 0xC6, 0x1D, 0xD0, 0xFC, 0x8F, 0xAA, @@ -97,14 +106,14 @@ class Spc700 { uint8_t SP = 0x00; // stack pointer struct Flags { - uint8_t N : 1; // Negative flag - uint8_t V : 1; // Overflow flag - uint8_t P : 1; // Direct page flag - uint8_t B : 1; // Break flag - uint8_t H : 1; // Half-carry flag - uint8_t I : 1; // Interrupt enable - uint8_t Z : 1; // Zero flag - uint8_t C : 1; // Carry flag + bool N : 1; // Negative flag + bool V : 1; // Overflow flag + bool P : 1; // Direct page flag + bool B : 1; // Break flag + bool H : 1; // Half-carry flag + bool I : 1; // Interrupt enable + bool Z : 1; // Zero flag + bool C : 1; // Carry flag }; Flags PSW; // Processor status word @@ -139,12 +148,12 @@ class Spc700 { uint16_t read_word(uint16_t address) { uint8_t adrl = address; uint8_t adrh = address + 1; - uint8_t value = read(adrl); - return value | (read(adrh) << 8); + uint8_t value = callbacks_.read(adrl); + return value | (callbacks_.read(adrh) << 8); } uint8_t ReadOpcode() { - uint8_t opcode = read(PC++); + uint8_t opcode = callbacks_.read(PC++); return opcode; } @@ -169,7 +178,7 @@ class Spc700 { } void push_byte(uint8_t value) { - write(0x100 | SP, value); + callbacks_.write(0x100 | SP, value); SP--; }