Update to v103r03 release.

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.
This commit is contained in:
Tim Allen 2017-06-28 17:24:46 +10:00
parent 3517d5c4a4
commit 78f341489e
10 changed files with 561 additions and 610 deletions

View File

@ -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/";

View File

@ -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);

View File

@ -54,6 +54,7 @@ auto M68K::instructionABCD(EffectiveAddress with, EffectiveAddress from) -> void
auto source = read<Byte>(from);
auto target = read<Byte, Hold>(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<Byte>(with, result);
r.c = sign<Byte>(result >> 1) < 0;
r.c = c;
r.v = v;
r.z = clip<Byte>(result) ? 0 : r.z;
r.n = sign<Byte>(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<Byte, Hold>(with);
auto source = read<Byte, Hold>(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<Byte>(with, result);
r.c = sign<Byte>(result >> 1) < 0;
r.c = c;
r.v = v;
r.z = clip<Byte>(result) ? 0 : r.z;
r.n = sign<Byte>(result) < 0;
r.x = r.c;
}
template<uint Size> auto M68K::instructionNEG(EffectiveAddress with) -> void {
@ -1011,6 +1017,7 @@ auto M68K::instructionSBCD(EffectiveAddress with, EffectiveAddress from) -> void
auto source = read<Byte>(from);
auto target = read<Byte, Hold>(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<Byte>(with, result);
r.c = sign<Byte>(result >> 1) < 0;
r.c = c;
r.v = v;
r.z = clip<Byte>(result) ? 0 : r.z;
r.n = sign<Byte>(result) < 0;
r.x = r.c;
}
auto M68K::instructionSCC(uint4 condition, EffectiveAddress to) -> void {

View File

@ -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)
}
}

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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;
}
}

View File

@ -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;
};

View File

@ -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();
}