mirror of https://github.com/bsnes-emu/bsnes.git
Update to v102r26 release.
byuu says: Changelog: - md/ym2612: initialize DAC sample to center volume [Cydrak] - processor/arm: add accumulate mode extra cycle to mlal [Jonas Quinn] - processor/huc6280: split off algorithms, improve naming of functions - processor/mos6502: split off algorithms - processor/spc700: major revamp of entire core (~50% completed) - processor/wdc65816: fixed several bugs introduced by rewrite For the SPC700, this turns out to be very old code as well, with global object state variables, those annoying `{Boolean,Natural}BitField` types, `under_case` naming conventions, heavily abbreviated function names, etc. I'm working to get the code to be in the same design as the MOS6502, HuC6280, WDC65816 cores, since they're all extremely similar in terms of architectural design (the SPC700 is more of an off-label reimplementation of a 6502 core, but still.) The main thing left is that about 90% of the actual instructions still need to be adapted to not use the internal state (`aa`, `rd`, `dp`, `sp`, `bit` variables.) I wanted to finish this today, but ran out of time before work. I wouldn't suggest too much testing just yet. We should wait until the SPC700 core is finished for that. However, if some does want to and spots regressions, please let me know.
This commit is contained in:
parent
b73d918776
commit
50411a17d1
|
@ -12,7 +12,7 @@ using namespace nall;
|
||||||
|
|
||||||
namespace Emulator {
|
namespace Emulator {
|
||||||
static const string Name = "higan";
|
static const string Name = "higan";
|
||||||
static const string Version = "102.25";
|
static const string Version = "102.26";
|
||||||
static const string Author = "byuu";
|
static const string Author = "byuu";
|
||||||
static const string License = "GPLv3";
|
static const string License = "GPLv3";
|
||||||
static const string Website = "http://byuu.org/";
|
static const string Website = "http://byuu.org/";
|
||||||
|
|
|
@ -32,7 +32,7 @@ private:
|
||||||
|
|
||||||
struct DAC {
|
struct DAC {
|
||||||
uint1 enable = 0;
|
uint1 enable = 0;
|
||||||
uint8 sample = 0;
|
uint8 sample = 0x80;
|
||||||
} dac;
|
} dac;
|
||||||
|
|
||||||
struct Envelope {
|
struct Envelope {
|
||||||
|
|
|
@ -108,6 +108,7 @@ auto ARM::arm_op_multiply_long() {
|
||||||
|
|
||||||
idle();
|
idle();
|
||||||
idle();
|
idle();
|
||||||
|
if(accumulate) idle();
|
||||||
|
|
||||||
//this instruction uses an 8-bit Booth algorithm for multiplication
|
//this instruction uses an 8-bit Booth algorithm for multiplication
|
||||||
//this supports short-circuiting, so that smaller numbers multiply faster
|
//this supports short-circuiting, so that smaller numbers multiply faster
|
||||||
|
|
|
@ -0,0 +1,184 @@
|
||||||
|
auto HuC6280::algorithmADC(uint8 i) -> uint8 {
|
||||||
|
int16 o;
|
||||||
|
if(!D) {
|
||||||
|
o = A + i + C;
|
||||||
|
V = ~(A ^ i) & (A ^ o) & 0x80;
|
||||||
|
} else {
|
||||||
|
io();
|
||||||
|
o = (A & 0x0f) + (i & 0x0f) + (C << 0);
|
||||||
|
if(o > 0x09) o += 0x06;
|
||||||
|
C = o > 0x0f;
|
||||||
|
o = (A & 0xf0) + (i & 0xf0) + (C << 4) + (o & 0x0f);
|
||||||
|
if(o > 0x9f) o += 0x60;
|
||||||
|
}
|
||||||
|
C = o.bit(8);
|
||||||
|
Z = uint8(o) == 0;
|
||||||
|
N = o.bit(7);
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto HuC6280::algorithmAND(uint8 i) -> uint8 {
|
||||||
|
uint8 o = A & i;
|
||||||
|
Z = o == 0;
|
||||||
|
N = o.bit(7);
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto HuC6280::algorithmASL(uint8 i) -> uint8 {
|
||||||
|
C = i.bit(7);
|
||||||
|
i <<= 1;
|
||||||
|
Z = i == 0;
|
||||||
|
N = i.bit(7);
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto HuC6280::algorithmBIT(uint8 i) -> uint8 {
|
||||||
|
Z = (A & i) == 0;
|
||||||
|
V = i.bit(6);
|
||||||
|
N = i.bit(7);
|
||||||
|
return A;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto HuC6280::algorithmCMP(uint8 i) -> uint8 {
|
||||||
|
uint9 o = A - i;
|
||||||
|
C = !o.bit(8);
|
||||||
|
Z = uint8(o) == 0;
|
||||||
|
N = o.bit(7);
|
||||||
|
return A;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto HuC6280::algorithmCPX(uint8 i) -> uint8 {
|
||||||
|
uint9 o = X - i;
|
||||||
|
C = !o.bit(8);
|
||||||
|
Z = uint8(o) == 0;
|
||||||
|
N = o.bit(7);
|
||||||
|
return X;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto HuC6280::algorithmCPY(uint8 i) -> uint8 {
|
||||||
|
uint9 o = Y - i;
|
||||||
|
C = !o.bit(8);
|
||||||
|
Z = uint8(o) == 0;
|
||||||
|
N = o.bit(7);
|
||||||
|
return Y;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto HuC6280::algorithmDEC(uint8 i) -> uint8 {
|
||||||
|
i--;
|
||||||
|
Z = i == 0;
|
||||||
|
N = i.bit(7);
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto HuC6280::algorithmEOR(uint8 i) -> uint8 {
|
||||||
|
uint8 o = A ^ i;
|
||||||
|
Z = o == 0;
|
||||||
|
N = o.bit(7);
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto HuC6280::algorithmINC(uint8 i) -> uint8 {
|
||||||
|
i++;
|
||||||
|
Z = i == 0;
|
||||||
|
N = i.bit(7);
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto HuC6280::algorithmLD(uint8 i) -> uint8 {
|
||||||
|
Z = i == 0;
|
||||||
|
N = i.bit(7);
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto HuC6280::algorithmLSR(uint8 i) -> uint8 {
|
||||||
|
C = i.bit(0);
|
||||||
|
i >>= 1;
|
||||||
|
Z = i == 0;
|
||||||
|
N = i.bit(7);
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto HuC6280::algorithmORA(uint8 i) -> uint8 {
|
||||||
|
uint8 o = A | i;
|
||||||
|
Z = o == 0;
|
||||||
|
N = o.bit(7);
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto HuC6280::algorithmROL(uint8 i) -> uint8 {
|
||||||
|
bool c = C;
|
||||||
|
C = i.bit(7);
|
||||||
|
i = i << 1 | c;
|
||||||
|
Z = i == 0;
|
||||||
|
N = i.bit(7);
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto HuC6280::algorithmROR(uint8 i) -> uint8 {
|
||||||
|
bool c = C;
|
||||||
|
C = i.bit(0);
|
||||||
|
i = c << 7 | i >> 1;
|
||||||
|
Z = i == 0;
|
||||||
|
N = i.bit(7);
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto HuC6280::algorithmSBC(uint8 i) -> uint8 {
|
||||||
|
i ^= 0xff;
|
||||||
|
int16 o;
|
||||||
|
if(!D) {
|
||||||
|
o = A + i + C;
|
||||||
|
V = ~(A ^ i) & (A ^ o) & 0x80;
|
||||||
|
} else {
|
||||||
|
io();
|
||||||
|
o = (A & 0x0f) + (i & 0x0f) + (C << 0);
|
||||||
|
if(o <= 0x0f) o -= 0x06;
|
||||||
|
C = o > 0x0f;
|
||||||
|
o = (A & 0xf0) + (i & 0xf0) + (C << 4) + (o & 0x0f);
|
||||||
|
if(o <= 0xff) o -= 0x60;
|
||||||
|
}
|
||||||
|
C = o.bit(8);
|
||||||
|
Z = uint8(o) == 0;
|
||||||
|
N = o.bit(7);
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto HuC6280::algorithmTRB(uint8 i) -> uint8 {
|
||||||
|
Z = (A & i) == 0;
|
||||||
|
V = i.bit(6);
|
||||||
|
N = i.bit(7);
|
||||||
|
return ~A & i;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto HuC6280::algorithmTSB(uint8 i) -> uint8 {
|
||||||
|
Z = (A & i) == 0;
|
||||||
|
V = i.bit(6);
|
||||||
|
N = i.bit(7);
|
||||||
|
return A | i;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
auto HuC6280::algorithmTAI(uint16& source, uint16& target, bool alternate) -> void {
|
||||||
|
!alternate ? source++ : source--;
|
||||||
|
target++;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto HuC6280::algorithmTDD(uint16& source, uint16& target, bool) -> void {
|
||||||
|
source--;
|
||||||
|
target--;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto HuC6280::algorithmTIA(uint16& source, uint16& target, bool alternate) -> void {
|
||||||
|
source++;
|
||||||
|
!alternate ? target++ : target--;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto HuC6280::algorithmTII(uint16& source, uint16& target, bool) -> void {
|
||||||
|
source++;
|
||||||
|
target++;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto HuC6280::algorithmTIN(uint16& source, uint16& target, bool) -> void {
|
||||||
|
source++;
|
||||||
|
}
|
|
@ -24,6 +24,7 @@ namespace Processor {
|
||||||
#define ALU (this->*alu)
|
#define ALU (this->*alu)
|
||||||
|
|
||||||
#include "memory.cpp"
|
#include "memory.cpp"
|
||||||
|
#include "algorithms.cpp"
|
||||||
#include "instruction.cpp"
|
#include "instruction.cpp"
|
||||||
#include "instructions.cpp"
|
#include "instructions.cpp"
|
||||||
#include "disassembler.cpp"
|
#include "disassembler.cpp"
|
||||||
|
|
|
@ -27,82 +27,83 @@ struct HuC6280 {
|
||||||
auto push(uint8) -> void;
|
auto push(uint8) -> void;
|
||||||
auto pull() -> uint8;
|
auto pull() -> uint8;
|
||||||
|
|
||||||
|
//instructions.cpp
|
||||||
|
using fp = auto (HuC6280::*)(uint8) -> uint8;
|
||||||
|
auto algorithmADC(uint8) -> uint8;
|
||||||
|
auto algorithmAND(uint8) -> uint8;
|
||||||
|
auto algorithmASL(uint8) -> uint8;
|
||||||
|
auto algorithmBIT(uint8) -> uint8;
|
||||||
|
auto algorithmCMP(uint8) -> uint8;
|
||||||
|
auto algorithmCPX(uint8) -> uint8;
|
||||||
|
auto algorithmCPY(uint8) -> uint8;
|
||||||
|
auto algorithmDEC(uint8) -> uint8;
|
||||||
|
auto algorithmEOR(uint8) -> uint8;
|
||||||
|
auto algorithmINC(uint8) -> uint8;
|
||||||
|
auto algorithmLD (uint8) -> uint8;
|
||||||
|
auto algorithmLSR(uint8) -> uint8;
|
||||||
|
auto algorithmORA(uint8) -> uint8;
|
||||||
|
auto algorithmROL(uint8) -> uint8;
|
||||||
|
auto algorithmROR(uint8) -> uint8;
|
||||||
|
auto algorithmSBC(uint8) -> uint8;
|
||||||
|
auto algorithmTRB(uint8) -> uint8;
|
||||||
|
auto algorithmTSB(uint8) -> uint8;
|
||||||
|
|
||||||
|
using bp = auto (HuC6280::*)(uint16&, uint16&, bool) -> void;
|
||||||
|
auto algorithmTAI(uint16&, uint16&, bool) -> void;
|
||||||
|
auto algorithmTDD(uint16&, uint16&, bool) -> void;
|
||||||
|
auto algorithmTIA(uint16&, uint16&, bool) -> void;
|
||||||
|
auto algorithmTII(uint16&, uint16&, bool) -> void;
|
||||||
|
auto algorithmTIN(uint16&, uint16&, bool) -> void;
|
||||||
|
|
||||||
//instruction.cpp
|
//instruction.cpp
|
||||||
auto interrupt(uint16 vector) -> void;
|
auto interrupt(uint16 vector) -> void;
|
||||||
auto instruction() -> void;
|
auto instruction() -> void;
|
||||||
|
|
||||||
//instructions.cpp
|
//instructions.cpp
|
||||||
using fp = auto (HuC6280::*)(uint8) -> uint8;
|
auto instructionAbsoluteModify(fp, uint8 = 0) -> void;
|
||||||
auto ADC(uint8) -> uint8;
|
auto instructionAbsoluteRead(fp, uint8&, uint8 = 0) -> void;
|
||||||
auto AND(uint8) -> uint8;
|
auto instructionAbsoluteWrite(uint8, uint8 = 0) -> void;
|
||||||
auto ASL(uint8) -> uint8;
|
auto instructionBlockMove(bp) -> void;
|
||||||
auto BIT(uint8) -> uint8;
|
auto instructionBranch(bool) -> void;
|
||||||
auto CMP(uint8) -> uint8;
|
auto instructionClear(uint8&) -> void;
|
||||||
auto CPX(uint8) -> uint8;
|
auto instructionClear(bool&) -> void;
|
||||||
auto CPY(uint8) -> uint8;
|
auto instructionImmediate(fp, uint8&) -> void;
|
||||||
auto DEC(uint8) -> uint8;
|
auto instructionImplied(fp, uint8&) -> void;
|
||||||
auto EOR(uint8) -> uint8;
|
auto instructionIndirectRead(fp, uint8&, uint8 = 0) -> void;
|
||||||
auto INC(uint8) -> uint8;
|
auto instructionIndirectWrite(uint8, uint8 = 0) -> void;
|
||||||
auto LD (uint8) -> uint8;
|
auto instructionIndirectYRead(fp, uint8&) -> void;
|
||||||
auto LSR(uint8) -> uint8;
|
auto instructionIndirectYWrite(uint8) -> void;
|
||||||
auto ORA(uint8) -> uint8;
|
auto instructionMemory(fp) -> void;
|
||||||
auto ROL(uint8) -> uint8;
|
auto instructionPull(uint8&) -> void;
|
||||||
auto ROR(uint8) -> uint8;
|
auto instructionPush(uint8) -> void;
|
||||||
auto SBC(uint8) -> uint8;
|
auto instructionSet(bool&) -> void;
|
||||||
auto TRB(uint8) -> uint8;
|
auto instructionSwap(uint8&, uint8&) -> void;
|
||||||
auto TSB(uint8) -> uint8;
|
auto instructionTransfer(uint8&, uint8&) -> void;
|
||||||
|
auto instructionZeroPageModify(fp, uint8 = 0) -> void;
|
||||||
|
auto instructionZeroPageRead(fp, uint8&, uint8 = 0) -> void;
|
||||||
|
auto instructionZeroPageWrite(uint8, uint8 = 0) -> void;
|
||||||
|
|
||||||
using bp = auto (HuC6280::*)(uint16&, uint16&, bool) -> void;
|
auto instructionBBR(uint3) -> void;
|
||||||
auto TAI(uint16&, uint16&, bool) -> void;
|
auto instructionBBS(uint3) -> void;
|
||||||
auto TDD(uint16&, uint16&, bool) -> void;
|
auto instructionBRK() -> void;
|
||||||
auto TIA(uint16&, uint16&, bool) -> void;
|
auto instructionBSR() -> void;
|
||||||
auto TII(uint16&, uint16&, bool) -> void;
|
auto instructionCSL() -> void;
|
||||||
auto TIN(uint16&, uint16&, bool) -> void;
|
auto instructionCSH() -> void;
|
||||||
|
auto instructionJMPAbsolute() -> void;
|
||||||
auto instruction_absoluteLoad(fp, uint8&, uint8 = 0) -> void;
|
auto instructionJMPIndirect(uint8 = 0) -> void;
|
||||||
auto instruction_absoluteModify(fp, uint8 = 0) -> void;
|
auto instructionJSR() -> void;
|
||||||
auto instruction_absoluteStore(uint8, uint8 = 0) -> void;
|
auto instructionNOP() -> void;
|
||||||
auto instruction_blockmove(bp) -> void;
|
auto instructionPLP() -> void;
|
||||||
auto instruction_branch(bool) -> void;
|
auto instructionRMB(uint3) -> void;
|
||||||
auto instruction_clear(uint8&) -> void;
|
auto instructionRTI() -> void;
|
||||||
auto instruction_clear(bool&) -> void;
|
auto instructionRTS() -> void;
|
||||||
auto instruction_immediate(fp, uint8&) -> void;
|
auto instructionSMB(uint3) -> void;
|
||||||
auto instruction_implied(fp, uint8&) -> void;
|
auto instructionST(uint2) -> void;
|
||||||
auto instruction_indirectLoad(fp, uint8&, uint8 = 0) -> void;
|
auto instructionTAM() -> void;
|
||||||
auto instruction_indirectStore(uint8, uint8 = 0) -> void;
|
auto instructionTMA() -> void;
|
||||||
auto instruction_indirectYLoad(fp, uint8&) -> void;
|
auto instructionTSTAbsolute(uint8 = 0) -> void;
|
||||||
auto instruction_indirectYStore(uint8) -> void;
|
auto instructionTSTZeroPage(uint8 = 0) -> void;
|
||||||
auto instruction_memory(fp) -> void;
|
auto instructionTXS() -> void;
|
||||||
auto instruction_pull(uint8&) -> void;
|
|
||||||
auto instruction_push(uint8) -> void;
|
|
||||||
auto instruction_set(bool&) -> void;
|
|
||||||
auto instruction_swap(uint8&, uint8&) -> void;
|
|
||||||
auto instruction_transfer(uint8&, uint8&) -> void;
|
|
||||||
auto instruction_zeropageLoad(fp, uint8&, uint8 = 0) -> void;
|
|
||||||
auto instruction_zeropageModify(fp, uint8 = 0) -> void;
|
|
||||||
auto instruction_zeropageStore(uint8, uint8 = 0) -> void;
|
|
||||||
|
|
||||||
auto instruction_BBR(uint3) -> void;
|
|
||||||
auto instruction_BBS(uint3) -> void;
|
|
||||||
auto instruction_BRK() -> void;
|
|
||||||
auto instruction_BSR() -> void;
|
|
||||||
auto instruction_CSL() -> void;
|
|
||||||
auto instruction_CSH() -> void;
|
|
||||||
auto instruction_JMP_absolute() -> void;
|
|
||||||
auto instruction_JMP_indirect(uint8 = 0) -> void;
|
|
||||||
auto instruction_JSR() -> void;
|
|
||||||
auto instruction_NOP() -> void;
|
|
||||||
auto instruction_PLP() -> void;
|
|
||||||
auto instruction_RMB(uint3) -> void;
|
|
||||||
auto instruction_RTI() -> void;
|
|
||||||
auto instruction_RTS() -> void;
|
|
||||||
auto instruction_SMB(uint3) -> void;
|
|
||||||
auto instruction_ST(uint2) -> void;
|
|
||||||
auto instruction_TAM() -> void;
|
|
||||||
auto instruction_TMA() -> void;
|
|
||||||
auto instruction_TST_absolute(uint8 = 0) -> void;
|
|
||||||
auto instruction_TST_zeropage(uint8 = 0) -> void;
|
|
||||||
auto instruction_TXS() -> void;
|
|
||||||
|
|
||||||
//disassembler.cpp
|
//disassembler.cpp
|
||||||
auto disassemble(uint16 pc) -> string;
|
auto disassemble(uint16 pc) -> string;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#define op(id, name, ...) case id: instruction_##name(__VA_ARGS__); return;
|
#define op(id, name, ...) case id: return instruction##name(__VA_ARGS__);
|
||||||
#define fp(name) &HuC6280::name
|
#define fp(name) &HuC6280::algorithm##name
|
||||||
|
|
||||||
auto HuC6280::interrupt(uint16 vector) -> void {
|
auto HuC6280::interrupt(uint16 vector) -> void {
|
||||||
io();
|
io();
|
||||||
|
@ -19,270 +19,270 @@ auto HuC6280::instruction() -> void {
|
||||||
if(T) {
|
if(T) {
|
||||||
T = 0;
|
T = 0;
|
||||||
switch(code) {
|
switch(code) {
|
||||||
op(0x09, memory, fp(ORA))
|
op(0x09, Memory, fp(ORA))
|
||||||
op(0x29, memory, fp(AND))
|
op(0x29, Memory, fp(AND))
|
||||||
op(0x49, memory, fp(EOR))
|
op(0x49, Memory, fp(EOR))
|
||||||
op(0x69, memory, fp(ADC))
|
op(0x69, Memory, fp(ADC))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define U
|
#define U
|
||||||
switch(code) {
|
switch(code) {
|
||||||
op(0x00, BRK)
|
op(0x00, BRK)
|
||||||
op(0x01, indirectLoad, fp(ORA), A, X)
|
op(0x01, IndirectRead, fp(ORA), A, X)
|
||||||
op(0x02, swap, X, Y)
|
op(0x02, Swap, X, Y)
|
||||||
op(0x03, ST, 0)
|
op(0x03, ST, 0)
|
||||||
op(0x04, zeropageModify, fp(TSB))
|
op(0x04, ZeroPageModify, fp(TSB))
|
||||||
op(0x05, zeropageLoad, fp(ORA), A)
|
op(0x05, ZeroPageRead, fp(ORA), A)
|
||||||
op(0x06, zeropageModify, fp(ASL))
|
op(0x06, ZeroPageModify, fp(ASL))
|
||||||
op(0x07, RMB, 0)
|
op(0x07, RMB, 0)
|
||||||
op(0x08, push, P)
|
op(0x08, Push, P)
|
||||||
op(0x09, immediate, fp(ORA), A)
|
op(0x09, Immediate, fp(ORA), A)
|
||||||
op(0x0a, implied, fp(ASL), A)
|
op(0x0a, Implied, fp(ASL), A)
|
||||||
U op(0x0b, NOP)
|
U op(0x0b, NOP)
|
||||||
op(0x0c, absoluteModify, fp(TSB))
|
op(0x0c, AbsoluteModify, fp(TSB))
|
||||||
op(0x0d, absoluteLoad, fp(ORA), A)
|
op(0x0d, AbsoluteRead, fp(ORA), A)
|
||||||
op(0x0e, absoluteModify, fp(ASL))
|
op(0x0e, AbsoluteModify, fp(ASL))
|
||||||
op(0x0f, BBR, 0)
|
op(0x0f, BBR, 0)
|
||||||
op(0x10, branch, N == 0)
|
op(0x10, Branch, N == 0)
|
||||||
op(0x11, indirectYLoad, fp(ORA), A)
|
op(0x11, IndirectYRead, fp(ORA), A)
|
||||||
op(0x12, indirectLoad, fp(ORA), A)
|
op(0x12, IndirectRead, fp(ORA), A)
|
||||||
op(0x13, ST, 1)
|
op(0x13, ST, 1)
|
||||||
op(0x14, zeropageModify, fp(TRB))
|
op(0x14, ZeroPageModify, fp(TRB))
|
||||||
op(0x15, zeropageLoad, fp(ORA), A, X)
|
op(0x15, ZeroPageRead, fp(ORA), A, X)
|
||||||
op(0x16, zeropageModify, fp(ASL), X)
|
op(0x16, ZeroPageModify, fp(ASL), X)
|
||||||
op(0x17, RMB, 1)
|
op(0x17, RMB, 1)
|
||||||
op(0x18, clear, C)
|
op(0x18, Clear, C)
|
||||||
op(0x19, absoluteLoad, fp(ORA), A, Y)
|
op(0x19, AbsoluteRead, fp(ORA), A, Y)
|
||||||
op(0x1a, implied, fp(INC), A)
|
op(0x1a, Implied, fp(INC), A)
|
||||||
U op(0x1b, NOP)
|
U op(0x1b, NOP)
|
||||||
op(0x1c, absoluteModify, fp(TRB))
|
op(0x1c, AbsoluteModify, fp(TRB))
|
||||||
op(0x1d, absoluteLoad, fp(ORA), A, X)
|
op(0x1d, AbsoluteRead, fp(ORA), A, X)
|
||||||
op(0x1e, absoluteModify, fp(ASL), X)
|
op(0x1e, AbsoluteModify, fp(ASL), X)
|
||||||
op(0x1f, BBR, 1)
|
op(0x1f, BBR, 1)
|
||||||
op(0x20, JSR)
|
op(0x20, JSR)
|
||||||
op(0x21, indirectLoad, fp(AND), A, X)
|
op(0x21, IndirectRead, fp(AND), A, X)
|
||||||
op(0x22, swap, A, X)
|
op(0x22, Swap, A, X)
|
||||||
op(0x23, ST, 2)
|
op(0x23, ST, 2)
|
||||||
op(0x24, zeropageLoad, fp(BIT), A)
|
op(0x24, ZeroPageRead, fp(BIT), A)
|
||||||
op(0x25, zeropageLoad, fp(AND), A)
|
op(0x25, ZeroPageRead, fp(AND), A)
|
||||||
op(0x26, zeropageModify, fp(ROL))
|
op(0x26, ZeroPageModify, fp(ROL))
|
||||||
op(0x27, RMB, 2)
|
op(0x27, RMB, 2)
|
||||||
op(0x28, PLP)
|
op(0x28, PLP)
|
||||||
op(0x29, immediate, fp(AND), A)
|
op(0x29, Immediate, fp(AND), A)
|
||||||
op(0x2a, implied, fp(ROL), A)
|
op(0x2a, Implied, fp(ROL), A)
|
||||||
U op(0x2b, NOP)
|
U op(0x2b, NOP)
|
||||||
op(0x2c, absoluteLoad, fp(BIT), A)
|
op(0x2c, AbsoluteRead, fp(BIT), A)
|
||||||
op(0x2d, absoluteLoad, fp(AND), A)
|
op(0x2d, AbsoluteRead, fp(AND), A)
|
||||||
op(0x2e, absoluteModify, fp(ROL))
|
op(0x2e, AbsoluteModify, fp(ROL))
|
||||||
op(0x2f, BBR, 2)
|
op(0x2f, BBR, 2)
|
||||||
op(0x30, branch, N == 1)
|
op(0x30, Branch, N == 1)
|
||||||
op(0x31, indirectYLoad, fp(AND), A)
|
op(0x31, IndirectYRead, fp(AND), A)
|
||||||
op(0x32, indirectLoad, fp(AND), A)
|
op(0x32, IndirectRead, fp(AND), A)
|
||||||
U op(0x33, NOP)
|
U op(0x33, NOP)
|
||||||
op(0x34, zeropageLoad, fp(BIT), A, X)
|
op(0x34, ZeroPageRead, fp(BIT), A, X)
|
||||||
op(0x35, zeropageLoad, fp(AND), A, X)
|
op(0x35, ZeroPageRead, fp(AND), A, X)
|
||||||
op(0x36, zeropageModify, fp(ROL), X)
|
op(0x36, ZeroPageModify, fp(ROL), X)
|
||||||
op(0x37, RMB, 3)
|
op(0x37, RMB, 3)
|
||||||
op(0x38, set, C)
|
op(0x38, Set, C)
|
||||||
op(0x39, absoluteLoad, fp(AND), A, Y)
|
op(0x39, AbsoluteRead, fp(AND), A, Y)
|
||||||
op(0x3a, implied, fp(DEC), A)
|
op(0x3a, Implied, fp(DEC), A)
|
||||||
U op(0x3b, NOP)
|
U op(0x3b, NOP)
|
||||||
op(0x3c, absoluteLoad, fp(BIT), A, X)
|
op(0x3c, AbsoluteRead, fp(BIT), A, X)
|
||||||
op(0x3d, absoluteLoad, fp(AND), A, X)
|
op(0x3d, AbsoluteRead, fp(AND), A, X)
|
||||||
op(0x3e, absoluteModify, fp(ROL), X)
|
op(0x3e, AbsoluteModify, fp(ROL), X)
|
||||||
op(0x3f, BBR, 3)
|
op(0x3f, BBR, 3)
|
||||||
op(0x40, RTI)
|
op(0x40, RTI)
|
||||||
op(0x41, indirectLoad, fp(EOR), A, X)
|
op(0x41, IndirectRead, fp(EOR), A, X)
|
||||||
op(0x42, swap, A, Y)
|
op(0x42, Swap, A, Y)
|
||||||
op(0x43, TMA)
|
op(0x43, TMA)
|
||||||
op(0x44, BSR)
|
op(0x44, BSR)
|
||||||
op(0x45, zeropageLoad, fp(EOR), A)
|
op(0x45, ZeroPageRead, fp(EOR), A)
|
||||||
op(0x46, zeropageModify, fp(LSR))
|
op(0x46, ZeroPageModify, fp(LSR))
|
||||||
op(0x47, RMB, 4)
|
op(0x47, RMB, 4)
|
||||||
op(0x48, push, A)
|
op(0x48, Push, A)
|
||||||
op(0x49, immediate, fp(EOR), A)
|
op(0x49, Immediate, fp(EOR), A)
|
||||||
op(0x4a, implied, fp(LSR), A)
|
op(0x4a, Implied, fp(LSR), A)
|
||||||
U op(0x4b, NOP)
|
U op(0x4b, NOP)
|
||||||
op(0x4c, JMP_absolute)
|
op(0x4c, JMPAbsolute)
|
||||||
op(0x4d, absoluteLoad, fp(EOR), A)
|
op(0x4d, AbsoluteRead, fp(EOR), A)
|
||||||
op(0x4e, absoluteModify, fp(LSR))
|
op(0x4e, AbsoluteModify, fp(LSR))
|
||||||
op(0x4f, BBR, 4)
|
op(0x4f, BBR, 4)
|
||||||
op(0x50, branch, V == 0)
|
op(0x50, Branch, V == 0)
|
||||||
op(0x51, indirectYLoad, fp(EOR), A)
|
op(0x51, IndirectYRead, fp(EOR), A)
|
||||||
op(0x52, indirectLoad, fp(EOR), A)
|
op(0x52, IndirectRead, fp(EOR), A)
|
||||||
op(0x53, TAM)
|
op(0x53, TAM)
|
||||||
op(0x54, CSL)
|
op(0x54, CSL)
|
||||||
op(0x55, zeropageLoad, fp(EOR), A, X)
|
op(0x55, ZeroPageRead, fp(EOR), A, X)
|
||||||
op(0x56, zeropageModify, fp(LSR), X)
|
op(0x56, ZeroPageModify, fp(LSR), X)
|
||||||
op(0x57, RMB, 5)
|
op(0x57, RMB, 5)
|
||||||
op(0x58, clear, I)
|
op(0x58, Clear, I)
|
||||||
op(0x59, absoluteLoad, fp(EOR), A, Y)
|
op(0x59, AbsoluteRead, fp(EOR), A, Y)
|
||||||
op(0x5a, push, Y)
|
op(0x5a, Push, Y)
|
||||||
U op(0x5b, NOP)
|
U op(0x5b, NOP)
|
||||||
U op(0x5c, NOP)
|
U op(0x5c, NOP)
|
||||||
op(0x5d, absoluteLoad, fp(EOR), A, X)
|
op(0x5d, AbsoluteRead, fp(EOR), A, X)
|
||||||
op(0x5e, absoluteModify, fp(LSR), X)
|
op(0x5e, AbsoluteModify, fp(LSR), X)
|
||||||
op(0x5f, BBR, 5)
|
op(0x5f, BBR, 5)
|
||||||
op(0x60, RTS)
|
op(0x60, RTS)
|
||||||
op(0x61, indirectLoad, fp(ADC), A, X)
|
op(0x61, IndirectRead, fp(ADC), A, X)
|
||||||
op(0x62, clear, A)
|
op(0x62, Clear, A)
|
||||||
U op(0x63, NOP)
|
U op(0x63, NOP)
|
||||||
op(0x64, zeropageStore, 0)
|
op(0x64, ZeroPageWrite, 0)
|
||||||
op(0x65, zeropageLoad, fp(ADC), A)
|
op(0x65, ZeroPageRead, fp(ADC), A)
|
||||||
op(0x66, zeropageModify, fp(ROR))
|
op(0x66, ZeroPageModify, fp(ROR))
|
||||||
op(0x67, RMB, 6)
|
op(0x67, RMB, 6)
|
||||||
op(0x68, pull, A)
|
op(0x68, Pull, A)
|
||||||
op(0x69, immediate, fp(ADC), A)
|
op(0x69, Immediate, fp(ADC), A)
|
||||||
op(0x6a, implied, fp(ROR), A)
|
op(0x6a, Implied, fp(ROR), A)
|
||||||
U op(0x6b, NOP)
|
U op(0x6b, NOP)
|
||||||
op(0x6c, JMP_indirect)
|
op(0x6c, JMPIndirect)
|
||||||
op(0x6d, absoluteLoad, fp(ADC), A)
|
op(0x6d, AbsoluteRead, fp(ADC), A)
|
||||||
op(0x6e, absoluteModify, fp(ROR))
|
op(0x6e, AbsoluteModify, fp(ROR))
|
||||||
op(0x6f, BBR, 6)
|
op(0x6f, BBR, 6)
|
||||||
op(0x70, branch, V == 1)
|
op(0x70, Branch, V == 1)
|
||||||
op(0x71, indirectYLoad, fp(ADC), A)
|
op(0x71, IndirectYRead, fp(ADC), A)
|
||||||
op(0x72, indirectLoad, fp(ADC), A)
|
op(0x72, IndirectRead, fp(ADC), A)
|
||||||
op(0x73, blockmove, fp(TII))
|
op(0x73, BlockMove, fp(TII))
|
||||||
op(0x74, zeropageStore, 0, X)
|
op(0x74, ZeroPageWrite, 0, X)
|
||||||
op(0x75, zeropageLoad, fp(ADC), A, X)
|
op(0x75, ZeroPageRead, fp(ADC), A, X)
|
||||||
op(0x76, zeropageModify, fp(ROR), X)
|
op(0x76, ZeroPageModify, fp(ROR), X)
|
||||||
op(0x77, RMB, 7)
|
op(0x77, RMB, 7)
|
||||||
op(0x78, set, I)
|
op(0x78, Set, I)
|
||||||
op(0x79, absoluteLoad, fp(ADC), A, Y)
|
op(0x79, AbsoluteRead, fp(ADC), A, Y)
|
||||||
op(0x7a, pull, Y)
|
op(0x7a, Pull, Y)
|
||||||
U op(0x7b, NOP)
|
U op(0x7b, NOP)
|
||||||
op(0x7c, JMP_indirect, X)
|
op(0x7c, JMPIndirect, X)
|
||||||
op(0x7d, absoluteLoad, fp(ADC), A, X)
|
op(0x7d, AbsoluteRead, fp(ADC), A, X)
|
||||||
op(0x7e, absoluteModify, fp(ROR), X)
|
op(0x7e, AbsoluteModify, fp(ROR), X)
|
||||||
op(0x7f, BBR, 7)
|
op(0x7f, BBR, 7)
|
||||||
op(0x80, branch, 1)
|
op(0x80, Branch, 1)
|
||||||
op(0x81, indirectStore, A, X)
|
op(0x81, IndirectWrite, A, X)
|
||||||
op(0x82, clear, X)
|
op(0x82, Clear, X)
|
||||||
op(0x83, TST_zeropage)
|
op(0x83, TSTZeroPage)
|
||||||
op(0x84, zeropageStore, Y)
|
op(0x84, ZeroPageWrite, Y)
|
||||||
op(0x85, zeropageStore, A)
|
op(0x85, ZeroPageWrite, A)
|
||||||
op(0x86, zeropageStore, X)
|
op(0x86, ZeroPageWrite, X)
|
||||||
op(0x87, SMB, 0)
|
op(0x87, SMB, 0)
|
||||||
op(0x88, implied, fp(DEC), Y)
|
op(0x88, Implied, fp(DEC), Y)
|
||||||
op(0x89, immediate, fp(BIT), A)
|
op(0x89, Immediate, fp(BIT), A)
|
||||||
op(0x8a, transfer, X, A)
|
op(0x8a, Transfer, X, A)
|
||||||
U op(0x8b, NOP)
|
U op(0x8b, NOP)
|
||||||
op(0x8c, absoluteStore, Y)
|
op(0x8c, AbsoluteWrite, Y)
|
||||||
op(0x8d, absoluteStore, A)
|
op(0x8d, AbsoluteWrite, A)
|
||||||
op(0x8e, absoluteStore, X)
|
op(0x8e, AbsoluteWrite, X)
|
||||||
op(0x8f, BBS, 0)
|
op(0x8f, BBS, 0)
|
||||||
op(0x90, branch, C == 0)
|
op(0x90, Branch, C == 0)
|
||||||
op(0x91, indirectYStore, A)
|
op(0x91, IndirectYWrite, A)
|
||||||
op(0x92, indirectStore, A)
|
op(0x92, IndirectWrite, A)
|
||||||
op(0x93, TST_absolute)
|
op(0x93, TSTAbsolute)
|
||||||
op(0x94, zeropageStore, Y, X)
|
op(0x94, ZeroPageWrite, Y, X)
|
||||||
op(0x95, zeropageStore, A, X)
|
op(0x95, ZeroPageWrite, A, X)
|
||||||
op(0x96, zeropageStore, X, Y)
|
op(0x96, ZeroPageWrite, X, Y)
|
||||||
op(0x97, SMB, 1)
|
op(0x97, SMB, 1)
|
||||||
op(0x98, transfer, Y, A)
|
op(0x98, Transfer, Y, A)
|
||||||
op(0x99, absoluteStore, A, Y)
|
op(0x99, AbsoluteWrite, A, Y)
|
||||||
op(0x9a, TXS)
|
op(0x9a, TXS)
|
||||||
U op(0x9b, NOP)
|
U op(0x9b, NOP)
|
||||||
op(0x9c, absoluteStore, 0)
|
op(0x9c, AbsoluteWrite, 0)
|
||||||
op(0x9d, absoluteStore, A, X)
|
op(0x9d, AbsoluteWrite, A, X)
|
||||||
op(0x9e, absoluteStore, 0, X)
|
op(0x9e, AbsoluteWrite, 0, X)
|
||||||
op(0x9f, BBS, 1)
|
op(0x9f, BBS, 1)
|
||||||
op(0xa0, immediate, fp(LD), Y)
|
op(0xa0, Immediate, fp(LD), Y)
|
||||||
op(0xa1, indirectLoad, fp(LD), A, X)
|
op(0xa1, IndirectRead, fp(LD), A, X)
|
||||||
op(0xa2, immediate, fp(LD), X)
|
op(0xa2, Immediate, fp(LD), X)
|
||||||
op(0xa3, TST_zeropage, X)
|
op(0xa3, TSTZeroPage, X)
|
||||||
op(0xa4, zeropageLoad, fp(LD), Y)
|
op(0xa4, ZeroPageRead, fp(LD), Y)
|
||||||
op(0xa5, zeropageLoad, fp(LD), A)
|
op(0xa5, ZeroPageRead, fp(LD), A)
|
||||||
op(0xa6, zeropageLoad, fp(LD), X)
|
op(0xa6, ZeroPageRead, fp(LD), X)
|
||||||
op(0xa7, SMB, 2)
|
op(0xa7, SMB, 2)
|
||||||
op(0xa8, transfer, A, Y)
|
op(0xa8, Transfer, A, Y)
|
||||||
op(0xa9, immediate, fp(LD), A)
|
op(0xa9, Immediate, fp(LD), A)
|
||||||
op(0xaa, transfer, A, X)
|
op(0xaa, Transfer, A, X)
|
||||||
U op(0xab, NOP)
|
U op(0xab, NOP)
|
||||||
op(0xac, absoluteLoad, fp(LD), Y)
|
op(0xac, AbsoluteRead, fp(LD), Y)
|
||||||
op(0xad, absoluteLoad, fp(LD), A)
|
op(0xad, AbsoluteRead, fp(LD), A)
|
||||||
op(0xae, absoluteLoad, fp(LD), X)
|
op(0xae, AbsoluteRead, fp(LD), X)
|
||||||
op(0xaf, BBS, 2)
|
op(0xaf, BBS, 2)
|
||||||
op(0xb0, branch, C == 1)
|
op(0xb0, Branch, C == 1)
|
||||||
op(0xb1, indirectYLoad, fp(LD), A)
|
op(0xb1, IndirectYRead, fp(LD), A)
|
||||||
op(0xb2, indirectLoad, fp(LD), A)
|
op(0xb2, IndirectRead, fp(LD), A)
|
||||||
op(0xb3, TST_absolute, X)
|
op(0xb3, TSTAbsolute, X)
|
||||||
op(0xb4, zeropageLoad, fp(LD), Y, X)
|
op(0xb4, ZeroPageRead, fp(LD), Y, X)
|
||||||
op(0xb5, zeropageLoad, fp(LD), A, X)
|
op(0xb5, ZeroPageRead, fp(LD), A, X)
|
||||||
op(0xb6, zeropageLoad, fp(LD), X, Y)
|
op(0xb6, ZeroPageRead, fp(LD), X, Y)
|
||||||
op(0xb7, SMB, 3)
|
op(0xb7, SMB, 3)
|
||||||
op(0xb8, clear, V)
|
op(0xb8, Clear, V)
|
||||||
op(0xb9, absoluteLoad, fp(LD), A, Y)
|
op(0xb9, AbsoluteRead, fp(LD), A, Y)
|
||||||
op(0xba, transfer, S, X)
|
op(0xba, Transfer, S, X)
|
||||||
U op(0xbb, NOP)
|
U op(0xbb, NOP)
|
||||||
op(0xbc, absoluteLoad, fp(LD), Y, X)
|
op(0xbc, AbsoluteRead, fp(LD), Y, X)
|
||||||
op(0xbd, absoluteLoad, fp(LD), A, X)
|
op(0xbd, AbsoluteRead, fp(LD), A, X)
|
||||||
op(0xbe, absoluteLoad, fp(LD), X, Y)
|
op(0xbe, AbsoluteRead, fp(LD), X, Y)
|
||||||
op(0xbf, BBS, 3)
|
op(0xbf, BBS, 3)
|
||||||
op(0xc0, immediate, fp(CPY), Y)
|
op(0xc0, Immediate, fp(CPY), Y)
|
||||||
op(0xc1, indirectLoad, fp(CMP), A, X)
|
op(0xc1, IndirectRead, fp(CMP), A, X)
|
||||||
op(0xc2, clear, Y)
|
op(0xc2, Clear, Y)
|
||||||
op(0xc3, blockmove, fp(TDD))
|
op(0xc3, BlockMove, fp(TDD))
|
||||||
op(0xc4, zeropageLoad, fp(CPY), Y)
|
op(0xc4, ZeroPageRead, fp(CPY), Y)
|
||||||
op(0xc5, zeropageLoad, fp(CMP), A)
|
op(0xc5, ZeroPageRead, fp(CMP), A)
|
||||||
op(0xc6, zeropageModify, fp(DEC))
|
op(0xc6, ZeroPageModify, fp(DEC))
|
||||||
op(0xc7, SMB, 4)
|
op(0xc7, SMB, 4)
|
||||||
op(0xc8, implied, fp(INC), Y)
|
op(0xc8, Implied, fp(INC), Y)
|
||||||
op(0xc9, immediate, fp(CMP), A)
|
op(0xc9, Immediate, fp(CMP), A)
|
||||||
op(0xca, implied, fp(DEC), X)
|
op(0xca, Implied, fp(DEC), X)
|
||||||
U op(0xcb, NOP)
|
U op(0xcb, NOP)
|
||||||
op(0xcc, absoluteLoad, fp(CPY), Y)
|
op(0xcc, AbsoluteRead, fp(CPY), Y)
|
||||||
op(0xcd, absoluteLoad, fp(CMP), A)
|
op(0xcd, AbsoluteRead, fp(CMP), A)
|
||||||
op(0xce, absoluteModify, fp(DEC))
|
op(0xce, AbsoluteModify, fp(DEC))
|
||||||
op(0xcf, BBS, 4)
|
op(0xcf, BBS, 4)
|
||||||
op(0xd0, branch, Z == 0)
|
op(0xd0, Branch, Z == 0)
|
||||||
op(0xd1, indirectYLoad, fp(CMP), A)
|
op(0xd1, IndirectYRead, fp(CMP), A)
|
||||||
op(0xd2, indirectLoad, fp(CMP), A)
|
op(0xd2, IndirectRead, fp(CMP), A)
|
||||||
op(0xd3, blockmove, fp(TIN))
|
op(0xd3, BlockMove, fp(TIN))
|
||||||
op(0xd4, CSH)
|
op(0xd4, CSH)
|
||||||
op(0xd5, zeropageLoad, fp(CMP), A, X)
|
op(0xd5, ZeroPageRead, fp(CMP), A, X)
|
||||||
op(0xd6, zeropageModify, fp(DEC), X)
|
op(0xd6, ZeroPageModify, fp(DEC), X)
|
||||||
op(0xd7, SMB, 5)
|
op(0xd7, SMB, 5)
|
||||||
op(0xd8, clear, D)
|
op(0xd8, Clear, D)
|
||||||
op(0xd9, absoluteLoad, fp(CMP), A, Y)
|
op(0xd9, AbsoluteRead, fp(CMP), A, Y)
|
||||||
op(0xda, push, X)
|
op(0xda, Push, X)
|
||||||
U op(0xdb, NOP)
|
U op(0xdb, NOP)
|
||||||
U op(0xdc, NOP)
|
U op(0xdc, NOP)
|
||||||
op(0xdd, absoluteLoad, fp(CMP), A, X)
|
op(0xdd, AbsoluteRead, fp(CMP), A, X)
|
||||||
op(0xde, absoluteModify, fp(DEC), X)
|
op(0xde, AbsoluteModify, fp(DEC), X)
|
||||||
op(0xdf, BBS, 5)
|
op(0xdf, BBS, 5)
|
||||||
op(0xe0, immediate, fp(CPX), X)
|
op(0xe0, Immediate, fp(CPX), X)
|
||||||
op(0xe1, indirectLoad, fp(SBC), A, X)
|
op(0xe1, IndirectRead, fp(SBC), A, X)
|
||||||
U op(0xe2, NOP)
|
U op(0xe2, NOP)
|
||||||
op(0xe3, blockmove, fp(TIA))
|
op(0xe3, BlockMove, fp(TIA))
|
||||||
op(0xe4, zeropageLoad, fp(CPX), X)
|
op(0xe4, ZeroPageRead, fp(CPX), X)
|
||||||
op(0xe5, zeropageLoad, fp(SBC), A)
|
op(0xe5, ZeroPageRead, fp(SBC), A)
|
||||||
op(0xe6, zeropageModify, fp(INC))
|
op(0xe6, ZeroPageModify, fp(INC))
|
||||||
op(0xe7, SMB, 6)
|
op(0xe7, SMB, 6)
|
||||||
op(0xe8, implied, fp(INC), X)
|
op(0xe8, Implied, fp(INC), X)
|
||||||
op(0xe9, immediate, fp(SBC), A)
|
op(0xe9, Immediate, fp(SBC), A)
|
||||||
op(0xea, NOP)
|
op(0xea, NOP)
|
||||||
U op(0xeb, NOP)
|
U op(0xeb, NOP)
|
||||||
op(0xec, absoluteLoad, fp(CPX), X)
|
op(0xec, AbsoluteRead, fp(CPX), X)
|
||||||
op(0xed, absoluteLoad, fp(SBC), A)
|
op(0xed, AbsoluteRead, fp(SBC), A)
|
||||||
op(0xee, absoluteModify, fp(INC))
|
op(0xee, AbsoluteModify, fp(INC))
|
||||||
op(0xef, BBS, 6)
|
op(0xef, BBS, 6)
|
||||||
op(0xf0, branch, Z == 1)
|
op(0xf0, Branch, Z == 1)
|
||||||
op(0xf1, indirectYLoad, fp(SBC), A)
|
op(0xf1, IndirectYRead, fp(SBC), A)
|
||||||
op(0xf2, indirectLoad, fp(SBC), A)
|
op(0xf2, IndirectRead, fp(SBC), A)
|
||||||
op(0xf3, blockmove, fp(TAI))
|
op(0xf3, BlockMove, fp(TAI))
|
||||||
op(0xf4, set, T)
|
op(0xf4, Set, T)
|
||||||
op(0xf5, zeropageLoad, fp(SBC), A, X)
|
op(0xf5, ZeroPageRead, fp(SBC), A, X)
|
||||||
op(0xf6, zeropageModify, fp(INC), X)
|
op(0xf6, ZeroPageModify, fp(INC), X)
|
||||||
op(0xf7, SMB, 7)
|
op(0xf7, SMB, 7)
|
||||||
op(0xf8, set, D)
|
op(0xf8, Set, D)
|
||||||
op(0xf9, absoluteLoad, fp(SBC), A, Y)
|
op(0xf9, AbsoluteRead, fp(SBC), A, Y)
|
||||||
op(0xfa, pull, X)
|
op(0xfa, Pull, X)
|
||||||
U op(0xfb, NOP)
|
U op(0xfb, NOP)
|
||||||
U op(0xfc, NOP)
|
U op(0xfc, NOP)
|
||||||
op(0xfd, absoluteLoad, fp(SBC), A, X)
|
op(0xfd, AbsoluteRead, fp(SBC), A, X)
|
||||||
op(0xfe, absoluteModify, fp(INC), X)
|
op(0xfe, AbsoluteModify, fp(INC), X)
|
||||||
op(0xff, BBS, 7)
|
op(0xff, BBS, 7)
|
||||||
}
|
}
|
||||||
#undef U
|
#undef U
|
||||||
|
|
|
@ -1,198 +1,4 @@
|
||||||
auto HuC6280::ADC(uint8 i) -> uint8 {
|
auto HuC6280::instructionAbsoluteModify(fp alu, uint8 index) -> void {
|
||||||
int16 o;
|
|
||||||
if(!D) {
|
|
||||||
o = A + i + C;
|
|
||||||
V = ~(A ^ i) & (A ^ o) & 0x80;
|
|
||||||
} else {
|
|
||||||
io();
|
|
||||||
o = (A & 0x0f) + (i & 0x0f) + (C << 0);
|
|
||||||
if(o > 0x09) o += 0x06;
|
|
||||||
C = o > 0x0f;
|
|
||||||
o = (A & 0xf0) + (i & 0xf0) + (C << 4) + (o & 0x0f);
|
|
||||||
if(o > 0x9f) o += 0x60;
|
|
||||||
}
|
|
||||||
C = o.bit(8);
|
|
||||||
Z = uint8(o) == 0;
|
|
||||||
N = o.bit(7);
|
|
||||||
return o;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto HuC6280::AND(uint8 i) -> uint8 {
|
|
||||||
uint8 o = A & i;
|
|
||||||
Z = o == 0;
|
|
||||||
N = o.bit(7);
|
|
||||||
return o;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto HuC6280::ASL(uint8 i) -> uint8 {
|
|
||||||
C = i.bit(7);
|
|
||||||
i <<= 1;
|
|
||||||
Z = i == 0;
|
|
||||||
N = i.bit(7);
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto HuC6280::BIT(uint8 i) -> uint8 {
|
|
||||||
Z = (A & i) == 0;
|
|
||||||
V = i.bit(6);
|
|
||||||
N = i.bit(7);
|
|
||||||
return A;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto HuC6280::CMP(uint8 i) -> uint8 {
|
|
||||||
uint9 o = A - i;
|
|
||||||
C = !o.bit(8);
|
|
||||||
Z = uint8(o) == 0;
|
|
||||||
N = o.bit(7);
|
|
||||||
return A;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto HuC6280::CPX(uint8 i) -> uint8 {
|
|
||||||
uint9 o = X - i;
|
|
||||||
C = !o.bit(8);
|
|
||||||
Z = uint8(o) == 0;
|
|
||||||
N = o.bit(7);
|
|
||||||
return X;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto HuC6280::CPY(uint8 i) -> uint8 {
|
|
||||||
uint9 o = Y - i;
|
|
||||||
C = !o.bit(8);
|
|
||||||
Z = uint8(o) == 0;
|
|
||||||
N = o.bit(7);
|
|
||||||
return Y;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto HuC6280::DEC(uint8 i) -> uint8 {
|
|
||||||
i--;
|
|
||||||
Z = i == 0;
|
|
||||||
N = i.bit(7);
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto HuC6280::EOR(uint8 i) -> uint8 {
|
|
||||||
uint8 o = A ^ i;
|
|
||||||
Z = o == 0;
|
|
||||||
N = o.bit(7);
|
|
||||||
return o;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto HuC6280::INC(uint8 i) -> uint8 {
|
|
||||||
i++;
|
|
||||||
Z = i == 0;
|
|
||||||
N = i.bit(7);
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto HuC6280::LD(uint8 i) -> uint8 {
|
|
||||||
Z = i == 0;
|
|
||||||
N = i.bit(7);
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto HuC6280::LSR(uint8 i) -> uint8 {
|
|
||||||
C = i.bit(0);
|
|
||||||
i >>= 1;
|
|
||||||
Z = i == 0;
|
|
||||||
N = i.bit(7);
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto HuC6280::ORA(uint8 i) -> uint8 {
|
|
||||||
uint8 o = A | i;
|
|
||||||
Z = o == 0;
|
|
||||||
N = o.bit(7);
|
|
||||||
return o;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto HuC6280::ROL(uint8 i) -> uint8 {
|
|
||||||
bool c = C;
|
|
||||||
C = i.bit(7);
|
|
||||||
i = i << 1 | c;
|
|
||||||
Z = i == 0;
|
|
||||||
N = i.bit(7);
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto HuC6280::ROR(uint8 i) -> uint8 {
|
|
||||||
bool c = C;
|
|
||||||
C = i.bit(0);
|
|
||||||
i = c << 7 | i >> 1;
|
|
||||||
Z = i == 0;
|
|
||||||
N = i.bit(7);
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto HuC6280::SBC(uint8 i) -> uint8 {
|
|
||||||
i ^= 0xff;
|
|
||||||
int16 o;
|
|
||||||
if(!D) {
|
|
||||||
o = A + i + C;
|
|
||||||
V = ~(A ^ i) & (A ^ o) & 0x80;
|
|
||||||
} else {
|
|
||||||
io();
|
|
||||||
o = (A & 0x0f) + (i & 0x0f) + (C << 0);
|
|
||||||
if(o <= 0x0f) o -= 0x06;
|
|
||||||
C = o > 0x0f;
|
|
||||||
o = (A & 0xf0) + (i & 0xf0) + (C << 4) + (o & 0x0f);
|
|
||||||
if(o <= 0xff) o -= 0x60;
|
|
||||||
}
|
|
||||||
C = o.bit(8);
|
|
||||||
Z = uint8(o) == 0;
|
|
||||||
N = o.bit(7);
|
|
||||||
return o;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto HuC6280::TRB(uint8 i) -> uint8 {
|
|
||||||
Z = (A & i) == 0;
|
|
||||||
V = i.bit(6);
|
|
||||||
N = i.bit(7);
|
|
||||||
return ~A & i;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto HuC6280::TSB(uint8 i) -> uint8 {
|
|
||||||
Z = (A & i) == 0;
|
|
||||||
V = i.bit(6);
|
|
||||||
N = i.bit(7);
|
|
||||||
return A | i;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
|
|
||||||
auto HuC6280::TAI(uint16& source, uint16& target, bool alternate) -> void {
|
|
||||||
!alternate ? source++ : source--;
|
|
||||||
target++;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto HuC6280::TDD(uint16& source, uint16& target, bool) -> void {
|
|
||||||
source--;
|
|
||||||
target--;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto HuC6280::TIA(uint16& source, uint16& target, bool alternate) -> void {
|
|
||||||
source++;
|
|
||||||
!alternate ? target++ : target--;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto HuC6280::TII(uint16& source, uint16& target, bool) -> void {
|
|
||||||
source++;
|
|
||||||
target++;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto HuC6280::TIN(uint16& source, uint16& target, bool) -> void {
|
|
||||||
source++;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
|
|
||||||
auto HuC6280::instruction_absoluteLoad(fp alu, uint8& data, uint8 index) -> void {
|
|
||||||
uint16 absolute = operand();
|
|
||||||
absolute |= operand() << 8;
|
|
||||||
io();
|
|
||||||
L data = ALU(load16(absolute + index));
|
|
||||||
}
|
|
||||||
|
|
||||||
auto HuC6280::instruction_absoluteModify(fp alu, uint8 index) -> void {
|
|
||||||
uint16 absolute = operand();
|
uint16 absolute = operand();
|
||||||
absolute |= operand() << 8;
|
absolute |= operand() << 8;
|
||||||
io();
|
io();
|
||||||
|
@ -201,14 +7,21 @@ auto HuC6280::instruction_absoluteModify(fp alu, uint8 index) -> void {
|
||||||
L store16(absolute + index, data);
|
L store16(absolute + index, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto HuC6280::instruction_absoluteStore(uint8 data, uint8 index) -> void {
|
auto HuC6280::instructionAbsoluteRead(fp alu, uint8& data, uint8 index) -> void {
|
||||||
|
uint16 absolute = operand();
|
||||||
|
absolute |= operand() << 8;
|
||||||
|
io();
|
||||||
|
L data = ALU(load16(absolute + index));
|
||||||
|
}
|
||||||
|
|
||||||
|
auto HuC6280::instructionAbsoluteWrite(uint8 data, uint8 index) -> void {
|
||||||
uint16 absolute = operand();
|
uint16 absolute = operand();
|
||||||
absolute |= operand() << 8;
|
absolute |= operand() << 8;
|
||||||
io();
|
io();
|
||||||
L store16(absolute + index, data);
|
L store16(absolute + index, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto HuC6280::instruction_blockmove(bp alu) -> void {
|
auto HuC6280::instructionBlockMove(bp alu) -> void {
|
||||||
uint16 source = operand();
|
uint16 source = operand();
|
||||||
source |= operand() << 8;
|
source |= operand() << 8;
|
||||||
uint16 target = operand();
|
uint16 target = operand();
|
||||||
|
@ -238,7 +51,7 @@ auto HuC6280::instruction_blockmove(bp alu) -> void {
|
||||||
L Y = pull();
|
L Y = pull();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto HuC6280::instruction_branch(bool take) -> void {
|
auto HuC6280::instructionBranch(bool take) -> void {
|
||||||
if(!take) {
|
if(!take) {
|
||||||
L operand();
|
L operand();
|
||||||
} else {
|
} else {
|
||||||
|
@ -249,26 +62,26 @@ auto HuC6280::instruction_branch(bool take) -> void {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto HuC6280::instruction_clear(uint8& data) -> void {
|
auto HuC6280::instructionClear(uint8& data) -> void {
|
||||||
L io();
|
L io();
|
||||||
data = 0;
|
data = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto HuC6280::instruction_clear(bool& flag) -> void {
|
auto HuC6280::instructionClear(bool& flag) -> void {
|
||||||
L io();
|
L io();
|
||||||
flag = 0;
|
flag = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto HuC6280::instruction_immediate(fp alu, uint8& data) -> void {
|
auto HuC6280::instructionImmediate(fp alu, uint8& data) -> void {
|
||||||
L data = ALU(operand());
|
L data = ALU(operand());
|
||||||
}
|
}
|
||||||
|
|
||||||
auto HuC6280::instruction_implied(fp alu, uint8& data) -> void {
|
auto HuC6280::instructionImplied(fp alu, uint8& data) -> void {
|
||||||
L io();
|
L io();
|
||||||
data = ALU(data);
|
data = ALU(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto HuC6280::instruction_indirectLoad(fp alu, uint8& data, uint8 index) -> void {
|
auto HuC6280::instructionIndirectRead(fp alu, uint8& data, uint8 index) -> void {
|
||||||
auto zeropage = operand();
|
auto zeropage = operand();
|
||||||
io();
|
io();
|
||||||
uint16 absolute = load8(zeropage + index + 0);
|
uint16 absolute = load8(zeropage + index + 0);
|
||||||
|
@ -277,7 +90,7 @@ auto HuC6280::instruction_indirectLoad(fp alu, uint8& data, uint8 index) -> void
|
||||||
L data = ALU(load16(absolute));
|
L data = ALU(load16(absolute));
|
||||||
}
|
}
|
||||||
|
|
||||||
auto HuC6280::instruction_indirectStore(uint8 data, uint8 index) -> void {
|
auto HuC6280::instructionIndirectWrite(uint8 data, uint8 index) -> void {
|
||||||
auto zeropage = operand();
|
auto zeropage = operand();
|
||||||
io();
|
io();
|
||||||
uint16 absolute = load8(zeropage + index + 0);
|
uint16 absolute = load8(zeropage + index + 0);
|
||||||
|
@ -285,7 +98,7 @@ auto HuC6280::instruction_indirectStore(uint8 data, uint8 index) -> void {
|
||||||
L store16(absolute, data);
|
L store16(absolute, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto HuC6280::instruction_indirectYLoad(fp alu, uint8& data) -> void {
|
auto HuC6280::instructionIndirectYRead(fp alu, uint8& data) -> void {
|
||||||
auto zeropage = operand();
|
auto zeropage = operand();
|
||||||
io();
|
io();
|
||||||
uint16 absolute = load8(zeropage + 0);
|
uint16 absolute = load8(zeropage + 0);
|
||||||
|
@ -294,7 +107,7 @@ auto HuC6280::instruction_indirectYLoad(fp alu, uint8& data) -> void {
|
||||||
L data = ALU(load16(absolute + Y));
|
L data = ALU(load16(absolute + Y));
|
||||||
}
|
}
|
||||||
|
|
||||||
auto HuC6280::instruction_indirectYStore(uint8 data) -> void {
|
auto HuC6280::instructionIndirectYWrite(uint8 data) -> void {
|
||||||
auto zeropage = operand();
|
auto zeropage = operand();
|
||||||
io();
|
io();
|
||||||
uint16 absolute = load8(zeropage + 0);
|
uint16 absolute = load8(zeropage + 0);
|
||||||
|
@ -302,14 +115,14 @@ auto HuC6280::instruction_indirectYStore(uint8 data) -> void {
|
||||||
L store16(absolute + Y, data);
|
L store16(absolute + Y, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto HuC6280::instruction_memory(fp alu) -> void {
|
auto HuC6280::instructionMemory(fp alu) -> void {
|
||||||
auto a = A;
|
auto a = A;
|
||||||
A = ALU(load8(X));
|
A = ALU(load8(X));
|
||||||
L store8(X, A);
|
L store8(X, A);
|
||||||
A = a;
|
A = a;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto HuC6280::instruction_pull(uint8& data) -> void {
|
auto HuC6280::instructionPull(uint8& data) -> void {
|
||||||
io();
|
io();
|
||||||
io();
|
io();
|
||||||
L data = pull();
|
L data = pull();
|
||||||
|
@ -317,36 +130,30 @@ L data = pull();
|
||||||
N = data.bit(7);
|
N = data.bit(7);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto HuC6280::instruction_push(uint8 data) -> void {
|
auto HuC6280::instructionPush(uint8 data) -> void {
|
||||||
io();
|
io();
|
||||||
L push(data);
|
L push(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto HuC6280::instruction_set(bool& flag) -> void {
|
auto HuC6280::instructionSet(bool& flag) -> void {
|
||||||
L io();
|
L io();
|
||||||
flag = 1;
|
flag = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto HuC6280::instruction_swap(uint8& lhs, uint8& rhs) -> void {
|
auto HuC6280::instructionSwap(uint8& lhs, uint8& rhs) -> void {
|
||||||
io();
|
io();
|
||||||
L io();
|
L io();
|
||||||
swap(lhs, rhs);
|
swap(lhs, rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto HuC6280::instruction_transfer(uint8& source, uint8& target) -> void {
|
auto HuC6280::instructionTransfer(uint8& source, uint8& target) -> void {
|
||||||
L io();
|
L io();
|
||||||
target = source;
|
target = source;
|
||||||
Z = target == 0;
|
Z = target == 0;
|
||||||
N = target.bit(7);
|
N = target.bit(7);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto HuC6280::instruction_zeropageLoad(fp alu, uint8& data, uint8 index) -> void {
|
auto HuC6280::instructionZeroPageModify(fp alu, uint8 index) -> void {
|
||||||
auto zeropage = operand();
|
|
||||||
io();
|
|
||||||
L data = ALU(load8(zeropage + index));
|
|
||||||
}
|
|
||||||
|
|
||||||
auto HuC6280::instruction_zeropageModify(fp alu, uint8 index) -> void {
|
|
||||||
auto zeropage = operand();
|
auto zeropage = operand();
|
||||||
io();
|
io();
|
||||||
io();
|
io();
|
||||||
|
@ -354,7 +161,13 @@ auto HuC6280::instruction_zeropageModify(fp alu, uint8 index) -> void {
|
||||||
L store8(zeropage + index, data);
|
L store8(zeropage + index, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto HuC6280::instruction_zeropageStore(uint8 data, uint8 index) -> void {
|
auto HuC6280::instructionZeroPageRead(fp alu, uint8& data, uint8 index) -> void {
|
||||||
|
auto zeropage = operand();
|
||||||
|
io();
|
||||||
|
L data = ALU(load8(zeropage + index));
|
||||||
|
}
|
||||||
|
|
||||||
|
auto HuC6280::instructionZeroPageWrite(uint8 data, uint8 index) -> void {
|
||||||
auto zeropage = operand();
|
auto zeropage = operand();
|
||||||
io();
|
io();
|
||||||
L store8(zeropage + index, data);
|
L store8(zeropage + index, data);
|
||||||
|
@ -362,7 +175,7 @@ L store8(zeropage + index, data);
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
auto HuC6280::instruction_BBR(uint3 index) -> void {
|
auto HuC6280::instructionBBR(uint3 index) -> void {
|
||||||
auto zeropage = operand();
|
auto zeropage = operand();
|
||||||
auto displacement = operand();
|
auto displacement = operand();
|
||||||
io();
|
io();
|
||||||
|
@ -373,7 +186,7 @@ L auto data = load8(zeropage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto HuC6280::instruction_BBS(uint3 index) -> void {
|
auto HuC6280::instructionBBS(uint3 index) -> void {
|
||||||
auto zeropage = operand();
|
auto zeropage = operand();
|
||||||
auto displacement = operand();
|
auto displacement = operand();
|
||||||
io();
|
io();
|
||||||
|
@ -384,7 +197,7 @@ L auto data = load8(zeropage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto HuC6280::instruction_BRK() -> void {
|
auto HuC6280::instructionBRK() -> void {
|
||||||
operand();
|
operand();
|
||||||
io();
|
io();
|
||||||
push(PC >> 8);
|
push(PC >> 8);
|
||||||
|
@ -397,7 +210,7 @@ auto HuC6280::instruction_BRK() -> void {
|
||||||
L PC.byte(1) = load16(0xfff7);
|
L PC.byte(1) = load16(0xfff7);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto HuC6280::instruction_BSR() -> void {
|
auto HuC6280::instructionBSR() -> void {
|
||||||
auto displacement = operand();
|
auto displacement = operand();
|
||||||
io();
|
io();
|
||||||
io();
|
io();
|
||||||
|
@ -408,24 +221,24 @@ L push((PC - 1) >> 0);
|
||||||
PC += (int8)displacement;
|
PC += (int8)displacement;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto HuC6280::instruction_CSL() -> void {
|
auto HuC6280::instructionCSL() -> void {
|
||||||
L io();
|
L io();
|
||||||
r.cs = 4;
|
r.cs = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto HuC6280::instruction_CSH() -> void {
|
auto HuC6280::instructionCSH() -> void {
|
||||||
L io();
|
L io();
|
||||||
r.cs = 1;
|
r.cs = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto HuC6280::instruction_JMP_absolute() -> void {
|
auto HuC6280::instructionJMPAbsolute() -> void {
|
||||||
uint16 address = operand();
|
uint16 address = operand();
|
||||||
address |= operand() << 8;
|
address |= operand() << 8;
|
||||||
L io();
|
L io();
|
||||||
PC = address;
|
PC = address;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto HuC6280::instruction_JMP_indirect(uint8 index) -> void {
|
auto HuC6280::instructionJMPIndirect(uint8 index) -> void {
|
||||||
uint16 address = operand();
|
uint16 address = operand();
|
||||||
address |= operand() << 8;
|
address |= operand() << 8;
|
||||||
io();
|
io();
|
||||||
|
@ -434,7 +247,7 @@ auto HuC6280::instruction_JMP_indirect(uint8 index) -> void {
|
||||||
L PC.byte(1) = load16(address + index + 1);
|
L PC.byte(1) = load16(address + index + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto HuC6280::instruction_JSR() -> void {
|
auto HuC6280::instructionJSR() -> void {
|
||||||
uint16 address = operand();
|
uint16 address = operand();
|
||||||
address |= operand() << 8;
|
address |= operand() << 8;
|
||||||
io();
|
io();
|
||||||
|
@ -444,17 +257,17 @@ L push((PC - 1) >> 0);
|
||||||
PC = address;
|
PC = address;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto HuC6280::instruction_NOP() -> void {
|
auto HuC6280::instructionNOP() -> void {
|
||||||
L io();
|
L io();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto HuC6280::instruction_PLP() -> void {
|
auto HuC6280::instructionPLP() -> void {
|
||||||
io();
|
io();
|
||||||
io();
|
io();
|
||||||
L P = pull();
|
L P = pull();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto HuC6280::instruction_RMB(uint3 index) -> void {
|
auto HuC6280::instructionRMB(uint3 index) -> void {
|
||||||
auto zeropage = operand();
|
auto zeropage = operand();
|
||||||
io();
|
io();
|
||||||
io();
|
io();
|
||||||
|
@ -464,7 +277,7 @@ auto HuC6280::instruction_RMB(uint3 index) -> void {
|
||||||
L store8(zeropage, data);
|
L store8(zeropage, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto HuC6280::instruction_RTI() -> void {
|
auto HuC6280::instructionRTI() -> void {
|
||||||
io();
|
io();
|
||||||
io();
|
io();
|
||||||
io();
|
io();
|
||||||
|
@ -473,7 +286,7 @@ auto HuC6280::instruction_RTI() -> void {
|
||||||
L PC.byte(1) = pull();
|
L PC.byte(1) = pull();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto HuC6280::instruction_RTS() -> void {
|
auto HuC6280::instructionRTS() -> void {
|
||||||
io();
|
io();
|
||||||
io();
|
io();
|
||||||
io();
|
io();
|
||||||
|
@ -483,7 +296,7 @@ L io();
|
||||||
PC++;
|
PC++;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto HuC6280::instruction_SMB(uint3 index) -> void {
|
auto HuC6280::instructionSMB(uint3 index) -> void {
|
||||||
auto zeropage = operand();
|
auto zeropage = operand();
|
||||||
io();
|
io();
|
||||||
io();
|
io();
|
||||||
|
@ -493,14 +306,14 @@ auto HuC6280::instruction_SMB(uint3 index) -> void {
|
||||||
L store8(zeropage, data);
|
L store8(zeropage, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto HuC6280::instruction_ST(uint2 index) -> void {
|
auto HuC6280::instructionST(uint2 index) -> void {
|
||||||
auto data = operand();
|
auto data = operand();
|
||||||
io();
|
io();
|
||||||
io();
|
io();
|
||||||
L store(index, data);
|
L store(index, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto HuC6280::instruction_TAM() -> void {
|
auto HuC6280::instructionTAM() -> void {
|
||||||
auto mask = operand();
|
auto mask = operand();
|
||||||
io();
|
io();
|
||||||
io();
|
io();
|
||||||
|
@ -510,7 +323,7 @@ L io();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto HuC6280::instruction_TMA() -> void {
|
auto HuC6280::instructionTMA() -> void {
|
||||||
auto mask = operand();
|
auto mask = operand();
|
||||||
io();
|
io();
|
||||||
L io();
|
L io();
|
||||||
|
@ -519,7 +332,7 @@ L io();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto HuC6280::instruction_TST_absolute(uint8 index) -> void {
|
auto HuC6280::instructionTSTAbsolute(uint8 index) -> void {
|
||||||
auto mask = operand();
|
auto mask = operand();
|
||||||
uint16 absolute = operand();
|
uint16 absolute = operand();
|
||||||
absolute |= operand() << 8;
|
absolute |= operand() << 8;
|
||||||
|
@ -532,7 +345,7 @@ L uint8 data = load16(absolute + index);
|
||||||
N = data.bit(7);
|
N = data.bit(7);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto HuC6280::instruction_TST_zeropage(uint8 index) -> void {
|
auto HuC6280::instructionTSTZeroPage(uint8 index) -> void {
|
||||||
auto mask = operand();
|
auto mask = operand();
|
||||||
auto zeropage = operand();
|
auto zeropage = operand();
|
||||||
io();
|
io();
|
||||||
|
@ -544,7 +357,7 @@ L uint8 data = load8(zeropage + index);
|
||||||
N = data.bit(7);
|
N = data.bit(7);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto HuC6280::instruction_TXS() -> void {
|
auto HuC6280::instructionTXS() -> void {
|
||||||
L io();
|
L io();
|
||||||
S = X;
|
S = X;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,144 @@
|
||||||
|
auto MOS6502::algorithmADC(uint8 i) -> uint8 {
|
||||||
|
int16 o;
|
||||||
|
if(!BCD || !D) {
|
||||||
|
o = A + i + C;
|
||||||
|
V = ~(A ^ i) & (A ^ o) & 0x80;
|
||||||
|
} else {
|
||||||
|
idle();
|
||||||
|
o = (A & 0x0f) + (i & 0x0f) + (C << 0);
|
||||||
|
if(o > 0x09) o += 0x06;
|
||||||
|
C = o > 0x0f;
|
||||||
|
o = (A & 0xf0) + (i & 0xf0) + (C << 4) + (o & 0x0f);
|
||||||
|
if(o > 0x9f) o += 0x60;
|
||||||
|
}
|
||||||
|
C = o.bit(8);
|
||||||
|
Z = uint8(o) == 0;
|
||||||
|
N = o.bit(7);
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto MOS6502::algorithmAND(uint8 i) -> uint8 {
|
||||||
|
uint8 o = A & i;
|
||||||
|
Z = o == 0;
|
||||||
|
N = o.bit(7);
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto MOS6502::algorithmASL(uint8 i) -> uint8 {
|
||||||
|
C = i.bit(7);
|
||||||
|
i <<= 1;
|
||||||
|
Z = i == 0;
|
||||||
|
N = i.bit(7);
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto MOS6502::algorithmBIT(uint8 i) -> uint8 {
|
||||||
|
Z = (A & i) == 0;
|
||||||
|
V = i.bit(6);
|
||||||
|
N = i.bit(7);
|
||||||
|
return A;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto MOS6502::algorithmCMP(uint8 i) -> uint8 {
|
||||||
|
uint9 o = A - i;
|
||||||
|
C = !o.bit(8);
|
||||||
|
Z = uint8(o) == 0;
|
||||||
|
N = o.bit(7);
|
||||||
|
return A;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto MOS6502::algorithmCPX(uint8 i) -> uint8 {
|
||||||
|
uint9 o = X - i;
|
||||||
|
C = !o.bit(8);
|
||||||
|
Z = uint8(o) == 0;
|
||||||
|
N = o.bit(7);
|
||||||
|
return X;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto MOS6502::algorithmCPY(uint8 i) -> uint8 {
|
||||||
|
uint9 o = Y - i;
|
||||||
|
C = !o.bit(8);
|
||||||
|
Z = uint8(o) == 0;
|
||||||
|
N = o.bit(7);
|
||||||
|
return Y;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto MOS6502::algorithmDEC(uint8 i) -> uint8 {
|
||||||
|
i--;
|
||||||
|
Z = i == 0;
|
||||||
|
N = i.bit(7);
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto MOS6502::algorithmEOR(uint8 i) -> uint8 {
|
||||||
|
uint8 o = A ^ i;
|
||||||
|
Z = o == 0;
|
||||||
|
N = o.bit(7);
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto MOS6502::algorithmINC(uint8 i) -> uint8 {
|
||||||
|
i++;
|
||||||
|
Z = i == 0;
|
||||||
|
N = i.bit(7);
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto MOS6502::algorithmLD(uint8 i) -> uint8 {
|
||||||
|
Z = i == 0;
|
||||||
|
N = i.bit(7);
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto MOS6502::algorithmLSR(uint8 i) -> uint8 {
|
||||||
|
C = i.bit(0);
|
||||||
|
i >>= 1;
|
||||||
|
Z = i == 0;
|
||||||
|
N = i.bit(7);
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto MOS6502::algorithmORA(uint8 i) -> uint8 {
|
||||||
|
uint8 o = A | i;
|
||||||
|
Z = o == 0;
|
||||||
|
N = o.bit(7);
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto MOS6502::algorithmROL(uint8 i) -> uint8 {
|
||||||
|
bool c = C;
|
||||||
|
C = i.bit(7);
|
||||||
|
i = i << 1 | c;
|
||||||
|
Z = i == 0;
|
||||||
|
N = i.bit(7);
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto MOS6502::algorithmROR(uint8 i) -> uint8 {
|
||||||
|
bool c = C;
|
||||||
|
C = i.bit(0);
|
||||||
|
i = c << 7 | i >> 1;
|
||||||
|
Z = i == 0;
|
||||||
|
N = i.bit(7);
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto MOS6502::algorithmSBC(uint8 i) -> uint8 {
|
||||||
|
i = ~i;
|
||||||
|
int16 o;
|
||||||
|
if(!BCD || !D) {
|
||||||
|
o = A + i + C;
|
||||||
|
V = ~(A ^ i) & (A ^ o) & 0x80;
|
||||||
|
} else {
|
||||||
|
idle();
|
||||||
|
o = (A & 0x0f) + (i & 0x0f) + (C << 0);
|
||||||
|
if(o <= 0x0f) o -= 0x06;
|
||||||
|
C = o > 0x0f;
|
||||||
|
o = (A & 0xf0) + (i & 0xf0) + (C << 4) + (o & 0x0f);
|
||||||
|
if(o <= 0xff) o -= 0x60;
|
||||||
|
}
|
||||||
|
C = o.bit(8);
|
||||||
|
Z = uint8(o) == 0;
|
||||||
|
N = o.bit(7);
|
||||||
|
return o;
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
#define op(id, name, ...) case id: return instruction##name(__VA_ARGS__);
|
#define op(id, name, ...) case id: return instruction##name(__VA_ARGS__);
|
||||||
#define fp(name) &MOS6502::name
|
#define fp(name) &MOS6502::algorithm##name
|
||||||
|
|
||||||
auto MOS6502::interrupt() -> void {
|
auto MOS6502::interrupt() -> void {
|
||||||
idle();
|
idle();
|
||||||
|
|
|
@ -1,150 +1,3 @@
|
||||||
auto MOS6502::ADC(uint8 i) -> uint8 {
|
|
||||||
int16 o;
|
|
||||||
if(!BCD || !D) {
|
|
||||||
o = A + i + C;
|
|
||||||
V = ~(A ^ i) & (A ^ o) & 0x80;
|
|
||||||
} else {
|
|
||||||
idle();
|
|
||||||
o = (A & 0x0f) + (i & 0x0f) + (C << 0);
|
|
||||||
if(o > 0x09) o += 0x06;
|
|
||||||
C = o > 0x0f;
|
|
||||||
o = (A & 0xf0) + (i & 0xf0) + (C << 4) + (o & 0x0f);
|
|
||||||
if(o > 0x9f) o += 0x60;
|
|
||||||
}
|
|
||||||
C = o.bit(8);
|
|
||||||
Z = uint8(o) == 0;
|
|
||||||
N = o.bit(7);
|
|
||||||
return o;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto MOS6502::AND(uint8 i) -> uint8 {
|
|
||||||
uint8 o = A & i;
|
|
||||||
Z = o == 0;
|
|
||||||
N = o.bit(7);
|
|
||||||
return o;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto MOS6502::ASL(uint8 i) -> uint8 {
|
|
||||||
C = i.bit(7);
|
|
||||||
i <<= 1;
|
|
||||||
Z = i == 0;
|
|
||||||
N = i.bit(7);
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto MOS6502::BIT(uint8 i) -> uint8 {
|
|
||||||
Z = (A & i) == 0;
|
|
||||||
V = i.bit(6);
|
|
||||||
N = i.bit(7);
|
|
||||||
return A;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto MOS6502::CMP(uint8 i) -> uint8 {
|
|
||||||
uint9 o = A - i;
|
|
||||||
C = !o.bit(8);
|
|
||||||
Z = uint8(o) == 0;
|
|
||||||
N = o.bit(7);
|
|
||||||
return A;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto MOS6502::CPX(uint8 i) -> uint8 {
|
|
||||||
uint9 o = X - i;
|
|
||||||
C = !o.bit(8);
|
|
||||||
Z = uint8(o) == 0;
|
|
||||||
N = o.bit(7);
|
|
||||||
return X;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto MOS6502::CPY(uint8 i) -> uint8 {
|
|
||||||
uint9 o = Y - i;
|
|
||||||
C = !o.bit(8);
|
|
||||||
Z = uint8(o) == 0;
|
|
||||||
N = o.bit(7);
|
|
||||||
return Y;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto MOS6502::DEC(uint8 i) -> uint8 {
|
|
||||||
i--;
|
|
||||||
Z = i == 0;
|
|
||||||
N = i.bit(7);
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto MOS6502::EOR(uint8 i) -> uint8 {
|
|
||||||
uint8 o = A ^ i;
|
|
||||||
Z = o == 0;
|
|
||||||
N = o.bit(7);
|
|
||||||
return o;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto MOS6502::INC(uint8 i) -> uint8 {
|
|
||||||
i++;
|
|
||||||
Z = i == 0;
|
|
||||||
N = i.bit(7);
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto MOS6502::LD(uint8 i) -> uint8 {
|
|
||||||
Z = i == 0;
|
|
||||||
N = i.bit(7);
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto MOS6502::LSR(uint8 i) -> uint8 {
|
|
||||||
C = i.bit(0);
|
|
||||||
i >>= 1;
|
|
||||||
Z = i == 0;
|
|
||||||
N = i.bit(7);
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto MOS6502::ORA(uint8 i) -> uint8 {
|
|
||||||
uint8 o = A | i;
|
|
||||||
Z = o == 0;
|
|
||||||
N = o.bit(7);
|
|
||||||
return o;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto MOS6502::ROL(uint8 i) -> uint8 {
|
|
||||||
bool c = C;
|
|
||||||
C = i.bit(7);
|
|
||||||
i = i << 1 | c;
|
|
||||||
Z = i == 0;
|
|
||||||
N = i.bit(7);
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto MOS6502::ROR(uint8 i) -> uint8 {
|
|
||||||
bool c = C;
|
|
||||||
C = i.bit(0);
|
|
||||||
i = c << 7 | i >> 1;
|
|
||||||
Z = i == 0;
|
|
||||||
N = i.bit(7);
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto MOS6502::SBC(uint8 i) -> uint8 {
|
|
||||||
i ^= 0xff;
|
|
||||||
int16 o;
|
|
||||||
if(!BCD || !D) {
|
|
||||||
o = A + i + C;
|
|
||||||
V = ~(A ^ i) & (A ^ o) & 0x80;
|
|
||||||
} else {
|
|
||||||
idle();
|
|
||||||
o = (A & 0x0f) + (i & 0x0f) + (C << 0);
|
|
||||||
if(o <= 0x0f) o -= 0x06;
|
|
||||||
C = o > 0x0f;
|
|
||||||
o = (A & 0xf0) + (i & 0xf0) + (C << 4) + (o & 0x0f);
|
|
||||||
if(o <= 0xff) o -= 0x60;
|
|
||||||
}
|
|
||||||
C = o.bit(8);
|
|
||||||
Z = uint8(o) == 0;
|
|
||||||
N = o.bit(7);
|
|
||||||
return o;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
|
|
||||||
auto MOS6502::instructionAbsoluteModify(fp alu) -> void {
|
auto MOS6502::instructionAbsoluteModify(fp alu) -> void {
|
||||||
uint16 absolute = operand();
|
uint16 absolute = operand();
|
||||||
absolute |= operand() << 8;
|
absolute |= operand() << 8;
|
||||||
|
|
|
@ -21,6 +21,7 @@ namespace Processor {
|
||||||
#define L lastCycle();
|
#define L lastCycle();
|
||||||
|
|
||||||
#include "memory.cpp"
|
#include "memory.cpp"
|
||||||
|
#include "algorithms.cpp"
|
||||||
#include "instruction.cpp"
|
#include "instruction.cpp"
|
||||||
#include "instructions.cpp"
|
#include "instructions.cpp"
|
||||||
#include "disassembler.cpp"
|
#include "disassembler.cpp"
|
||||||
|
|
|
@ -26,29 +26,30 @@ struct MOS6502 {
|
||||||
auto push(uint8 data) -> void;
|
auto push(uint8 data) -> void;
|
||||||
auto pull() -> uint8;
|
auto pull() -> uint8;
|
||||||
|
|
||||||
|
//algorithms.cpp
|
||||||
|
using fp = auto (MOS6502::*)(uint8) -> uint8;
|
||||||
|
auto algorithmADC(uint8) -> uint8;
|
||||||
|
auto algorithmAND(uint8) -> uint8;
|
||||||
|
auto algorithmASL(uint8) -> uint8;
|
||||||
|
auto algorithmBIT(uint8) -> uint8;
|
||||||
|
auto algorithmCMP(uint8) -> uint8;
|
||||||
|
auto algorithmCPX(uint8) -> uint8;
|
||||||
|
auto algorithmCPY(uint8) -> uint8;
|
||||||
|
auto algorithmDEC(uint8) -> uint8;
|
||||||
|
auto algorithmEOR(uint8) -> uint8;
|
||||||
|
auto algorithmINC(uint8) -> uint8;
|
||||||
|
auto algorithmLD (uint8) -> uint8;
|
||||||
|
auto algorithmLSR(uint8) -> uint8;
|
||||||
|
auto algorithmORA(uint8) -> uint8;
|
||||||
|
auto algorithmROL(uint8) -> uint8;
|
||||||
|
auto algorithmROR(uint8) -> uint8;
|
||||||
|
auto algorithmSBC(uint8) -> uint8;
|
||||||
|
|
||||||
//instruction.cpp
|
//instruction.cpp
|
||||||
auto interrupt() -> void;
|
auto interrupt() -> void;
|
||||||
auto instruction() -> void;
|
auto instruction() -> void;
|
||||||
|
|
||||||
//instructions.cpp
|
//instructions.cpp
|
||||||
using fp = auto (MOS6502::*)(uint8) -> uint8;
|
|
||||||
auto ADC(uint8) -> uint8;
|
|
||||||
auto AND(uint8) -> uint8;
|
|
||||||
auto ASL(uint8) -> uint8;
|
|
||||||
auto BIT(uint8) -> uint8;
|
|
||||||
auto CMP(uint8) -> uint8;
|
|
||||||
auto CPX(uint8) -> uint8;
|
|
||||||
auto CPY(uint8) -> uint8;
|
|
||||||
auto DEC(uint8) -> uint8;
|
|
||||||
auto EOR(uint8) -> uint8;
|
|
||||||
auto INC(uint8) -> uint8;
|
|
||||||
auto LD (uint8) -> uint8;
|
|
||||||
auto LSR(uint8) -> uint8;
|
|
||||||
auto ORA(uint8) -> uint8;
|
|
||||||
auto ROL(uint8) -> uint8;
|
|
||||||
auto ROR(uint8) -> uint8;
|
|
||||||
auto SBC(uint8) -> uint8;
|
|
||||||
|
|
||||||
auto instructionAbsoluteModify(fp alu) -> void;
|
auto instructionAbsoluteModify(fp alu) -> void;
|
||||||
auto instructionAbsoluteModify(fp alu, uint8 index) -> void;
|
auto instructionAbsoluteModify(fp alu, uint8 index) -> void;
|
||||||
auto instructionAbsoluteRead(fp alu, uint8& data) -> void;
|
auto instructionAbsoluteRead(fp alu, uint8& data) -> void;
|
||||||
|
|
|
@ -1,134 +1,134 @@
|
||||||
auto SPC700::op_adc(uint8 x, uint8 y) -> uint8 {
|
auto SPC700::algorithmADC(uint8 x, uint8 y) -> uint8 {
|
||||||
int r = x + y + regs.p.c;
|
int z = x + y + CF;
|
||||||
regs.p.n = r & 0x80;
|
CF = z > 0xff;
|
||||||
regs.p.v = ~(x ^ y) & (x ^ r) & 0x80;
|
ZF = (uint8)z == 0;
|
||||||
regs.p.h = (x ^ y ^ r) & 0x10;
|
HF = (x ^ y ^ z) & 0x10;
|
||||||
regs.p.z = (uint8)r == 0;
|
VF = ~(x ^ y) & (x ^ z) & 0x80;
|
||||||
regs.p.c = r > 0xff;
|
NF = z & 0x80;
|
||||||
return r;
|
return z;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto SPC700::op_and(uint8 x, uint8 y) -> uint8 {
|
auto SPC700::algorithmAND(uint8 x, uint8 y) -> uint8 {
|
||||||
x &= y;
|
x &= y;
|
||||||
regs.p.n = x & 0x80;
|
ZF = x == 0;
|
||||||
regs.p.z = x == 0;
|
NF = x & 0x80;
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto SPC700::op_asl(uint8 x) -> uint8 {
|
auto SPC700::algorithmASL(uint8 x) -> uint8 {
|
||||||
regs.p.c = x & 0x80;
|
CF = x & 0x80;
|
||||||
x <<= 1;
|
x <<= 1;
|
||||||
regs.p.n = x & 0x80;
|
ZF = x == 0;
|
||||||
regs.p.z = x == 0;
|
NF = x & 0x80;
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto SPC700::op_cmp(uint8 x, uint8 y) -> uint8 {
|
auto SPC700::algorithmCMP(uint8 x, uint8 y) -> uint8 {
|
||||||
int r = x - y;
|
int z = x - y;
|
||||||
regs.p.n = r & 0x80;
|
CF = z >= 0;
|
||||||
regs.p.z = (uint8)r == 0;
|
ZF = (uint8)z == 0;
|
||||||
regs.p.c = r >= 0;
|
NF = z & 0x80;
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto SPC700::op_dec(uint8 x) -> uint8 {
|
auto SPC700::algorithmDEC(uint8 x) -> uint8 {
|
||||||
x--;
|
x--;
|
||||||
regs.p.n = x & 0x80;
|
ZF = x == 0;
|
||||||
regs.p.z = x == 0;
|
NF = x & 0x80;
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto SPC700::op_eor(uint8 x, uint8 y) -> uint8 {
|
auto SPC700::algorithmEOR(uint8 x, uint8 y) -> uint8 {
|
||||||
x ^= y;
|
x ^= y;
|
||||||
regs.p.n = x & 0x80;
|
ZF = x == 0;
|
||||||
regs.p.z = x == 0;
|
NF = x & 0x80;
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto SPC700::op_inc(uint8 x) -> uint8 {
|
auto SPC700::algorithmINC(uint8 x) -> uint8 {
|
||||||
x++;
|
x++;
|
||||||
regs.p.n = x & 0x80;
|
ZF = x == 0;
|
||||||
regs.p.z = x == 0;
|
NF = x & 0x80;
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto SPC700::op_ld(uint8 x, uint8 y) -> uint8 {
|
auto SPC700::algorithmLD(uint8 x, uint8 y) -> uint8 {
|
||||||
regs.p.n = y & 0x80;
|
ZF = y == 0;
|
||||||
regs.p.z = y == 0;
|
NF = y & 0x80;
|
||||||
return y;
|
return y;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto SPC700::op_lsr(uint8 x) -> uint8 {
|
auto SPC700::algorithmLSR(uint8 x) -> uint8 {
|
||||||
regs.p.c = x & 0x01;
|
CF = x & 0x01;
|
||||||
x >>= 1;
|
x >>= 1;
|
||||||
regs.p.n = x & 0x80;
|
ZF = x == 0;
|
||||||
regs.p.z = x == 0;
|
NF = x & 0x80;
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto SPC700::op_or(uint8 x, uint8 y) -> uint8 {
|
auto SPC700::algorithmOR(uint8 x, uint8 y) -> uint8 {
|
||||||
x |= y;
|
x |= y;
|
||||||
regs.p.n = x & 0x80;
|
ZF = x == 0;
|
||||||
regs.p.z = x == 0;
|
NF = x & 0x80;
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto SPC700::op_rol(uint8 x) -> uint8 {
|
auto SPC700::algorithmROL(uint8 x) -> uint8 {
|
||||||
uint carry = regs.p.c << 0;
|
bool carry = CF;
|
||||||
regs.p.c = x & 0x80;
|
CF = x & 0x80;
|
||||||
x = (x << 1) | carry;
|
x = x << 1 | carry;
|
||||||
regs.p.n = x & 0x80;
|
ZF = x == 0;
|
||||||
regs.p.z = x == 0;
|
NF = x & 0x80;
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto SPC700::op_ror(uint8 x) -> uint8 {
|
auto SPC700::algorithmROR(uint8 x) -> uint8 {
|
||||||
uint carry = regs.p.c << 7;
|
bool carry = CF;
|
||||||
regs.p.c = x & 0x01;
|
CF = x & 0x01;
|
||||||
x = carry | (x >> 1);
|
x = carry << 7 | x >> 1;
|
||||||
regs.p.n = x & 0x80;
|
ZF = x == 0;
|
||||||
regs.p.z = x == 0;
|
NF = x & 0x80;
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto SPC700::op_sbc(uint8 x, uint8 y) -> uint8 {
|
auto SPC700::algorithmSBC(uint8 x, uint8 y) -> uint8 {
|
||||||
return op_adc(x, ~y);
|
return algorithmADC(x, ~y);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto SPC700::op_st(uint8 x, uint8 y) -> uint8 {
|
auto SPC700::algorithmST(uint8 x, uint8 y) -> uint8 {
|
||||||
return y;
|
return y;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
auto SPC700::op_adw(uint16 x, uint16 y) -> uint16 {
|
auto SPC700::algorithmADW(uint16 x, uint16 y) -> uint16 {
|
||||||
uint16 r;
|
uint16 z;
|
||||||
regs.p.c = 0;
|
CF = 0;
|
||||||
r = op_adc(x, y);
|
z = algorithmADC(x, y);
|
||||||
r |= op_adc(x >> 8, y >> 8) << 8;
|
z |= algorithmADC(x >> 8, y >> 8) << 8;
|
||||||
regs.p.z = r == 0;
|
ZF = z == 0;
|
||||||
return r;
|
return z;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto SPC700::op_cpw(uint16 x, uint16 y) -> uint16 {
|
auto SPC700::algorithmCPW(uint16 x, uint16 y) -> uint16 {
|
||||||
int r = x - y;
|
int z = x - y;
|
||||||
regs.p.n = r & 0x8000;
|
CF = z >= 0;
|
||||||
regs.p.z = (uint16)r == 0;
|
ZF = (uint16)z == 0;
|
||||||
regs.p.c = r >= 0;
|
NF = z & 0x8000;
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto SPC700::op_ldw(uint16 x, uint16 y) -> uint16 {
|
auto SPC700::algorithmLDW(uint16 x, uint16 y) -> uint16 {
|
||||||
regs.p.n = y & 0x8000;
|
ZF = y == 0;
|
||||||
regs.p.z = y == 0;
|
NF = y & 0x8000;
|
||||||
return y;
|
return y;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto SPC700::op_sbw(uint16 x, uint16 y) -> uint16 {
|
auto SPC700::algorithmSBW(uint16 x, uint16 y) -> uint16 {
|
||||||
uint16 r;
|
uint16 z;
|
||||||
regs.p.c = 1;
|
CF = 1;
|
||||||
r = op_sbc(x, y);
|
z = algorithmSBC(x, y);
|
||||||
r |= op_sbc(x >> 8, y >> 8) << 8;
|
z |= algorithmSBC(x >> 8, y >> 8) << 8;
|
||||||
regs.p.z = r == 0;
|
ZF = z == 0;
|
||||||
return r;
|
return z;
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ auto SPC700::disassemble(uint16 addr, bool p) -> string {
|
||||||
|
|
||||||
auto a = [&] { return hex((read(addr + 1) << 0) + (read(addr + 2) << 8), 4L); };
|
auto a = [&] { return hex((read(addr + 1) << 0) + (read(addr + 2) << 8), 4L); };
|
||||||
auto b = [&](uint n) { return hex(read(addr + 1 + n), 2L); };
|
auto b = [&](uint n) { return hex(read(addr + 1 + n), 2L); };
|
||||||
auto r = [&](uint r, uint n = 0) { return hex(addr + r + (int8)read(addr + 1 + n), 4L); };
|
auto rel = [&](uint r, uint n = 0) { return hex(addr + r + (int8)read(addr + 1 + n), 4L); };
|
||||||
auto dp = [&](uint n) { return hex((p << 8) + read(addr + 1 + n), 3L); };
|
auto dp = [&](uint n) { return hex((p << 8) + read(addr + 1 + n), 3L); };
|
||||||
auto ab = [&] {
|
auto ab = [&] {
|
||||||
uint n = (read(addr + 1) << 0) + (read(addr + 2) << 8);
|
uint n = (read(addr + 1) << 0) + (read(addr + 2) << 8);
|
||||||
|
@ -22,7 +22,7 @@ auto SPC700::disassemble(uint16 addr, bool p) -> string {
|
||||||
case 0x00: return { "nop" };
|
case 0x00: return { "nop" };
|
||||||
case 0x01: return { "jst $ffde" };
|
case 0x01: return { "jst $ffde" };
|
||||||
case 0x02: return { "set $", dp(0), ":0" };
|
case 0x02: return { "set $", dp(0), ":0" };
|
||||||
case 0x03: return { "bbs $", dp(0), ":0=$", r(+3, 1) };
|
case 0x03: return { "bbs $", dp(0), ":0=$", rel(+3, 1) };
|
||||||
case 0x04: return { "ora $", dp(0) };
|
case 0x04: return { "ora $", dp(0) };
|
||||||
case 0x05: return { "ora $", a() };
|
case 0x05: return { "ora $", a() };
|
||||||
case 0x06: return { "ora (x)" };
|
case 0x06: return { "ora (x)" };
|
||||||
|
@ -35,10 +35,10 @@ auto SPC700::disassemble(uint16 addr, bool p) -> string {
|
||||||
case 0x0d: return { "php" };
|
case 0x0d: return { "php" };
|
||||||
case 0x0e: return { "tsb $", a() };
|
case 0x0e: return { "tsb $", a() };
|
||||||
case 0x0f: return { "brk" };
|
case 0x0f: return { "brk" };
|
||||||
case 0x10: return { "bpl $", r(+2) };
|
case 0x10: return { "bpl $", rel(+2) };
|
||||||
case 0x11: return { "jst $ffdc" };
|
case 0x11: return { "jst $ffdc" };
|
||||||
case 0x12: return { "clr $", dp(0), ":0" };
|
case 0x12: return { "clr $", dp(0), ":0" };
|
||||||
case 0x13: return { "bbc $", dp(0), ":0=$", r(+3, 1) };
|
case 0x13: return { "bbc $", dp(0), ":0=$", rel(+3, 1) };
|
||||||
case 0x14: return { "ora $", dp(0), ",x" };
|
case 0x14: return { "ora $", dp(0), ",x" };
|
||||||
case 0x15: return { "ora $", a(), ",x" };
|
case 0x15: return { "ora $", a(), ",x" };
|
||||||
case 0x16: return { "ora $", a(), ",y" };
|
case 0x16: return { "ora $", a(), ",y" };
|
||||||
|
@ -54,7 +54,7 @@ auto SPC700::disassemble(uint16 addr, bool p) -> string {
|
||||||
case 0x20: return { "clp" };
|
case 0x20: return { "clp" };
|
||||||
case 0x21: return { "jst $ffda" };
|
case 0x21: return { "jst $ffda" };
|
||||||
case 0x22: return { "set $", dp(0), ":1" };
|
case 0x22: return { "set $", dp(0), ":1" };
|
||||||
case 0x23: return { "bbs $", dp(0), ":1=$", r(+3, 1) };
|
case 0x23: return { "bbs $", dp(0), ":1=$", rel(+3, 1) };
|
||||||
case 0x24: return { "and $", dp(0) };
|
case 0x24: return { "and $", dp(0) };
|
||||||
case 0x25: return { "and $", a() };
|
case 0x25: return { "and $", a() };
|
||||||
case 0x26: return { "and (x)" };
|
case 0x26: return { "and (x)" };
|
||||||
|
@ -64,13 +64,13 @@ auto SPC700::disassemble(uint16 addr, bool p) -> string {
|
||||||
case 0x2b: return { "rol $", dp(0) };
|
case 0x2b: return { "rol $", dp(0) };
|
||||||
case 0x2c: return { "rol $", a() };
|
case 0x2c: return { "rol $", a() };
|
||||||
case 0x2d: return { "pha" };
|
case 0x2d: return { "pha" };
|
||||||
case 0x2e: return { "bne $", dp(0), "=$", r(+3, 1) };
|
case 0x2e: return { "bne $", dp(0), "=$", rel(+3, 1) };
|
||||||
case 0x28: return { "and #$", b(0) };
|
case 0x28: return { "and #$", b(0) };
|
||||||
case 0x2f: return { "bra $", r(+2) };
|
case 0x2f: return { "bra $", rel(+2) };
|
||||||
case 0x30: return { "bmi $", r(+2) };
|
case 0x30: return { "bmi $", rel(+2) };
|
||||||
case 0x31: return { "jst $ffd8" };
|
case 0x31: return { "jst $ffd8" };
|
||||||
case 0x32: return { "clr $", dp(0), ":1" };
|
case 0x32: return { "clr $", dp(0), ":1" };
|
||||||
case 0x33: return { "bbc $", dp(0), ":1=$", r(+3, 1) };
|
case 0x33: return { "bbc $", dp(0), ":1=$", rel(+3, 1) };
|
||||||
case 0x34: return { "and $", dp(0), ",x" };
|
case 0x34: return { "and $", dp(0), ",x" };
|
||||||
case 0x35: return { "and $", a(), ",x" };
|
case 0x35: return { "and $", a(), ",x" };
|
||||||
case 0x36: return { "and $", a(), ",y" };
|
case 0x36: return { "and $", a(), ",y" };
|
||||||
|
@ -86,7 +86,7 @@ auto SPC700::disassemble(uint16 addr, bool p) -> string {
|
||||||
case 0x40: return { "sep" };
|
case 0x40: return { "sep" };
|
||||||
case 0x41: return { "jst $ffd6" };
|
case 0x41: return { "jst $ffd6" };
|
||||||
case 0x42: return { "set $", dp(0), ":2" };
|
case 0x42: return { "set $", dp(0), ":2" };
|
||||||
case 0x43: return { "bbs $", dp(0), ":2=$", r(+3, 1) };
|
case 0x43: return { "bbs $", dp(0), ":2=$", rel(+3, 1) };
|
||||||
case 0x44: return { "eor $", dp(0) };
|
case 0x44: return { "eor $", dp(0) };
|
||||||
case 0x45: return { "eor $", a() };
|
case 0x45: return { "eor $", a() };
|
||||||
case 0x46: return { "eor (x)" };
|
case 0x46: return { "eor (x)" };
|
||||||
|
@ -99,10 +99,10 @@ auto SPC700::disassemble(uint16 addr, bool p) -> string {
|
||||||
case 0x4d: return { "phx" };
|
case 0x4d: return { "phx" };
|
||||||
case 0x4e: return { "trb $", a() };
|
case 0x4e: return { "trb $", a() };
|
||||||
case 0x4f: return { "jsp $ff", b(0) };
|
case 0x4f: return { "jsp $ff", b(0) };
|
||||||
case 0x50: return { "bvc $", r(+2) };
|
case 0x50: return { "bvc $", rel(+2) };
|
||||||
case 0x51: return { "jst $ffd4" };
|
case 0x51: return { "jst $ffd4" };
|
||||||
case 0x52: return { "clr $", dp(0), ":2" };
|
case 0x52: return { "clr $", dp(0), ":2" };
|
||||||
case 0x53: return { "bbc $", dp(0), ":2=$", r(+3, 1) };
|
case 0x53: return { "bbc $", dp(0), ":2=$", rel(+3, 1) };
|
||||||
case 0x54: return { "eor $", dp(0), ",x" };
|
case 0x54: return { "eor $", dp(0), ",x" };
|
||||||
case 0x55: return { "eor $", a(), ",x" };
|
case 0x55: return { "eor $", a(), ",x" };
|
||||||
case 0x56: return { "eor $", a(), ",y" };
|
case 0x56: return { "eor $", a(), ",y" };
|
||||||
|
@ -118,7 +118,7 @@ auto SPC700::disassemble(uint16 addr, bool p) -> string {
|
||||||
case 0x60: return { "clc" };
|
case 0x60: return { "clc" };
|
||||||
case 0x61: return { "jst $ffd2" };
|
case 0x61: return { "jst $ffd2" };
|
||||||
case 0x62: return { "set $", dp(0), ":3" };
|
case 0x62: return { "set $", dp(0), ":3" };
|
||||||
case 0x63: return { "bbs $", dp(0), ":3=$", r(+3, 1) };
|
case 0x63: return { "bbs $", dp(0), ":3=$", rel(+3, 1) };
|
||||||
case 0x64: return { "cmp $", dp(0) };
|
case 0x64: return { "cmp $", dp(0) };
|
||||||
case 0x65: return { "cmp $", a() };
|
case 0x65: return { "cmp $", a() };
|
||||||
case 0x66: return { "cmp (x)" };
|
case 0x66: return { "cmp (x)" };
|
||||||
|
@ -129,12 +129,12 @@ auto SPC700::disassemble(uint16 addr, bool p) -> string {
|
||||||
case 0x6b: return { "ror $", dp(0) };
|
case 0x6b: return { "ror $", dp(0) };
|
||||||
case 0x6c: return { "ror $", a() };
|
case 0x6c: return { "ror $", a() };
|
||||||
case 0x6d: return { "phy" };
|
case 0x6d: return { "phy" };
|
||||||
case 0x6e: return { "bne --$", dp(0), "=$", r(+3, 1) };
|
case 0x6e: return { "bne --$", dp(0), "=$", rel(+3, 1) };
|
||||||
case 0x6f: return { "rts" };
|
case 0x6f: return { "rts" };
|
||||||
case 0x70: return { "bvs $", r(+2) };
|
case 0x70: return { "bvs $", rel(+2) };
|
||||||
case 0x71: return { "jst $ffd0" };
|
case 0x71: return { "jst $ffd0" };
|
||||||
case 0x72: return { "clr $", dp(0), ":3" };
|
case 0x72: return { "clr $", dp(0), ":3" };
|
||||||
case 0x73: return { "bbc $", dp(0), ":3=$", r(+3, 1) };
|
case 0x73: return { "bbc $", dp(0), ":3=$", rel(+3, 1) };
|
||||||
case 0x74: return { "cmp $", dp(0), ",x" };
|
case 0x74: return { "cmp $", dp(0), ",x" };
|
||||||
case 0x75: return { "cmp $", a(), ",x" };
|
case 0x75: return { "cmp $", a(), ",x" };
|
||||||
case 0x76: return { "cmp $", a(), ",y" };
|
case 0x76: return { "cmp $", a(), ",y" };
|
||||||
|
@ -150,7 +150,7 @@ auto SPC700::disassemble(uint16 addr, bool p) -> string {
|
||||||
case 0x80: return { "sec" };
|
case 0x80: return { "sec" };
|
||||||
case 0x81: return { "jst $ffce" };
|
case 0x81: return { "jst $ffce" };
|
||||||
case 0x82: return { "set $", dp(0), ":4" };
|
case 0x82: return { "set $", dp(0), ":4" };
|
||||||
case 0x83: return { "bbs $", dp(0), ":4=$", r(+3, 1) };
|
case 0x83: return { "bbs $", dp(0), ":4=$", rel(+3, 1) };
|
||||||
case 0x84: return { "adc $", dp(0) };
|
case 0x84: return { "adc $", dp(0) };
|
||||||
case 0x85: return { "adc $", a() };
|
case 0x85: return { "adc $", a() };
|
||||||
case 0x86: return { "adc (x)" };
|
case 0x86: return { "adc (x)" };
|
||||||
|
@ -163,10 +163,10 @@ auto SPC700::disassemble(uint16 addr, bool p) -> string {
|
||||||
case 0x8d: return { "ldy #$", b(0) };
|
case 0x8d: return { "ldy #$", b(0) };
|
||||||
case 0x8e: return { "plp" };
|
case 0x8e: return { "plp" };
|
||||||
case 0x8f: return { "str $", dp(1), "=#$", b(0) };
|
case 0x8f: return { "str $", dp(1), "=#$", b(0) };
|
||||||
case 0x90: return { "bcc $", r(+2) };
|
case 0x90: return { "bcc $", rel(+2) };
|
||||||
case 0x91: return { "jst $ffcc" };
|
case 0x91: return { "jst $ffcc" };
|
||||||
case 0x92: return { "clr $", dp(0), ":4" };
|
case 0x92: return { "clr $", dp(0), ":4" };
|
||||||
case 0x93: return { "bbc $", dp(0), ":4=$", r(+3, 1) };
|
case 0x93: return { "bbc $", dp(0), ":4=$", rel(+3, 1) };
|
||||||
case 0x94: return { "adc $", dp(0), ",x" };
|
case 0x94: return { "adc $", dp(0), ",x" };
|
||||||
case 0x95: return { "adc $", a(), ",x" };
|
case 0x95: return { "adc $", a(), ",x" };
|
||||||
case 0x96: return { "adc $", a(), ",y" };
|
case 0x96: return { "adc $", a(), ",y" };
|
||||||
|
@ -182,7 +182,7 @@ auto SPC700::disassemble(uint16 addr, bool p) -> string {
|
||||||
case 0xa0: return { "sei" };
|
case 0xa0: return { "sei" };
|
||||||
case 0xa1: return { "jst $ffca" };
|
case 0xa1: return { "jst $ffca" };
|
||||||
case 0xa2: return { "set $", dp(0), ":5" };
|
case 0xa2: return { "set $", dp(0), ":5" };
|
||||||
case 0xa3: return { "bbs $", dp(0), ":5=$", r(+3, 1) };
|
case 0xa3: return { "bbs $", dp(0), ":5=$", rel(+3, 1) };
|
||||||
case 0xa4: return { "sbc $", dp(0) };
|
case 0xa4: return { "sbc $", dp(0) };
|
||||||
case 0xa5: return { "sbc $", a() };
|
case 0xa5: return { "sbc $", a() };
|
||||||
case 0xa6: return { "sbc (x)" };
|
case 0xa6: return { "sbc (x)" };
|
||||||
|
@ -195,10 +195,10 @@ auto SPC700::disassemble(uint16 addr, bool p) -> string {
|
||||||
case 0xad: return { "cpy #$", b(0) };
|
case 0xad: return { "cpy #$", b(0) };
|
||||||
case 0xae: return { "pla" };
|
case 0xae: return { "pla" };
|
||||||
case 0xaf: return { "sta (x++)" };
|
case 0xaf: return { "sta (x++)" };
|
||||||
case 0xb0: return { "bcs $", r(+2) };
|
case 0xb0: return { "bcs $", rel(+2) };
|
||||||
case 0xb1: return { "jst $ffc8" };
|
case 0xb1: return { "jst $ffc8" };
|
||||||
case 0xb2: return { "clr $", dp(0), ":5" };
|
case 0xb2: return { "clr $", dp(0), ":5" };
|
||||||
case 0xb3: return { "bbc $", dp(0), ":5=$", r(+3, 1) };
|
case 0xb3: return { "bbc $", dp(0), ":5=$", rel(+3, 1) };
|
||||||
case 0xb4: return { "sbc $", dp(0), ",x" };
|
case 0xb4: return { "sbc $", dp(0), ",x" };
|
||||||
case 0xb5: return { "sbc $", a(), ",x" };
|
case 0xb5: return { "sbc $", a(), ",x" };
|
||||||
case 0xb6: return { "sbc $", a(), ",y" };
|
case 0xb6: return { "sbc $", a(), ",y" };
|
||||||
|
@ -214,7 +214,7 @@ auto SPC700::disassemble(uint16 addr, bool p) -> string {
|
||||||
case 0xc0: return { "cli" };
|
case 0xc0: return { "cli" };
|
||||||
case 0xc1: return { "jst $ffc6" };
|
case 0xc1: return { "jst $ffc6" };
|
||||||
case 0xc2: return { "set $", dp(0), ":6" };
|
case 0xc2: return { "set $", dp(0), ":6" };
|
||||||
case 0xc3: return { "bbs $", dp(0), ":6=$", r(+3, 1) };
|
case 0xc3: return { "bbs $", dp(0), ":6=$", rel(+3, 1) };
|
||||||
case 0xc4: return { "sta $", dp(0) };
|
case 0xc4: return { "sta $", dp(0) };
|
||||||
case 0xc5: return { "sta $", a() };
|
case 0xc5: return { "sta $", a() };
|
||||||
case 0xc6: return { "sta (x)" };
|
case 0xc6: return { "sta (x)" };
|
||||||
|
@ -227,10 +227,10 @@ auto SPC700::disassemble(uint16 addr, bool p) -> string {
|
||||||
case 0xcd: return { "ldx #$", b(0) };
|
case 0xcd: return { "ldx #$", b(0) };
|
||||||
case 0xce: return { "plx" };
|
case 0xce: return { "plx" };
|
||||||
case 0xcf: return { "mul" };
|
case 0xcf: return { "mul" };
|
||||||
case 0xd0: return { "bne $", r(+2) };
|
case 0xd0: return { "bne $", rel(+2) };
|
||||||
case 0xd1: return { "jst $ffc4" };
|
case 0xd1: return { "jst $ffc4" };
|
||||||
case 0xd2: return { "clr $", dp(0), ":6" };
|
case 0xd2: return { "clr $", dp(0), ":6" };
|
||||||
case 0xd3: return { "bbc $", dp(0), ":6=$", r(+3, 1) };
|
case 0xd3: return { "bbc $", dp(0), ":6=$", rel(+3, 1) };
|
||||||
case 0xd4: return { "sta $", dp(0), ",x" };
|
case 0xd4: return { "sta $", dp(0), ",x" };
|
||||||
case 0xd5: return { "sta $", a(), ",x" };
|
case 0xd5: return { "sta $", a(), ",x" };
|
||||||
case 0xd6: return { "sta $", a(), ",y" };
|
case 0xd6: return { "sta $", a(), ",y" };
|
||||||
|
@ -241,12 +241,12 @@ auto SPC700::disassemble(uint16 addr, bool p) -> string {
|
||||||
case 0xdb: return { "sty $", dp(0), ",x" };
|
case 0xdb: return { "sty $", dp(0), ",x" };
|
||||||
case 0xdc: return { "dey" };
|
case 0xdc: return { "dey" };
|
||||||
case 0xdd: return { "tya" };
|
case 0xdd: return { "tya" };
|
||||||
case 0xde: return { "bne $", dp(0), ",x=$", r(+3, 1) };
|
case 0xde: return { "bne $", dp(0), ",x=$", rel(+3, 1) };
|
||||||
case 0xdf: return { "daa" };
|
case 0xdf: return { "daa" };
|
||||||
case 0xe0: return { "clv" };
|
case 0xe0: return { "clv" };
|
||||||
case 0xe1: return { "jst $ffc2" };
|
case 0xe1: return { "jst $ffc2" };
|
||||||
case 0xe2: return { "set $", dp(0), ":7" };
|
case 0xe2: return { "set $", dp(0), ":7" };
|
||||||
case 0xe3: return { "bbs $", dp(0), ":7=$", r(+3, 1) };
|
case 0xe3: return { "bbs $", dp(0), ":7=$", rel(+3, 1) };
|
||||||
case 0xe4: return { "lda $", dp(0) };
|
case 0xe4: return { "lda $", dp(0) };
|
||||||
case 0xe5: return { "lda $", a() };
|
case 0xe5: return { "lda $", a() };
|
||||||
case 0xe6: return { "lda (x)" };
|
case 0xe6: return { "lda (x)" };
|
||||||
|
@ -259,10 +259,10 @@ auto SPC700::disassemble(uint16 addr, bool p) -> string {
|
||||||
case 0xed: return { "cmc" };
|
case 0xed: return { "cmc" };
|
||||||
case 0xee: return { "ply" };
|
case 0xee: return { "ply" };
|
||||||
case 0xef: return { "wai" };
|
case 0xef: return { "wai" };
|
||||||
case 0xf0: return { "beq $", r(+2) };
|
case 0xf0: return { "beq $", rel(+2) };
|
||||||
case 0xf1: return { "jst $ffc0" };
|
case 0xf1: return { "jst $ffc0" };
|
||||||
case 0xf2: return { "clr $", dp(0), ":7" };
|
case 0xf2: return { "clr $", dp(0), ":7" };
|
||||||
case 0xf3: return { "bbc $", dp(0), ":7=$", r(+3, 1) };
|
case 0xf3: return { "bbc $", dp(0), ":7=$", rel(+3, 1) };
|
||||||
case 0xf4: return { "lda $", dp(0), ",x" };
|
case 0xf4: return { "lda $", dp(0), ",x" };
|
||||||
case 0xf5: return { "lda $", a(), ",x" };
|
case 0xf5: return { "lda $", a(), ",x" };
|
||||||
case 0xf6: return { "lda $", a(), ",y" };
|
case 0xf6: return { "lda $", a(), ",y" };
|
||||||
|
@ -273,7 +273,7 @@ auto SPC700::disassemble(uint16 addr, bool p) -> string {
|
||||||
case 0xfb: return { "ldy $", dp(0), ",x" };
|
case 0xfb: return { "ldy $", dp(0), ",x" };
|
||||||
case 0xfc: return { "iny" };
|
case 0xfc: return { "iny" };
|
||||||
case 0xfd: return { "tay" };
|
case 0xfd: return { "tay" };
|
||||||
case 0xfe: return { "bne --y=$", r(+2) };
|
case 0xfe: return { "bne --y=$", rel(+2) };
|
||||||
case 0xff: return { "stp" };
|
case 0xff: return { "stp" };
|
||||||
}
|
}
|
||||||
throw;
|
throw;
|
||||||
|
@ -285,20 +285,20 @@ auto SPC700::disassemble(uint16 addr, bool p) -> string {
|
||||||
while(length++ < 30) output.append(" ");
|
while(length++ < 30) output.append(" ");
|
||||||
|
|
||||||
output.append(
|
output.append(
|
||||||
"YA:", hex(regs.ya, 4L),
|
"YA:", hex(YA, 4L),
|
||||||
" A:", hex(regs.a, 2L),
|
" A:", hex(A, 2L),
|
||||||
" X:", hex(regs.x, 2L),
|
" X:", hex(X, 2L),
|
||||||
" Y:", hex(regs.y, 2L),
|
" Y:", hex(Y, 2L),
|
||||||
" S:", hex(regs.s, 2L),
|
" S:", hex(S, 2L),
|
||||||
" ",
|
" ",
|
||||||
regs.p.n ? "N" : "n",
|
NF ? "N" : "n",
|
||||||
regs.p.v ? "V" : "v",
|
VF ? "V" : "v",
|
||||||
regs.p.p ? "P" : "p",
|
PF ? "P" : "p",
|
||||||
regs.p.b ? "B" : "b",
|
BF ? "B" : "b",
|
||||||
regs.p.h ? "H" : "h",
|
HF ? "H" : "h",
|
||||||
regs.p.i ? "I" : "i",
|
IF ? "I" : "i",
|
||||||
regs.p.z ? "Z" : "z",
|
ZF ? "Z" : "z",
|
||||||
regs.p.c ? "C" : "c"
|
CF ? "C" : "c"
|
||||||
);
|
);
|
||||||
|
|
||||||
return output;
|
return output;
|
||||||
|
|
|
@ -0,0 +1,266 @@
|
||||||
|
#define op(id, name, ...) case id: return instruction##name(__VA_ARGS__);
|
||||||
|
#define fp(name) &SPC700::algorithm##name
|
||||||
|
|
||||||
|
auto SPC700::instruction() -> void {
|
||||||
|
switch(opcode = fetch()) {
|
||||||
|
op(0x00, NOP)
|
||||||
|
op(0x01, JST, 0)
|
||||||
|
op(0x02, SET, 0)
|
||||||
|
op(0x03, BBS, 0)
|
||||||
|
op(0x04, DirectPageRead, fp(OR), A)
|
||||||
|
op(0x05, AbsoluteRead, fp(OR), A)
|
||||||
|
op(0x06, IndirectXRead, fp(OR))
|
||||||
|
op(0x07, IndirectPageXRead, fp(OR))
|
||||||
|
op(0x08, ImmediateRead, fp(OR), A)
|
||||||
|
op(0x09, DirectPageWriteDirectPage, fp(OR))
|
||||||
|
op(0x0a, AbsoluteModifyBit)
|
||||||
|
op(0x0b, DirectPageModify, fp(ASL))
|
||||||
|
op(0x0c, AbsoluteModify, fp(ASL))
|
||||||
|
op(0x0d, Push, P)
|
||||||
|
op(0x0e, TSBAbsolute)
|
||||||
|
op(0x0f, BRK)
|
||||||
|
op(0x10, Branch, NF == 0)
|
||||||
|
op(0x11, JST, 1)
|
||||||
|
op(0x12, CLR, 0)
|
||||||
|
op(0x13, BBC, 0)
|
||||||
|
op(0x14, DirectPageIndexedRead, fp(OR), A, X)
|
||||||
|
op(0x15, AbsoluteIndexedRead, fp(OR), X)
|
||||||
|
op(0x16, AbsoluteIndexedRead, fp(OR), Y)
|
||||||
|
op(0x17, IndirectPageYRead, fp(OR))
|
||||||
|
op(0x18, DirectPageWriteImmediate, fp(OR))
|
||||||
|
op(0x19, IndirectXWriteIndirectY, fp(OR))
|
||||||
|
op(0x1a, DirectPageModifyWord, -1)
|
||||||
|
op(0x1b, DirectPageXModify, fp(ASL))
|
||||||
|
op(0x1c, ImpliedModify, fp(ASL), A)
|
||||||
|
op(0x1d, ImpliedModify, fp(DEC), X)
|
||||||
|
op(0x1e, AbsoluteRead, fp(CMP), X)
|
||||||
|
op(0x1f, JMPIndirectAbsoluteX)
|
||||||
|
op(0x20, FlagClear, PF)
|
||||||
|
op(0x21, JST, 2)
|
||||||
|
op(0x22, SET, 1)
|
||||||
|
op(0x23, BBS, 1)
|
||||||
|
op(0x24, DirectPageRead, fp(AND), A)
|
||||||
|
op(0x25, AbsoluteRead, fp(AND), A)
|
||||||
|
op(0x26, IndirectXRead, fp(AND))
|
||||||
|
op(0x27, IndirectPageXRead, fp(AND))
|
||||||
|
op(0x28, ImmediateRead, fp(AND), A)
|
||||||
|
op(0x29, DirectPageWriteDirectPage, fp(AND))
|
||||||
|
op(0x2a, AbsoluteModifyBit)
|
||||||
|
op(0x2b, DirectPageModify, fp(ROL))
|
||||||
|
op(0x2c, AbsoluteModify, fp(ROL))
|
||||||
|
op(0x2d, Push, A)
|
||||||
|
op(0x2e, BNEDirectPage)
|
||||||
|
op(0x2f, Branch, true)
|
||||||
|
op(0x30, Branch, NF == 1)
|
||||||
|
op(0x31, JST, 3)
|
||||||
|
op(0x32, CLR, 1)
|
||||||
|
op(0x33, BBC, 1)
|
||||||
|
op(0x34, DirectPageIndexedRead, fp(AND), A, X)
|
||||||
|
op(0x35, AbsoluteIndexedRead, fp(AND), X)
|
||||||
|
op(0x36, AbsoluteIndexedRead, fp(AND), Y)
|
||||||
|
op(0x37, IndirectPageYRead, fp(AND))
|
||||||
|
op(0x38, DirectPageWriteImmediate, fp(AND))
|
||||||
|
op(0x39, IndirectXWriteIndirectY, fp(AND))
|
||||||
|
op(0x3a, DirectPageModifyWord, +1)
|
||||||
|
op(0x3b, DirectPageXModify, fp(ROL))
|
||||||
|
op(0x3c, ImpliedModify, fp(ROL), A)
|
||||||
|
op(0x3d, ImpliedModify, fp(INC), X)
|
||||||
|
op(0x3e, DirectPageRead, fp(CMP), X)
|
||||||
|
op(0x3f, JSRAbsolute)
|
||||||
|
op(0x40, FlagSet, PF)
|
||||||
|
op(0x41, JST, 4)
|
||||||
|
op(0x42, SET, 2)
|
||||||
|
op(0x43, BBS, 2)
|
||||||
|
op(0x44, DirectPageRead, fp(EOR), A)
|
||||||
|
op(0x45, AbsoluteRead, fp(EOR), A)
|
||||||
|
op(0x46, IndirectXRead, fp(EOR))
|
||||||
|
op(0x47, IndirectPageXRead, fp(EOR))
|
||||||
|
op(0x48, ImmediateRead, fp(EOR), A)
|
||||||
|
op(0x49, DirectPageWriteDirectPage, fp(EOR))
|
||||||
|
op(0x4a, AbsoluteModifyBit)
|
||||||
|
op(0x4b, DirectPageModify, fp(LSR))
|
||||||
|
op(0x4c, AbsoluteModify, fp(LSR))
|
||||||
|
op(0x4d, Push, X)
|
||||||
|
op(0x4e, TRBAbsolute)
|
||||||
|
op(0x4f, JSPDirectPage)
|
||||||
|
op(0x50, Branch, VF == 0)
|
||||||
|
op(0x51, JST, 5)
|
||||||
|
op(0x52, CLR, 2)
|
||||||
|
op(0x53, BBC, 2)
|
||||||
|
op(0x54, DirectPageIndexedRead, fp(EOR), A, X)
|
||||||
|
op(0x55, AbsoluteIndexedRead, fp(EOR), X)
|
||||||
|
op(0x56, AbsoluteIndexedRead, fp(EOR), Y)
|
||||||
|
op(0x57, IndirectPageYRead, fp(EOR))
|
||||||
|
op(0x58, DirectPageWriteImmediate, fp(EOR))
|
||||||
|
op(0x59, IndirectXWriteIndirectY, fp(EOR))
|
||||||
|
op(0x5a, DirectPageReadWord, fp(CPW))
|
||||||
|
op(0x5b, DirectPageXModify, fp(LSR))
|
||||||
|
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(0x64, DirectPageRead, fp(CMP), A)
|
||||||
|
op(0x65, AbsoluteRead, fp(CMP), A)
|
||||||
|
op(0x66, IndirectXRead, fp(CMP))
|
||||||
|
op(0x67, IndirectPageXRead, fp(CMP))
|
||||||
|
op(0x68, ImmediateRead, fp(CMP), A)
|
||||||
|
op(0x69, DirectPageWriteDirectPage, fp(CMP))
|
||||||
|
op(0x6a, AbsoluteModifyBit)
|
||||||
|
op(0x6b, DirectPageModify, fp(ROR))
|
||||||
|
op(0x6c, AbsoluteModify, fp(ROR))
|
||||||
|
op(0x6d, Push, Y)
|
||||||
|
op(0x6e, BNEDirectPageDecrement)
|
||||||
|
op(0x6f, RTS)
|
||||||
|
op(0x70, Branch, VF == 1)
|
||||||
|
op(0x71, JST, 7)
|
||||||
|
op(0x72, CLR, 3)
|
||||||
|
op(0x73, BBC, 3)
|
||||||
|
op(0x74, DirectPageIndexedRead, fp(CMP), A, X)
|
||||||
|
op(0x75, AbsoluteIndexedRead, fp(CMP), X)
|
||||||
|
op(0x76, AbsoluteIndexedRead, fp(CMP), Y)
|
||||||
|
op(0x77, IndirectPageYRead, fp(CMP))
|
||||||
|
op(0x78, DirectPageWriteImmediate, fp(CMP))
|
||||||
|
op(0x79, IndirectXWriteIndirectY, fp(CMP))
|
||||||
|
op(0x7a, DirectPageReadWord, fp(ADW))
|
||||||
|
op(0x7b, DirectPageXModify, fp(ROR))
|
||||||
|
op(0x7c, ImpliedModify, fp(ROR), A)
|
||||||
|
op(0x7d, Transfer, X, A)
|
||||||
|
op(0x7e, DirectPageRead, fp(CMP), Y)
|
||||||
|
op(0x7f, RTI)
|
||||||
|
op(0x80, FlagSet, CF)
|
||||||
|
op(0x81, JST, 8)
|
||||||
|
op(0x82, SET, 4)
|
||||||
|
op(0x83, BBS, 4)
|
||||||
|
op(0x84, DirectPageRead, fp(ADC), A)
|
||||||
|
op(0x85, AbsoluteRead, fp(ADC), A)
|
||||||
|
op(0x86, IndirectXRead, fp(ADC))
|
||||||
|
op(0x87, IndirectPageXRead, fp(ADC))
|
||||||
|
op(0x88, ImmediateRead, fp(ADC), A)
|
||||||
|
op(0x89, DirectPageWriteDirectPage, fp(ADC))
|
||||||
|
op(0x8a, AbsoluteModifyBit)
|
||||||
|
op(0x8b, DirectPageModify, fp(DEC))
|
||||||
|
op(0x8c, AbsoluteModify, fp(DEC))
|
||||||
|
op(0x8d, ImmediateRead, fp(LD), Y)
|
||||||
|
op(0x8e, PLP)
|
||||||
|
op(0x8f, DirectPageWriteImmediate, fp(ST))
|
||||||
|
op(0x90, Branch, CF == 0)
|
||||||
|
op(0x91, JST, 9)
|
||||||
|
op(0x92, CLR, 4)
|
||||||
|
op(0x93, BBC, 4)
|
||||||
|
op(0x94, DirectPageIndexedRead, fp(ADC), A, X)
|
||||||
|
op(0x95, AbsoluteIndexedRead, fp(ADC), X)
|
||||||
|
op(0x96, AbsoluteIndexedRead, fp(ADC), Y)
|
||||||
|
op(0x97, IndirectPageYRead, fp(ADC))
|
||||||
|
op(0x98, DirectPageWriteImmediate, fp(ADC))
|
||||||
|
op(0x99, IndirectXWriteIndirectY, fp(ADC))
|
||||||
|
op(0x9a, DirectPageReadWord, fp(SBW))
|
||||||
|
op(0x9b, DirectPageXModify, fp(DEC))
|
||||||
|
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(0xa4, DirectPageRead, fp(SBC), A)
|
||||||
|
op(0xa5, AbsoluteRead, fp(SBC), A)
|
||||||
|
op(0xa6, IndirectXRead, fp(SBC))
|
||||||
|
op(0xa7, IndirectPageXRead, fp(SBC))
|
||||||
|
op(0xa8, ImmediateRead, fp(SBC), A)
|
||||||
|
op(0xa9, DirectPageWriteDirectPage, fp(SBC))
|
||||||
|
op(0xaa, AbsoluteModifyBit)
|
||||||
|
op(0xab, DirectPageModify, fp(INC))
|
||||||
|
op(0xac, AbsoluteModify, fp(INC))
|
||||||
|
op(0xad, ImmediateRead, fp(CMP), Y)
|
||||||
|
op(0xae, Pull, A)
|
||||||
|
op(0xaf, STAIndirectXIncrement)
|
||||||
|
op(0xb0, Branch, CF == 1)
|
||||||
|
op(0xb1, JST, 11)
|
||||||
|
op(0xb2, CLR, 5)
|
||||||
|
op(0xb3, BBC, 5)
|
||||||
|
op(0xb4, DirectPageIndexedRead, fp(SBC), A, X)
|
||||||
|
op(0xb5, AbsoluteIndexedRead, fp(SBC), X)
|
||||||
|
op(0xb6, AbsoluteIndexedRead, fp(SBC), Y)
|
||||||
|
op(0xb7, IndirectPageYRead, fp(SBC))
|
||||||
|
op(0xb8, DirectPageWriteImmediate, fp(SBC))
|
||||||
|
op(0xb9, IndirectXWriteIndirectY, fp(SBC))
|
||||||
|
op(0xba, DirectPageReadWord, fp(LDW))
|
||||||
|
op(0xbb, DirectPageXModify, fp(INC))
|
||||||
|
op(0xbc, ImpliedModify, fp(INC), A)
|
||||||
|
op(0xbd, Transfer, X, S)
|
||||||
|
op(0xbe, DAS)
|
||||||
|
op(0xbf, LDAIndirectXIncrement)
|
||||||
|
op(0xc0, FlagClear, IF)
|
||||||
|
op(0xc1, JST, 12)
|
||||||
|
op(0xc2, SET, 6)
|
||||||
|
op(0xc3, BBS, 6)
|
||||||
|
op(0xc4, DirectPageWrite, A)
|
||||||
|
op(0xc5, AbsoluteWrite, A)
|
||||||
|
op(0xc6, STAIndirectX)
|
||||||
|
op(0xc7, STAIndirectPageX)
|
||||||
|
op(0xc8, ImmediateRead, fp(CMP), X)
|
||||||
|
op(0xc9, AbsoluteWrite, X)
|
||||||
|
op(0xca, AbsoluteModifyBit)
|
||||||
|
op(0xcb, DirectPageWrite, Y)
|
||||||
|
op(0xcc, AbsoluteWrite, Y)
|
||||||
|
op(0xcd, ImmediateRead, fp(LD), X)
|
||||||
|
op(0xce, Pull, X)
|
||||||
|
op(0xcf, MUL)
|
||||||
|
op(0xd0, Branch, ZF == 0)
|
||||||
|
op(0xd1, JST, 13)
|
||||||
|
op(0xd2, CLR, 6)
|
||||||
|
op(0xd3, BBC, 6)
|
||||||
|
op(0xd4, DirectPageIndexedWrite, A, X)
|
||||||
|
op(0xd5, AbsoluteIndexedWrite, X)
|
||||||
|
op(0xd6, AbsoluteIndexedWrite, Y)
|
||||||
|
op(0xd7, STAIndirectPageY)
|
||||||
|
op(0xd8, DirectPageWrite, X)
|
||||||
|
op(0xd9, DirectPageIndexedWrite, X, Y)
|
||||||
|
op(0xda, STWDirectPage)
|
||||||
|
op(0xdb, DirectPageIndexedWrite, Y, X)
|
||||||
|
op(0xdc, ImpliedModify, fp(DEC), Y)
|
||||||
|
op(0xdd, Transfer, Y, A)
|
||||||
|
op(0xde, BNEDirectPageX)
|
||||||
|
op(0xdf, DAA)
|
||||||
|
op(0xe0, CLV)
|
||||||
|
op(0xe1, JST, 14)
|
||||||
|
op(0xe2, SET, 7)
|
||||||
|
op(0xe3, BBS, 7)
|
||||||
|
op(0xe4, DirectPageRead, fp(LD), A)
|
||||||
|
op(0xe5, AbsoluteRead, fp(LD), A)
|
||||||
|
op(0xe6, IndirectXRead, fp(LD))
|
||||||
|
op(0xe7, IndirectPageXRead, fp(LD))
|
||||||
|
op(0xe8, ImmediateRead, fp(LD), A)
|
||||||
|
op(0xe9, AbsoluteRead, fp(LD), X)
|
||||||
|
op(0xea, AbsoluteModifyBit)
|
||||||
|
op(0xeb, DirectPageRead, fp(LD), Y)
|
||||||
|
op(0xec, AbsoluteRead, fp(LD), Y)
|
||||||
|
op(0xed, CMC)
|
||||||
|
op(0xee, Pull, Y)
|
||||||
|
op(0xef, WAI)
|
||||||
|
op(0xf0, Branch, ZF == 1)
|
||||||
|
op(0xf1, JST, 15)
|
||||||
|
op(0xf2, CLR, 7)
|
||||||
|
op(0xf3, BBC, 7)
|
||||||
|
op(0xf4, DirectPageIndexedRead, fp(LD), A, X)
|
||||||
|
op(0xf5, AbsoluteIndexedRead, fp(LD), X)
|
||||||
|
op(0xf6, AbsoluteIndexedRead, fp(LD), Y)
|
||||||
|
op(0xf7, IndirectPageYRead, fp(LD))
|
||||||
|
op(0xf8, DirectPageRead, fp(LD), X)
|
||||||
|
op(0xf9, DirectPageIndexedRead, fp(LD), X, Y)
|
||||||
|
op(0xfa, DirectPageWriteDirectPage, fp(ST))
|
||||||
|
op(0xfb, DirectPageIndexedRead, fp(LD), Y, X)
|
||||||
|
op(0xfc, ImpliedModify, fp(INC), Y)
|
||||||
|
op(0xfd, Transfer, A, Y)
|
||||||
|
op(0xfe, BNEYDecrement)
|
||||||
|
op(0xff, STP)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef op
|
||||||
|
#undef fp
|
|
@ -1,142 +1,128 @@
|
||||||
#define call (this->*op)
|
#define alu (this->*op)
|
||||||
|
|
||||||
auto SPC700::op_adjust(fps op, reg r) {
|
auto SPC700::instructionImpliedModify(fps op, uint8& target) -> void {
|
||||||
idle();
|
idle();
|
||||||
r = call(r);
|
target = alu(target);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto SPC700::op_adjust_addr(fps op) {
|
auto SPC700::instructionAbsoluteModify(fps op) -> void {
|
||||||
dp.l = readPC();
|
uint16 absolute = fetch();
|
||||||
dp.h = readPC();
|
absolute |= fetch() << 8;
|
||||||
rd = read(dp);
|
uint8 data = read(absolute);
|
||||||
rd = call(rd);
|
write(absolute, alu(data));
|
||||||
write(dp, rd);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto SPC700::op_adjust_dp(fps op) {
|
auto SPC700::instructionDirectPageModify(fps op) -> void {
|
||||||
dp = readPC();
|
uint8 direct = fetch();
|
||||||
rd = readDP(dp);
|
uint8 data = load(direct);
|
||||||
rd = call(rd);
|
store(direct, alu(data));
|
||||||
writeDP(dp, rd);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto SPC700::op_adjust_dpw(int n) {
|
auto SPC700::instructionDirectPageModifyWord(int adjust) -> void {
|
||||||
dp = readPC();
|
uint8 direct = fetch();
|
||||||
rd.w = readDP(dp) + n;
|
uint16 data = load(direct) + adjust;
|
||||||
writeDP(dp++, rd.l);
|
store(direct++, data >> 0);
|
||||||
rd.h += readDP(dp);
|
data += load(direct) << 8;
|
||||||
writeDP(dp++, rd.h);
|
store(direct++, data >> 8);
|
||||||
regs.p.n = rd & 0x8000;
|
ZF = data == 0;
|
||||||
regs.p.z = rd == 0;
|
NF = data & 0x8000;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto SPC700::op_adjust_dpx(fps op) {
|
auto SPC700::instructionDirectPageXModify(fps op) -> void {
|
||||||
dp = readPC();
|
uint8 direct = fetch();
|
||||||
idle();
|
idle();
|
||||||
rd = readDP(dp + regs.x);
|
uint8 data = load(direct + X);
|
||||||
rd = call(rd);
|
store(direct + X, alu(data));
|
||||||
writeDP(dp + regs.x, rd);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto SPC700::op_branch(bool condition) {
|
auto SPC700::instructionBranch(bool take) -> void {
|
||||||
rd = readPC();
|
uint8 data = fetch();
|
||||||
if(!condition) return;
|
if(!take) return;
|
||||||
idle();
|
idle();
|
||||||
idle();
|
idle();
|
||||||
regs.pc += (int8)rd;
|
PC += (int8)data;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto SPC700::op_branch_bit() {
|
auto SPC700::instructionPull(uint8& data) -> void {
|
||||||
dp = readPC();
|
|
||||||
sp = readDP(dp);
|
|
||||||
rd = readPC();
|
|
||||||
idle();
|
|
||||||
if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) return;
|
|
||||||
idle();
|
idle();
|
||||||
idle();
|
idle();
|
||||||
regs.pc += (int8)rd;
|
data = pull();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto SPC700::op_pull(reg r) {
|
auto SPC700::instructionPush(uint8 data) -> void {
|
||||||
idle();
|
idle();
|
||||||
idle();
|
idle();
|
||||||
r = readSP();
|
push(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto SPC700::op_push(uint8 r) {
|
auto SPC700::instructionAbsoluteRead(fpb op, uint8& target) -> void {
|
||||||
|
uint16 absolute = fetch();
|
||||||
|
absolute |= fetch() << 8;
|
||||||
|
uint8 data = read(absolute);
|
||||||
|
target = alu(target, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto SPC700::instructionAbsoluteIndexedRead(fpb op, uint8& index) -> void {
|
||||||
|
uint16 absolute = fetch();
|
||||||
|
absolute |= fetch() << 8;
|
||||||
idle();
|
idle();
|
||||||
|
uint8 data = read(absolute + index);
|
||||||
|
A = alu(A, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto SPC700::instructionImmediateRead(fpb op, uint8& target) -> void {
|
||||||
|
uint8 data = fetch();
|
||||||
|
target = alu(target, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto SPC700::instructionDirectPageRead(fpb op, uint8& target) -> void {
|
||||||
|
uint8 direct = fetch();
|
||||||
|
uint8 data = load(direct);
|
||||||
|
target = alu(target, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto SPC700::instructionDirectPageIndexedRead(fpb op, uint8& data, uint8& index) -> void {
|
||||||
|
dp = fetch();
|
||||||
idle();
|
idle();
|
||||||
writeSP(r);
|
rd = load(dp + index);
|
||||||
|
data = alu(data, rd);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto SPC700::op_read_addr(fpb op, reg r) {
|
auto SPC700::instructionDirectPageReadWord(fpw op) -> void {
|
||||||
dp.l = readPC();
|
dp = fetch();
|
||||||
dp.h = readPC();
|
rd.l = load(dp++);
|
||||||
rd = read(dp);
|
if(op != &SPC700::algorithmCPW) idle();
|
||||||
r = call(r, rd);
|
rd.h = load(dp++);
|
||||||
|
YA = alu(YA, rd);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto SPC700::op_read_addri(fpb op, reg r) {
|
auto SPC700::instructionIndirectPageXRead(fpb op) -> void {
|
||||||
dp.l = readPC();
|
dp = fetch() + X;
|
||||||
dp.h = readPC();
|
|
||||||
idle();
|
idle();
|
||||||
rd = read(dp + r);
|
sp.l = load(dp++);
|
||||||
regs.a = call(regs.a, rd);
|
sp.h = load(dp++);
|
||||||
}
|
|
||||||
|
|
||||||
auto SPC700::op_read_const(fpb op, reg r) {
|
|
||||||
rd = readPC();
|
|
||||||
r = call(r, rd);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto SPC700::op_read_dp(fpb op, reg r) {
|
|
||||||
dp = readPC();
|
|
||||||
rd = readDP(dp);
|
|
||||||
r = call(r, rd);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto SPC700::op_read_dpi(fpb op, reg r, reg i) {
|
|
||||||
dp = readPC();
|
|
||||||
idle();
|
|
||||||
rd = readDP(dp + i);
|
|
||||||
r = call(r, rd);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto SPC700::op_read_dpw(fpw op) {
|
|
||||||
dp = readPC();
|
|
||||||
rd.l = readDP(dp++);
|
|
||||||
if(op != &SPC700::op_cpw) idle();
|
|
||||||
rd.h = readDP(dp++);
|
|
||||||
regs.ya = call(regs.ya, rd);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto SPC700::op_read_idpx(fpb op) {
|
|
||||||
dp = readPC() + regs.x;
|
|
||||||
idle();
|
|
||||||
sp.l = readDP(dp++);
|
|
||||||
sp.h = readDP(dp++);
|
|
||||||
rd = read(sp);
|
rd = read(sp);
|
||||||
regs.a = call(regs.a, rd);
|
A = alu(A, rd);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto SPC700::op_read_idpy(fpb op) {
|
auto SPC700::instructionIndirectPageYRead(fpb op) -> void {
|
||||||
dp = readPC();
|
dp = fetch();
|
||||||
idle();
|
idle();
|
||||||
sp.l = readDP(dp++);
|
sp.l = load(dp++);
|
||||||
sp.h = readDP(dp++);
|
sp.h = load(dp++);
|
||||||
rd = read(sp + regs.y);
|
rd = read(sp + Y);
|
||||||
regs.a = call(regs.a, rd);
|
A = alu(A, rd);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto SPC700::op_read_ix(fpb op) {
|
auto SPC700::instructionIndirectXRead(fpb op) -> void {
|
||||||
idle();
|
idle();
|
||||||
rd = readDP(regs.x);
|
rd = load(X);
|
||||||
regs.a = call(regs.a, rd);
|
A = alu(A, rd);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto SPC700::op_set_addr_bit() {
|
auto SPC700::instructionAbsoluteModifyBit() -> void {
|
||||||
dp.l = readPC();
|
dp.l = fetch();
|
||||||
dp.h = readPC();
|
dp.h = fetch();
|
||||||
bit = dp >> 13;
|
bit = dp >> 13;
|
||||||
dp &= 0x1fff;
|
dp &= 0x1fff;
|
||||||
rd = read(dp);
|
rd = read(dp);
|
||||||
|
@ -144,22 +130,22 @@ auto SPC700::op_set_addr_bit() {
|
||||||
case 0: //orc addr:bit
|
case 0: //orc addr:bit
|
||||||
case 1: //orc !addr:bit
|
case 1: //orc !addr:bit
|
||||||
idle();
|
idle();
|
||||||
regs.p.c |= (rd & (1 << bit)) ^ (bool)(opcode & 0x20);
|
CF |= (rd & (1 << bit)) ^ (bool)(opcode & 0x20);
|
||||||
break;
|
break;
|
||||||
case 2: //and addr:bit
|
case 2: //and addr:bit
|
||||||
case 3: //and !addr:bit
|
case 3: //and !addr:bit
|
||||||
regs.p.c &= (rd & (1 << bit)) ^ (bool)(opcode & 0x20);
|
CF &= (rd & (1 << bit)) ^ (bool)(opcode & 0x20);
|
||||||
break;
|
break;
|
||||||
case 4: //eor addr:bit
|
case 4: //eor addr:bit
|
||||||
idle();
|
idle();
|
||||||
regs.p.c ^= (bool)(rd & (1 << bit));
|
CF ^= (bool)(rd & (1 << bit));
|
||||||
break;
|
break;
|
||||||
case 5: //ldc addr:bit
|
case 5: //ldc addr:bit
|
||||||
regs.p.c = (rd & (1 << bit));
|
CF = (rd & (1 << bit));
|
||||||
break;
|
break;
|
||||||
case 6: //stc addr:bit
|
case 6: //stc addr:bit
|
||||||
idle();
|
idle();
|
||||||
rd = (rd & ~(1 << bit)) | (regs.p.c << bit);
|
rd = (rd & ~(1 << bit)) | (CF << bit);
|
||||||
write(dp, rd);
|
write(dp, rd);
|
||||||
break;
|
break;
|
||||||
case 7: //not addr:bit
|
case 7: //not addr:bit
|
||||||
|
@ -169,190 +155,209 @@ auto SPC700::op_set_addr_bit() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto SPC700::op_set_bit() {
|
auto SPC700::instructionFlagClear(bool& flag) -> void {
|
||||||
dp = readPC();
|
|
||||||
rd = readDP(dp) & ~(1 << (opcode >> 5));
|
|
||||||
writeDP(dp, rd | (!(opcode & 0x10) << (opcode >> 5)));
|
|
||||||
}
|
|
||||||
|
|
||||||
auto SPC700::op_set_flag(uint bit, bool value) {
|
|
||||||
idle();
|
idle();
|
||||||
if(bit == regs.p.i.bit) idle();
|
if(&flag == &IF) idle();
|
||||||
regs.p = value ? (regs.p | (1 << bit)) : (regs.p & ~(1 << bit));
|
flag = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto SPC700::op_test_addr(bool set) {
|
auto SPC700::instructionFlagSet(bool& flag) -> void {
|
||||||
dp.l = readPC();
|
idle();
|
||||||
dp.h = readPC();
|
if(&flag == &IF) idle();
|
||||||
rd = read(dp);
|
flag = 1;
|
||||||
regs.p.n = (regs.a - rd) & 0x80;
|
|
||||||
regs.p.z = (regs.a - rd) == 0;
|
|
||||||
read(dp);
|
|
||||||
write(dp, set ? rd | regs.a : rd & ~regs.a);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto SPC700::op_transfer(reg from, reg to) {
|
auto SPC700::instructionTransfer(uint8& from, uint8& to) -> void {
|
||||||
idle();
|
idle();
|
||||||
to = from;
|
to = from;
|
||||||
if(&to == ®s.s) return;
|
if(&to == &S) return;
|
||||||
regs.p.n = (to & 0x80);
|
ZF = to == 0;
|
||||||
regs.p.z = (to == 0);
|
NF = to & 0x80;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto SPC700::op_write_addr(reg r) {
|
auto SPC700::instructionAbsoluteWrite(uint8& data) -> void {
|
||||||
dp.l = readPC();
|
dp.l = fetch();
|
||||||
dp.h = readPC();
|
dp.h = fetch();
|
||||||
read(dp);
|
read(dp);
|
||||||
write(dp, r);
|
write(dp, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto SPC700::op_write_addri(reg i) {
|
auto SPC700::instructionAbsoluteIndexedWrite(uint8& index) -> void {
|
||||||
dp.l = readPC();
|
dp.l = fetch();
|
||||||
dp.h = readPC();
|
dp.h = fetch();
|
||||||
idle();
|
idle();
|
||||||
dp += i;
|
dp += index;
|
||||||
read(dp);
|
read(dp);
|
||||||
write(dp, regs.a);
|
write(dp, A);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto SPC700::op_write_dp(reg r) {
|
auto SPC700::instructionDirectPageWrite(uint8& data) -> void {
|
||||||
dp = readPC();
|
dp = fetch();
|
||||||
readDP(dp);
|
load(dp);
|
||||||
writeDP(dp, r);
|
store(dp, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto SPC700::op_write_dpi(reg r, reg i) {
|
auto SPC700::instructionDirectPageIndexedWrite(uint8& data, uint8& index) -> void {
|
||||||
dp = readPC() + i;
|
dp = fetch() + index;
|
||||||
idle();
|
idle();
|
||||||
readDP(dp);
|
load(dp);
|
||||||
writeDP(dp, r);
|
store(dp, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto SPC700::op_write_dp_const(fpb op) {
|
auto SPC700::instructionDirectPageWriteImmediate(fpb op) -> void {
|
||||||
rd = readPC();
|
rd = fetch();
|
||||||
dp = readPC();
|
dp = fetch();
|
||||||
wr = readDP(dp);
|
wr = load(dp);
|
||||||
wr = call(wr, rd);
|
wr = alu(wr, rd);
|
||||||
op != &SPC700::op_cmp ? writeDP(dp, wr) : idle();
|
op != &SPC700::algorithmCMP ? store(dp, wr) : idle();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto SPC700::op_write_dp_dp(fpb op) {
|
auto SPC700::instructionDirectPageWriteDirectPage(fpb op) -> void {
|
||||||
sp = readPC();
|
sp = fetch();
|
||||||
rd = readDP(sp);
|
rd = load(sp);
|
||||||
dp = readPC();
|
dp = fetch();
|
||||||
if(op != &SPC700::op_st) wr = readDP(dp);
|
if(op != &SPC700::algorithmST) wr = load(dp);
|
||||||
wr = call(wr, rd);
|
wr = alu(wr, rd);
|
||||||
op != &SPC700::op_cmp ? writeDP(dp, wr) : idle();
|
op != &SPC700::algorithmCMP ? store(dp, wr) : idle();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto SPC700::op_write_ix_iy(fpb op) {
|
auto SPC700::instructionIndirectXWriteIndirectY(fpb op) -> void {
|
||||||
idle();
|
idle();
|
||||||
rd = readDP(regs.y);
|
rd = load(Y);
|
||||||
wr = readDP(regs.x);
|
wr = load(X);
|
||||||
wr = call(wr, rd);
|
wr = alu(wr, rd);
|
||||||
op != &SPC700::op_cmp ? writeDP(regs.x, wr) : idle();
|
op != &SPC700::algorithmCMP ? store(X, wr) : idle();
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
auto SPC700::op_bne_dp() {
|
auto SPC700::instructionBBC(uint3 bit) -> void {
|
||||||
dp = readPC();
|
dp = fetch();
|
||||||
sp = readDP(dp);
|
uint8 data = load(dp);
|
||||||
rd = readPC();
|
rd = fetch();
|
||||||
idle();
|
idle();
|
||||||
if(regs.a == sp) return;
|
if(data.bit(bit) == 1) return;
|
||||||
idle();
|
idle();
|
||||||
idle();
|
idle();
|
||||||
regs.pc += (int8)rd;
|
PC += (int8)rd;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto SPC700::op_bne_dpdec() {
|
auto SPC700::instructionBBS(uint3 bit) -> void {
|
||||||
dp = readPC();
|
dp = fetch();
|
||||||
wr = readDP(dp);
|
uint8 data = load(dp);
|
||||||
writeDP(dp, --wr);
|
rd = fetch();
|
||||||
rd = readPC();
|
idle();
|
||||||
|
if(data.bit(bit) == 0) return;
|
||||||
|
idle();
|
||||||
|
idle();
|
||||||
|
PC += (int8)rd;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto SPC700::instructionBNEDirectPage() -> void {
|
||||||
|
dp = fetch();
|
||||||
|
sp = load(dp);
|
||||||
|
rd = fetch();
|
||||||
|
idle();
|
||||||
|
if(A == sp) return;
|
||||||
|
idle();
|
||||||
|
idle();
|
||||||
|
PC += (int8)rd;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto SPC700::instructionBNEDirectPageDecrement() -> void {
|
||||||
|
dp = fetch();
|
||||||
|
wr = load(dp);
|
||||||
|
store(dp, --wr);
|
||||||
|
rd = fetch();
|
||||||
if(wr == 0) return;
|
if(wr == 0) return;
|
||||||
idle();
|
idle();
|
||||||
idle();
|
idle();
|
||||||
regs.pc += (int8)rd;
|
PC += (int8)rd;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto SPC700::op_bne_dpx() {
|
auto SPC700::instructionBNEDirectPageX() -> void {
|
||||||
dp = readPC();
|
dp = fetch();
|
||||||
idle();
|
idle();
|
||||||
sp = readDP(dp + regs.x);
|
sp = load(dp + X);
|
||||||
rd = readPC();
|
rd = fetch();
|
||||||
idle();
|
idle();
|
||||||
if(regs.a == sp) return;
|
if(A == sp) return;
|
||||||
idle();
|
idle();
|
||||||
idle();
|
idle();
|
||||||
regs.pc += (int8)rd;
|
PC += (int8)rd;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto SPC700::op_bne_ydec() {
|
auto SPC700::instructionBNEYDecrement() -> void {
|
||||||
rd = readPC();
|
rd = fetch();
|
||||||
idle();
|
idle();
|
||||||
idle();
|
idle();
|
||||||
if(--regs.y == 0) return;
|
if(--Y == 0) return;
|
||||||
idle();
|
idle();
|
||||||
idle();
|
idle();
|
||||||
regs.pc += (int8)rd;
|
PC += (int8)rd;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto SPC700::op_brk() {
|
auto SPC700::instructionBRK() -> void {
|
||||||
rd.l = read(0xffde);
|
rd.l = read(0xffde);
|
||||||
rd.h = read(0xffdf);
|
rd.h = read(0xffdf);
|
||||||
idle();
|
idle();
|
||||||
idle();
|
idle();
|
||||||
writeSP(regs.pc.h);
|
push(PC >> 8);
|
||||||
writeSP(regs.pc.l);
|
push(PC >> 0);
|
||||||
writeSP(regs.p);
|
push(P);
|
||||||
regs.pc = rd;
|
PC = rd;
|
||||||
regs.p.b = 1;
|
IF = 0;
|
||||||
regs.p.i = 0;
|
BF = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto SPC700::op_clv() {
|
auto SPC700::instructionCLR(uint3 bit) -> void {
|
||||||
idle();
|
uint8 direct = fetch();
|
||||||
regs.p.v = 0;
|
uint8 data = load(direct);
|
||||||
regs.p.h = 0;
|
data.bit(bit) = 0;
|
||||||
|
store(direct, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto SPC700::op_cmc() {
|
auto SPC700::instructionCLV() -> void {
|
||||||
idle();
|
idle();
|
||||||
idle();
|
HF = 0;
|
||||||
regs.p.c = !regs.p.c;
|
VF = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto SPC700::op_daa() {
|
auto SPC700::instructionCMC() -> void {
|
||||||
idle();
|
idle();
|
||||||
idle();
|
idle();
|
||||||
if(regs.p.c || (regs.a) > 0x99) {
|
CF = !CF;
|
||||||
regs.a += 0x60;
|
}
|
||||||
regs.p.c = 1;
|
|
||||||
|
auto SPC700::instructionDAA() -> void {
|
||||||
|
idle();
|
||||||
|
idle();
|
||||||
|
if(CF || A > 0x99) {
|
||||||
|
A += 0x60;
|
||||||
|
CF = 1;
|
||||||
}
|
}
|
||||||
if(regs.p.h || (regs.a & 15) > 0x09) {
|
if(HF || (A & 15) > 0x09) {
|
||||||
regs.a += 0x06;
|
A += 0x06;
|
||||||
}
|
}
|
||||||
regs.p.n = (regs.a & 0x80);
|
ZF = A == 0;
|
||||||
regs.p.z = (regs.a == 0);
|
NF = A & 0x80;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto SPC700::op_das() {
|
auto SPC700::instructionDAS() -> void {
|
||||||
idle();
|
idle();
|
||||||
idle();
|
idle();
|
||||||
if(!regs.p.c || (regs.a) > 0x99) {
|
if(!CF || A > 0x99) {
|
||||||
regs.a -= 0x60;
|
A -= 0x60;
|
||||||
regs.p.c = 0;
|
CF = 0;
|
||||||
}
|
}
|
||||||
if(!regs.p.h || (regs.a & 15) > 0x09) {
|
if(!HF || (A & 15) > 0x09) {
|
||||||
regs.a -= 0x06;
|
A -= 0x06;
|
||||||
}
|
}
|
||||||
regs.p.n = (regs.a & 0x80);
|
ZF = A == 0;
|
||||||
regs.p.z = (regs.a == 0);
|
NF = A & 0x80;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto SPC700::op_div_ya_x() {
|
auto SPC700::instructionDIV() -> void {
|
||||||
idle();
|
idle();
|
||||||
idle();
|
idle();
|
||||||
idle();
|
idle();
|
||||||
|
@ -364,82 +369,82 @@ auto SPC700::op_div_ya_x() {
|
||||||
idle();
|
idle();
|
||||||
idle();
|
idle();
|
||||||
idle();
|
idle();
|
||||||
ya = regs.ya;
|
uint16 ya = YA;
|
||||||
//overflow set if quotient >= 256
|
//overflow set if quotient >= 256
|
||||||
regs.p.v = (regs.y >= regs.x);
|
HF = (Y & 15) >= (X & 15);
|
||||||
regs.p.h = ((regs.y & 15) >= (regs.x & 15));
|
VF = Y >= X;
|
||||||
if(regs.y < (regs.x << 1)) {
|
if(Y < (X << 1)) {
|
||||||
//if quotient is <= 511 (will fit into 9-bit result)
|
//if quotient is <= 511 (will fit into 9-bit result)
|
||||||
regs.a = ya / regs.x;
|
A = ya / X;
|
||||||
regs.y = ya % regs.x;
|
Y = ya % X;
|
||||||
} else {
|
} else {
|
||||||
//otherwise, the quotient won't fit into regs.p.v + regs.a
|
//otherwise, the quotient won't fit into VF + A
|
||||||
//this emulates the odd behavior of the S-SMP in this case
|
//this emulates the odd behavior of the S-SMP in this case
|
||||||
regs.a = 255 - (ya - (regs.x << 9)) / (256 - regs.x);
|
A = 255 - (ya - (X << 9)) / (256 - X);
|
||||||
regs.y = regs.x + (ya - (regs.x << 9)) % (256 - regs.x);
|
Y = X + (ya - (X << 9)) % (256 - X);
|
||||||
}
|
}
|
||||||
//result is set based on a (quotient) only
|
//result is set based on a (quotient) only
|
||||||
regs.p.n = (regs.a & 0x80);
|
ZF = A == 0;
|
||||||
regs.p.z = (regs.a == 0);
|
NF = A & 0x80;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto SPC700::op_jmp_addr() {
|
auto SPC700::instructionJMPAbsolute() -> void {
|
||||||
rd.l = readPC();
|
rd.l = fetch();
|
||||||
rd.h = readPC();
|
rd.h = fetch();
|
||||||
regs.pc = rd;
|
PC = rd;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto SPC700::op_jmp_iaddrx() {
|
auto SPC700::instructionJMPIndirectAbsoluteX() -> void {
|
||||||
dp.l = readPC();
|
dp.l = fetch();
|
||||||
dp.h = readPC();
|
dp.h = fetch();
|
||||||
idle();
|
idle();
|
||||||
dp += regs.x;
|
dp += X;
|
||||||
rd.l = read(dp++);
|
rd.l = read(dp++);
|
||||||
rd.h = read(dp++);
|
rd.h = read(dp++);
|
||||||
regs.pc = rd;
|
PC = rd;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto SPC700::op_jsp_dp() {
|
auto SPC700::instructionJSPDirectPage() -> void {
|
||||||
rd = readPC();
|
rd = fetch();
|
||||||
idle();
|
idle();
|
||||||
idle();
|
idle();
|
||||||
writeSP(regs.pc.h);
|
push(PC >> 8);
|
||||||
writeSP(regs.pc.l);
|
push(PC >> 0);
|
||||||
regs.pc = 0xff00 | rd;
|
PC = 0xff00 | rd;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto SPC700::op_jsr_addr() {
|
auto SPC700::instructionJSRAbsolute() -> void {
|
||||||
rd.l = readPC();
|
rd.l = fetch();
|
||||||
rd.h = readPC();
|
rd.h = fetch();
|
||||||
idle();
|
idle();
|
||||||
idle();
|
idle();
|
||||||
idle();
|
idle();
|
||||||
writeSP(regs.pc.h);
|
push(PC >> 8);
|
||||||
writeSP(regs.pc.l);
|
push(PC >> 0);
|
||||||
regs.pc = rd;
|
PC = rd;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto SPC700::op_jst() {
|
auto SPC700::instructionJST(uint4 vector) -> void {
|
||||||
dp = 0xffde - ((opcode >> 4) << 1);
|
dp = 0xffde - (vector << 1);
|
||||||
rd.l = read(dp++);
|
rd.l = read(dp++);
|
||||||
rd.h = read(dp++);
|
rd.h = read(dp++);
|
||||||
idle();
|
idle();
|
||||||
idle();
|
idle();
|
||||||
idle();
|
idle();
|
||||||
writeSP(regs.pc.h);
|
push(PC >> 8);
|
||||||
writeSP(regs.pc.l);
|
push(PC >> 0);
|
||||||
regs.pc = rd;
|
PC = rd;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto SPC700::op_lda_ixinc() {
|
auto SPC700::instructionLDAIndirectXIncrement() -> void {
|
||||||
idle();
|
idle();
|
||||||
regs.a = readDP(regs.x++);
|
A = load(X++);
|
||||||
idle();
|
idle();
|
||||||
regs.p.n = regs.a & 0x80;
|
ZF = A == 0;
|
||||||
regs.p.z = regs.a == 0;
|
NF = A & 0x80;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto SPC700::op_mul_ya() {
|
auto SPC700::instructionMUL() -> void {
|
||||||
idle();
|
idle();
|
||||||
idle();
|
idle();
|
||||||
idle();
|
idle();
|
||||||
|
@ -448,94 +453,128 @@ auto SPC700::op_mul_ya() {
|
||||||
idle();
|
idle();
|
||||||
idle();
|
idle();
|
||||||
idle();
|
idle();
|
||||||
ya = regs.y * regs.a;
|
uint16 ya = Y * A;
|
||||||
regs.a = ya;
|
A = ya >> 0;
|
||||||
regs.y = ya >> 8;
|
Y = ya >> 8;
|
||||||
//result is set based on y (high-byte) only
|
//result is set based on y (high-byte) only
|
||||||
regs.p.n = (regs.y & 0x80);
|
ZF = Y == 0;
|
||||||
regs.p.z = (regs.y == 0);
|
NF = Y & 0x80;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto SPC700::op_nop() {
|
auto SPC700::instructionNOP() -> void {
|
||||||
idle();
|
idle();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto SPC700::op_plp() {
|
auto SPC700::instructionPLP() -> void {
|
||||||
idle();
|
idle();
|
||||||
idle();
|
idle();
|
||||||
regs.p = readSP();
|
P = pull();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto SPC700::op_rti() {
|
auto SPC700::instructionRTI() -> void {
|
||||||
regs.p = readSP();
|
P = pull();
|
||||||
rd.l = readSP();
|
rd.l = pull();
|
||||||
rd.h = readSP();
|
rd.h = pull();
|
||||||
idle();
|
idle();
|
||||||
idle();
|
idle();
|
||||||
regs.pc = rd;
|
PC = rd;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto SPC700::op_rts() {
|
auto SPC700::instructionRTS() -> void {
|
||||||
rd.l = readSP();
|
rd.l = pull();
|
||||||
rd.h = readSP();
|
rd.h = pull();
|
||||||
idle();
|
idle();
|
||||||
idle();
|
idle();
|
||||||
regs.pc = rd;
|
PC = rd;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto SPC700::op_sta_idpx() {
|
auto SPC700::instructionSET(uint3 bit) -> void {
|
||||||
sp = readPC() + regs.x;
|
uint8 direct = fetch();
|
||||||
|
uint8 data = load(direct);
|
||||||
|
data.bit(bit) = 1;
|
||||||
|
store(direct, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto SPC700::instructionSTAIndirectPageX() -> void {
|
||||||
|
sp = fetch() + X;
|
||||||
idle();
|
idle();
|
||||||
dp.l = readDP(sp++);
|
dp.l = load(sp++);
|
||||||
dp.h = readDP(sp++);
|
dp.h = load(sp++);
|
||||||
read(dp);
|
read(dp);
|
||||||
write(dp, regs.a);
|
write(dp, A);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto SPC700::op_sta_idpy() {
|
auto SPC700::instructionSTAIndirectPageY() -> void {
|
||||||
sp = readPC();
|
sp = fetch();
|
||||||
dp.l = readDP(sp++);
|
dp.l = load(sp++);
|
||||||
dp.h = readDP(sp++);
|
dp.h = load(sp++);
|
||||||
idle();
|
idle();
|
||||||
dp += regs.y;
|
dp += Y;
|
||||||
read(dp);
|
read(dp);
|
||||||
write(dp, regs.a);
|
write(dp, A);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto SPC700::op_sta_ix() {
|
auto SPC700::instructionSTAIndirectX() -> void {
|
||||||
idle();
|
idle();
|
||||||
readDP(regs.x);
|
load(X);
|
||||||
writeDP(regs.x, regs.a);
|
store(X, A);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto SPC700::op_sta_ixinc() {
|
auto SPC700::instructionSTAIndirectXIncrement() -> void {
|
||||||
idle();
|
idle();
|
||||||
idle();
|
idle();
|
||||||
writeDP(regs.x++, regs.a);
|
store(X++, A);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto SPC700::op_stw_dp() {
|
auto SPC700::instructionSTP() -> void {
|
||||||
dp = readPC();
|
|
||||||
readDP(dp);
|
|
||||||
writeDP(dp++, regs.a);
|
|
||||||
writeDP(dp++, regs.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto SPC700::op_wait() {
|
|
||||||
while(true) {
|
while(true) {
|
||||||
idle();
|
idle();
|
||||||
idle();
|
idle();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto SPC700::op_xcn() {
|
auto SPC700::instructionSTWDirectPage() -> void {
|
||||||
idle();
|
dp = fetch();
|
||||||
idle();
|
load(dp);
|
||||||
idle();
|
store(dp++, A);
|
||||||
idle();
|
store(dp++, Y);
|
||||||
regs.a = (regs.a >> 4) | (regs.a << 4);
|
|
||||||
regs.p.n = regs.a & 0x80;
|
|
||||||
regs.p.z = regs.a == 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef call
|
auto SPC700::instructionTRBAbsolute() -> void {
|
||||||
|
dp.l = fetch();
|
||||||
|
dp.h = fetch();
|
||||||
|
rd = read(dp);
|
||||||
|
ZF = (A - rd) == 0;
|
||||||
|
NF = (A - rd) & 0x80;
|
||||||
|
read(dp);
|
||||||
|
write(dp, rd & ~A);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto SPC700::instructionTSBAbsolute() -> void {
|
||||||
|
dp.l = fetch();
|
||||||
|
dp.h = fetch();
|
||||||
|
rd = read(dp);
|
||||||
|
ZF = (A - rd) == 0;
|
||||||
|
NF = (A - rd) & 0x80;
|
||||||
|
read(dp);
|
||||||
|
write(dp, rd | A);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto SPC700::instructionWAI() -> void {
|
||||||
|
while(true) {
|
||||||
|
idle();
|
||||||
|
idle();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto SPC700::instructionXCN() -> void {
|
||||||
|
idle();
|
||||||
|
idle();
|
||||||
|
idle();
|
||||||
|
idle();
|
||||||
|
A = A >> 4 | A << 4;
|
||||||
|
ZF = A == 0;
|
||||||
|
NF = A & 0x80;
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef alu
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
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);
|
||||||
|
}
|
|
@ -1,19 +0,0 @@
|
||||||
alwaysinline auto readPC() -> uint8 {
|
|
||||||
return read(regs.pc++);
|
|
||||||
}
|
|
||||||
|
|
||||||
alwaysinline auto readSP() -> uint8 {
|
|
||||||
return read(0x0100 | ++regs.s);
|
|
||||||
}
|
|
||||||
|
|
||||||
alwaysinline auto writeSP(uint8 data) -> void {
|
|
||||||
return write(0x0100 | regs.s--, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
alwaysinline auto readDP(uint8 addr) -> uint8 {
|
|
||||||
return read(regs.p.p << 8 | addr);
|
|
||||||
}
|
|
||||||
|
|
||||||
alwaysinline auto writeDP(uint8 addr, uint8 data) -> void {
|
|
||||||
return write(regs.p.p << 8 | addr, data);
|
|
||||||
}
|
|
|
@ -1,53 +0,0 @@
|
||||||
struct Flags {
|
|
||||||
union {
|
|
||||||
uint8_t data = 0;
|
|
||||||
BooleanBitField<uint8_t, 7> n;
|
|
||||||
BooleanBitField<uint8_t, 6> v;
|
|
||||||
BooleanBitField<uint8_t, 5> p;
|
|
||||||
BooleanBitField<uint8_t, 4> b;
|
|
||||||
BooleanBitField<uint8_t, 3> h;
|
|
||||||
BooleanBitField<uint8_t, 2> i;
|
|
||||||
BooleanBitField<uint8_t, 1> z;
|
|
||||||
BooleanBitField<uint8_t, 0> c;
|
|
||||||
};
|
|
||||||
|
|
||||||
inline operator uint() const { return data; }
|
|
||||||
inline auto& operator =(uint value) { return data = value, *this; }
|
|
||||||
inline auto& operator&=(uint value) { return data &= value, *this; }
|
|
||||||
inline auto& operator|=(uint value) { return data |= value, *this; }
|
|
||||||
inline auto& operator^=(uint value) { return data ^= value, *this; }
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Register {
|
|
||||||
union {
|
|
||||||
uint16_t w = 0;
|
|
||||||
NaturalBitField<uint16_t, 0, 7> l;
|
|
||||||
NaturalBitField<uint16_t, 8, 15> h;
|
|
||||||
};
|
|
||||||
|
|
||||||
inline operator uint() const { return w; }
|
|
||||||
inline auto operator=(const Register& value) { w = value.w; }
|
|
||||||
|
|
||||||
inline auto operator++(int) { uint value = w++; return value; }
|
|
||||||
inline auto operator--(int) { uint value = w--; return value; }
|
|
||||||
|
|
||||||
inline auto& operator++() { return ++w, *this; }
|
|
||||||
inline auto& operator--() { return --w, *this; }
|
|
||||||
|
|
||||||
inline auto& operator =(uint value) { return w = value, *this; }
|
|
||||||
inline auto& operator&=(uint value) { return w &= value, *this; }
|
|
||||||
inline auto& operator|=(uint value) { return w |= value, *this; }
|
|
||||||
inline auto& operator^=(uint value) { return w ^= value, *this; }
|
|
||||||
inline auto& operator+=(uint value) { return w += value, *this; }
|
|
||||||
inline auto& operator-=(uint value) { return w -= value, *this; }
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Registers {
|
|
||||||
Register pc;
|
|
||||||
union {
|
|
||||||
uint16_t ya;
|
|
||||||
struct { uint8_t order_lsb2(a, y); };
|
|
||||||
};
|
|
||||||
uint8_t x, s;
|
|
||||||
Flags p;
|
|
||||||
};
|
|
|
@ -1,10 +1,16 @@
|
||||||
auto SPC700::serialize(serializer& s) -> void {
|
auto SPC700::serialize(serializer& s) -> void {
|
||||||
s.integer(regs.pc.w);
|
s.integer(r.pc.w);
|
||||||
s.integer(regs.a);
|
s.integer(r.ya.w);
|
||||||
s.integer(regs.x);
|
s.integer(r.x);
|
||||||
s.integer(regs.y);
|
s.integer(r.s);
|
||||||
s.integer(regs.s);
|
s.integer(r.p.c);
|
||||||
s.integer(regs.p.data);
|
s.integer(r.p.z);
|
||||||
|
s.integer(r.p.i);
|
||||||
|
s.integer(r.p.h);
|
||||||
|
s.integer(r.p.b);
|
||||||
|
s.integer(r.p.p);
|
||||||
|
s.integer(r.p.v);
|
||||||
|
s.integer(r.p.n);
|
||||||
|
|
||||||
s.integer(opcode);
|
s.integer(opcode);
|
||||||
s.integer(dp.w);
|
s.integer(dp.w);
|
||||||
|
@ -12,5 +18,4 @@ auto SPC700::serialize(serializer& s) -> void {
|
||||||
s.integer(rd.w);
|
s.integer(rd.w);
|
||||||
s.integer(wr.w);
|
s.integer(wr.w);
|
||||||
s.integer(bit.w);
|
s.integer(bit.w);
|
||||||
s.integer(ya.w);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,276 +3,53 @@
|
||||||
|
|
||||||
namespace Processor {
|
namespace Processor {
|
||||||
|
|
||||||
|
#define PC r.pc.w
|
||||||
|
#define YA r.ya.w
|
||||||
|
#define A r.ya.byte.l
|
||||||
|
#define X r.x
|
||||||
|
#define Y r.ya.byte.h
|
||||||
|
#define S r.s
|
||||||
|
#define P r.p
|
||||||
|
|
||||||
|
#define CF r.p.c
|
||||||
|
#define ZF r.p.z
|
||||||
|
#define IF r.p.i
|
||||||
|
#define HF r.p.h
|
||||||
|
#define BF r.p.b
|
||||||
|
#define PF r.p.p
|
||||||
|
#define VF r.p.v
|
||||||
|
#define NF r.p.n
|
||||||
|
|
||||||
|
#include "memory.cpp"
|
||||||
#include "algorithms.cpp"
|
#include "algorithms.cpp"
|
||||||
#include "instructions.cpp"
|
#include "instructions.cpp"
|
||||||
#include "disassembler.cpp"
|
#include "instruction.cpp"
|
||||||
#include "serialization.cpp"
|
#include "serialization.cpp"
|
||||||
|
#include "disassembler.cpp"
|
||||||
|
|
||||||
#define op(id, name, ...) case id: return op_##name(__VA_ARGS__);
|
#undef PC
|
||||||
#define fp(name) &SPC700::op_##name
|
#undef YA
|
||||||
|
#undef A
|
||||||
|
#undef X
|
||||||
|
#undef Y
|
||||||
|
#undef S
|
||||||
|
#undef P
|
||||||
|
|
||||||
auto SPC700::instruction() -> void {
|
#undef CF
|
||||||
switch(opcode = readPC()) {
|
#undef ZF
|
||||||
op(0x00, nop)
|
#undef IF
|
||||||
op(0x01, jst)
|
#undef HF
|
||||||
op(0x02, set_bit)
|
#undef BF
|
||||||
op(0x03, branch_bit)
|
#undef PF
|
||||||
op(0x04, read_dp, fp(or), regs.a)
|
#undef VF
|
||||||
op(0x05, read_addr, fp(or), regs.a)
|
#undef NF
|
||||||
op(0x06, read_ix, fp(or))
|
|
||||||
op(0x07, read_idpx, fp(or))
|
auto SPC700::power() -> void {
|
||||||
op(0x08, read_const, fp(or), regs.a)
|
r.pc.w = 0x0000;
|
||||||
op(0x09, write_dp_dp, fp(or))
|
r.ya.w = 0x0000;
|
||||||
op(0x0a, set_addr_bit)
|
r.x = 0x00;
|
||||||
op(0x0b, adjust_dp, fp(asl))
|
r.s = 0xef;
|
||||||
op(0x0c, adjust_addr, fp(asl))
|
r.p = 0x02;
|
||||||
op(0x0d, push, regs.p)
|
|
||||||
op(0x0e, test_addr, 1)
|
|
||||||
op(0x0f, brk)
|
|
||||||
op(0x10, branch, regs.p.n == 0)
|
|
||||||
op(0x11, jst)
|
|
||||||
op(0x12, set_bit)
|
|
||||||
op(0x13, branch_bit)
|
|
||||||
op(0x14, read_dpi, fp(or), regs.a, regs.x)
|
|
||||||
op(0x15, read_addri, fp(or), regs.x)
|
|
||||||
op(0x16, read_addri, fp(or), regs.y)
|
|
||||||
op(0x17, read_idpy, fp(or))
|
|
||||||
op(0x18, write_dp_const, fp(or))
|
|
||||||
op(0x19, write_ix_iy, fp(or))
|
|
||||||
op(0x1a, adjust_dpw, -1)
|
|
||||||
op(0x1b, adjust_dpx, fp(asl))
|
|
||||||
op(0x1c, adjust, fp(asl), regs.a)
|
|
||||||
op(0x1d, adjust, fp(dec), regs.x)
|
|
||||||
op(0x1e, read_addr, fp(cmp), regs.x)
|
|
||||||
op(0x1f, jmp_iaddrx)
|
|
||||||
op(0x20, set_flag, regs.p.p.bit, 0)
|
|
||||||
op(0x21, jst)
|
|
||||||
op(0x22, set_bit)
|
|
||||||
op(0x23, branch_bit)
|
|
||||||
op(0x24, read_dp, fp(and), regs.a)
|
|
||||||
op(0x25, read_addr, fp(and), regs.a)
|
|
||||||
op(0x26, read_ix, fp(and))
|
|
||||||
op(0x27, read_idpx, fp(and))
|
|
||||||
op(0x28, read_const, fp(and), regs.a)
|
|
||||||
op(0x29, write_dp_dp, fp(and))
|
|
||||||
op(0x2a, set_addr_bit)
|
|
||||||
op(0x2b, adjust_dp, fp(rol))
|
|
||||||
op(0x2c, adjust_addr, fp(rol))
|
|
||||||
op(0x2d, push, regs.a)
|
|
||||||
op(0x2e, bne_dp)
|
|
||||||
op(0x2f, branch, true)
|
|
||||||
op(0x30, branch, regs.p.n == 1)
|
|
||||||
op(0x31, jst)
|
|
||||||
op(0x32, set_bit)
|
|
||||||
op(0x33, branch_bit)
|
|
||||||
op(0x34, read_dpi, fp(and), regs.a, regs.x)
|
|
||||||
op(0x35, read_addri, fp(and), regs.x)
|
|
||||||
op(0x36, read_addri, fp(and), regs.y)
|
|
||||||
op(0x37, read_idpy, fp(and))
|
|
||||||
op(0x38, write_dp_const, fp(and))
|
|
||||||
op(0x39, write_ix_iy, fp(and))
|
|
||||||
op(0x3a, adjust_dpw, +1)
|
|
||||||
op(0x3b, adjust_dpx, fp(rol))
|
|
||||||
op(0x3c, adjust, fp(rol), regs.a)
|
|
||||||
op(0x3d, adjust, fp(inc), regs.x)
|
|
||||||
op(0x3e, read_dp, fp(cmp), regs.x)
|
|
||||||
op(0x3f, jsr_addr)
|
|
||||||
op(0x40, set_flag, regs.p.p.bit, 1)
|
|
||||||
op(0x41, jst)
|
|
||||||
op(0x42, set_bit)
|
|
||||||
op(0x43, branch_bit)
|
|
||||||
op(0x44, read_dp, fp(eor), regs.a)
|
|
||||||
op(0x45, read_addr, fp(eor), regs.a)
|
|
||||||
op(0x46, read_ix, fp(eor))
|
|
||||||
op(0x47, read_idpx, fp(eor))
|
|
||||||
op(0x48, read_const, fp(eor), regs.a)
|
|
||||||
op(0x49, write_dp_dp, fp(eor))
|
|
||||||
op(0x4a, set_addr_bit)
|
|
||||||
op(0x4b, adjust_dp, fp(lsr))
|
|
||||||
op(0x4c, adjust_addr, fp(lsr))
|
|
||||||
op(0x4d, push, regs.x)
|
|
||||||
op(0x4e, test_addr, 0)
|
|
||||||
op(0x4f, jsp_dp)
|
|
||||||
op(0x50, branch, regs.p.v == 0)
|
|
||||||
op(0x51, jst)
|
|
||||||
op(0x52, set_bit)
|
|
||||||
op(0x53, branch_bit)
|
|
||||||
op(0x54, read_dpi, fp(eor), regs.a, regs.x)
|
|
||||||
op(0x55, read_addri, fp(eor), regs.x)
|
|
||||||
op(0x56, read_addri, fp(eor), regs.y)
|
|
||||||
op(0x57, read_idpy, fp(eor))
|
|
||||||
op(0x58, write_dp_const, fp(eor))
|
|
||||||
op(0x59, write_ix_iy, fp(eor))
|
|
||||||
op(0x5a, read_dpw, fp(cpw))
|
|
||||||
op(0x5b, adjust_dpx, fp(lsr))
|
|
||||||
op(0x5c, adjust, fp(lsr), regs.a)
|
|
||||||
op(0x5d, transfer, regs.a, regs.x)
|
|
||||||
op(0x5e, read_addr, fp(cmp), regs.y)
|
|
||||||
op(0x5f, jmp_addr)
|
|
||||||
op(0x60, set_flag, regs.p.c.bit, 0)
|
|
||||||
op(0x61, jst)
|
|
||||||
op(0x62, set_bit)
|
|
||||||
op(0x63, branch_bit)
|
|
||||||
op(0x64, read_dp, fp(cmp), regs.a)
|
|
||||||
op(0x65, read_addr, fp(cmp), regs.a)
|
|
||||||
op(0x66, read_ix, fp(cmp))
|
|
||||||
op(0x67, read_idpx, fp(cmp))
|
|
||||||
op(0x68, read_const, fp(cmp), regs.a)
|
|
||||||
op(0x69, write_dp_dp, fp(cmp))
|
|
||||||
op(0x6a, set_addr_bit)
|
|
||||||
op(0x6b, adjust_dp, fp(ror))
|
|
||||||
op(0x6c, adjust_addr, fp(ror))
|
|
||||||
op(0x6d, push, regs.y)
|
|
||||||
op(0x6e, bne_dpdec)
|
|
||||||
op(0x6f, rts)
|
|
||||||
op(0x70, branch, regs.p.v == 1)
|
|
||||||
op(0x71, jst)
|
|
||||||
op(0x72, set_bit)
|
|
||||||
op(0x73, branch_bit)
|
|
||||||
op(0x74, read_dpi, fp(cmp), regs.a, regs.x)
|
|
||||||
op(0x75, read_addri, fp(cmp), regs.x)
|
|
||||||
op(0x76, read_addri, fp(cmp), regs.y)
|
|
||||||
op(0x77, read_idpy, fp(cmp))
|
|
||||||
op(0x78, write_dp_const, fp(cmp))
|
|
||||||
op(0x79, write_ix_iy, fp(cmp))
|
|
||||||
op(0x7a, read_dpw, fp(adw))
|
|
||||||
op(0x7b, adjust_dpx, fp(ror))
|
|
||||||
op(0x7c, adjust, fp(ror), regs.a)
|
|
||||||
op(0x7d, transfer, regs.x, regs.a)
|
|
||||||
op(0x7e, read_dp, fp(cmp), regs.y)
|
|
||||||
op(0x7f, rti)
|
|
||||||
op(0x80, set_flag, regs.p.c.bit, 1)
|
|
||||||
op(0x81, jst)
|
|
||||||
op(0x82, set_bit)
|
|
||||||
op(0x83, branch_bit)
|
|
||||||
op(0x84, read_dp, fp(adc), regs.a)
|
|
||||||
op(0x85, read_addr, fp(adc), regs.a)
|
|
||||||
op(0x86, read_ix, fp(adc))
|
|
||||||
op(0x87, read_idpx, fp(adc))
|
|
||||||
op(0x88, read_const, fp(adc), regs.a)
|
|
||||||
op(0x89, write_dp_dp, fp(adc))
|
|
||||||
op(0x8a, set_addr_bit)
|
|
||||||
op(0x8b, adjust_dp, fp(dec))
|
|
||||||
op(0x8c, adjust_addr, fp(dec))
|
|
||||||
op(0x8d, read_const, fp(ld), regs.y)
|
|
||||||
op(0x8e, plp)
|
|
||||||
op(0x8f, write_dp_const, fp(st))
|
|
||||||
op(0x90, branch, regs.p.c == 0)
|
|
||||||
op(0x91, jst)
|
|
||||||
op(0x92, set_bit)
|
|
||||||
op(0x93, branch_bit)
|
|
||||||
op(0x94, read_dpi, fp(adc), regs.a, regs.x)
|
|
||||||
op(0x95, read_addri, fp(adc), regs.x)
|
|
||||||
op(0x96, read_addri, fp(adc), regs.y)
|
|
||||||
op(0x97, read_idpy, fp(adc))
|
|
||||||
op(0x98, write_dp_const, fp(adc))
|
|
||||||
op(0x99, write_ix_iy, fp(adc))
|
|
||||||
op(0x9a, read_dpw, fp(sbw))
|
|
||||||
op(0x9b, adjust_dpx, fp(dec))
|
|
||||||
op(0x9c, adjust, fp(dec), regs.a)
|
|
||||||
op(0x9d, transfer, regs.s, regs.x)
|
|
||||||
op(0x9e, div_ya_x)
|
|
||||||
op(0x9f, xcn)
|
|
||||||
op(0xa0, set_flag, regs.p.i.bit, 1)
|
|
||||||
op(0xa1, jst)
|
|
||||||
op(0xa2, set_bit)
|
|
||||||
op(0xa3, branch_bit)
|
|
||||||
op(0xa4, read_dp, fp(sbc), regs.a)
|
|
||||||
op(0xa5, read_addr, fp(sbc), regs.a)
|
|
||||||
op(0xa6, read_ix, fp(sbc))
|
|
||||||
op(0xa7, read_idpx, fp(sbc))
|
|
||||||
op(0xa8, read_const, fp(sbc), regs.a)
|
|
||||||
op(0xa9, write_dp_dp, fp(sbc))
|
|
||||||
op(0xaa, set_addr_bit)
|
|
||||||
op(0xab, adjust_dp, fp(inc))
|
|
||||||
op(0xac, adjust_addr, fp(inc))
|
|
||||||
op(0xad, read_const, fp(cmp), regs.y)
|
|
||||||
op(0xae, pull, regs.a)
|
|
||||||
op(0xaf, sta_ixinc)
|
|
||||||
op(0xb0, branch, regs.p.c == 1)
|
|
||||||
op(0xb1, jst)
|
|
||||||
op(0xb2, set_bit)
|
|
||||||
op(0xb3, branch_bit)
|
|
||||||
op(0xb4, read_dpi, fp(sbc), regs.a, regs.x)
|
|
||||||
op(0xb5, read_addri, fp(sbc), regs.x)
|
|
||||||
op(0xb6, read_addri, fp(sbc), regs.y)
|
|
||||||
op(0xb7, read_idpy, fp(sbc))
|
|
||||||
op(0xb8, write_dp_const, fp(sbc))
|
|
||||||
op(0xb9, write_ix_iy, fp(sbc))
|
|
||||||
op(0xba, read_dpw, fp(ldw))
|
|
||||||
op(0xbb, adjust_dpx, fp(inc))
|
|
||||||
op(0xbc, adjust, fp(inc), regs.a)
|
|
||||||
op(0xbd, transfer, regs.x, regs.s)
|
|
||||||
op(0xbe, das)
|
|
||||||
op(0xbf, lda_ixinc)
|
|
||||||
op(0xc0, set_flag, regs.p.i.bit, 0)
|
|
||||||
op(0xc1, jst)
|
|
||||||
op(0xc2, set_bit)
|
|
||||||
op(0xc3, branch_bit)
|
|
||||||
op(0xc4, write_dp, regs.a)
|
|
||||||
op(0xc5, write_addr, regs.a)
|
|
||||||
op(0xc6, sta_ix)
|
|
||||||
op(0xc7, sta_idpx)
|
|
||||||
op(0xc8, read_const, fp(cmp), regs.x)
|
|
||||||
op(0xc9, write_addr, regs.x)
|
|
||||||
op(0xca, set_addr_bit)
|
|
||||||
op(0xcb, write_dp, regs.y)
|
|
||||||
op(0xcc, write_addr, regs.y)
|
|
||||||
op(0xcd, read_const, fp(ld), regs.x)
|
|
||||||
op(0xce, pull, regs.x)
|
|
||||||
op(0xcf, mul_ya)
|
|
||||||
op(0xd0, branch, regs.p.z == 0)
|
|
||||||
op(0xd1, jst)
|
|
||||||
op(0xd2, set_bit)
|
|
||||||
op(0xd3, branch_bit)
|
|
||||||
op(0xd4, write_dpi, regs.a, regs.x)
|
|
||||||
op(0xd5, write_addri, regs.x)
|
|
||||||
op(0xd6, write_addri, regs.y)
|
|
||||||
op(0xd7, sta_idpy)
|
|
||||||
op(0xd8, write_dp, regs.x)
|
|
||||||
op(0xd9, write_dpi, regs.x, regs.y)
|
|
||||||
op(0xda, stw_dp)
|
|
||||||
op(0xdb, write_dpi, regs.y, regs.x)
|
|
||||||
op(0xdc, adjust, fp(dec), regs.y)
|
|
||||||
op(0xdd, transfer, regs.y, regs.a)
|
|
||||||
op(0xde, bne_dpx)
|
|
||||||
op(0xdf, daa)
|
|
||||||
op(0xe0, clv)
|
|
||||||
op(0xe1, jst)
|
|
||||||
op(0xe2, set_bit)
|
|
||||||
op(0xe3, branch_bit)
|
|
||||||
op(0xe4, read_dp, fp(ld), regs.a)
|
|
||||||
op(0xe5, read_addr, fp(ld), regs.a)
|
|
||||||
op(0xe6, read_ix, fp(ld))
|
|
||||||
op(0xe7, read_idpx, fp(ld))
|
|
||||||
op(0xe8, read_const, fp(ld), regs.a)
|
|
||||||
op(0xe9, read_addr, fp(ld), regs.x)
|
|
||||||
op(0xea, set_addr_bit)
|
|
||||||
op(0xeb, read_dp, fp(ld), regs.y)
|
|
||||||
op(0xec, read_addr, fp(ld), regs.y)
|
|
||||||
op(0xed, cmc)
|
|
||||||
op(0xee, pull, regs.y)
|
|
||||||
op(0xef, wait)
|
|
||||||
op(0xf0, branch, regs.p.z == 1)
|
|
||||||
op(0xf1, jst)
|
|
||||||
op(0xf2, set_bit)
|
|
||||||
op(0xf3, branch_bit)
|
|
||||||
op(0xf4, read_dpi, fp(ld), regs.a, regs.x)
|
|
||||||
op(0xf5, read_addri, fp(ld), regs.x)
|
|
||||||
op(0xf6, read_addri, fp(ld), regs.y)
|
|
||||||
op(0xf7, read_idpy, fp(ld))
|
|
||||||
op(0xf8, read_dp, fp(ld), regs.x)
|
|
||||||
op(0xf9, read_dpi, fp(ld), regs.x, regs.y)
|
|
||||||
op(0xfa, write_dp_dp, fp(st))
|
|
||||||
op(0xfb, read_dpi, fp(ld), regs.y, regs.x)
|
|
||||||
op(0xfc, adjust, fp(inc), regs.y)
|
|
||||||
op(0xfd, transfer, regs.a, regs.y)
|
|
||||||
op(0xfe, bne_ydec)
|
|
||||||
op(0xff, wait)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef op
|
|
||||||
#undef fp
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,103 +8,178 @@ struct SPC700 {
|
||||||
virtual auto write(uint16 addr, uint8 data) -> void = 0;
|
virtual auto write(uint16 addr, uint8 data) -> void = 0;
|
||||||
virtual auto readDisassembler(uint16 addr) -> uint8 = 0;
|
virtual auto readDisassembler(uint16 addr) -> uint8 = 0;
|
||||||
|
|
||||||
|
//spc700.cpp
|
||||||
|
auto power() -> void;
|
||||||
|
|
||||||
|
//instruction.cpp
|
||||||
auto instruction() -> void;
|
auto instruction() -> void;
|
||||||
|
|
||||||
auto serialize(serializer&) -> void;
|
//memory.cpp
|
||||||
|
auto fetch() -> uint8;
|
||||||
|
auto pull() -> uint8;
|
||||||
|
auto push(uint8 data) -> void;
|
||||||
|
auto load(uint8 addr) -> uint8;
|
||||||
|
auto store(uint8 addr, uint8 data) -> void;
|
||||||
|
|
||||||
auto disassemble(uint16 addr, bool p) -> string;
|
//algorithms.cpp
|
||||||
|
auto algorithmADC(uint8, uint8) -> uint8;
|
||||||
|
auto algorithmAND(uint8, uint8) -> uint8;
|
||||||
|
auto algorithmASL(uint8) -> uint8;
|
||||||
|
auto algorithmCMP(uint8, uint8) -> uint8;
|
||||||
|
auto algorithmDEC(uint8) -> uint8;
|
||||||
|
auto algorithmEOR(uint8, uint8) -> uint8;
|
||||||
|
auto algorithmINC(uint8) -> uint8;
|
||||||
|
auto algorithmLD (uint8, uint8) -> uint8;
|
||||||
|
auto algorithmLSR(uint8) -> uint8;
|
||||||
|
auto algorithmOR (uint8, uint8) -> uint8;
|
||||||
|
auto algorithmROL(uint8) -> uint8;
|
||||||
|
auto algorithmROR(uint8) -> uint8;
|
||||||
|
auto algorithmSBC(uint8, uint8) -> uint8;
|
||||||
|
auto algorithmST (uint8, uint8) -> uint8;
|
||||||
|
auto algorithmADW(uint16, uint16) -> uint16;
|
||||||
|
auto algorithmCPW(uint16, uint16) -> uint16;
|
||||||
|
auto algorithmLDW(uint16, uint16) -> uint16;
|
||||||
|
auto algorithmSBW(uint16, uint16) -> uint16;
|
||||||
|
|
||||||
#include "registers.hpp"
|
//instructions.cpp
|
||||||
#include "memory.hpp"
|
|
||||||
|
|
||||||
Registers regs;
|
|
||||||
Register dp, sp, rd, wr, bit, ya;
|
|
||||||
uint8 opcode;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
using fps = auto (SPC700::*)(uint8) -> uint8;
|
using fps = auto (SPC700::*)(uint8) -> uint8;
|
||||||
using fpb = auto (SPC700::*)(uint8, uint8) -> uint8;
|
using fpb = auto (SPC700::*)(uint8, uint8) -> uint8;
|
||||||
using fpw = auto (SPC700::*)(uint16, uint16) -> uint16;
|
using fpw = auto (SPC700::*)(uint16, uint16) -> uint16;
|
||||||
using reg = uint8_t&;
|
|
||||||
|
|
||||||
auto op_adc(uint8, uint8) -> uint8;
|
auto instructionImpliedModify(fps, uint8&) -> void;
|
||||||
auto op_and(uint8, uint8) -> uint8;
|
auto instructionAbsoluteModify(fps) -> void;
|
||||||
auto op_asl(uint8) -> uint8;
|
auto instructionDirectPageModify(fps) -> void;
|
||||||
auto op_cmp(uint8, uint8) -> uint8;
|
auto instructionDirectPageModifyWord(int) -> void;
|
||||||
auto op_dec(uint8) -> uint8;
|
auto instructionDirectPageXModify(fps) -> void;
|
||||||
auto op_eor(uint8, uint8) -> uint8;
|
auto instructionBranch(bool) -> void;
|
||||||
auto op_inc(uint8) -> uint8;
|
auto instructionPull(uint8&) -> void;
|
||||||
auto op_ld (uint8, uint8) -> uint8;
|
auto instructionPush(uint8) -> void;
|
||||||
auto op_lsr(uint8) -> uint8;
|
auto instructionAbsoluteRead(fpb, uint8&) -> void;
|
||||||
auto op_or (uint8, uint8) -> uint8;
|
auto instructionAbsoluteIndexedRead(fpb, uint8&) -> void;
|
||||||
auto op_rol(uint8) -> uint8;
|
auto instructionImmediateRead(fpb, uint8&) -> void;
|
||||||
auto op_ror(uint8) -> uint8;
|
auto instructionDirectPageRead(fpb, uint8&) -> void;
|
||||||
auto op_sbc(uint8, uint8) -> uint8;
|
auto instructionDirectPageIndexedRead(fpb, uint8&, uint8&) -> void;
|
||||||
auto op_st (uint8, uint8) -> uint8;
|
auto instructionDirectPageReadWord(fpw) -> void;
|
||||||
auto op_adw(uint16, uint16) -> uint16;
|
auto instructionIndirectPageXRead(fpb) -> void;
|
||||||
auto op_cpw(uint16, uint16) -> uint16;
|
auto instructionIndirectPageYRead(fpb) -> void;
|
||||||
auto op_ldw(uint16, uint16) -> uint16;
|
auto instructionIndirectXRead(fpb) -> void;
|
||||||
auto op_sbw(uint16, uint16) -> uint16;
|
auto instructionAbsoluteModifyBit() -> void;
|
||||||
|
auto instructionFlagClear(bool&) -> void;
|
||||||
|
auto instructionFlagSet(bool&) -> void;
|
||||||
|
auto instructionTransfer(uint8&, uint8&) -> void;
|
||||||
|
auto instructionAbsoluteWrite(uint8&) -> void;
|
||||||
|
auto instructionAbsoluteIndexedWrite(uint8&) -> void;
|
||||||
|
auto instructionDirectPageWrite(uint8&) -> void;
|
||||||
|
auto instructionDirectPageIndexedWrite(uint8&, uint8&) -> void;
|
||||||
|
auto instructionDirectPageWriteImmediate(fpb) -> void;
|
||||||
|
auto instructionDirectPageWriteDirectPage(fpb) -> void;
|
||||||
|
auto instructionIndirectXWriteIndirectY(fpb) -> void;
|
||||||
|
|
||||||
auto op_adjust(fps, reg);
|
auto instructionBBC(uint3) -> void;
|
||||||
auto op_adjust_addr(fps);
|
auto instructionBBS(uint3) -> void;
|
||||||
auto op_adjust_dp(fps);
|
auto instructionBNEDirectPage() -> void;
|
||||||
auto op_adjust_dpw(int);
|
auto instructionBNEDirectPageDecrement() -> void;
|
||||||
auto op_adjust_dpx(fps);
|
auto instructionBNEDirectPageX() -> void;
|
||||||
auto op_branch(bool);
|
auto instructionBNEYDecrement() -> void;
|
||||||
auto op_branch_bit();
|
auto instructionBRK() -> void;
|
||||||
auto op_pull(reg);
|
auto instructionCLR(uint3) -> void;
|
||||||
auto op_push(uint8);
|
auto instructionCLV() -> void;
|
||||||
auto op_read_addr(fpb, reg);
|
auto instructionCMC() -> void;
|
||||||
auto op_read_addri(fpb, reg);
|
auto instructionDAA() -> void;
|
||||||
auto op_read_const(fpb, reg);
|
auto instructionDAS() -> void;
|
||||||
auto op_read_dp(fpb, reg);
|
auto instructionDIV() -> void;
|
||||||
auto op_read_dpi(fpb, reg, reg);
|
auto instructionJMPAbsolute() -> void;
|
||||||
auto op_read_dpw(fpw);
|
auto instructionJMPIndirectAbsoluteX() -> void;
|
||||||
auto op_read_idpx(fpb);
|
auto instructionJSPDirectPage() -> void;
|
||||||
auto op_read_idpy(fpb);
|
auto instructionJSRAbsolute() -> void;
|
||||||
auto op_read_ix(fpb);
|
auto instructionJST(uint4) -> void;
|
||||||
auto op_set_addr_bit();
|
auto instructionLDAIndirectXIncrement() -> void;
|
||||||
auto op_set_bit();
|
auto instructionMUL() -> void;
|
||||||
auto op_set_flag(uint, bool);
|
auto instructionNOP() -> void;
|
||||||
auto op_test_addr(bool);
|
auto instructionPLP() -> void;
|
||||||
auto op_transfer(reg, reg);
|
auto instructionRTI() -> void;
|
||||||
auto op_write_addr(reg);
|
auto instructionRTS() -> void;
|
||||||
auto op_write_addri(reg);
|
auto instructionSET(uint3) -> void;
|
||||||
auto op_write_dp(reg);
|
auto instructionSTAIndirectPageX() -> void;
|
||||||
auto op_write_dpi(reg, reg);
|
auto instructionSTAIndirectPageY() -> void;
|
||||||
auto op_write_dp_const(fpb);
|
auto instructionSTAIndirectX() -> void;
|
||||||
auto op_write_dp_dp(fpb);
|
auto instructionSTAIndirectXIncrement() -> void;
|
||||||
auto op_write_ix_iy(fpb);
|
auto instructionSTP() -> void;
|
||||||
|
auto instructionSTWDirectPage() -> void;
|
||||||
|
auto instructionTRBAbsolute() -> void;
|
||||||
|
auto instructionTSBAbsolute() -> void;
|
||||||
|
auto instructionWAI() -> void;
|
||||||
|
auto instructionXCN() -> void;
|
||||||
|
|
||||||
auto op_bne_dp();
|
//serialization.cpp
|
||||||
auto op_bne_dpdec();
|
auto serialize(serializer&) -> void;
|
||||||
auto op_bne_dpx();
|
|
||||||
auto op_bne_ydec();
|
//disassembler.cpp
|
||||||
auto op_brk();
|
auto disassemble(uint16 addr, bool p) -> string;
|
||||||
auto op_clv();
|
|
||||||
auto op_cmc();
|
struct Flags {
|
||||||
auto op_daa();
|
bool c; //carry
|
||||||
auto op_das();
|
bool z; //zero
|
||||||
auto op_div_ya_x();
|
bool i; //interrupt disable
|
||||||
auto op_jmp_addr();
|
bool h; //half-carry
|
||||||
auto op_jmp_iaddrx();
|
bool b; //break
|
||||||
auto op_jsp_dp();
|
bool p; //page
|
||||||
auto op_jsr_addr();
|
bool v; //overflow
|
||||||
auto op_jst();
|
bool n; //negative
|
||||||
auto op_lda_ixinc();
|
|
||||||
auto op_mul_ya();
|
inline operator uint() const {
|
||||||
auto op_nop();
|
return c << 0 | z << 1 | i << 2 | h << 3 | b << 4 | p << 5 | v << 6 | n << 7;
|
||||||
auto op_plp();
|
}
|
||||||
auto op_rti();
|
|
||||||
auto op_rts();
|
inline auto& operator=(uint8 data) {
|
||||||
auto op_sta_idpx();
|
c = data.bit(0);
|
||||||
auto op_sta_idpy();
|
z = data.bit(1);
|
||||||
auto op_sta_ix();
|
i = data.bit(2);
|
||||||
auto op_sta_ixinc();
|
h = data.bit(3);
|
||||||
auto op_stw_dp();
|
b = data.bit(4);
|
||||||
auto op_wait();
|
p = data.bit(5);
|
||||||
auto op_xcn();
|
v = data.bit(6);
|
||||||
|
n = data.bit(7);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Registers {
|
||||||
|
union Pair {
|
||||||
|
Pair() : w(0) {}
|
||||||
|
uint16 w;
|
||||||
|
struct Byte { uint8 order_lsb2(l, h); } byte;
|
||||||
|
} pc, ya;
|
||||||
|
uint8 x, s;
|
||||||
|
Flags p;
|
||||||
|
} r;
|
||||||
|
|
||||||
|
struct Register {
|
||||||
|
union {
|
||||||
|
uint16_t w = 0;
|
||||||
|
NaturalBitField<uint16_t, 0, 7> l;
|
||||||
|
NaturalBitField<uint16_t, 8, 15> h;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline operator uint() const { return w; }
|
||||||
|
inline auto operator=(const Register& value) { w = value.w; }
|
||||||
|
|
||||||
|
inline auto operator++(int) { uint value = w++; return value; }
|
||||||
|
inline auto operator--(int) { uint value = w--; return value; }
|
||||||
|
|
||||||
|
inline auto& operator++() { return ++w, *this; }
|
||||||
|
inline auto& operator--() { return --w, *this; }
|
||||||
|
|
||||||
|
inline auto& operator =(uint value) { return w = value, *this; }
|
||||||
|
inline auto& operator&=(uint value) { return w &= value, *this; }
|
||||||
|
inline auto& operator|=(uint value) { return w |= value, *this; }
|
||||||
|
inline auto& operator^=(uint value) { return w ^= value, *this; }
|
||||||
|
inline auto& operator+=(uint value) { return w += value, *this; }
|
||||||
|
inline auto& operator-=(uint value) { return w -= value, *this; }
|
||||||
|
};
|
||||||
|
|
||||||
|
Register dp, sp, rd, wr, bit;
|
||||||
|
uint8 opcode;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,7 +38,7 @@ auto WDC65816::algorithmADC16(uint16 data) -> uint16 {
|
||||||
}
|
}
|
||||||
|
|
||||||
VF = ~(A ^ data) & (A ^ result) & 0x8000;
|
VF = ~(A ^ data) & (A ^ result) & 0x8000;
|
||||||
if(D && result > 0x9fff) result += 0x6000;
|
if(DF && result > 0x9fff) result += 0x6000;
|
||||||
CF = result > 0xffff;
|
CF = result > 0xffff;
|
||||||
ZF = (uint16)result == 0;
|
ZF = (uint16)result == 0;
|
||||||
NF = result & 0x8000;
|
NF = result & 0x8000;
|
||||||
|
@ -48,7 +48,7 @@ auto WDC65816::algorithmADC16(uint16 data) -> uint16 {
|
||||||
|
|
||||||
auto WDC65816::algorithmAND8(uint8 data) -> uint8 {
|
auto WDC65816::algorithmAND8(uint8 data) -> uint8 {
|
||||||
lo(A) &= data;
|
lo(A) &= data;
|
||||||
ZF = A == 0;
|
ZF = lo(A) == 0;
|
||||||
NF = A & 0x80;
|
NF = A & 0x80;
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
@ -148,13 +148,13 @@ auto WDC65816::algorithmDEC8(uint8 data) -> uint8 {
|
||||||
auto WDC65816::algorithmDEC16(uint16 data) -> uint16 {
|
auto WDC65816::algorithmDEC16(uint16 data) -> uint16 {
|
||||||
data--;
|
data--;
|
||||||
ZF = data == 0;
|
ZF = data == 0;
|
||||||
NF = data & 0x80;
|
NF = data & 0x8000;
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto WDC65816::algorithmEOR8(uint8 data) -> uint8 {
|
auto WDC65816::algorithmEOR8(uint8 data) -> uint8 {
|
||||||
lo(A) ^= data;
|
lo(A) ^= data;
|
||||||
ZF = A == 0;
|
ZF = lo(A) == 0;
|
||||||
NF = A & 0x80;
|
NF = A & 0x80;
|
||||||
return lo(A);
|
return lo(A);
|
||||||
}
|
}
|
||||||
|
|
|
@ -171,7 +171,7 @@ L push(lo(data));
|
||||||
auto WDC65816::instructionPHD() -> void {
|
auto WDC65816::instructionPHD() -> void {
|
||||||
idle();
|
idle();
|
||||||
pushN(hi(D));
|
pushN(hi(D));
|
||||||
L pushN(hi(D));
|
L pushN(lo(D));
|
||||||
E hi(S) = 0x01;
|
E hi(S) = 0x01;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -112,7 +112,7 @@ auto WDC65816::instructionRTS() -> void {
|
||||||
uint16 data = pull();
|
uint16 data = pull();
|
||||||
hi(data) = pull();
|
hi(data) = pull();
|
||||||
L idle();
|
L idle();
|
||||||
PC = data;
|
aa(PC) = data;
|
||||||
aa(PC)++;
|
aa(PC)++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -50,11 +50,6 @@ auto CPU::main() -> void {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 1
|
|
||||||
static uint counter = 0;
|
|
||||||
if(++counter < 40) print(disassemble(), "\n");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
instruction();
|
instruction();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -74,7 +74,7 @@ auto SMP::readBus(uint16 addr) -> uint8 {
|
||||||
auto SMP::writeBus(uint16 addr, uint8 data) -> void {
|
auto SMP::writeBus(uint16 addr, uint8 data) -> void {
|
||||||
switch(addr) {
|
switch(addr) {
|
||||||
case 0xf0: //TEST
|
case 0xf0: //TEST
|
||||||
if(regs.p.p) break; //writes only valid when P flag is clear
|
if(r.p.p) break; //writes only valid when P flag is clear
|
||||||
|
|
||||||
io.clockSpeed = (data >> 6) & 3;
|
io.clockSpeed = (data >> 6) & 3;
|
||||||
io.timerSpeed = (data >> 4) & 3;
|
io.timerSpeed = (data >> 4) & 3;
|
||||||
|
|
|
@ -27,15 +27,11 @@ auto SMP::load(Markup::Node node) -> bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
auto SMP::power() -> void {
|
auto SMP::power() -> void {
|
||||||
|
SPC700::power();
|
||||||
create(Enter, 32040.0 * 768.0);
|
create(Enter, 32040.0 * 768.0);
|
||||||
|
|
||||||
regs.pc.l = iplrom[62];
|
r.pc.byte.l = iplrom[62];
|
||||||
regs.pc.h = iplrom[63];
|
r.pc.byte.h = iplrom[63];
|
||||||
regs.a = 0x00;
|
|
||||||
regs.x = 0x00;
|
|
||||||
regs.y = 0x00;
|
|
||||||
regs.s = 0xef;
|
|
||||||
regs.p = 0x02;
|
|
||||||
|
|
||||||
for(auto& byte : apuram) byte = random(0x00);
|
for(auto& byte : apuram) byte = random(0x00);
|
||||||
apuram[0x00f4] = 0x00;
|
apuram[0x00f4] = 0x00;
|
||||||
|
|
Loading…
Reference in New Issue