From 78f341489ed325aa6a7ea423bb308e51e925072f Mon Sep 17 00:00:00 2001 From: Tim Allen Date: Wed, 28 Jun 2017 17:24:46 +1000 Subject: [PATCH] Update to v103r03 release. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit byuu says: Changelog: - md/psg: fixed output frequency rate regression from v103r02 - processor/m68k: fixed calculations for ABCD, NBCD, SBCD [hex\_usr, SuperMikeMan] - processor/spc700: renamed abbreviated instructions to functional descriptions (eg `XCN` → `ExchangeNibble`) - processor/spc700: removed memory.cpp shorthand functions (fetch, load, store, pull, push) - processor/spc700: updated all instructions to follow cycle behavior as documented by Overload with a logic analyzer Once again, the changes to the SPC700 core are really quite massive. And this time it's not just cosmetic: the idle cycles have been updated to pull from various memory addresses. This is why I removed the shorthand functions -- so that I could handle the at-times very bizarre addresses the SPC700 has on its address bus during its idle cycles. There is one behavior Overload mentioned that I don't emulate ... one of the cycles of the (X) transfer functions seems to not actually access the $f0-ff internal SMP registers? I don't fully understand what Overload is getting at, so I haven't tried to support it just yet. Also, there are limits to logic analyzers. In many cases the same address is read from twice consecutively. It is unclear which of the two reads the SPC700 actually utilizes. I tried to choose the most logical values (usually the first one), but ... I don't know that we'll be able to figure this one out. It's going to be virtually impossible to test this through software, because the PC can't really execute out of registers that have side effects on reads. --- higan/emulator/emulator.hpp | 2 +- higan/md/psg/psg.cpp | 4 +- higan/processor/m68k/instructions.cpp | 24 +- higan/processor/spc700/instruction.cpp | 160 ++--- higan/processor/spc700/instructions.cpp | 830 +++++++++++------------ higan/processor/spc700/memory.cpp | 23 - higan/processor/spc700/serialization.cpp | 4 +- higan/processor/spc700/spc700.cpp | 35 +- higan/processor/spc700/spc700.hpp | 85 ++- higan/sfc/smp/smp.cpp | 4 +- 10 files changed, 561 insertions(+), 610 deletions(-) delete mode 100644 higan/processor/spc700/memory.cpp diff --git a/higan/emulator/emulator.hpp b/higan/emulator/emulator.hpp index 9405fafb..a5ef90bc 100644 --- a/higan/emulator/emulator.hpp +++ b/higan/emulator/emulator.hpp @@ -12,7 +12,7 @@ using namespace nall; namespace Emulator { static const string Name = "higan"; - static const string Version = "103.02"; + static const string Version = "103.03"; static const string Author = "byuu"; static const string License = "GPLv3"; static const string Website = "http://byuu.org/"; diff --git a/higan/md/psg/psg.cpp b/higan/md/psg/psg.cpp index ee48a500..9fd68721 100644 --- a/higan/md/psg/psg.cpp +++ b/higan/md/psg/psg.cpp @@ -25,7 +25,7 @@ auto PSG::main() -> void { output += levels[noise.volume] * noise.output; stream->sample(sclamp<16>(output) / 32768.0); - step(1); + step(16); } auto PSG::step(uint clocks) -> void { @@ -36,7 +36,7 @@ auto PSG::step(uint clocks) -> void { auto PSG::power() -> void { create(PSG::Enter, system.frequency() / 15.0); - stream = Emulator::audio.createStream(1, frequency()); + stream = Emulator::audio.createStream(1, frequency() / 16.0); stream->addFilter(Emulator::Filter::Order::First, Emulator::Filter::Type::HighPass, 20.0); stream->addFilter(Emulator::Filter::Order::First, Emulator::Filter::Type::LowPass, 2840.0); stream->addFilter(Emulator::Filter::Order::Second, Emulator::Filter::Type::LowPass, 20000.0, 3); diff --git a/higan/processor/m68k/instructions.cpp b/higan/processor/m68k/instructions.cpp index 9afb359f..9285bdbc 100644 --- a/higan/processor/m68k/instructions.cpp +++ b/higan/processor/m68k/instructions.cpp @@ -54,6 +54,7 @@ auto M68K::instructionABCD(EffectiveAddress with, EffectiveAddress from) -> void auto source = read(from); auto target = read(with); auto result = source + target + r.x; + bool c = false; bool v = false; if(((target ^ source ^ result) & 0x10) || (result & 0x0f) >= 0x0a) { @@ -65,12 +66,13 @@ auto M68K::instructionABCD(EffectiveAddress with, EffectiveAddress from) -> void if(result >= 0xa0) { auto previous = result; result += 0x60; + c = true; v |= ((~previous & 0x80) & (result & 0x80)); } write(with, result); - r.c = sign(result >> 1) < 0; + r.c = c; r.v = v; r.z = clip(result) ? 0 : r.z; r.n = sign(result) < 0; @@ -754,9 +756,10 @@ auto M68K::instructionMULU(DataRegister with, EffectiveAddress from) -> void { } auto M68K::instructionNBCD(EffectiveAddress with) -> void { - auto source = 0u; - auto target = read(with); + auto source = read(with); + auto target = 0u; auto result = target - source - r.x; + bool c = false; bool v = false; const bool adjustLo = (target ^ source ^ result) & 0x10; @@ -765,21 +768,24 @@ auto M68K::instructionNBCD(EffectiveAddress with) -> void { if(adjustLo) { auto previous = result; result -= 0x06; - v |= (previous & 0x80) & (~result & 0x80); + c = (~previous & 0x80) & ( result & 0x80); + v |= ( previous & 0x80) & (~result & 0x80); } if(adjustHi) { auto previous = result; result -= 0x60; + c = true; v |= (previous & 0x80) & (~result & 0x80); } write(with, result); - r.c = sign(result >> 1) < 0; + r.c = c; r.v = v; r.z = clip(result) ? 0 : r.z; r.n = sign(result) < 0; + r.x = r.c; } template auto M68K::instructionNEG(EffectiveAddress with) -> void { @@ -1011,6 +1017,7 @@ auto M68K::instructionSBCD(EffectiveAddress with, EffectiveAddress from) -> void auto source = read(from); auto target = read(with); auto result = target - source - r.x; + bool c = false; bool v = false; const bool adjustLo = (target ^ source ^ result) & 0x10; @@ -1019,21 +1026,24 @@ auto M68K::instructionSBCD(EffectiveAddress with, EffectiveAddress from) -> void if(adjustLo) { auto previous = result; result -= 0x06; - v |= (previous & 0x80) & (~result & 0x80); + c = (~previous & 0x80) & ( result & 0x80); + v |= ( previous & 0x80) & (~result & 0x80); } if(adjustHi) { auto previous = result; result -= 0x60; + c = true; v |= (previous & 0x80) & (~result & 0x80); } write(with, result); - r.c = sign(result >> 1) < 0; + r.c = c; r.v = v; r.z = clip(result) ? 0 : r.z; r.n = sign(result) < 0; + r.x = r.c; } auto M68K::instructionSCC(uint4 condition, EffectiveAddress to) -> void { diff --git a/higan/processor/spc700/instruction.cpp b/higan/processor/spc700/instruction.cpp index 1c5c43bc..ba7af3ec 100644 --- a/higan/processor/spc700/instruction.cpp +++ b/higan/processor/spc700/instruction.cpp @@ -2,11 +2,11 @@ #define fp(name) &SPC700::algorithm##name auto SPC700::instruction() -> void { - switch(fetch()) { - op(0x00, NOP) - op(0x01, JST, 0) - op(0x02, SET, 0) - op(0x03, BBS, 0) + switch(read(PC++)) { + op(0x00, NoOperation) + op(0x01, CallTable, 0) + op(0x02, AbsoluteBitSet, 0, true) + op(0x03, BranchBit, 0, true) op(0x04, DirectRead, fp(OR), A) op(0x05, AbsoluteRead, fp(OR), A) op(0x06, IndirectXRead, fp(OR)) @@ -17,12 +17,12 @@ auto SPC700::instruction() -> void { op(0x0b, DirectModify, fp(ASL)) op(0x0c, AbsoluteModify, fp(ASL)) op(0x0d, Push, P) - op(0x0e, TSBAbsolute) - op(0x0f, BRK) + op(0x0e, TestSetBitsAbsolute, true) + op(0x0f, Break) op(0x10, Branch, NF == 0) - op(0x11, JST, 1) - op(0x12, CLR, 0) - op(0x13, BBC, 0) + op(0x11, CallTable, 1) + op(0x12, AbsoluteBitSet, 0, false) + op(0x13, BranchBit, 0, false) op(0x14, DirectIndexedRead, fp(OR), A, X) op(0x15, AbsoluteIndexedRead, fp(OR), X) op(0x16, AbsoluteIndexedRead, fp(OR), Y) @@ -34,11 +34,11 @@ auto SPC700::instruction() -> void { op(0x1c, ImpliedModify, fp(ASL), A) op(0x1d, ImpliedModify, fp(DEC), X) op(0x1e, AbsoluteRead, fp(CMP), X) - op(0x1f, JMPIndirectX) - op(0x20, FlagClear, PF) - op(0x21, JST, 2) - op(0x22, SET, 1) - op(0x23, BBS, 1) + op(0x1f, JumpIndirectX) + op(0x20, FlagSet, PF, false) + op(0x21, CallTable, 2) + op(0x22, AbsoluteBitSet, 1, true) + op(0x23, BranchBit, 1, true) op(0x24, DirectRead, fp(AND), A) op(0x25, AbsoluteRead, fp(AND), A) op(0x26, IndirectXRead, fp(AND)) @@ -49,12 +49,12 @@ auto SPC700::instruction() -> void { op(0x2b, DirectModify, fp(ROL)) op(0x2c, AbsoluteModify, fp(ROL)) op(0x2d, Push, A) - op(0x2e, BNEDirect) + op(0x2e, BranchNotDirect) op(0x2f, Branch, true) op(0x30, Branch, NF == 1) - op(0x31, JST, 3) - op(0x32, CLR, 1) - op(0x33, BBC, 1) + op(0x31, CallTable, 3) + op(0x32, AbsoluteBitSet, 1, false) + op(0x33, BranchBit, 1, false) op(0x34, DirectIndexedRead, fp(AND), A, X) op(0x35, AbsoluteIndexedRead, fp(AND), X) op(0x36, AbsoluteIndexedRead, fp(AND), Y) @@ -66,11 +66,11 @@ auto SPC700::instruction() -> void { op(0x3c, ImpliedModify, fp(ROL), A) op(0x3d, ImpliedModify, fp(INC), X) op(0x3e, DirectRead, fp(CMP), X) - op(0x3f, JSRAbsolute) - op(0x40, FlagSet, PF) - op(0x41, JST, 4) - op(0x42, SET, 2) - op(0x43, BBS, 2) + op(0x3f, CallAbsolute) + op(0x40, FlagSet, PF, true) + op(0x41, CallTable, 4) + op(0x42, AbsoluteBitSet, 2, true) + op(0x43, BranchBit, 2, true) op(0x44, DirectRead, fp(EOR), A) op(0x45, AbsoluteRead, fp(EOR), A) op(0x46, IndirectXRead, fp(EOR)) @@ -81,12 +81,12 @@ auto SPC700::instruction() -> void { op(0x4b, DirectModify, fp(LSR)) op(0x4c, AbsoluteModify, fp(LSR)) op(0x4d, Push, X) - op(0x4e, TRBAbsolute) - op(0x4f, JSPDirect) + op(0x4e, TestSetBitsAbsolute, false) + op(0x4f, CallPage) op(0x50, Branch, VF == 0) - op(0x51, JST, 5) - op(0x52, CLR, 2) - op(0x53, BBC, 2) + op(0x51, CallTable, 5) + op(0x52, AbsoluteBitSet, 2, false) + op(0x53, BranchBit, 2, false) op(0x54, DirectIndexedRead, fp(EOR), A, X) op(0x55, AbsoluteIndexedRead, fp(EOR), X) op(0x56, AbsoluteIndexedRead, fp(EOR), Y) @@ -98,11 +98,11 @@ auto SPC700::instruction() -> void { op(0x5c, ImpliedModify, fp(LSR), A) op(0x5d, Transfer, A, X) op(0x5e, AbsoluteRead, fp(CMP), Y) - op(0x5f, JMPAbsolute) - op(0x60, FlagClear, CF) - op(0x61, JST, 6) - op(0x62, SET, 3) - op(0x63, BBS, 3) + op(0x5f, JumpAbsolute) + op(0x60, FlagSet, CF, false) + op(0x61, CallTable, 6) + op(0x62, AbsoluteBitSet, 3, true) + op(0x63, BranchBit, 3, true) op(0x64, DirectRead, fp(CMP), A) op(0x65, AbsoluteRead, fp(CMP), A) op(0x66, IndirectXRead, fp(CMP)) @@ -113,12 +113,12 @@ auto SPC700::instruction() -> void { op(0x6b, DirectModify, fp(ROR)) op(0x6c, AbsoluteModify, fp(ROR)) op(0x6d, Push, Y) - op(0x6e, BNEDirectDecrement) - op(0x6f, RTS) + op(0x6e, BranchNotDirectDecrement) + op(0x6f, ReturnSubroutine) op(0x70, Branch, VF == 1) - op(0x71, JST, 7) - op(0x72, CLR, 3) - op(0x73, BBC, 3) + op(0x71, CallTable, 7) + op(0x72, AbsoluteBitSet, 3, false) + op(0x73, BranchBit, 3, false) op(0x74, DirectIndexedRead, fp(CMP), A, X) op(0x75, AbsoluteIndexedRead, fp(CMP), X) op(0x76, AbsoluteIndexedRead, fp(CMP), Y) @@ -130,11 +130,11 @@ auto SPC700::instruction() -> void { op(0x7c, ImpliedModify, fp(ROR), A) op(0x7d, Transfer, X, A) op(0x7e, DirectRead, fp(CMP), Y) - op(0x7f, RTI) - op(0x80, FlagSet, CF) - op(0x81, JST, 8) - op(0x82, SET, 4) - op(0x83, BBS, 4) + op(0x7f, ReturnInterrupt) + op(0x80, FlagSet, CF, true) + op(0x81, CallTable, 8) + op(0x82, AbsoluteBitSet, 4, true) + op(0x83, BranchBit, 4, true) op(0x84, DirectRead, fp(ADC), A) op(0x85, AbsoluteRead, fp(ADC), A) op(0x86, IndirectXRead, fp(ADC)) @@ -145,12 +145,12 @@ auto SPC700::instruction() -> void { op(0x8b, DirectModify, fp(DEC)) op(0x8c, AbsoluteModify, fp(DEC)) op(0x8d, ImmediateRead, fp(LD), Y) - op(0x8e, PLP) + op(0x8e, PullP) op(0x8f, DirectWriteImmediate, fp(ST)) op(0x90, Branch, CF == 0) - op(0x91, JST, 9) - op(0x92, CLR, 4) - op(0x93, BBC, 4) + op(0x91, CallTable, 9) + op(0x92, AbsoluteBitSet, 4, false) + op(0x93, BranchBit, 4, false) op(0x94, DirectIndexedRead, fp(ADC), A, X) op(0x95, AbsoluteIndexedRead, fp(ADC), X) op(0x96, AbsoluteIndexedRead, fp(ADC), Y) @@ -161,12 +161,12 @@ auto SPC700::instruction() -> void { op(0x9b, DirectIndexedModify, fp(DEC), X) op(0x9c, ImpliedModify, fp(DEC), A) op(0x9d, Transfer, S, X) - op(0x9e, DIV) - op(0x9f, XCN) - op(0xa0, FlagSet, IF) - op(0xa1, JST, 10) - op(0xa2, SET, 5) - op(0xa3, BBS, 5) + op(0x9e, Divide) + op(0x9f, ExchangeNibble) + op(0xa0, FlagSet, IF, true) + op(0xa1, CallTable, 10) + op(0xa2, AbsoluteBitSet, 5, true) + op(0xa3, BranchBit, 5, true) op(0xa4, DirectRead, fp(SBC), A) op(0xa5, AbsoluteRead, fp(SBC), A) op(0xa6, IndirectXRead, fp(SBC)) @@ -180,9 +180,9 @@ auto SPC700::instruction() -> void { op(0xae, Pull, A) op(0xaf, IndirectXIncrementWrite, A) op(0xb0, Branch, CF == 1) - op(0xb1, JST, 11) - op(0xb2, CLR, 5) - op(0xb3, BBC, 5) + op(0xb1, CallTable, 11) + op(0xb2, AbsoluteBitSet, 5, false) + op(0xb3, BranchBit, 5, false) op(0xb4, DirectIndexedRead, fp(SBC), A, X) op(0xb5, AbsoluteIndexedRead, fp(SBC), X) op(0xb6, AbsoluteIndexedRead, fp(SBC), Y) @@ -193,12 +193,12 @@ auto SPC700::instruction() -> void { op(0xbb, DirectIndexedModify, fp(INC), X) op(0xbc, ImpliedModify, fp(INC), A) op(0xbd, Transfer, X, S) - op(0xbe, DAS) + op(0xbe, DecimalAdjustSub) op(0xbf, IndirectXIncrementRead, A) - op(0xc0, FlagClear, IF) - op(0xc1, JST, 12) - op(0xc2, SET, 6) - op(0xc3, BBS, 6) + op(0xc0, FlagSet, IF, false) + op(0xc1, CallTable, 12) + op(0xc2, AbsoluteBitSet, 6, true) + op(0xc3, BranchBit, 6, true) op(0xc4, DirectWrite, A) op(0xc5, AbsoluteWrite, A) op(0xc6, IndirectXWrite, A) @@ -210,27 +210,27 @@ auto SPC700::instruction() -> void { op(0xcc, AbsoluteWrite, Y) op(0xcd, ImmediateRead, fp(LD), X) op(0xce, Pull, X) - op(0xcf, MUL) + op(0xcf, Multiply) op(0xd0, Branch, ZF == 0) - op(0xd1, JST, 13) - op(0xd2, CLR, 6) - op(0xd3, BBC, 6) + op(0xd1, CallTable, 13) + op(0xd2, AbsoluteBitSet, 6, false) + op(0xd3, BranchBit, 6, false) op(0xd4, DirectIndexedWrite, A, X) op(0xd5, AbsoluteIndexedWrite, X) op(0xd6, AbsoluteIndexedWrite, Y) op(0xd7, IndirectIndexedWrite, A, Y) op(0xd8, DirectWrite, X) op(0xd9, DirectIndexedWrite, X, Y) - op(0xda, STWDirect) + op(0xda, DirectWriteWord) op(0xdb, DirectIndexedWrite, Y, X) op(0xdc, ImpliedModify, fp(DEC), Y) op(0xdd, Transfer, Y, A) - op(0xde, BNEDirectX) - op(0xdf, DAA) - op(0xe0, CLV) - op(0xe1, JST, 14) - op(0xe2, SET, 7) - op(0xe3, BBS, 7) + op(0xde, BranchNotDirectX) + op(0xdf, DecimalAdjustAdd) + op(0xe0, OverflowClear) + op(0xe1, CallTable, 14) + op(0xe2, AbsoluteBitSet, 7, true) + op(0xe3, BranchBit, 7, true) op(0xe4, DirectRead, fp(LD), A) op(0xe5, AbsoluteRead, fp(LD), A) op(0xe6, IndirectXRead, fp(LD)) @@ -240,13 +240,13 @@ auto SPC700::instruction() -> void { op(0xea, AbsoluteBitModify, 7) op(0xeb, DirectRead, fp(LD), Y) op(0xec, AbsoluteRead, fp(LD), Y) - op(0xed, CMC) + op(0xed, ComplementCarry) op(0xee, Pull, Y) - op(0xef, WAI) + op(0xef, Wait) op(0xf0, Branch, ZF == 1) - op(0xf1, JST, 15) - op(0xf2, CLR, 7) - op(0xf3, BBC, 7) + op(0xf1, CallTable, 15) + op(0xf2, AbsoluteBitSet, 7, false) + op(0xf3, BranchBit, 7, false) op(0xf4, DirectIndexedRead, fp(LD), A, X) op(0xf5, AbsoluteIndexedRead, fp(LD), X) op(0xf6, AbsoluteIndexedRead, fp(LD), Y) @@ -257,8 +257,8 @@ auto SPC700::instruction() -> void { op(0xfb, DirectIndexedRead, fp(LD), Y, X) op(0xfc, ImpliedModify, fp(INC), Y) op(0xfd, Transfer, A, Y) - op(0xfe, BNEYDecrement) - op(0xff, STP) + op(0xfe, BranchNotYDecrement) + op(0xff, Stop) } } diff --git a/higan/processor/spc700/instructions.cpp b/higan/processor/spc700/instructions.cpp index 904f197f..86a42e6c 100644 --- a/higan/processor/spc700/instructions.cpp +++ b/higan/processor/spc700/instructions.cpp @@ -1,379 +1,204 @@ auto SPC700::instructionAbsoluteBitModify(uint3 mode) -> void { - uint16 absolute = fetch(); - absolute |= fetch() << 8; - uint3 bit = absolute >> 13; - absolute &= 0x1fff; - uint8 data = read(absolute); + uint16 address = read(PC++); + address |= read(PC++) << 8; + uint3 bit = address >> 13; + address &= 0x1fff; + uint8 data = read(address); switch(mode) { - case 0: //orc addr:bit - idle(); + case 0: //or addr:bit + idle(address); CF |= data.bit(bit); break; - case 1: //orc !addr:bit - idle(); + case 1: //or !addr:bit + idle(address); CF |= !data.bit(bit); break; - case 2: //and addr:bit + case 2: //and addr:bit CF &= data.bit(bit); break; case 3: //and !addr:bit CF &= !data.bit(bit); break; - case 4: //eor addr:bit - idle(); + case 4: //eor addr:bit + idle(address); CF ^= data.bit(bit); break; - case 5: //ldc addr:bit + case 5: //ld addr:bit CF = data.bit(bit); break; - case 6: //stc addr:bit - idle(); + case 6: //st addr:bit + idle(address); data.bit(bit) = CF; - write(absolute, data); + write(address, data); break; - case 7: //not addr:bit + case 7: //not addr:bit data.bit(bit) ^= 1; - write(absolute, data); + write(address, data); break; } } +auto SPC700::instructionAbsoluteBitSet(uint3 bit, bool value) -> void { + uint8 address = read(PC++); + uint8 data = read(page(address)); + data.bit(bit) = value; + write(page(address), data); +} + auto SPC700::instructionAbsoluteRead(fpb op, uint8& target) -> void { - uint16 absolute = fetch(); - absolute |= fetch() << 8; - uint8 data = read(absolute); + uint16 address = read(PC++); + address |= read(PC++) << 8; + uint8 data = read(address); target = alu(target, data); } auto SPC700::instructionAbsoluteModify(fps op) -> void { - uint16 absolute = fetch(); - absolute |= fetch() << 8; - uint8 data = read(absolute); - write(absolute, alu(data)); + uint16 address = read(PC++); + address |= read(PC++) << 8; + uint8 data = read(address); + write(address, alu(data)); } auto SPC700::instructionAbsoluteWrite(uint8& data) -> void { - uint16 absolute = fetch(); - absolute |= fetch() << 8; - read(absolute); - write(absolute, data); + uint16 address = read(PC++); + address |= read(PC++) << 8; + read(address); + write(address, data); } auto SPC700::instructionAbsoluteIndexedRead(fpb op, uint8& index) -> void { - uint16 absolute = fetch(); - absolute |= fetch() << 8; - idle(); - uint8 data = read(absolute + index); + uint16 address = read(PC++); + address |= read(PC++) << 8; + idle(PC - 1); + uint8 data = read(address + index); A = alu(A, data); } auto SPC700::instructionAbsoluteIndexedWrite(uint8& index) -> void { - uint16 absolute = fetch(); - absolute |= fetch() << 8; - idle(); - absolute += index; - read(absolute); - write(absolute, A); + uint16 address = read(PC++); + address |= read(PC++) << 8; + idle(PC - 1); + read(address + index); + write(address + index, A); } auto SPC700::instructionBranch(bool take) -> void { - uint8 data = fetch(); + uint8 data = read(PC++); if(!take) return; - idle(); - idle(); + idle(PC - 1); + idle(PC - 1); PC += (int8)data; } -auto SPC700::instructionDirectRead(fpb op, uint8& target) -> void { - uint8 direct = fetch(); - uint8 data = load(direct); - target = alu(target, data); -} - -auto SPC700::instructionDirectModify(fps op) -> void { - uint8 direct = fetch(); - uint8 data = load(direct); - store(direct, alu(data)); -} - -auto SPC700::instructionDirectWrite(uint8& data) -> void { - uint8 direct = fetch(); - load(direct); - store(direct, data); -} - -auto SPC700::instructionDirectWriteDirect(fpb op) -> void { - uint8 source = fetch(); - uint8 rhs = load(source); - uint8 target = fetch(); - uint8 lhs; - if(op != &SPC700::algorithmST) lhs = load(target); - lhs = alu(lhs, rhs); - op != &SPC700::algorithmCMP ? store(target, lhs) : idle(); -} - -auto SPC700::instructionDirectWriteImmediate(fpb op) -> void { - uint8 immediate = fetch(); - uint8 direct = fetch(); - uint8 data = load(direct); - data = alu(data, immediate); - op != &SPC700::algorithmCMP ? store(direct, data) : idle(); -} - -auto SPC700::instructionDirectReadWord(fpw op) -> void { - uint8 direct = fetch(); - uint16 data = load(direct++); - if(op != &SPC700::algorithmCPW) idle(); - data |= load(direct++) << 8; - YA = alu(YA, data); -} - -auto SPC700::instructionDirectModifyWord(int adjust) -> void { - uint8 direct = fetch(); - uint16 data = load(direct) + adjust; - store(direct++, data >> 0); - data += load(direct) << 8; - store(direct++, data >> 8); - ZF = data == 0; - NF = data & 0x8000; -} - -auto SPC700::instructionDirectIndexedRead(fpb op, uint8& target, uint8& index) -> void { - uint8 direct = fetch(); - idle(); - uint8 data = load(direct + index); - target = alu(target, data); -} - -auto SPC700::instructionDirectIndexedModify(fps op, uint8& index) -> void { - uint8 direct = fetch(); - idle(); - uint8 data = load(direct + index); - store(direct + index, alu(data)); -} - -auto SPC700::instructionDirectIndexedWrite(uint8& data, uint8& index) -> void { - uint8 direct = fetch() + index; - idle(); - load(direct); - store(direct, data); -} - -auto SPC700::instructionFlagClear(bool& flag) -> void { - idle(); - if(&flag == &IF) idle(); - flag = 0; -} - -auto SPC700::instructionFlagSet(bool& flag) -> void { - idle(); - if(&flag == &IF) idle(); - flag = 1; -} - -auto SPC700::instructionImmediateRead(fpb op, uint8& target) -> void { - uint8 data = fetch(); - target = alu(target, data); -} - -auto SPC700::instructionImpliedModify(fps op, uint8& target) -> void { - idle(); - target = alu(target); -} - -auto SPC700::instructionIndexedIndirectRead(fpb op, uint8& index) -> void { - uint8 direct = fetch() + index; - idle(); - uint16 absolute = load(direct++); - absolute |= load(direct++) << 8; - uint8 data = read(absolute); - A = alu(A, data); -} - -auto SPC700::instructionIndexedIndirectWrite(uint8& data, uint8& index) -> void { - uint8 direct = fetch() + index; - idle(); - uint16 absolute = load(direct++); - absolute |= load(direct++) << 8; - read(absolute); - write(absolute, data); -} - -auto SPC700::instructionIndirectIndexedRead(fpb op, uint8& index) -> void { - uint8 direct = fetch(); - uint16 absolute = load(direct++); - absolute |= load(direct++) << 8; - idle(); - uint8 data = read(absolute + index); - A = alu(A, data); -} - -auto SPC700::instructionIndirectIndexedWrite(uint8& data, uint8& index) -> void { - uint8 direct = fetch(); - uint16 absolute = load(direct++); - absolute |= load(direct++) << 8; - idle(); - read(absolute + index); - write(absolute + index, data); -} - -auto SPC700::instructionIndirectXRead(fpb op) -> void { - idle(); - uint8 data = load(X); - A = alu(A, data); -} - -auto SPC700::instructionIndirectXWrite(uint8& data) -> void { - idle(); - load(X); - store(X, data); -} - -auto SPC700::instructionIndirectXIncrementRead(uint8& data) -> void { - idle(); - data = load(X++); - idle(); - ZF = data == 0; - NF = data & 0x80; -} - -auto SPC700::instructionIndirectXIncrementWrite(uint8& data) -> void { - idle(); - idle(); - store(X++, data); -} - -auto SPC700::instructionIndirectXWriteIndirectY(fpb op) -> void { - idle(); - uint8 rhs = load(Y); - uint8 lhs = load(X); - lhs = alu(lhs, rhs); - op != &SPC700::algorithmCMP ? store(X, lhs) : idle(); -} - -auto SPC700::instructionPull(uint8& data) -> void { - idle(); - idle(); - data = pull(); -} - -auto SPC700::instructionPush(uint8 data) -> void { - idle(); - idle(); - push(data); -} - -auto SPC700::instructionTransfer(uint8& from, uint8& to) -> void { - idle(); - to = from; - if(&to == &S) return; - ZF = to == 0; - NF = to & 0x80; -} - -// - -auto SPC700::instructionBBC(uint3 bit) -> void { - uint8 direct = fetch(); - uint8 data = load(direct); - uint8 displacement = fetch(); - idle(); - if(data.bit(bit) == 1) return; - idle(); - idle(); +auto SPC700::instructionBranchBit(uint3 bit, bool match) -> void { + uint8 address = read(PC++); + uint8 data = read(page(address)); + idle(page(address)); + uint8 displacement = read(PC++); + if(data.bit(bit) != match) return; + idle(PC - 1); + idle(PC - 1); PC += (int8)displacement; } -auto SPC700::instructionBBS(uint3 bit) -> void { - uint8 direct = fetch(); - uint8 data = load(direct); - uint8 displacement = fetch(); - idle(); - if(data.bit(bit) == 0) return; - idle(); - idle(); - PC += (int8)displacement; -} - -auto SPC700::instructionBNEDirect() -> void { - uint8 direct = fetch(); - uint8 data = load(direct); - uint8 displacement = fetch(); - idle(); +auto SPC700::instructionBranchNotDirect() -> void { + uint8 address = read(PC++); + uint8 data = read(page(address)); + idle(page(address)); + uint8 displacement = read(PC++); if(A == data) return; - idle(); - idle(); + idle(PC - 1); + idle(PC - 1); PC += (int8)displacement; } -auto SPC700::instructionBNEDirectDecrement() -> void { - uint8 direct = fetch(); - uint8 data = load(direct); - store(direct, --data); - uint8 displacement = fetch(); +auto SPC700::instructionBranchNotDirectDecrement() -> void { + uint8 address = read(PC++); + uint8 data = read(page(address)); + write(page(address), --data); + uint8 displacement = read(PC++); if(data == 0) return; - idle(); - idle(); + idle(PC - 1); + idle(PC - 1); PC += (int8)displacement; } -auto SPC700::instructionBNEDirectX() -> void { - uint8 direct = fetch(); - idle(); - uint8 data = load(direct + X); - uint8 displacement = fetch(); - idle(); +auto SPC700::instructionBranchNotDirectX() -> void { + uint8 address = read(PC++); + idle(PC - 1); + uint8 data = read(page(address + X)); + idle(page(address + X)); + uint8 displacement = read(PC++); if(A == data) return; - idle(); - idle(); + idle(PC - 1); + idle(PC - 1); PC += (int8)displacement; } -auto SPC700::instructionBNEYDecrement() -> void { - uint8 displacement = fetch(); - idle(); - idle(); +auto SPC700::instructionBranchNotYDecrement() -> void { + idle(PC); + idle(PC); + uint8 displacement = read(PC++); if(--Y == 0) return; - idle(); - idle(); + idle(PC - 1); + idle(PC - 1); PC += (int8)displacement; } -auto SPC700::instructionBRK() -> void { - uint16 absolute = read(0xffde); - absolute |= read(0xffdf) << 8; - idle(); - idle(); - push(PC >> 8); - push(PC >> 0); - push(P); - PC = absolute; +auto SPC700::instructionBreak() -> void { + idle(PC); + write(stack(S--), PC >> 8); + write(stack(S--), PC >> 0); + write(stack(S--), P); + idle(stack(S + 1)); + uint16 address = read(0xffde + 0); + address |= read(0xffde + 1) << 8; + PC = address; IF = 0; BF = 1; } -auto SPC700::instructionCLR(uint3 bit) -> void { - uint8 direct = fetch(); - uint8 data = load(direct); - data.bit(bit) = 0; - store(direct, data); +auto SPC700::instructionCallAbsolute() -> void { + uint16 address = read(PC++); + address |= read(PC++) << 8; + idle(stack(S)); + write(stack(S--), PC >> 8); + write(stack(S--), PC >> 0); + idle(stack(S + 1)); + idle(stack(S + 1)); + PC = address; } -auto SPC700::instructionCLV() -> void { - idle(); - HF = 0; - VF = 0; +auto SPC700::instructionCallPage() -> void { + uint8 address = read(PC++); + idle(PC - 1); + write(stack(S--), PC >> 8); + write(stack(S--), PC >> 0); + idle(stack(S + 1)); + PC = 0xff00 | address; } -auto SPC700::instructionCMC() -> void { - idle(); - idle(); +auto SPC700::instructionCallTable(uint4 vector) -> void { + idle(PC); + idle(stack(S)); + write(stack(S--), PC >> 8); + write(stack(S--), PC >> 0); + idle(stack(S + 1)); + uint16 address = 0xffde - (vector << 1); + uint16 pc = read(address + 0); + pc |= read(address + 1) << 8; + PC = pc; +} + +auto SPC700::instructionComplementCarry() -> void { + idle(PC); + idle(PC); CF = !CF; } -auto SPC700::instructionDAA() -> void { - idle(); - idle(); +auto SPC700::instructionDecimalAdjustAdd() -> void { + idle(PC); + idle(PC); if(CF || A > 0x99) { A += 0x60; CF = 1; @@ -385,9 +210,9 @@ auto SPC700::instructionDAA() -> void { NF = A & 0x80; } -auto SPC700::instructionDAS() -> void { - idle(); - idle(); +auto SPC700::instructionDecimalAdjustSub() -> void { + idle(PC); + idle(PC); if(!CF || A > 0x99) { A -= 0x60; CF = 0; @@ -399,18 +224,100 @@ auto SPC700::instructionDAS() -> void { NF = A & 0x80; } -auto SPC700::instructionDIV() -> void { - idle(); - idle(); - idle(); - idle(); - idle(); - idle(); - idle(); - idle(); - idle(); - idle(); - idle(); +auto SPC700::instructionDirectRead(fpb op, uint8& target) -> void { + uint8 address = read(PC++); + uint8 data = read(page(address)); + target = alu(target, data); +} + +auto SPC700::instructionDirectModify(fps op) -> void { + uint8 address = read(PC++); + uint8 data = read(page(address)); + write(page(address), alu(data)); +} + +auto SPC700::instructionDirectWriteWord() -> void { + uint8 address = read(PC++); + idle(page(address + 0)); + write(page(address + 0), A); + write(page(address + 1), Y); +} + +auto SPC700::instructionDirectWriteDirect(fpb op) -> void { + uint8 source = read(PC++); + uint8 rhs = read(page(source)); + uint8 target = read(PC++); + uint8 lhs; + if(op != &SPC700::algorithmST) lhs = read(page(target)); + lhs = alu(lhs, rhs); + op != &SPC700::algorithmCMP ? write(page(target), lhs) : idle(page(target)); +} + +auto SPC700::instructionDirectWriteImmediate(fpb op) -> void { + uint8 immediate = read(PC++); + uint8 address = read(PC++); + uint8 data = read(page(address)); + data = alu(data, immediate); + op != &SPC700::algorithmCMP ? write(page(address), data) : idle(page(address)); +} + +auto SPC700::instructionDirectReadWord(fpw op) -> void { + uint8 address = read(PC++); + uint16 data = read(page(address + 0)); + if(op != &SPC700::algorithmCPW) idle(page(address + 0)); + data |= read(page(address + 1)) << 8; + YA = alu(YA, data); +} + +auto SPC700::instructionDirectModifyWord(int adjust) -> void { + uint8 address = read(PC++); + uint16 data = read(page(address + 0)) + adjust; + write(page(address + 0), data >> 0); + data += read(page(address + 1)) << 8; + write(page(address + 1), data >> 8); + ZF = data == 0; + NF = data & 0x8000; +} + +auto SPC700::instructionDirectWrite(uint8& data) -> void { + uint8 address = read(PC++); + idle(page(address)); + write(page(address), data); +} + +auto SPC700::instructionDirectIndexedRead(fpb op, uint8& target, uint8& index) -> void { + uint8 address = read(PC++); + idle(PC - 1); + uint8 data = read(page(address + index)); + target = alu(target, data); +} + +auto SPC700::instructionDirectIndexedModify(fps op, uint8& index) -> void { + uint8 address = read(PC++); + idle(PC - 1); + uint8 data = read(page(address + index)); + write(page(address + index), alu(data)); +} + +auto SPC700::instructionDirectIndexedWrite(uint8& data, uint8& index) -> void { + uint8 address = read(PC++); + idle(PC - 1); + idle(page(address + index)); + write(page(address + index), data); +} + +auto SPC700::instructionDivide() -> void { + idle(PC); + idle(PC); + idle(PC); + idle(PC); + idle(PC); + idle(PC); + idle(PC); + idle(PC); + idle(PC); + idle(PC); + idle(PC); uint16 ya = YA; //overflow set if quotient >= 256 HF = (Y & 15) >= (X & 15); @@ -430,63 +337,126 @@ auto SPC700::instructionDIV() -> void { NF = A & 0x80; } -auto SPC700::instructionJMPAbsolute() -> void { - uint16 absolute = fetch(); - absolute |= fetch() << 8; - PC = absolute; +auto SPC700::instructionExchangeNibble() -> void { + idle(PC); + idle(PC); + idle(PC); + idle(PC); + A = A >> 4 | A << 4; + ZF = A == 0; + NF = A & 0x80; } -auto SPC700::instructionJMPIndirectX() -> void { - uint16 absolute = fetch(); - absolute |= fetch() << 8; - idle(); - absolute += X; - uint16 pc = read(absolute++); - pc |= read(absolute++) << 8; +auto SPC700::instructionFlagSet(bool& flag, bool value) -> void { + idle(PC); + if(&flag == &IF) idle(PC); + flag = value; +} + +auto SPC700::instructionImmediateRead(fpb op, uint8& target) -> void { + uint8 data = read(PC++); + target = alu(target, data); +} + +auto SPC700::instructionImpliedModify(fps op, uint8& target) -> void { + idle(PC); + target = alu(target); +} + +auto SPC700::instructionIndexedIndirectRead(fpb op, uint8& index) -> void { + uint8 indirect = read(PC++); + idle(PC - 1); + uint16 address = read(page(indirect + index + 0)); + address |= read(page(indirect + index + 1)) << 8; + uint8 data = read(address); + A = alu(A, data); +} + +auto SPC700::instructionIndexedIndirectWrite(uint8& data, uint8& index) -> void { + uint8 indirect = read(PC++); + idle(PC - 1); + uint16 address = read(page(indirect + index + 0)); + address |= read(page(indirect + index + 1)) << 8; + read(address); + write(address, data); +} + +auto SPC700::instructionIndirectIndexedRead(fpb op, uint8& index) -> void { + uint8 indirect = read(PC++); + uint16 address = read(page(indirect + 0)); + address |= read(page(indirect + 1)) << 8; + idle(page(indirect + 1)); + uint8 data = read(address + index); + A = alu(A, data); +} + +auto SPC700::instructionIndirectIndexedWrite(uint8& data, uint8& index) -> void { + uint8 indirect = read(PC++); + uint16 address = read(page(indirect + 0)); + address |= read(page(indirect + 1)) << 8; + idle(page(indirect + 1)); + read(address + index); + write(address + index, data); +} + +auto SPC700::instructionIndirectXRead(fpb op) -> void { + idle(PC); + uint8 data = read(page(X)); + A = alu(A, data); +} + +auto SPC700::instructionIndirectXWrite(uint8& data) -> void { + idle(PC); + idle(page(X)); + write(page(X), data); +} + +auto SPC700::instructionIndirectXIncrementRead(uint8& data) -> void { + idle(PC); + data = read(page(X)); //todo: $f0-ff not accessible on this cycle? + idle(page(X++)); + ZF = data == 0; + NF = data & 0x80; +} + +auto SPC700::instructionIndirectXIncrementWrite(uint8& data) -> void { + idle(PC); + idle(page(X)); //todo: $f0-ff not accessible on this cycle? + write(page(X++), data); +} + +auto SPC700::instructionIndirectXWriteIndirectY(fpb op) -> void { + idle(PC); + uint8 rhs = read(page(Y)); + uint8 lhs = read(page(X)); + lhs = alu(lhs, rhs); + op != &SPC700::algorithmCMP ? write(page(X), lhs) : idle(page(X)); +} + +auto SPC700::instructionJumpAbsolute() -> void { + uint16 address = read(PC++); + address |= read(PC++) << 8; + PC = address; +} + +auto SPC700::instructionJumpIndirectX() -> void { + uint16 address = read(PC++); + address |= read(PC++) << 8; + idle(PC - 1); + uint16 pc = read(address + X + 0); + pc |= read(address + X + 1) << 8; PC = pc; } -auto SPC700::instructionJSPDirect() -> void { - uint8 direct = fetch(); - idle(); - idle(); - push(PC >> 8); - push(PC >> 0); - PC = 0xff00 | direct; -} - -auto SPC700::instructionJSRAbsolute() -> void { - uint16 absolute = fetch(); - absolute |= fetch() << 8; - idle(); - idle(); - idle(); - push(PC >> 8); - push(PC >> 0); - PC = absolute; -} - -auto SPC700::instructionJST(uint4 vector) -> void { - uint16 absolute = 0xffde - (vector << 1); - uint16 pc = read(absolute++); - pc |= read(absolute++) << 8; - idle(); - idle(); - idle(); - push(PC >> 8); - push(PC >> 0); - PC = pc; -} - -auto SPC700::instructionMUL() -> void { - idle(); - idle(); - idle(); - idle(); - idle(); - idle(); - idle(); - idle(); +auto SPC700::instructionMultiply() -> void { + idle(PC); + idle(PC); + idle(PC); + idle(PC); + idle(PC); + idle(PC); + idle(PC); + idle(PC); uint16 ya = Y * A; A = ya >> 0; Y = ya >> 8; @@ -495,89 +465,81 @@ auto SPC700::instructionMUL() -> void { NF = Y & 0x80; } -auto SPC700::instructionNOP() -> void { - idle(); +auto SPC700::instructionNoOperation() -> void { + idle(PC); } -auto SPC700::instructionPLP() -> void { - idle(); - idle(); - P = pull(); +auto SPC700::instructionOverflowClear() -> void { + idle(PC); + HF = 0; + VF = 0; } -auto SPC700::instructionRTI() -> void { - P = pull(); - uint16 absolute = pull(); - absolute |= pull() << 8; - idle(); - idle(); - PC = absolute; +auto SPC700::instructionPull(uint8& data) -> void { + idle(PC); + idle(stack(S)); + data = read(stack(++S)); } -auto SPC700::instructionRTS() -> void { - uint16 absolute = pull(); - absolute |= pull() << 8; - idle(); - idle(); - PC = absolute; +auto SPC700::instructionPullP() -> void { + idle(PC); + idle(stack(S)); + P = read(stack(++S)); } -auto SPC700::instructionSET(uint3 bit) -> void { - uint8 direct = fetch(); - uint8 data = load(direct); - data.bit(bit) = 1; - store(direct, data); +auto SPC700::instructionPush(uint8 data) -> void { + idle(PC); + write(stack(S--), data); + idle(stack(S + 1)); } -auto SPC700::instructionSTP() -> void { - r.stp = true; - while(r.stp && !synchronizing()) { - idle(); - idle(); +auto SPC700::instructionReturnInterrupt() -> void { + idle(PC); + idle(stack(S)); + P = read(stack(++S)); + uint16 address = read(stack(++S)); + address |= read(stack(++S)) << 8; + PC = address; +} + +auto SPC700::instructionReturnSubroutine() -> void { + idle(PC); + idle(stack(S)); + uint16 address = read(stack(++S)); + address |= read(stack(++S)) << 8; + PC = address; +} + +auto SPC700::instructionStop() -> void { + r.stop = true; + while(r.stop && !synchronizing()) { + idle(PC); + idle(PC); } } -auto SPC700::instructionSTWDirect() -> void { - uint8 direct = fetch(); - load(direct); - store(direct++, A); - store(direct++, Y); -} - -auto SPC700::instructionTRBAbsolute() -> void { - uint16 absolute = fetch(); - absolute |= fetch() << 8; - uint8 data = read(absolute); +auto SPC700::instructionTestSetBitsAbsolute(bool set) -> void { + uint16 address = read(PC++); + address |= read(PC++) << 8; + uint8 data = read(address); ZF = (A - data) == 0; NF = (A - data) & 0x80; - read(absolute); - write(absolute, data & ~A); + idle(address); + write(address, set ? data | A : data & ~A); } -auto SPC700::instructionTSBAbsolute() -> void { - uint16 absolute = fetch(); - absolute |= fetch() << 8; - uint8 data = read(absolute); - ZF = (A - data) == 0; - NF = (A - data) & 0x80; - read(absolute); - write(absolute, data | A); +auto SPC700::instructionTransfer(uint8& from, uint8& to) -> void { + idle(PC); + to = from; + if(&to == &S) return; + ZF = to == 0; + NF = to & 0x80; } -auto SPC700::instructionWAI() -> void { - r.wai = true; - while(r.wai && !synchronizing()) { - idle(); - idle(); +auto SPC700::instructionWait() -> void { + r.wait = true; + while(r.wait && !synchronizing()) { + idle(PC); + idle(PC); } } - -auto SPC700::instructionXCN() -> void { - idle(); - idle(); - idle(); - idle(); - A = A >> 4 | A << 4; - ZF = A == 0; - NF = A & 0x80; -} diff --git a/higan/processor/spc700/memory.cpp b/higan/processor/spc700/memory.cpp deleted file mode 100644 index 85aea3c0..00000000 --- a/higan/processor/spc700/memory.cpp +++ /dev/null @@ -1,23 +0,0 @@ -auto SPC700::idle() -> void { - read(PC); -} - -auto SPC700::fetch() -> uint8 { - return read(PC++); -} - -auto SPC700::pull() -> uint8 { - return read(0x0100 | ++S); -} - -auto SPC700::push(uint8 data) -> void { - return write(0x0100 | S--, data); -} - -auto SPC700::load(uint8 addr) -> uint8 { - return read(PF << 8 | addr); -} - -auto SPC700::store(uint8 addr, uint8 data) -> void { - return write(PF << 8 | addr, data); -} diff --git a/higan/processor/spc700/serialization.cpp b/higan/processor/spc700/serialization.cpp index 5ae8f32f..2c258f56 100644 --- a/higan/processor/spc700/serialization.cpp +++ b/higan/processor/spc700/serialization.cpp @@ -12,6 +12,6 @@ auto SPC700::serialize(serializer& s) -> void { s.integer(r.p.v); s.integer(r.p.n); - s.integer(r.wai); - s.integer(r.stp); + s.integer(r.wait); + s.integer(r.stop); } diff --git a/higan/processor/spc700/spc700.cpp b/higan/processor/spc700/spc700.cpp index 15c1f54c..0e1cfce6 100644 --- a/higan/processor/spc700/spc700.cpp +++ b/higan/processor/spc700/spc700.cpp @@ -22,13 +22,35 @@ namespace Processor { #define alu (this->*op) -#include "memory.cpp" #include "algorithms.cpp" #include "instructions.cpp" #include "instruction.cpp" #include "serialization.cpp" #include "disassembler.cpp" +auto SPC700::idle(uint16 address) -> void { + read(address); +} + +auto SPC700::page(uint8 address) const -> uint16 { + return PF << 8 | address; +} + +auto SPC700::stack(uint8 address) const -> uint16 { + return 1 << 8 | address; +} + +auto SPC700::power() -> void { + PC = 0x0000; + YA = 0x0000; + X = 0x00; + S = 0xef; + P = 0x02; + + r.wait = false; + r.stop = false; +} + #undef PC #undef YA #undef A @@ -48,15 +70,4 @@ namespace Processor { #undef alu -auto SPC700::power() -> void { - r.pc.w = 0x0000; - r.ya.w = 0x0000; - r.x = 0x00; - r.s = 0xef; - r.p = 0x02; - - r.wai = false; - r.stp = false; -} - } diff --git a/higan/processor/spc700/spc700.hpp b/higan/processor/spc700/spc700.hpp index 01f9ca65..b2eb1f14 100644 --- a/higan/processor/spc700/spc700.hpp +++ b/higan/processor/spc700/spc700.hpp @@ -3,26 +3,22 @@ namespace Processor { struct SPC700 { - virtual auto read(uint16 addr) -> uint8 = 0; - virtual auto write(uint16 addr, uint8 data) -> void = 0; + virtual auto read(uint16 address) -> uint8 = 0; + virtual auto write(uint16 addessr, uint8 data) -> void = 0; virtual auto synchronizing() const -> bool = 0; - virtual auto readDisassembler(uint16 addr) -> uint8 { return 0; } + virtual auto readDisassembler(uint16 address) -> uint8 { return 0; } //spc700.cpp + inline auto idle(uint16 address) -> void; + inline auto page(uint8 address) const -> uint16; + inline auto stack(uint8 address) const -> uint16; + auto power() -> void; //instruction.cpp auto instruction() -> void; - //memory.cpp - auto idle() -> void; - auto fetch() -> uint8; - auto pull() -> uint8; - auto push(uint8 data) -> void; - auto load(uint8 addr) -> uint8; - auto store(uint8 addr, uint8 data) -> void; - //algorithms.cpp auto algorithmADC(uint8, uint8) -> uint8; auto algorithmAND(uint8, uint8) -> uint8; @@ -49,12 +45,25 @@ struct SPC700 { using fpw = auto (SPC700::*)(uint16, uint16) -> uint16; auto instructionAbsoluteBitModify(uint3) -> void; + auto instructionAbsoluteBitSet(uint3, bool) -> void; auto instructionAbsoluteRead(fpb, uint8&) -> void; auto instructionAbsoluteModify(fps) -> void; auto instructionAbsoluteWrite(uint8&) -> void; auto instructionAbsoluteIndexedRead(fpb, uint8&) -> void; auto instructionAbsoluteIndexedWrite(uint8&) -> void; auto instructionBranch(bool) -> void; + auto instructionBranchBit(uint3, bool) -> void; + auto instructionBranchNotDirect() -> void; + auto instructionBranchNotDirectDecrement() -> void; + auto instructionBranchNotDirectX() -> void; + auto instructionBranchNotYDecrement() -> void; + auto instructionBreak() -> void; + auto instructionCallAbsolute() -> void; + auto instructionCallPage() -> void; + auto instructionCallTable(uint4) -> void; + auto instructionComplementCarry() -> void; + auto instructionDecimalAdjustAdd() -> void; + auto instructionDecimalAdjustSub() -> void; auto instructionDirectRead(fpb, uint8&) -> void; auto instructionDirectModify(fps) -> void; auto instructionDirectWrite(uint8&) -> void; @@ -62,11 +71,13 @@ struct SPC700 { auto instructionDirectWriteImmediate(fpb) -> void; auto instructionDirectReadWord(fpw) -> void; auto instructionDirectModifyWord(int) -> void; + auto instructionDirectWriteWord() -> void; auto instructionDirectIndexedRead(fpb, uint8&, uint8&) -> void; auto instructionDirectIndexedModify(fps, uint8&) -> void; auto instructionDirectIndexedWrite(uint8&, uint8&) -> void; - auto instructionFlagClear(bool&) -> void; - auto instructionFlagSet(bool&) -> void; + auto instructionDivide() -> void; + auto instructionExchangeNibble() -> void; + auto instructionFlagSet(bool&, bool) -> void; auto instructionImmediateRead(fpb, uint8&) -> void; auto instructionImpliedModify(fps, uint8&) -> void; auto instructionIndexedIndirectRead(fpb, uint8&) -> void; @@ -78,46 +89,26 @@ struct SPC700 { auto instructionIndirectXIncrementRead(uint8&) -> void; auto instructionIndirectXIncrementWrite(uint8&) -> void; auto instructionIndirectXWriteIndirectY(fpb) -> void; + auto instructionJumpAbsolute() -> void; + auto instructionJumpIndirectX() -> void; + auto instructionMultiply() -> void; + auto instructionNoOperation() -> void; + auto instructionOverflowClear() -> void; auto instructionPull(uint8&) -> void; + auto instructionPullP() -> void; auto instructionPush(uint8) -> void; + auto instructionReturnInterrupt() -> void; + auto instructionReturnSubroutine() -> void; + auto instructionStop() -> void; + auto instructionTestSetBitsAbsolute(bool) -> void; auto instructionTransfer(uint8&, uint8&) -> void; - - auto instructionBBC(uint3) -> void; - auto instructionBBS(uint3) -> void; - auto instructionBNEDirect() -> void; - auto instructionBNEDirectDecrement() -> void; - auto instructionBNEDirectX() -> void; - auto instructionBNEYDecrement() -> void; - auto instructionBRK() -> void; - auto instructionCLR(uint3) -> void; - auto instructionCLV() -> void; - auto instructionCMC() -> void; - auto instructionDAA() -> void; - auto instructionDAS() -> void; - auto instructionDIV() -> void; - auto instructionJMPAbsolute() -> void; - auto instructionJMPIndirectX() -> void; - auto instructionJSPDirect() -> void; - auto instructionJSRAbsolute() -> void; - auto instructionJST(uint4) -> void; - auto instructionMUL() -> void; - auto instructionNOP() -> void; - auto instructionPLP() -> void; - auto instructionRTI() -> void; - auto instructionRTS() -> void; - auto instructionSET(uint3) -> void; - auto instructionSTP() -> void; - auto instructionSTWDirect() -> void; - auto instructionTRBAbsolute() -> void; - auto instructionTSBAbsolute() -> void; - auto instructionWAI() -> void; - auto instructionXCN() -> void; + auto instructionWait() -> void; //serialization.cpp auto serialize(serializer&) -> void; //disassembler.cpp - auto disassemble(uint16 addr, bool p) -> string; + auto disassemble(uint16 address, bool p) -> string; struct Flags { bool c; //carry @@ -155,8 +146,8 @@ struct SPC700 { uint8 x, s; Flags p; - bool wai = false; - bool stp = false; + bool wait = false; + bool stop = false; } r; }; diff --git a/higan/sfc/smp/smp.cpp b/higan/sfc/smp/smp.cpp index eda23318..b53f5001 100644 --- a/higan/sfc/smp/smp.cpp +++ b/higan/sfc/smp/smp.cpp @@ -17,8 +17,8 @@ auto SMP::Enter() -> void { } auto SMP::main() -> void { - if(r.wai) return instructionWAI(); - if(r.stp) return instructionSTP(); + if(r.wait) return instructionWait(); + if(r.stop) return instructionStop(); instruction(); }