add experimental single-cycle step control to spc700

This commit is contained in:
scawful
2024-05-11 13:56:19 -04:00
parent d42421a5a6
commit a6907044bd
3 changed files with 57 additions and 25 deletions

View File

@@ -20,18 +20,24 @@ void Spc700::MOVY(uint16_t adr) {
} }
void Spc700::MOVS(uint16_t adr) { void Spc700::MOVS(uint16_t adr) {
read(adr); switch (bstep) {
write(adr, A); case 0: read(adr); break;
case 1: write(adr, A); bstep = 0; break;
}
} }
void Spc700::MOVSX(uint16_t adr) { void Spc700::MOVSX(uint16_t adr) {
read(adr); switch (bstep) {
write(adr, X); case 0: read(adr); break;
case 1: write(adr, X); bstep = 0; break;
}
} }
void Spc700::MOVSY(uint16_t adr) { void Spc700::MOVSY(uint16_t adr) {
read(adr); switch (bstep) {
write(adr, Y); case 0: read(adr); break;
case 1: write(adr, Y); bstep = 0; break;
}
} }
void Spc700::MOV(uint16_t adr) { void Spc700::MOV(uint16_t adr) {

View File

@@ -22,6 +22,7 @@ void Spc700::Reset(bool hard) {
SP = 0x00; SP = 0x00;
PSW = ByteToFlags(0x00); PSW = ByteToFlags(0x00);
} }
step = 0;
stopped_ = false; stopped_ = false;
reset_wanted_ = true; reset_wanted_ = true;
} }
@@ -44,7 +45,14 @@ void Spc700::RunOpcode() {
callbacks_.idle(true); callbacks_.idle(true);
return; 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) { void Spc700::ExecuteInstructions(uint8_t opcode) {
@@ -814,7 +822,6 @@ void Spc700::ExecuteInstructions(uint8_t opcode) {
A--; A--;
PSW.Z = (A == 0); PSW.Z = (A == 0);
PSW.N = (A & 0x80); PSW.N = (A & 0x80);
;
break; break;
} }
case 0x9d: { // movxp imp case 0x9d: { // movxp imp
@@ -843,7 +850,6 @@ void Spc700::ExecuteInstructions(uint8_t opcode) {
A = yva & 0xff; A = yva & 0xff;
PSW.Z = (A == 0); PSW.Z = (A == 0);
PSW.N = (A & 0x80); PSW.N = (A & 0x80);
;
break; break;
} }
case 0x9f: { // xcn imp case 0x9f: { // xcn imp
@@ -991,7 +997,6 @@ void Spc700::ExecuteInstructions(uint8_t opcode) {
} }
PSW.Z = (A == 0); PSW.Z = (A == 0);
PSW.N = (A & 0x80); PSW.N = (A & 0x80);
;
break; break;
} }
case 0xbf: { // mov ind+ case 0xbf: { // mov ind+
@@ -1069,7 +1074,21 @@ void Spc700::ExecuteInstructions(uint8_t opcode) {
break; break;
} }
case 0xd0: { // bne rel 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; break;
} }
case 0xd4: { // movs dpx 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)); throw std::runtime_error("Unknown SPC opcode: " + std::to_string(opcode));
break; break;
} }
//LogInstruction(initialPC, opcode);
} }
void Spc700::LogInstruction(uint16_t initial_pc, uint8_t opcode) { void Spc700::LogInstruction(uint16_t initial_pc, uint8_t opcode) {

View File

@@ -76,6 +76,15 @@ class Spc700 {
bool stopped_; bool stopped_;
bool reset_wanted_; 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]{ const uint8_t ipl_rom_[64]{
0xCD, 0xEF, 0xBD, 0xE8, 0x00, 0xC6, 0x1D, 0xD0, 0xFC, 0x8F, 0xAA, 0xCD, 0xEF, 0xBD, 0xE8, 0x00, 0xC6, 0x1D, 0xD0, 0xFC, 0x8F, 0xAA,
@@ -97,14 +106,14 @@ class Spc700 {
uint8_t SP = 0x00; // stack pointer uint8_t SP = 0x00; // stack pointer
struct Flags { struct Flags {
uint8_t N : 1; // Negative flag bool N : 1; // Negative flag
uint8_t V : 1; // Overflow flag bool V : 1; // Overflow flag
uint8_t P : 1; // Direct page flag bool P : 1; // Direct page flag
uint8_t B : 1; // Break flag bool B : 1; // Break flag
uint8_t H : 1; // Half-carry flag bool H : 1; // Half-carry flag
uint8_t I : 1; // Interrupt enable bool I : 1; // Interrupt enable
uint8_t Z : 1; // Zero flag bool Z : 1; // Zero flag
uint8_t C : 1; // Carry flag bool C : 1; // Carry flag
}; };
Flags PSW; // Processor status word Flags PSW; // Processor status word
@@ -139,12 +148,12 @@ class Spc700 {
uint16_t read_word(uint16_t address) { uint16_t read_word(uint16_t address) {
uint8_t adrl = address; uint8_t adrl = address;
uint8_t adrh = address + 1; uint8_t adrh = address + 1;
uint8_t value = read(adrl); uint8_t value = callbacks_.read(adrl);
return value | (read(adrh) << 8); return value | (callbacks_.read(adrh) << 8);
} }
uint8_t ReadOpcode() { uint8_t ReadOpcode() {
uint8_t opcode = read(PC++); uint8_t opcode = callbacks_.read(PC++);
return opcode; return opcode;
} }
@@ -169,7 +178,7 @@ class Spc700 {
} }
void push_byte(uint8_t value) { void push_byte(uint8_t value) {
write(0x100 | SP, value); callbacks_.write(0x100 | SP, value);
SP--; SP--;
} }