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 {
|
||||
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 License = "GPLv3";
|
||||
static const string Website = "http://byuu.org/";
|
||||
|
|
|
@ -32,7 +32,7 @@ private:
|
|||
|
||||
struct DAC {
|
||||
uint1 enable = 0;
|
||||
uint8 sample = 0;
|
||||
uint8 sample = 0x80;
|
||||
} dac;
|
||||
|
||||
struct Envelope {
|
||||
|
|
|
@ -108,6 +108,7 @@ auto ARM::arm_op_multiply_long() {
|
|||
|
||||
idle();
|
||||
idle();
|
||||
if(accumulate) idle();
|
||||
|
||||
//this instruction uses an 8-bit Booth algorithm for multiplication
|
||||
//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)
|
||||
|
||||
#include "memory.cpp"
|
||||
#include "algorithms.cpp"
|
||||
#include "instruction.cpp"
|
||||
#include "instructions.cpp"
|
||||
#include "disassembler.cpp"
|
||||
|
|
|
@ -27,82 +27,83 @@ struct HuC6280 {
|
|||
auto push(uint8) -> void;
|
||||
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
|
||||
auto interrupt(uint16 vector) -> void;
|
||||
auto instruction() -> void;
|
||||
|
||||
//instructions.cpp
|
||||
using fp = auto (HuC6280::*)(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 TRB(uint8) -> uint8;
|
||||
auto TSB(uint8) -> uint8;
|
||||
auto instructionAbsoluteModify(fp, uint8 = 0) -> void;
|
||||
auto instructionAbsoluteRead(fp, uint8&, uint8 = 0) -> void;
|
||||
auto instructionAbsoluteWrite(uint8, uint8 = 0) -> void;
|
||||
auto instructionBlockMove(bp) -> void;
|
||||
auto instructionBranch(bool) -> void;
|
||||
auto instructionClear(uint8&) -> void;
|
||||
auto instructionClear(bool&) -> void;
|
||||
auto instructionImmediate(fp, uint8&) -> void;
|
||||
auto instructionImplied(fp, uint8&) -> void;
|
||||
auto instructionIndirectRead(fp, uint8&, uint8 = 0) -> void;
|
||||
auto instructionIndirectWrite(uint8, uint8 = 0) -> void;
|
||||
auto instructionIndirectYRead(fp, uint8&) -> void;
|
||||
auto instructionIndirectYWrite(uint8) -> void;
|
||||
auto instructionMemory(fp) -> void;
|
||||
auto instructionPull(uint8&) -> void;
|
||||
auto instructionPush(uint8) -> void;
|
||||
auto instructionSet(bool&) -> void;
|
||||
auto instructionSwap(uint8&, uint8&) -> void;
|
||||
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 TAI(uint16&, uint16&, bool) -> void;
|
||||
auto TDD(uint16&, uint16&, bool) -> void;
|
||||
auto TIA(uint16&, uint16&, bool) -> void;
|
||||
auto TII(uint16&, uint16&, bool) -> void;
|
||||
auto TIN(uint16&, uint16&, bool) -> void;
|
||||
|
||||
auto instruction_absoluteLoad(fp, uint8&, uint8 = 0) -> void;
|
||||
auto instruction_absoluteModify(fp, uint8 = 0) -> void;
|
||||
auto instruction_absoluteStore(uint8, uint8 = 0) -> void;
|
||||
auto instruction_blockmove(bp) -> void;
|
||||
auto instruction_branch(bool) -> void;
|
||||
auto instruction_clear(uint8&) -> void;
|
||||
auto instruction_clear(bool&) -> void;
|
||||
auto instruction_immediate(fp, uint8&) -> void;
|
||||
auto instruction_implied(fp, uint8&) -> void;
|
||||
auto instruction_indirectLoad(fp, uint8&, uint8 = 0) -> void;
|
||||
auto instruction_indirectStore(uint8, uint8 = 0) -> void;
|
||||
auto instruction_indirectYLoad(fp, uint8&) -> void;
|
||||
auto instruction_indirectYStore(uint8) -> void;
|
||||
auto instruction_memory(fp) -> 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;
|
||||
auto instructionBBR(uint3) -> void;
|
||||
auto instructionBBS(uint3) -> void;
|
||||
auto instructionBRK() -> void;
|
||||
auto instructionBSR() -> void;
|
||||
auto instructionCSL() -> void;
|
||||
auto instructionCSH() -> void;
|
||||
auto instructionJMPAbsolute() -> void;
|
||||
auto instructionJMPIndirect(uint8 = 0) -> void;
|
||||
auto instructionJSR() -> void;
|
||||
auto instructionNOP() -> void;
|
||||
auto instructionPLP() -> void;
|
||||
auto instructionRMB(uint3) -> void;
|
||||
auto instructionRTI() -> void;
|
||||
auto instructionRTS() -> void;
|
||||
auto instructionSMB(uint3) -> void;
|
||||
auto instructionST(uint2) -> void;
|
||||
auto instructionTAM() -> void;
|
||||
auto instructionTMA() -> void;
|
||||
auto instructionTSTAbsolute(uint8 = 0) -> void;
|
||||
auto instructionTSTZeroPage(uint8 = 0) -> void;
|
||||
auto instructionTXS() -> void;
|
||||
|
||||
//disassembler.cpp
|
||||
auto disassemble(uint16 pc) -> string;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#define op(id, name, ...) case id: instruction_##name(__VA_ARGS__); return;
|
||||
#define fp(name) &HuC6280::name
|
||||
#define op(id, name, ...) case id: return instruction##name(__VA_ARGS__);
|
||||
#define fp(name) &HuC6280::algorithm##name
|
||||
|
||||
auto HuC6280::interrupt(uint16 vector) -> void {
|
||||
io();
|
||||
|
@ -19,270 +19,270 @@ auto HuC6280::instruction() -> void {
|
|||
if(T) {
|
||||
T = 0;
|
||||
switch(code) {
|
||||
op(0x09, memory, fp(ORA))
|
||||
op(0x29, memory, fp(AND))
|
||||
op(0x49, memory, fp(EOR))
|
||||
op(0x69, memory, fp(ADC))
|
||||
op(0x09, Memory, fp(ORA))
|
||||
op(0x29, Memory, fp(AND))
|
||||
op(0x49, Memory, fp(EOR))
|
||||
op(0x69, Memory, fp(ADC))
|
||||
}
|
||||
}
|
||||
|
||||
#define U
|
||||
switch(code) {
|
||||
op(0x00, BRK)
|
||||
op(0x01, indirectLoad, fp(ORA), A, X)
|
||||
op(0x02, swap, X, Y)
|
||||
op(0x01, IndirectRead, fp(ORA), A, X)
|
||||
op(0x02, Swap, X, Y)
|
||||
op(0x03, ST, 0)
|
||||
op(0x04, zeropageModify, fp(TSB))
|
||||
op(0x05, zeropageLoad, fp(ORA), A)
|
||||
op(0x06, zeropageModify, fp(ASL))
|
||||
op(0x04, ZeroPageModify, fp(TSB))
|
||||
op(0x05, ZeroPageRead, fp(ORA), A)
|
||||
op(0x06, ZeroPageModify, fp(ASL))
|
||||
op(0x07, RMB, 0)
|
||||
op(0x08, push, P)
|
||||
op(0x09, immediate, fp(ORA), A)
|
||||
op(0x0a, implied, fp(ASL), A)
|
||||
op(0x08, Push, P)
|
||||
op(0x09, Immediate, fp(ORA), A)
|
||||
op(0x0a, Implied, fp(ASL), A)
|
||||
U op(0x0b, NOP)
|
||||
op(0x0c, absoluteModify, fp(TSB))
|
||||
op(0x0d, absoluteLoad, fp(ORA), A)
|
||||
op(0x0e, absoluteModify, fp(ASL))
|
||||
op(0x0c, AbsoluteModify, fp(TSB))
|
||||
op(0x0d, AbsoluteRead, fp(ORA), A)
|
||||
op(0x0e, AbsoluteModify, fp(ASL))
|
||||
op(0x0f, BBR, 0)
|
||||
op(0x10, branch, N == 0)
|
||||
op(0x11, indirectYLoad, fp(ORA), A)
|
||||
op(0x12, indirectLoad, fp(ORA), A)
|
||||
op(0x10, Branch, N == 0)
|
||||
op(0x11, IndirectYRead, fp(ORA), A)
|
||||
op(0x12, IndirectRead, fp(ORA), A)
|
||||
op(0x13, ST, 1)
|
||||
op(0x14, zeropageModify, fp(TRB))
|
||||
op(0x15, zeropageLoad, fp(ORA), A, X)
|
||||
op(0x16, zeropageModify, fp(ASL), X)
|
||||
op(0x14, ZeroPageModify, fp(TRB))
|
||||
op(0x15, ZeroPageRead, fp(ORA), A, X)
|
||||
op(0x16, ZeroPageModify, fp(ASL), X)
|
||||
op(0x17, RMB, 1)
|
||||
op(0x18, clear, C)
|
||||
op(0x19, absoluteLoad, fp(ORA), A, Y)
|
||||
op(0x1a, implied, fp(INC), A)
|
||||
op(0x18, Clear, C)
|
||||
op(0x19, AbsoluteRead, fp(ORA), A, Y)
|
||||
op(0x1a, Implied, fp(INC), A)
|
||||
U op(0x1b, NOP)
|
||||
op(0x1c, absoluteModify, fp(TRB))
|
||||
op(0x1d, absoluteLoad, fp(ORA), A, X)
|
||||
op(0x1e, absoluteModify, fp(ASL), X)
|
||||
op(0x1c, AbsoluteModify, fp(TRB))
|
||||
op(0x1d, AbsoluteRead, fp(ORA), A, X)
|
||||
op(0x1e, AbsoluteModify, fp(ASL), X)
|
||||
op(0x1f, BBR, 1)
|
||||
op(0x20, JSR)
|
||||
op(0x21, indirectLoad, fp(AND), A, X)
|
||||
op(0x22, swap, A, X)
|
||||
op(0x21, IndirectRead, fp(AND), A, X)
|
||||
op(0x22, Swap, A, X)
|
||||
op(0x23, ST, 2)
|
||||
op(0x24, zeropageLoad, fp(BIT), A)
|
||||
op(0x25, zeropageLoad, fp(AND), A)
|
||||
op(0x26, zeropageModify, fp(ROL))
|
||||
op(0x24, ZeroPageRead, fp(BIT), A)
|
||||
op(0x25, ZeroPageRead, fp(AND), A)
|
||||
op(0x26, ZeroPageModify, fp(ROL))
|
||||
op(0x27, RMB, 2)
|
||||
op(0x28, PLP)
|
||||
op(0x29, immediate, fp(AND), A)
|
||||
op(0x2a, implied, fp(ROL), A)
|
||||
op(0x29, Immediate, fp(AND), A)
|
||||
op(0x2a, Implied, fp(ROL), A)
|
||||
U op(0x2b, NOP)
|
||||
op(0x2c, absoluteLoad, fp(BIT), A)
|
||||
op(0x2d, absoluteLoad, fp(AND), A)
|
||||
op(0x2e, absoluteModify, fp(ROL))
|
||||
op(0x2c, AbsoluteRead, fp(BIT), A)
|
||||
op(0x2d, AbsoluteRead, fp(AND), A)
|
||||
op(0x2e, AbsoluteModify, fp(ROL))
|
||||
op(0x2f, BBR, 2)
|
||||
op(0x30, branch, N == 1)
|
||||
op(0x31, indirectYLoad, fp(AND), A)
|
||||
op(0x32, indirectLoad, fp(AND), A)
|
||||
op(0x30, Branch, N == 1)
|
||||
op(0x31, IndirectYRead, fp(AND), A)
|
||||
op(0x32, IndirectRead, fp(AND), A)
|
||||
U op(0x33, NOP)
|
||||
op(0x34, zeropageLoad, fp(BIT), A, X)
|
||||
op(0x35, zeropageLoad, fp(AND), A, X)
|
||||
op(0x36, zeropageModify, fp(ROL), X)
|
||||
op(0x34, ZeroPageRead, fp(BIT), A, X)
|
||||
op(0x35, ZeroPageRead, fp(AND), A, X)
|
||||
op(0x36, ZeroPageModify, fp(ROL), X)
|
||||
op(0x37, RMB, 3)
|
||||
op(0x38, set, C)
|
||||
op(0x39, absoluteLoad, fp(AND), A, Y)
|
||||
op(0x3a, implied, fp(DEC), A)
|
||||
op(0x38, Set, C)
|
||||
op(0x39, AbsoluteRead, fp(AND), A, Y)
|
||||
op(0x3a, Implied, fp(DEC), A)
|
||||
U op(0x3b, NOP)
|
||||
op(0x3c, absoluteLoad, fp(BIT), A, X)
|
||||
op(0x3d, absoluteLoad, fp(AND), A, X)
|
||||
op(0x3e, absoluteModify, fp(ROL), X)
|
||||
op(0x3c, AbsoluteRead, fp(BIT), A, X)
|
||||
op(0x3d, AbsoluteRead, fp(AND), A, X)
|
||||
op(0x3e, AbsoluteModify, fp(ROL), X)
|
||||
op(0x3f, BBR, 3)
|
||||
op(0x40, RTI)
|
||||
op(0x41, indirectLoad, fp(EOR), A, X)
|
||||
op(0x42, swap, A, Y)
|
||||
op(0x41, IndirectRead, fp(EOR), A, X)
|
||||
op(0x42, Swap, A, Y)
|
||||
op(0x43, TMA)
|
||||
op(0x44, BSR)
|
||||
op(0x45, zeropageLoad, fp(EOR), A)
|
||||
op(0x46, zeropageModify, fp(LSR))
|
||||
op(0x45, ZeroPageRead, fp(EOR), A)
|
||||
op(0x46, ZeroPageModify, fp(LSR))
|
||||
op(0x47, RMB, 4)
|
||||
op(0x48, push, A)
|
||||
op(0x49, immediate, fp(EOR), A)
|
||||
op(0x4a, implied, fp(LSR), A)
|
||||
op(0x48, Push, A)
|
||||
op(0x49, Immediate, fp(EOR), A)
|
||||
op(0x4a, Implied, fp(LSR), A)
|
||||
U op(0x4b, NOP)
|
||||
op(0x4c, JMP_absolute)
|
||||
op(0x4d, absoluteLoad, fp(EOR), A)
|
||||
op(0x4e, absoluteModify, fp(LSR))
|
||||
op(0x4c, JMPAbsolute)
|
||||
op(0x4d, AbsoluteRead, fp(EOR), A)
|
||||
op(0x4e, AbsoluteModify, fp(LSR))
|
||||
op(0x4f, BBR, 4)
|
||||
op(0x50, branch, V == 0)
|
||||
op(0x51, indirectYLoad, fp(EOR), A)
|
||||
op(0x52, indirectLoad, fp(EOR), A)
|
||||
op(0x50, Branch, V == 0)
|
||||
op(0x51, IndirectYRead, fp(EOR), A)
|
||||
op(0x52, IndirectRead, fp(EOR), A)
|
||||
op(0x53, TAM)
|
||||
op(0x54, CSL)
|
||||
op(0x55, zeropageLoad, fp(EOR), A, X)
|
||||
op(0x56, zeropageModify, fp(LSR), X)
|
||||
op(0x55, ZeroPageRead, fp(EOR), A, X)
|
||||
op(0x56, ZeroPageModify, fp(LSR), X)
|
||||
op(0x57, RMB, 5)
|
||||
op(0x58, clear, I)
|
||||
op(0x59, absoluteLoad, fp(EOR), A, Y)
|
||||
op(0x5a, push, Y)
|
||||
op(0x58, Clear, I)
|
||||
op(0x59, AbsoluteRead, fp(EOR), A, Y)
|
||||
op(0x5a, Push, Y)
|
||||
U op(0x5b, NOP)
|
||||
U op(0x5c, NOP)
|
||||
op(0x5d, absoluteLoad, fp(EOR), A, X)
|
||||
op(0x5e, absoluteModify, fp(LSR), X)
|
||||
op(0x5d, AbsoluteRead, fp(EOR), A, X)
|
||||
op(0x5e, AbsoluteModify, fp(LSR), X)
|
||||
op(0x5f, BBR, 5)
|
||||
op(0x60, RTS)
|
||||
op(0x61, indirectLoad, fp(ADC), A, X)
|
||||
op(0x62, clear, A)
|
||||
op(0x61, IndirectRead, fp(ADC), A, X)
|
||||
op(0x62, Clear, A)
|
||||
U op(0x63, NOP)
|
||||
op(0x64, zeropageStore, 0)
|
||||
op(0x65, zeropageLoad, fp(ADC), A)
|
||||
op(0x66, zeropageModify, fp(ROR))
|
||||
op(0x64, ZeroPageWrite, 0)
|
||||
op(0x65, ZeroPageRead, fp(ADC), A)
|
||||
op(0x66, ZeroPageModify, fp(ROR))
|
||||
op(0x67, RMB, 6)
|
||||
op(0x68, pull, A)
|
||||
op(0x69, immediate, fp(ADC), A)
|
||||
op(0x6a, implied, fp(ROR), A)
|
||||
op(0x68, Pull, A)
|
||||
op(0x69, Immediate, fp(ADC), A)
|
||||
op(0x6a, Implied, fp(ROR), A)
|
||||
U op(0x6b, NOP)
|
||||
op(0x6c, JMP_indirect)
|
||||
op(0x6d, absoluteLoad, fp(ADC), A)
|
||||
op(0x6e, absoluteModify, fp(ROR))
|
||||
op(0x6c, JMPIndirect)
|
||||
op(0x6d, AbsoluteRead, fp(ADC), A)
|
||||
op(0x6e, AbsoluteModify, fp(ROR))
|
||||
op(0x6f, BBR, 6)
|
||||
op(0x70, branch, V == 1)
|
||||
op(0x71, indirectYLoad, fp(ADC), A)
|
||||
op(0x72, indirectLoad, fp(ADC), A)
|
||||
op(0x73, blockmove, fp(TII))
|
||||
op(0x74, zeropageStore, 0, X)
|
||||
op(0x75, zeropageLoad, fp(ADC), A, X)
|
||||
op(0x76, zeropageModify, fp(ROR), X)
|
||||
op(0x70, Branch, V == 1)
|
||||
op(0x71, IndirectYRead, fp(ADC), A)
|
||||
op(0x72, IndirectRead, fp(ADC), A)
|
||||
op(0x73, BlockMove, fp(TII))
|
||||
op(0x74, ZeroPageWrite, 0, X)
|
||||
op(0x75, ZeroPageRead, fp(ADC), A, X)
|
||||
op(0x76, ZeroPageModify, fp(ROR), X)
|
||||
op(0x77, RMB, 7)
|
||||
op(0x78, set, I)
|
||||
op(0x79, absoluteLoad, fp(ADC), A, Y)
|
||||
op(0x7a, pull, Y)
|
||||
op(0x78, Set, I)
|
||||
op(0x79, AbsoluteRead, fp(ADC), A, Y)
|
||||
op(0x7a, Pull, Y)
|
||||
U op(0x7b, NOP)
|
||||
op(0x7c, JMP_indirect, X)
|
||||
op(0x7d, absoluteLoad, fp(ADC), A, X)
|
||||
op(0x7e, absoluteModify, fp(ROR), X)
|
||||
op(0x7c, JMPIndirect, X)
|
||||
op(0x7d, AbsoluteRead, fp(ADC), A, X)
|
||||
op(0x7e, AbsoluteModify, fp(ROR), X)
|
||||
op(0x7f, BBR, 7)
|
||||
op(0x80, branch, 1)
|
||||
op(0x81, indirectStore, A, X)
|
||||
op(0x82, clear, X)
|
||||
op(0x83, TST_zeropage)
|
||||
op(0x84, zeropageStore, Y)
|
||||
op(0x85, zeropageStore, A)
|
||||
op(0x86, zeropageStore, X)
|
||||
op(0x80, Branch, 1)
|
||||
op(0x81, IndirectWrite, A, X)
|
||||
op(0x82, Clear, X)
|
||||
op(0x83, TSTZeroPage)
|
||||
op(0x84, ZeroPageWrite, Y)
|
||||
op(0x85, ZeroPageWrite, A)
|
||||
op(0x86, ZeroPageWrite, X)
|
||||
op(0x87, SMB, 0)
|
||||
op(0x88, implied, fp(DEC), Y)
|
||||
op(0x89, immediate, fp(BIT), A)
|
||||
op(0x8a, transfer, X, A)
|
||||
op(0x88, Implied, fp(DEC), Y)
|
||||
op(0x89, Immediate, fp(BIT), A)
|
||||
op(0x8a, Transfer, X, A)
|
||||
U op(0x8b, NOP)
|
||||
op(0x8c, absoluteStore, Y)
|
||||
op(0x8d, absoluteStore, A)
|
||||
op(0x8e, absoluteStore, X)
|
||||
op(0x8c, AbsoluteWrite, Y)
|
||||
op(0x8d, AbsoluteWrite, A)
|
||||
op(0x8e, AbsoluteWrite, X)
|
||||
op(0x8f, BBS, 0)
|
||||
op(0x90, branch, C == 0)
|
||||
op(0x91, indirectYStore, A)
|
||||
op(0x92, indirectStore, A)
|
||||
op(0x93, TST_absolute)
|
||||
op(0x94, zeropageStore, Y, X)
|
||||
op(0x95, zeropageStore, A, X)
|
||||
op(0x96, zeropageStore, X, Y)
|
||||
op(0x90, Branch, C == 0)
|
||||
op(0x91, IndirectYWrite, A)
|
||||
op(0x92, IndirectWrite, A)
|
||||
op(0x93, TSTAbsolute)
|
||||
op(0x94, ZeroPageWrite, Y, X)
|
||||
op(0x95, ZeroPageWrite, A, X)
|
||||
op(0x96, ZeroPageWrite, X, Y)
|
||||
op(0x97, SMB, 1)
|
||||
op(0x98, transfer, Y, A)
|
||||
op(0x99, absoluteStore, A, Y)
|
||||
op(0x98, Transfer, Y, A)
|
||||
op(0x99, AbsoluteWrite, A, Y)
|
||||
op(0x9a, TXS)
|
||||
U op(0x9b, NOP)
|
||||
op(0x9c, absoluteStore, 0)
|
||||
op(0x9d, absoluteStore, A, X)
|
||||
op(0x9e, absoluteStore, 0, X)
|
||||
op(0x9c, AbsoluteWrite, 0)
|
||||
op(0x9d, AbsoluteWrite, A, X)
|
||||
op(0x9e, AbsoluteWrite, 0, X)
|
||||
op(0x9f, BBS, 1)
|
||||
op(0xa0, immediate, fp(LD), Y)
|
||||
op(0xa1, indirectLoad, fp(LD), A, X)
|
||||
op(0xa2, immediate, fp(LD), X)
|
||||
op(0xa3, TST_zeropage, X)
|
||||
op(0xa4, zeropageLoad, fp(LD), Y)
|
||||
op(0xa5, zeropageLoad, fp(LD), A)
|
||||
op(0xa6, zeropageLoad, fp(LD), X)
|
||||
op(0xa0, Immediate, fp(LD), Y)
|
||||
op(0xa1, IndirectRead, fp(LD), A, X)
|
||||
op(0xa2, Immediate, fp(LD), X)
|
||||
op(0xa3, TSTZeroPage, X)
|
||||
op(0xa4, ZeroPageRead, fp(LD), Y)
|
||||
op(0xa5, ZeroPageRead, fp(LD), A)
|
||||
op(0xa6, ZeroPageRead, fp(LD), X)
|
||||
op(0xa7, SMB, 2)
|
||||
op(0xa8, transfer, A, Y)
|
||||
op(0xa9, immediate, fp(LD), A)
|
||||
op(0xaa, transfer, A, X)
|
||||
op(0xa8, Transfer, A, Y)
|
||||
op(0xa9, Immediate, fp(LD), A)
|
||||
op(0xaa, Transfer, A, X)
|
||||
U op(0xab, NOP)
|
||||
op(0xac, absoluteLoad, fp(LD), Y)
|
||||
op(0xad, absoluteLoad, fp(LD), A)
|
||||
op(0xae, absoluteLoad, fp(LD), X)
|
||||
op(0xac, AbsoluteRead, fp(LD), Y)
|
||||
op(0xad, AbsoluteRead, fp(LD), A)
|
||||
op(0xae, AbsoluteRead, fp(LD), X)
|
||||
op(0xaf, BBS, 2)
|
||||
op(0xb0, branch, C == 1)
|
||||
op(0xb1, indirectYLoad, fp(LD), A)
|
||||
op(0xb2, indirectLoad, fp(LD), A)
|
||||
op(0xb3, TST_absolute, X)
|
||||
op(0xb4, zeropageLoad, fp(LD), Y, X)
|
||||
op(0xb5, zeropageLoad, fp(LD), A, X)
|
||||
op(0xb6, zeropageLoad, fp(LD), X, Y)
|
||||
op(0xb0, Branch, C == 1)
|
||||
op(0xb1, IndirectYRead, fp(LD), A)
|
||||
op(0xb2, IndirectRead, fp(LD), A)
|
||||
op(0xb3, TSTAbsolute, X)
|
||||
op(0xb4, ZeroPageRead, fp(LD), Y, X)
|
||||
op(0xb5, ZeroPageRead, fp(LD), A, X)
|
||||
op(0xb6, ZeroPageRead, fp(LD), X, Y)
|
||||
op(0xb7, SMB, 3)
|
||||
op(0xb8, clear, V)
|
||||
op(0xb9, absoluteLoad, fp(LD), A, Y)
|
||||
op(0xba, transfer, S, X)
|
||||
op(0xb8, Clear, V)
|
||||
op(0xb9, AbsoluteRead, fp(LD), A, Y)
|
||||
op(0xba, Transfer, S, X)
|
||||
U op(0xbb, NOP)
|
||||
op(0xbc, absoluteLoad, fp(LD), Y, X)
|
||||
op(0xbd, absoluteLoad, fp(LD), A, X)
|
||||
op(0xbe, absoluteLoad, fp(LD), X, Y)
|
||||
op(0xbc, AbsoluteRead, fp(LD), Y, X)
|
||||
op(0xbd, AbsoluteRead, fp(LD), A, X)
|
||||
op(0xbe, AbsoluteRead, fp(LD), X, Y)
|
||||
op(0xbf, BBS, 3)
|
||||
op(0xc0, immediate, fp(CPY), Y)
|
||||
op(0xc1, indirectLoad, fp(CMP), A, X)
|
||||
op(0xc2, clear, Y)
|
||||
op(0xc3, blockmove, fp(TDD))
|
||||
op(0xc4, zeropageLoad, fp(CPY), Y)
|
||||
op(0xc5, zeropageLoad, fp(CMP), A)
|
||||
op(0xc6, zeropageModify, fp(DEC))
|
||||
op(0xc0, Immediate, fp(CPY), Y)
|
||||
op(0xc1, IndirectRead, fp(CMP), A, X)
|
||||
op(0xc2, Clear, Y)
|
||||
op(0xc3, BlockMove, fp(TDD))
|
||||
op(0xc4, ZeroPageRead, fp(CPY), Y)
|
||||
op(0xc5, ZeroPageRead, fp(CMP), A)
|
||||
op(0xc6, ZeroPageModify, fp(DEC))
|
||||
op(0xc7, SMB, 4)
|
||||
op(0xc8, implied, fp(INC), Y)
|
||||
op(0xc9, immediate, fp(CMP), A)
|
||||
op(0xca, implied, fp(DEC), X)
|
||||
op(0xc8, Implied, fp(INC), Y)
|
||||
op(0xc9, Immediate, fp(CMP), A)
|
||||
op(0xca, Implied, fp(DEC), X)
|
||||
U op(0xcb, NOP)
|
||||
op(0xcc, absoluteLoad, fp(CPY), Y)
|
||||
op(0xcd, absoluteLoad, fp(CMP), A)
|
||||
op(0xce, absoluteModify, fp(DEC))
|
||||
op(0xcc, AbsoluteRead, fp(CPY), Y)
|
||||
op(0xcd, AbsoluteRead, fp(CMP), A)
|
||||
op(0xce, AbsoluteModify, fp(DEC))
|
||||
op(0xcf, BBS, 4)
|
||||
op(0xd0, branch, Z == 0)
|
||||
op(0xd1, indirectYLoad, fp(CMP), A)
|
||||
op(0xd2, indirectLoad, fp(CMP), A)
|
||||
op(0xd3, blockmove, fp(TIN))
|
||||
op(0xd0, Branch, Z == 0)
|
||||
op(0xd1, IndirectYRead, fp(CMP), A)
|
||||
op(0xd2, IndirectRead, fp(CMP), A)
|
||||
op(0xd3, BlockMove, fp(TIN))
|
||||
op(0xd4, CSH)
|
||||
op(0xd5, zeropageLoad, fp(CMP), A, X)
|
||||
op(0xd6, zeropageModify, fp(DEC), X)
|
||||
op(0xd5, ZeroPageRead, fp(CMP), A, X)
|
||||
op(0xd6, ZeroPageModify, fp(DEC), X)
|
||||
op(0xd7, SMB, 5)
|
||||
op(0xd8, clear, D)
|
||||
op(0xd9, absoluteLoad, fp(CMP), A, Y)
|
||||
op(0xda, push, X)
|
||||
op(0xd8, Clear, D)
|
||||
op(0xd9, AbsoluteRead, fp(CMP), A, Y)
|
||||
op(0xda, Push, X)
|
||||
U op(0xdb, NOP)
|
||||
U op(0xdc, NOP)
|
||||
op(0xdd, absoluteLoad, fp(CMP), A, X)
|
||||
op(0xde, absoluteModify, fp(DEC), X)
|
||||
op(0xdd, AbsoluteRead, fp(CMP), A, X)
|
||||
op(0xde, AbsoluteModify, fp(DEC), X)
|
||||
op(0xdf, BBS, 5)
|
||||
op(0xe0, immediate, fp(CPX), X)
|
||||
op(0xe1, indirectLoad, fp(SBC), A, X)
|
||||
op(0xe0, Immediate, fp(CPX), X)
|
||||
op(0xe1, IndirectRead, fp(SBC), A, X)
|
||||
U op(0xe2, NOP)
|
||||
op(0xe3, blockmove, fp(TIA))
|
||||
op(0xe4, zeropageLoad, fp(CPX), X)
|
||||
op(0xe5, zeropageLoad, fp(SBC), A)
|
||||
op(0xe6, zeropageModify, fp(INC))
|
||||
op(0xe3, BlockMove, fp(TIA))
|
||||
op(0xe4, ZeroPageRead, fp(CPX), X)
|
||||
op(0xe5, ZeroPageRead, fp(SBC), A)
|
||||
op(0xe6, ZeroPageModify, fp(INC))
|
||||
op(0xe7, SMB, 6)
|
||||
op(0xe8, implied, fp(INC), X)
|
||||
op(0xe9, immediate, fp(SBC), A)
|
||||
op(0xe8, Implied, fp(INC), X)
|
||||
op(0xe9, Immediate, fp(SBC), A)
|
||||
op(0xea, NOP)
|
||||
U op(0xeb, NOP)
|
||||
op(0xec, absoluteLoad, fp(CPX), X)
|
||||
op(0xed, absoluteLoad, fp(SBC), A)
|
||||
op(0xee, absoluteModify, fp(INC))
|
||||
op(0xec, AbsoluteRead, fp(CPX), X)
|
||||
op(0xed, AbsoluteRead, fp(SBC), A)
|
||||
op(0xee, AbsoluteModify, fp(INC))
|
||||
op(0xef, BBS, 6)
|
||||
op(0xf0, branch, Z == 1)
|
||||
op(0xf1, indirectYLoad, fp(SBC), A)
|
||||
op(0xf2, indirectLoad, fp(SBC), A)
|
||||
op(0xf3, blockmove, fp(TAI))
|
||||
op(0xf4, set, T)
|
||||
op(0xf5, zeropageLoad, fp(SBC), A, X)
|
||||
op(0xf6, zeropageModify, fp(INC), X)
|
||||
op(0xf0, Branch, Z == 1)
|
||||
op(0xf1, IndirectYRead, fp(SBC), A)
|
||||
op(0xf2, IndirectRead, fp(SBC), A)
|
||||
op(0xf3, BlockMove, fp(TAI))
|
||||
op(0xf4, Set, T)
|
||||
op(0xf5, ZeroPageRead, fp(SBC), A, X)
|
||||
op(0xf6, ZeroPageModify, fp(INC), X)
|
||||
op(0xf7, SMB, 7)
|
||||
op(0xf8, set, D)
|
||||
op(0xf9, absoluteLoad, fp(SBC), A, Y)
|
||||
op(0xfa, pull, X)
|
||||
op(0xf8, Set, D)
|
||||
op(0xf9, AbsoluteRead, fp(SBC), A, Y)
|
||||
op(0xfa, Pull, X)
|
||||
U op(0xfb, NOP)
|
||||
U op(0xfc, NOP)
|
||||
op(0xfd, absoluteLoad, fp(SBC), A, X)
|
||||
op(0xfe, absoluteModify, fp(INC), X)
|
||||
op(0xfd, AbsoluteRead, fp(SBC), A, X)
|
||||
op(0xfe, AbsoluteModify, fp(INC), X)
|
||||
op(0xff, BBS, 7)
|
||||
}
|
||||
#undef U
|
||||
|
|
|
@ -1,198 +1,4 @@
|
|||
auto HuC6280::ADC(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::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 {
|
||||
auto HuC6280::instructionAbsoluteModify(fp alu, uint8 index) -> void {
|
||||
uint16 absolute = operand();
|
||||
absolute |= operand() << 8;
|
||||
io();
|
||||
|
@ -201,14 +7,21 @@ auto HuC6280::instruction_absoluteModify(fp alu, uint8 index) -> void {
|
|||
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();
|
||||
absolute |= operand() << 8;
|
||||
io();
|
||||
L store16(absolute + index, data);
|
||||
}
|
||||
|
||||
auto HuC6280::instruction_blockmove(bp alu) -> void {
|
||||
auto HuC6280::instructionBlockMove(bp alu) -> void {
|
||||
uint16 source = operand();
|
||||
source |= operand() << 8;
|
||||
uint16 target = operand();
|
||||
|
@ -238,7 +51,7 @@ auto HuC6280::instruction_blockmove(bp alu) -> void {
|
|||
L Y = pull();
|
||||
}
|
||||
|
||||
auto HuC6280::instruction_branch(bool take) -> void {
|
||||
auto HuC6280::instructionBranch(bool take) -> void {
|
||||
if(!take) {
|
||||
L operand();
|
||||
} 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();
|
||||
data = 0;
|
||||
}
|
||||
|
||||
auto HuC6280::instruction_clear(bool& flag) -> void {
|
||||
auto HuC6280::instructionClear(bool& flag) -> void {
|
||||
L io();
|
||||
flag = 0;
|
||||
}
|
||||
|
||||
auto HuC6280::instruction_immediate(fp alu, uint8& data) -> void {
|
||||
auto HuC6280::instructionImmediate(fp alu, uint8& data) -> void {
|
||||
L data = ALU(operand());
|
||||
}
|
||||
|
||||
auto HuC6280::instruction_implied(fp alu, uint8& data) -> void {
|
||||
auto HuC6280::instructionImplied(fp alu, uint8& data) -> void {
|
||||
L io();
|
||||
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();
|
||||
io();
|
||||
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));
|
||||
}
|
||||
|
||||
auto HuC6280::instruction_indirectStore(uint8 data, uint8 index) -> void {
|
||||
auto HuC6280::instructionIndirectWrite(uint8 data, uint8 index) -> void {
|
||||
auto zeropage = operand();
|
||||
io();
|
||||
uint16 absolute = load8(zeropage + index + 0);
|
||||
|
@ -285,7 +98,7 @@ auto HuC6280::instruction_indirectStore(uint8 data, uint8 index) -> void {
|
|||
L store16(absolute, data);
|
||||
}
|
||||
|
||||
auto HuC6280::instruction_indirectYLoad(fp alu, uint8& data) -> void {
|
||||
auto HuC6280::instructionIndirectYRead(fp alu, uint8& data) -> void {
|
||||
auto zeropage = operand();
|
||||
io();
|
||||
uint16 absolute = load8(zeropage + 0);
|
||||
|
@ -294,7 +107,7 @@ auto HuC6280::instruction_indirectYLoad(fp alu, uint8& data) -> void {
|
|||
L data = ALU(load16(absolute + Y));
|
||||
}
|
||||
|
||||
auto HuC6280::instruction_indirectYStore(uint8 data) -> void {
|
||||
auto HuC6280::instructionIndirectYWrite(uint8 data) -> void {
|
||||
auto zeropage = operand();
|
||||
io();
|
||||
uint16 absolute = load8(zeropage + 0);
|
||||
|
@ -302,14 +115,14 @@ auto HuC6280::instruction_indirectYStore(uint8 data) -> void {
|
|||
L store16(absolute + Y, data);
|
||||
}
|
||||
|
||||
auto HuC6280::instruction_memory(fp alu) -> void {
|
||||
auto HuC6280::instructionMemory(fp alu) -> void {
|
||||
auto a = A;
|
||||
A = ALU(load8(X));
|
||||
L store8(X, A);
|
||||
A = a;
|
||||
}
|
||||
|
||||
auto HuC6280::instruction_pull(uint8& data) -> void {
|
||||
auto HuC6280::instructionPull(uint8& data) -> void {
|
||||
io();
|
||||
io();
|
||||
L data = pull();
|
||||
|
@ -317,36 +130,30 @@ L data = pull();
|
|||
N = data.bit(7);
|
||||
}
|
||||
|
||||
auto HuC6280::instruction_push(uint8 data) -> void {
|
||||
auto HuC6280::instructionPush(uint8 data) -> void {
|
||||
io();
|
||||
L push(data);
|
||||
}
|
||||
|
||||
auto HuC6280::instruction_set(bool& flag) -> void {
|
||||
auto HuC6280::instructionSet(bool& flag) -> void {
|
||||
L io();
|
||||
flag = 1;
|
||||
}
|
||||
|
||||
auto HuC6280::instruction_swap(uint8& lhs, uint8& rhs) -> void {
|
||||
auto HuC6280::instructionSwap(uint8& lhs, uint8& rhs) -> void {
|
||||
io();
|
||||
L io();
|
||||
swap(lhs, rhs);
|
||||
}
|
||||
|
||||
auto HuC6280::instruction_transfer(uint8& source, uint8& target) -> void {
|
||||
auto HuC6280::instructionTransfer(uint8& source, uint8& target) -> void {
|
||||
L io();
|
||||
target = source;
|
||||
Z = target == 0;
|
||||
N = target.bit(7);
|
||||
}
|
||||
|
||||
auto HuC6280::instruction_zeropageLoad(fp alu, uint8& data, uint8 index) -> void {
|
||||
auto zeropage = operand();
|
||||
io();
|
||||
L data = ALU(load8(zeropage + index));
|
||||
}
|
||||
|
||||
auto HuC6280::instruction_zeropageModify(fp alu, uint8 index) -> void {
|
||||
auto HuC6280::instructionZeroPageModify(fp alu, uint8 index) -> void {
|
||||
auto zeropage = operand();
|
||||
io();
|
||||
io();
|
||||
|
@ -354,7 +161,13 @@ auto HuC6280::instruction_zeropageModify(fp alu, uint8 index) -> void {
|
|||
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();
|
||||
io();
|
||||
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 displacement = operand();
|
||||
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 displacement = operand();
|
||||
io();
|
||||
|
@ -384,7 +197,7 @@ L auto data = load8(zeropage);
|
|||
}
|
||||
}
|
||||
|
||||
auto HuC6280::instruction_BRK() -> void {
|
||||
auto HuC6280::instructionBRK() -> void {
|
||||
operand();
|
||||
io();
|
||||
push(PC >> 8);
|
||||
|
@ -397,7 +210,7 @@ auto HuC6280::instruction_BRK() -> void {
|
|||
L PC.byte(1) = load16(0xfff7);
|
||||
}
|
||||
|
||||
auto HuC6280::instruction_BSR() -> void {
|
||||
auto HuC6280::instructionBSR() -> void {
|
||||
auto displacement = operand();
|
||||
io();
|
||||
io();
|
||||
|
@ -408,24 +221,24 @@ L push((PC - 1) >> 0);
|
|||
PC += (int8)displacement;
|
||||
}
|
||||
|
||||
auto HuC6280::instruction_CSL() -> void {
|
||||
auto HuC6280::instructionCSL() -> void {
|
||||
L io();
|
||||
r.cs = 4;
|
||||
}
|
||||
|
||||
auto HuC6280::instruction_CSH() -> void {
|
||||
auto HuC6280::instructionCSH() -> void {
|
||||
L io();
|
||||
r.cs = 1;
|
||||
}
|
||||
|
||||
auto HuC6280::instruction_JMP_absolute() -> void {
|
||||
auto HuC6280::instructionJMPAbsolute() -> void {
|
||||
uint16 address = operand();
|
||||
address |= operand() << 8;
|
||||
L io();
|
||||
PC = address;
|
||||
}
|
||||
|
||||
auto HuC6280::instruction_JMP_indirect(uint8 index) -> void {
|
||||
auto HuC6280::instructionJMPIndirect(uint8 index) -> void {
|
||||
uint16 address = operand();
|
||||
address |= operand() << 8;
|
||||
io();
|
||||
|
@ -434,7 +247,7 @@ auto HuC6280::instruction_JMP_indirect(uint8 index) -> void {
|
|||
L PC.byte(1) = load16(address + index + 1);
|
||||
}
|
||||
|
||||
auto HuC6280::instruction_JSR() -> void {
|
||||
auto HuC6280::instructionJSR() -> void {
|
||||
uint16 address = operand();
|
||||
address |= operand() << 8;
|
||||
io();
|
||||
|
@ -444,17 +257,17 @@ L push((PC - 1) >> 0);
|
|||
PC = address;
|
||||
}
|
||||
|
||||
auto HuC6280::instruction_NOP() -> void {
|
||||
auto HuC6280::instructionNOP() -> void {
|
||||
L io();
|
||||
}
|
||||
|
||||
auto HuC6280::instruction_PLP() -> void {
|
||||
auto HuC6280::instructionPLP() -> void {
|
||||
io();
|
||||
io();
|
||||
L P = pull();
|
||||
}
|
||||
|
||||
auto HuC6280::instruction_RMB(uint3 index) -> void {
|
||||
auto HuC6280::instructionRMB(uint3 index) -> void {
|
||||
auto zeropage = operand();
|
||||
io();
|
||||
io();
|
||||
|
@ -464,7 +277,7 @@ auto HuC6280::instruction_RMB(uint3 index) -> void {
|
|||
L store8(zeropage, data);
|
||||
}
|
||||
|
||||
auto HuC6280::instruction_RTI() -> void {
|
||||
auto HuC6280::instructionRTI() -> void {
|
||||
io();
|
||||
io();
|
||||
io();
|
||||
|
@ -473,7 +286,7 @@ auto HuC6280::instruction_RTI() -> void {
|
|||
L PC.byte(1) = pull();
|
||||
}
|
||||
|
||||
auto HuC6280::instruction_RTS() -> void {
|
||||
auto HuC6280::instructionRTS() -> void {
|
||||
io();
|
||||
io();
|
||||
io();
|
||||
|
@ -483,7 +296,7 @@ L io();
|
|||
PC++;
|
||||
}
|
||||
|
||||
auto HuC6280::instruction_SMB(uint3 index) -> void {
|
||||
auto HuC6280::instructionSMB(uint3 index) -> void {
|
||||
auto zeropage = operand();
|
||||
io();
|
||||
io();
|
||||
|
@ -493,14 +306,14 @@ auto HuC6280::instruction_SMB(uint3 index) -> void {
|
|||
L store8(zeropage, data);
|
||||
}
|
||||
|
||||
auto HuC6280::instruction_ST(uint2 index) -> void {
|
||||
auto HuC6280::instructionST(uint2 index) -> void {
|
||||
auto data = operand();
|
||||
io();
|
||||
io();
|
||||
L store(index, data);
|
||||
}
|
||||
|
||||
auto HuC6280::instruction_TAM() -> void {
|
||||
auto HuC6280::instructionTAM() -> void {
|
||||
auto mask = operand();
|
||||
io();
|
||||
io();
|
||||
|
@ -510,7 +323,7 @@ L io();
|
|||
}
|
||||
}
|
||||
|
||||
auto HuC6280::instruction_TMA() -> void {
|
||||
auto HuC6280::instructionTMA() -> void {
|
||||
auto mask = operand();
|
||||
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();
|
||||
uint16 absolute = operand();
|
||||
absolute |= operand() << 8;
|
||||
|
@ -532,7 +345,7 @@ L uint8 data = load16(absolute + index);
|
|||
N = data.bit(7);
|
||||
}
|
||||
|
||||
auto HuC6280::instruction_TST_zeropage(uint8 index) -> void {
|
||||
auto HuC6280::instructionTSTZeroPage(uint8 index) -> void {
|
||||
auto mask = operand();
|
||||
auto zeropage = operand();
|
||||
io();
|
||||
|
@ -544,7 +357,7 @@ L uint8 data = load8(zeropage + index);
|
|||
N = data.bit(7);
|
||||
}
|
||||
|
||||
auto HuC6280::instruction_TXS() -> void {
|
||||
auto HuC6280::instructionTXS() -> void {
|
||||
L io();
|
||||
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 fp(name) &MOS6502::name
|
||||
#define fp(name) &MOS6502::algorithm##name
|
||||
|
||||
auto MOS6502::interrupt() -> void {
|
||||
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 {
|
||||
uint16 absolute = operand();
|
||||
absolute |= operand() << 8;
|
||||
|
|
|
@ -21,6 +21,7 @@ namespace Processor {
|
|||
#define L lastCycle();
|
||||
|
||||
#include "memory.cpp"
|
||||
#include "algorithms.cpp"
|
||||
#include "instruction.cpp"
|
||||
#include "instructions.cpp"
|
||||
#include "disassembler.cpp"
|
||||
|
|
|
@ -26,29 +26,30 @@ struct MOS6502 {
|
|||
auto push(uint8 data) -> void;
|
||||
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
|
||||
auto interrupt() -> void;
|
||||
auto instruction() -> void;
|
||||
|
||||
//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, uint8 index) -> void;
|
||||
auto instructionAbsoluteRead(fp alu, uint8& data) -> void;
|
||||
|
|
|
@ -1,134 +1,134 @@
|
|||
auto SPC700::op_adc(uint8 x, uint8 y) -> uint8 {
|
||||
int r = x + y + regs.p.c;
|
||||
regs.p.n = r & 0x80;
|
||||
regs.p.v = ~(x ^ y) & (x ^ r) & 0x80;
|
||||
regs.p.h = (x ^ y ^ r) & 0x10;
|
||||
regs.p.z = (uint8)r == 0;
|
||||
regs.p.c = r > 0xff;
|
||||
return r;
|
||||
auto SPC700::algorithmADC(uint8 x, uint8 y) -> uint8 {
|
||||
int z = x + y + CF;
|
||||
CF = z > 0xff;
|
||||
ZF = (uint8)z == 0;
|
||||
HF = (x ^ y ^ z) & 0x10;
|
||||
VF = ~(x ^ y) & (x ^ z) & 0x80;
|
||||
NF = z & 0x80;
|
||||
return z;
|
||||
}
|
||||
|
||||
auto SPC700::op_and(uint8 x, uint8 y) -> uint8 {
|
||||
auto SPC700::algorithmAND(uint8 x, uint8 y) -> uint8 {
|
||||
x &= y;
|
||||
regs.p.n = x & 0x80;
|
||||
regs.p.z = x == 0;
|
||||
ZF = x == 0;
|
||||
NF = x & 0x80;
|
||||
return x;
|
||||
}
|
||||
|
||||
auto SPC700::op_asl(uint8 x) -> uint8 {
|
||||
regs.p.c = x & 0x80;
|
||||
auto SPC700::algorithmASL(uint8 x) -> uint8 {
|
||||
CF = x & 0x80;
|
||||
x <<= 1;
|
||||
regs.p.n = x & 0x80;
|
||||
regs.p.z = x == 0;
|
||||
ZF = x == 0;
|
||||
NF = x & 0x80;
|
||||
return x;
|
||||
}
|
||||
|
||||
auto SPC700::op_cmp(uint8 x, uint8 y) -> uint8 {
|
||||
int r = x - y;
|
||||
regs.p.n = r & 0x80;
|
||||
regs.p.z = (uint8)r == 0;
|
||||
regs.p.c = r >= 0;
|
||||
auto SPC700::algorithmCMP(uint8 x, uint8 y) -> uint8 {
|
||||
int z = x - y;
|
||||
CF = z >= 0;
|
||||
ZF = (uint8)z == 0;
|
||||
NF = z & 0x80;
|
||||
return x;
|
||||
}
|
||||
|
||||
auto SPC700::op_dec(uint8 x) -> uint8 {
|
||||
auto SPC700::algorithmDEC(uint8 x) -> uint8 {
|
||||
x--;
|
||||
regs.p.n = x & 0x80;
|
||||
regs.p.z = x == 0;
|
||||
ZF = x == 0;
|
||||
NF = x & 0x80;
|
||||
return x;
|
||||
}
|
||||
|
||||
auto SPC700::op_eor(uint8 x, uint8 y) -> uint8 {
|
||||
auto SPC700::algorithmEOR(uint8 x, uint8 y) -> uint8 {
|
||||
x ^= y;
|
||||
regs.p.n = x & 0x80;
|
||||
regs.p.z = x == 0;
|
||||
ZF = x == 0;
|
||||
NF = x & 0x80;
|
||||
return x;
|
||||
}
|
||||
|
||||
auto SPC700::op_inc(uint8 x) -> uint8 {
|
||||
auto SPC700::algorithmINC(uint8 x) -> uint8 {
|
||||
x++;
|
||||
regs.p.n = x & 0x80;
|
||||
regs.p.z = x == 0;
|
||||
ZF = x == 0;
|
||||
NF = x & 0x80;
|
||||
return x;
|
||||
}
|
||||
|
||||
auto SPC700::op_ld(uint8 x, uint8 y) -> uint8 {
|
||||
regs.p.n = y & 0x80;
|
||||
regs.p.z = y == 0;
|
||||
auto SPC700::algorithmLD(uint8 x, uint8 y) -> uint8 {
|
||||
ZF = y == 0;
|
||||
NF = y & 0x80;
|
||||
return y;
|
||||
}
|
||||
|
||||
auto SPC700::op_lsr(uint8 x) -> uint8 {
|
||||
regs.p.c = x & 0x01;
|
||||
auto SPC700::algorithmLSR(uint8 x) -> uint8 {
|
||||
CF = x & 0x01;
|
||||
x >>= 1;
|
||||
regs.p.n = x & 0x80;
|
||||
regs.p.z = x == 0;
|
||||
ZF = x == 0;
|
||||
NF = x & 0x80;
|
||||
return x;
|
||||
}
|
||||
|
||||
auto SPC700::op_or(uint8 x, uint8 y) -> uint8 {
|
||||
auto SPC700::algorithmOR(uint8 x, uint8 y) -> uint8 {
|
||||
x |= y;
|
||||
regs.p.n = x & 0x80;
|
||||
regs.p.z = x == 0;
|
||||
ZF = x == 0;
|
||||
NF = x & 0x80;
|
||||
return x;
|
||||
}
|
||||
|
||||
auto SPC700::op_rol(uint8 x) -> uint8 {
|
||||
uint carry = regs.p.c << 0;
|
||||
regs.p.c = x & 0x80;
|
||||
x = (x << 1) | carry;
|
||||
regs.p.n = x & 0x80;
|
||||
regs.p.z = x == 0;
|
||||
auto SPC700::algorithmROL(uint8 x) -> uint8 {
|
||||
bool carry = CF;
|
||||
CF = x & 0x80;
|
||||
x = x << 1 | carry;
|
||||
ZF = x == 0;
|
||||
NF = x & 0x80;
|
||||
return x;
|
||||
}
|
||||
|
||||
auto SPC700::op_ror(uint8 x) -> uint8 {
|
||||
uint carry = regs.p.c << 7;
|
||||
regs.p.c = x & 0x01;
|
||||
x = carry | (x >> 1);
|
||||
regs.p.n = x & 0x80;
|
||||
regs.p.z = x == 0;
|
||||
auto SPC700::algorithmROR(uint8 x) -> uint8 {
|
||||
bool carry = CF;
|
||||
CF = x & 0x01;
|
||||
x = carry << 7 | x >> 1;
|
||||
ZF = x == 0;
|
||||
NF = x & 0x80;
|
||||
return x;
|
||||
}
|
||||
|
||||
auto SPC700::op_sbc(uint8 x, uint8 y) -> uint8 {
|
||||
return op_adc(x, ~y);
|
||||
auto SPC700::algorithmSBC(uint8 x, uint8 y) -> uint8 {
|
||||
return algorithmADC(x, ~y);
|
||||
}
|
||||
|
||||
auto SPC700::op_st(uint8 x, uint8 y) -> uint8 {
|
||||
auto SPC700::algorithmST(uint8 x, uint8 y) -> uint8 {
|
||||
return y;
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
auto SPC700::op_adw(uint16 x, uint16 y) -> uint16 {
|
||||
uint16 r;
|
||||
regs.p.c = 0;
|
||||
r = op_adc(x, y);
|
||||
r |= op_adc(x >> 8, y >> 8) << 8;
|
||||
regs.p.z = r == 0;
|
||||
return r;
|
||||
auto SPC700::algorithmADW(uint16 x, uint16 y) -> uint16 {
|
||||
uint16 z;
|
||||
CF = 0;
|
||||
z = algorithmADC(x, y);
|
||||
z |= algorithmADC(x >> 8, y >> 8) << 8;
|
||||
ZF = z == 0;
|
||||
return z;
|
||||
}
|
||||
|
||||
auto SPC700::op_cpw(uint16 x, uint16 y) -> uint16 {
|
||||
int r = x - y;
|
||||
regs.p.n = r & 0x8000;
|
||||
regs.p.z = (uint16)r == 0;
|
||||
regs.p.c = r >= 0;
|
||||
auto SPC700::algorithmCPW(uint16 x, uint16 y) -> uint16 {
|
||||
int z = x - y;
|
||||
CF = z >= 0;
|
||||
ZF = (uint16)z == 0;
|
||||
NF = z & 0x8000;
|
||||
return x;
|
||||
}
|
||||
|
||||
auto SPC700::op_ldw(uint16 x, uint16 y) -> uint16 {
|
||||
regs.p.n = y & 0x8000;
|
||||
regs.p.z = y == 0;
|
||||
auto SPC700::algorithmLDW(uint16 x, uint16 y) -> uint16 {
|
||||
ZF = y == 0;
|
||||
NF = y & 0x8000;
|
||||
return y;
|
||||
}
|
||||
|
||||
auto SPC700::op_sbw(uint16 x, uint16 y) -> uint16 {
|
||||
uint16 r;
|
||||
regs.p.c = 1;
|
||||
r = op_sbc(x, y);
|
||||
r |= op_sbc(x >> 8, y >> 8) << 8;
|
||||
regs.p.z = r == 0;
|
||||
return r;
|
||||
auto SPC700::algorithmSBW(uint16 x, uint16 y) -> uint16 {
|
||||
uint16 z;
|
||||
CF = 1;
|
||||
z = algorithmSBC(x, y);
|
||||
z |= algorithmSBC(x >> 8, y >> 8) << 8;
|
||||
ZF = z == 0;
|
||||
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 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 ab = [&] {
|
||||
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 0x01: return { "jst $ffde" };
|
||||
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 0x05: return { "ora $", a() };
|
||||
case 0x06: return { "ora (x)" };
|
||||
|
@ -35,10 +35,10 @@ auto SPC700::disassemble(uint16 addr, bool p) -> string {
|
|||
case 0x0d: return { "php" };
|
||||
case 0x0e: return { "tsb $", a() };
|
||||
case 0x0f: return { "brk" };
|
||||
case 0x10: return { "bpl $", r(+2) };
|
||||
case 0x10: return { "bpl $", rel(+2) };
|
||||
case 0x11: return { "jst $ffdc" };
|
||||
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 0x15: return { "ora $", a(), ",x" };
|
||||
case 0x16: return { "ora $", a(), ",y" };
|
||||
|
@ -54,7 +54,7 @@ auto SPC700::disassemble(uint16 addr, bool p) -> string {
|
|||
case 0x20: return { "clp" };
|
||||
case 0x21: return { "jst $ffda" };
|
||||
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 0x25: return { "and $", a() };
|
||||
case 0x26: return { "and (x)" };
|
||||
|
@ -64,13 +64,13 @@ auto SPC700::disassemble(uint16 addr, bool p) -> string {
|
|||
case 0x2b: return { "rol $", dp(0) };
|
||||
case 0x2c: return { "rol $", a() };
|
||||
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 0x2f: return { "bra $", r(+2) };
|
||||
case 0x30: return { "bmi $", r(+2) };
|
||||
case 0x2f: return { "bra $", rel(+2) };
|
||||
case 0x30: return { "bmi $", rel(+2) };
|
||||
case 0x31: return { "jst $ffd8" };
|
||||
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 0x35: return { "and $", a(), ",x" };
|
||||
case 0x36: return { "and $", a(), ",y" };
|
||||
|
@ -86,7 +86,7 @@ auto SPC700::disassemble(uint16 addr, bool p) -> string {
|
|||
case 0x40: return { "sep" };
|
||||
case 0x41: return { "jst $ffd6" };
|
||||
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 0x45: return { "eor $", a() };
|
||||
case 0x46: return { "eor (x)" };
|
||||
|
@ -99,10 +99,10 @@ auto SPC700::disassemble(uint16 addr, bool p) -> string {
|
|||
case 0x4d: return { "phx" };
|
||||
case 0x4e: return { "trb $", a() };
|
||||
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 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 0x55: return { "eor $", a(), ",x" };
|
||||
case 0x56: return { "eor $", a(), ",y" };
|
||||
|
@ -118,7 +118,7 @@ auto SPC700::disassemble(uint16 addr, bool p) -> string {
|
|||
case 0x60: return { "clc" };
|
||||
case 0x61: return { "jst $ffd2" };
|
||||
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 0x65: return { "cmp $", a() };
|
||||
case 0x66: return { "cmp (x)" };
|
||||
|
@ -129,12 +129,12 @@ auto SPC700::disassemble(uint16 addr, bool p) -> string {
|
|||
case 0x6b: return { "ror $", dp(0) };
|
||||
case 0x6c: return { "ror $", a() };
|
||||
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 0x70: return { "bvs $", r(+2) };
|
||||
case 0x70: return { "bvs $", rel(+2) };
|
||||
case 0x71: return { "jst $ffd0" };
|
||||
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 0x75: return { "cmp $", a(), ",x" };
|
||||
case 0x76: return { "cmp $", a(), ",y" };
|
||||
|
@ -150,7 +150,7 @@ auto SPC700::disassemble(uint16 addr, bool p) -> string {
|
|||
case 0x80: return { "sec" };
|
||||
case 0x81: return { "jst $ffce" };
|
||||
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 0x85: return { "adc $", a() };
|
||||
case 0x86: return { "adc (x)" };
|
||||
|
@ -163,10 +163,10 @@ auto SPC700::disassemble(uint16 addr, bool p) -> string {
|
|||
case 0x8d: return { "ldy #$", b(0) };
|
||||
case 0x8e: return { "plp" };
|
||||
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 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 0x95: return { "adc $", a(), ",x" };
|
||||
case 0x96: return { "adc $", a(), ",y" };
|
||||
|
@ -182,7 +182,7 @@ auto SPC700::disassemble(uint16 addr, bool p) -> string {
|
|||
case 0xa0: return { "sei" };
|
||||
case 0xa1: return { "jst $ffca" };
|
||||
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 0xa5: return { "sbc $", a() };
|
||||
case 0xa6: return { "sbc (x)" };
|
||||
|
@ -195,10 +195,10 @@ auto SPC700::disassemble(uint16 addr, bool p) -> string {
|
|||
case 0xad: return { "cpy #$", b(0) };
|
||||
case 0xae: return { "pla" };
|
||||
case 0xaf: return { "sta (x++)" };
|
||||
case 0xb0: return { "bcs $", r(+2) };
|
||||
case 0xb0: return { "bcs $", rel(+2) };
|
||||
case 0xb1: return { "jst $ffc8" };
|
||||
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 0xb5: return { "sbc $", a(), ",x" };
|
||||
case 0xb6: return { "sbc $", a(), ",y" };
|
||||
|
@ -214,7 +214,7 @@ auto SPC700::disassemble(uint16 addr, bool p) -> string {
|
|||
case 0xc0: return { "cli" };
|
||||
case 0xc1: return { "jst $ffc6" };
|
||||
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 0xc5: return { "sta $", a() };
|
||||
case 0xc6: return { "sta (x)" };
|
||||
|
@ -227,10 +227,10 @@ auto SPC700::disassemble(uint16 addr, bool p) -> string {
|
|||
case 0xcd: return { "ldx #$", b(0) };
|
||||
case 0xce: return { "plx" };
|
||||
case 0xcf: return { "mul" };
|
||||
case 0xd0: return { "bne $", r(+2) };
|
||||
case 0xd0: return { "bne $", rel(+2) };
|
||||
case 0xd1: return { "jst $ffc4" };
|
||||
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 0xd5: return { "sta $", a(), ",x" };
|
||||
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 0xdc: return { "dey" };
|
||||
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 0xe0: return { "clv" };
|
||||
case 0xe1: return { "jst $ffc2" };
|
||||
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 0xe5: return { "lda $", a() };
|
||||
case 0xe6: return { "lda (x)" };
|
||||
|
@ -259,10 +259,10 @@ auto SPC700::disassemble(uint16 addr, bool p) -> string {
|
|||
case 0xed: return { "cmc" };
|
||||
case 0xee: return { "ply" };
|
||||
case 0xef: return { "wai" };
|
||||
case 0xf0: return { "beq $", r(+2) };
|
||||
case 0xf0: return { "beq $", rel(+2) };
|
||||
case 0xf1: return { "jst $ffc0" };
|
||||
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 0xf5: return { "lda $", a(), ",x" };
|
||||
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 0xfc: return { "iny" };
|
||||
case 0xfd: return { "tay" };
|
||||
case 0xfe: return { "bne --y=$", r(+2) };
|
||||
case 0xfe: return { "bne --y=$", rel(+2) };
|
||||
case 0xff: return { "stp" };
|
||||
}
|
||||
throw;
|
||||
|
@ -285,20 +285,20 @@ auto SPC700::disassemble(uint16 addr, bool p) -> string {
|
|||
while(length++ < 30) output.append(" ");
|
||||
|
||||
output.append(
|
||||
"YA:", hex(regs.ya, 4L),
|
||||
" A:", hex(regs.a, 2L),
|
||||
" X:", hex(regs.x, 2L),
|
||||
" Y:", hex(regs.y, 2L),
|
||||
" S:", hex(regs.s, 2L),
|
||||
"YA:", hex(YA, 4L),
|
||||
" A:", hex(A, 2L),
|
||||
" X:", hex(X, 2L),
|
||||
" Y:", hex(Y, 2L),
|
||||
" S:", hex(S, 2L),
|
||||
" ",
|
||||
regs.p.n ? "N" : "n",
|
||||
regs.p.v ? "V" : "v",
|
||||
regs.p.p ? "P" : "p",
|
||||
regs.p.b ? "B" : "b",
|
||||
regs.p.h ? "H" : "h",
|
||||
regs.p.i ? "I" : "i",
|
||||
regs.p.z ? "Z" : "z",
|
||||
regs.p.c ? "C" : "c"
|
||||
NF ? "N" : "n",
|
||||
VF ? "V" : "v",
|
||||
PF ? "P" : "p",
|
||||
BF ? "B" : "b",
|
||||
HF ? "H" : "h",
|
||||
IF ? "I" : "i",
|
||||
ZF ? "Z" : "z",
|
||||
CF ? "C" : "c"
|
||||
);
|
||||
|
||||
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();
|
||||
r = call(r);
|
||||
target = alu(target);
|
||||
}
|
||||
|
||||
auto SPC700::op_adjust_addr(fps op) {
|
||||
dp.l = readPC();
|
||||
dp.h = readPC();
|
||||
rd = read(dp);
|
||||
rd = call(rd);
|
||||
write(dp, rd);
|
||||
auto SPC700::instructionAbsoluteModify(fps op) -> void {
|
||||
uint16 absolute = fetch();
|
||||
absolute |= fetch() << 8;
|
||||
uint8 data = read(absolute);
|
||||
write(absolute, alu(data));
|
||||
}
|
||||
|
||||
auto SPC700::op_adjust_dp(fps op) {
|
||||
dp = readPC();
|
||||
rd = readDP(dp);
|
||||
rd = call(rd);
|
||||
writeDP(dp, rd);
|
||||
auto SPC700::instructionDirectPageModify(fps op) -> void {
|
||||
uint8 direct = fetch();
|
||||
uint8 data = load(direct);
|
||||
store(direct, alu(data));
|
||||
}
|
||||
|
||||
auto SPC700::op_adjust_dpw(int n) {
|
||||
dp = readPC();
|
||||
rd.w = readDP(dp) + n;
|
||||
writeDP(dp++, rd.l);
|
||||
rd.h += readDP(dp);
|
||||
writeDP(dp++, rd.h);
|
||||
regs.p.n = rd & 0x8000;
|
||||
regs.p.z = rd == 0;
|
||||
auto SPC700::instructionDirectPageModifyWord(int adjust) -> void {
|
||||
uint8 direct = fetch();
|
||||
uint16 data = load(direct) + adjust;
|
||||
store(direct++, data >> 0);
|
||||
data += load(direct) << 8;
|
||||
store(direct++, data >> 8);
|
||||
ZF = data == 0;
|
||||
NF = data & 0x8000;
|
||||
}
|
||||
|
||||
auto SPC700::op_adjust_dpx(fps op) {
|
||||
dp = readPC();
|
||||
auto SPC700::instructionDirectPageXModify(fps op) -> void {
|
||||
uint8 direct = fetch();
|
||||
idle();
|
||||
rd = readDP(dp + regs.x);
|
||||
rd = call(rd);
|
||||
writeDP(dp + regs.x, rd);
|
||||
uint8 data = load(direct + X);
|
||||
store(direct + X, alu(data));
|
||||
}
|
||||
|
||||
auto SPC700::op_branch(bool condition) {
|
||||
rd = readPC();
|
||||
if(!condition) return;
|
||||
auto SPC700::instructionBranch(bool take) -> void {
|
||||
uint8 data = fetch();
|
||||
if(!take) return;
|
||||
idle();
|
||||
idle();
|
||||
regs.pc += (int8)rd;
|
||||
PC += (int8)data;
|
||||
}
|
||||
|
||||
auto SPC700::op_branch_bit() {
|
||||
dp = readPC();
|
||||
sp = readDP(dp);
|
||||
rd = readPC();
|
||||
idle();
|
||||
if((bool)(sp & (1 << (opcode >> 5))) == (bool)(opcode & 0x10)) return;
|
||||
auto SPC700::instructionPull(uint8& data) -> void {
|
||||
idle();
|
||||
idle();
|
||||
regs.pc += (int8)rd;
|
||||
data = pull();
|
||||
}
|
||||
|
||||
auto SPC700::op_pull(reg r) {
|
||||
auto SPC700::instructionPush(uint8 data) -> void {
|
||||
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();
|
||||
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();
|
||||
writeSP(r);
|
||||
rd = load(dp + index);
|
||||
data = alu(data, rd);
|
||||
}
|
||||
|
||||
auto SPC700::op_read_addr(fpb op, reg r) {
|
||||
dp.l = readPC();
|
||||
dp.h = readPC();
|
||||
rd = read(dp);
|
||||
r = call(r, rd);
|
||||
auto SPC700::instructionDirectPageReadWord(fpw op) -> void {
|
||||
dp = fetch();
|
||||
rd.l = load(dp++);
|
||||
if(op != &SPC700::algorithmCPW) idle();
|
||||
rd.h = load(dp++);
|
||||
YA = alu(YA, rd);
|
||||
}
|
||||
|
||||
auto SPC700::op_read_addri(fpb op, reg r) {
|
||||
dp.l = readPC();
|
||||
dp.h = readPC();
|
||||
auto SPC700::instructionIndirectPageXRead(fpb op) -> void {
|
||||
dp = fetch() + X;
|
||||
idle();
|
||||
rd = read(dp + r);
|
||||
regs.a = call(regs.a, rd);
|
||||
}
|
||||
|
||||
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++);
|
||||
sp.l = load(dp++);
|
||||
sp.h = load(dp++);
|
||||
rd = read(sp);
|
||||
regs.a = call(regs.a, rd);
|
||||
A = alu(A, rd);
|
||||
}
|
||||
|
||||
auto SPC700::op_read_idpy(fpb op) {
|
||||
dp = readPC();
|
||||
auto SPC700::instructionIndirectPageYRead(fpb op) -> void {
|
||||
dp = fetch();
|
||||
idle();
|
||||
sp.l = readDP(dp++);
|
||||
sp.h = readDP(dp++);
|
||||
rd = read(sp + regs.y);
|
||||
regs.a = call(regs.a, rd);
|
||||
sp.l = load(dp++);
|
||||
sp.h = load(dp++);
|
||||
rd = read(sp + Y);
|
||||
A = alu(A, rd);
|
||||
}
|
||||
|
||||
auto SPC700::op_read_ix(fpb op) {
|
||||
auto SPC700::instructionIndirectXRead(fpb op) -> void {
|
||||
idle();
|
||||
rd = readDP(regs.x);
|
||||
regs.a = call(regs.a, rd);
|
||||
rd = load(X);
|
||||
A = alu(A, rd);
|
||||
}
|
||||
|
||||
auto SPC700::op_set_addr_bit() {
|
||||
dp.l = readPC();
|
||||
dp.h = readPC();
|
||||
auto SPC700::instructionAbsoluteModifyBit() -> void {
|
||||
dp.l = fetch();
|
||||
dp.h = fetch();
|
||||
bit = dp >> 13;
|
||||
dp &= 0x1fff;
|
||||
rd = read(dp);
|
||||
|
@ -144,22 +130,22 @@ auto SPC700::op_set_addr_bit() {
|
|||
case 0: //orc addr:bit
|
||||
case 1: //orc !addr:bit
|
||||
idle();
|
||||
regs.p.c |= (rd & (1 << bit)) ^ (bool)(opcode & 0x20);
|
||||
CF |= (rd & (1 << bit)) ^ (bool)(opcode & 0x20);
|
||||
break;
|
||||
case 2: //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;
|
||||
case 4: //eor addr:bit
|
||||
idle();
|
||||
regs.p.c ^= (bool)(rd & (1 << bit));
|
||||
CF ^= (bool)(rd & (1 << bit));
|
||||
break;
|
||||
case 5: //ldc addr:bit
|
||||
regs.p.c = (rd & (1 << bit));
|
||||
CF = (rd & (1 << bit));
|
||||
break;
|
||||
case 6: //stc addr:bit
|
||||
idle();
|
||||
rd = (rd & ~(1 << bit)) | (regs.p.c << bit);
|
||||
rd = (rd & ~(1 << bit)) | (CF << bit);
|
||||
write(dp, rd);
|
||||
break;
|
||||
case 7: //not addr:bit
|
||||
|
@ -169,190 +155,209 @@ auto SPC700::op_set_addr_bit() {
|
|||
}
|
||||
}
|
||||
|
||||
auto SPC700::op_set_bit() {
|
||||
dp = readPC();
|
||||
rd = readDP(dp) & ~(1 << (opcode >> 5));
|
||||
writeDP(dp, rd | (!(opcode & 0x10) << (opcode >> 5)));
|
||||
}
|
||||
|
||||
auto SPC700::op_set_flag(uint bit, bool value) {
|
||||
auto SPC700::instructionFlagClear(bool& flag) -> void {
|
||||
idle();
|
||||
if(bit == regs.p.i.bit) idle();
|
||||
regs.p = value ? (regs.p | (1 << bit)) : (regs.p & ~(1 << bit));
|
||||
if(&flag == &IF) idle();
|
||||
flag = 0;
|
||||
}
|
||||
|
||||
auto SPC700::op_test_addr(bool set) {
|
||||
dp.l = readPC();
|
||||
dp.h = readPC();
|
||||
rd = read(dp);
|
||||
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::instructionFlagSet(bool& flag) -> void {
|
||||
idle();
|
||||
if(&flag == &IF) idle();
|
||||
flag = 1;
|
||||
}
|
||||
|
||||
auto SPC700::op_transfer(reg from, reg to) {
|
||||
auto SPC700::instructionTransfer(uint8& from, uint8& to) -> void {
|
||||
idle();
|
||||
to = from;
|
||||
if(&to == ®s.s) return;
|
||||
regs.p.n = (to & 0x80);
|
||||
regs.p.z = (to == 0);
|
||||
if(&to == &S) return;
|
||||
ZF = to == 0;
|
||||
NF = to & 0x80;
|
||||
}
|
||||
|
||||
auto SPC700::op_write_addr(reg r) {
|
||||
dp.l = readPC();
|
||||
dp.h = readPC();
|
||||
auto SPC700::instructionAbsoluteWrite(uint8& data) -> void {
|
||||
dp.l = fetch();
|
||||
dp.h = fetch();
|
||||
read(dp);
|
||||
write(dp, r);
|
||||
write(dp, data);
|
||||
}
|
||||
|
||||
auto SPC700::op_write_addri(reg i) {
|
||||
dp.l = readPC();
|
||||
dp.h = readPC();
|
||||
auto SPC700::instructionAbsoluteIndexedWrite(uint8& index) -> void {
|
||||
dp.l = fetch();
|
||||
dp.h = fetch();
|
||||
idle();
|
||||
dp += i;
|
||||
dp += index;
|
||||
read(dp);
|
||||
write(dp, regs.a);
|
||||
write(dp, A);
|
||||
}
|
||||
|
||||
auto SPC700::op_write_dp(reg r) {
|
||||
dp = readPC();
|
||||
readDP(dp);
|
||||
writeDP(dp, r);
|
||||
auto SPC700::instructionDirectPageWrite(uint8& data) -> void {
|
||||
dp = fetch();
|
||||
load(dp);
|
||||
store(dp, data);
|
||||
}
|
||||
|
||||
auto SPC700::op_write_dpi(reg r, reg i) {
|
||||
dp = readPC() + i;
|
||||
auto SPC700::instructionDirectPageIndexedWrite(uint8& data, uint8& index) -> void {
|
||||
dp = fetch() + index;
|
||||
idle();
|
||||
readDP(dp);
|
||||
writeDP(dp, r);
|
||||
load(dp);
|
||||
store(dp, data);
|
||||
}
|
||||
|
||||
auto SPC700::op_write_dp_const(fpb op) {
|
||||
rd = readPC();
|
||||
dp = readPC();
|
||||
wr = readDP(dp);
|
||||
wr = call(wr, rd);
|
||||
op != &SPC700::op_cmp ? writeDP(dp, wr) : idle();
|
||||
auto SPC700::instructionDirectPageWriteImmediate(fpb op) -> void {
|
||||
rd = fetch();
|
||||
dp = fetch();
|
||||
wr = load(dp);
|
||||
wr = alu(wr, rd);
|
||||
op != &SPC700::algorithmCMP ? store(dp, wr) : idle();
|
||||
}
|
||||
|
||||
auto SPC700::op_write_dp_dp(fpb op) {
|
||||
sp = readPC();
|
||||
rd = readDP(sp);
|
||||
dp = readPC();
|
||||
if(op != &SPC700::op_st) wr = readDP(dp);
|
||||
wr = call(wr, rd);
|
||||
op != &SPC700::op_cmp ? writeDP(dp, wr) : idle();
|
||||
auto SPC700::instructionDirectPageWriteDirectPage(fpb op) -> void {
|
||||
sp = fetch();
|
||||
rd = load(sp);
|
||||
dp = fetch();
|
||||
if(op != &SPC700::algorithmST) wr = load(dp);
|
||||
wr = alu(wr, rd);
|
||||
op != &SPC700::algorithmCMP ? store(dp, wr) : idle();
|
||||
}
|
||||
|
||||
auto SPC700::op_write_ix_iy(fpb op) {
|
||||
auto SPC700::instructionIndirectXWriteIndirectY(fpb op) -> void {
|
||||
idle();
|
||||
rd = readDP(regs.y);
|
||||
wr = readDP(regs.x);
|
||||
wr = call(wr, rd);
|
||||
op != &SPC700::op_cmp ? writeDP(regs.x, wr) : idle();
|
||||
rd = load(Y);
|
||||
wr = load(X);
|
||||
wr = alu(wr, rd);
|
||||
op != &SPC700::algorithmCMP ? store(X, wr) : idle();
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
auto SPC700::op_bne_dp() {
|
||||
dp = readPC();
|
||||
sp = readDP(dp);
|
||||
rd = readPC();
|
||||
auto SPC700::instructionBBC(uint3 bit) -> void {
|
||||
dp = fetch();
|
||||
uint8 data = load(dp);
|
||||
rd = fetch();
|
||||
idle();
|
||||
if(regs.a == sp) return;
|
||||
if(data.bit(bit) == 1) return;
|
||||
idle();
|
||||
idle();
|
||||
regs.pc += (int8)rd;
|
||||
PC += (int8)rd;
|
||||
}
|
||||
|
||||
auto SPC700::op_bne_dpdec() {
|
||||
dp = readPC();
|
||||
wr = readDP(dp);
|
||||
writeDP(dp, --wr);
|
||||
rd = readPC();
|
||||
auto SPC700::instructionBBS(uint3 bit) -> void {
|
||||
dp = fetch();
|
||||
uint8 data = load(dp);
|
||||
rd = fetch();
|
||||
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;
|
||||
idle();
|
||||
idle();
|
||||
regs.pc += (int8)rd;
|
||||
PC += (int8)rd;
|
||||
}
|
||||
|
||||
auto SPC700::op_bne_dpx() {
|
||||
dp = readPC();
|
||||
auto SPC700::instructionBNEDirectPageX() -> void {
|
||||
dp = fetch();
|
||||
idle();
|
||||
sp = readDP(dp + regs.x);
|
||||
rd = readPC();
|
||||
sp = load(dp + X);
|
||||
rd = fetch();
|
||||
idle();
|
||||
if(regs.a == sp) return;
|
||||
if(A == sp) return;
|
||||
idle();
|
||||
idle();
|
||||
regs.pc += (int8)rd;
|
||||
PC += (int8)rd;
|
||||
}
|
||||
|
||||
auto SPC700::op_bne_ydec() {
|
||||
rd = readPC();
|
||||
auto SPC700::instructionBNEYDecrement() -> void {
|
||||
rd = fetch();
|
||||
idle();
|
||||
idle();
|
||||
if(--regs.y == 0) return;
|
||||
if(--Y == 0) return;
|
||||
idle();
|
||||
idle();
|
||||
regs.pc += (int8)rd;
|
||||
PC += (int8)rd;
|
||||
}
|
||||
|
||||
auto SPC700::op_brk() {
|
||||
auto SPC700::instructionBRK() -> void {
|
||||
rd.l = read(0xffde);
|
||||
rd.h = read(0xffdf);
|
||||
idle();
|
||||
idle();
|
||||
writeSP(regs.pc.h);
|
||||
writeSP(regs.pc.l);
|
||||
writeSP(regs.p);
|
||||
regs.pc = rd;
|
||||
regs.p.b = 1;
|
||||
regs.p.i = 0;
|
||||
push(PC >> 8);
|
||||
push(PC >> 0);
|
||||
push(P);
|
||||
PC = rd;
|
||||
IF = 0;
|
||||
BF = 1;
|
||||
}
|
||||
|
||||
auto SPC700::op_clv() {
|
||||
idle();
|
||||
regs.p.v = 0;
|
||||
regs.p.h = 0;
|
||||
auto SPC700::instructionCLR(uint3 bit) -> void {
|
||||
uint8 direct = fetch();
|
||||
uint8 data = load(direct);
|
||||
data.bit(bit) = 0;
|
||||
store(direct, data);
|
||||
}
|
||||
|
||||
auto SPC700::op_cmc() {
|
||||
auto SPC700::instructionCLV() -> void {
|
||||
idle();
|
||||
idle();
|
||||
regs.p.c = !regs.p.c;
|
||||
HF = 0;
|
||||
VF = 0;
|
||||
}
|
||||
|
||||
auto SPC700::op_daa() {
|
||||
auto SPC700::instructionCMC() -> void {
|
||||
idle();
|
||||
idle();
|
||||
if(regs.p.c || (regs.a) > 0x99) {
|
||||
regs.a += 0x60;
|
||||
regs.p.c = 1;
|
||||
}
|
||||
if(regs.p.h || (regs.a & 15) > 0x09) {
|
||||
regs.a += 0x06;
|
||||
}
|
||||
regs.p.n = (regs.a & 0x80);
|
||||
regs.p.z = (regs.a == 0);
|
||||
CF = !CF;
|
||||
}
|
||||
|
||||
auto SPC700::op_das() {
|
||||
auto SPC700::instructionDAA() -> void {
|
||||
idle();
|
||||
idle();
|
||||
if(!regs.p.c || (regs.a) > 0x99) {
|
||||
regs.a -= 0x60;
|
||||
regs.p.c = 0;
|
||||
if(CF || A > 0x99) {
|
||||
A += 0x60;
|
||||
CF = 1;
|
||||
}
|
||||
if(!regs.p.h || (regs.a & 15) > 0x09) {
|
||||
regs.a -= 0x06;
|
||||
if(HF || (A & 15) > 0x09) {
|
||||
A += 0x06;
|
||||
}
|
||||
regs.p.n = (regs.a & 0x80);
|
||||
regs.p.z = (regs.a == 0);
|
||||
ZF = A == 0;
|
||||
NF = A & 0x80;
|
||||
}
|
||||
|
||||
auto SPC700::op_div_ya_x() {
|
||||
auto SPC700::instructionDAS() -> void {
|
||||
idle();
|
||||
idle();
|
||||
if(!CF || A > 0x99) {
|
||||
A -= 0x60;
|
||||
CF = 0;
|
||||
}
|
||||
if(!HF || (A & 15) > 0x09) {
|
||||
A -= 0x06;
|
||||
}
|
||||
ZF = A == 0;
|
||||
NF = A & 0x80;
|
||||
}
|
||||
|
||||
auto SPC700::instructionDIV() -> void {
|
||||
idle();
|
||||
idle();
|
||||
idle();
|
||||
|
@ -364,82 +369,82 @@ auto SPC700::op_div_ya_x() {
|
|||
idle();
|
||||
idle();
|
||||
idle();
|
||||
ya = regs.ya;
|
||||
uint16 ya = YA;
|
||||
//overflow set if quotient >= 256
|
||||
regs.p.v = (regs.y >= regs.x);
|
||||
regs.p.h = ((regs.y & 15) >= (regs.x & 15));
|
||||
if(regs.y < (regs.x << 1)) {
|
||||
HF = (Y & 15) >= (X & 15);
|
||||
VF = Y >= X;
|
||||
if(Y < (X << 1)) {
|
||||
//if quotient is <= 511 (will fit into 9-bit result)
|
||||
regs.a = ya / regs.x;
|
||||
regs.y = ya % regs.x;
|
||||
A = ya / X;
|
||||
Y = ya % X;
|
||||
} 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
|
||||
regs.a = 255 - (ya - (regs.x << 9)) / (256 - regs.x);
|
||||
regs.y = regs.x + (ya - (regs.x << 9)) % (256 - regs.x);
|
||||
A = 255 - (ya - (X << 9)) / (256 - X);
|
||||
Y = X + (ya - (X << 9)) % (256 - X);
|
||||
}
|
||||
//result is set based on a (quotient) only
|
||||
regs.p.n = (regs.a & 0x80);
|
||||
regs.p.z = (regs.a == 0);
|
||||
ZF = A == 0;
|
||||
NF = A & 0x80;
|
||||
}
|
||||
|
||||
auto SPC700::op_jmp_addr() {
|
||||
rd.l = readPC();
|
||||
rd.h = readPC();
|
||||
regs.pc = rd;
|
||||
auto SPC700::instructionJMPAbsolute() -> void {
|
||||
rd.l = fetch();
|
||||
rd.h = fetch();
|
||||
PC = rd;
|
||||
}
|
||||
|
||||
auto SPC700::op_jmp_iaddrx() {
|
||||
dp.l = readPC();
|
||||
dp.h = readPC();
|
||||
auto SPC700::instructionJMPIndirectAbsoluteX() -> void {
|
||||
dp.l = fetch();
|
||||
dp.h = fetch();
|
||||
idle();
|
||||
dp += regs.x;
|
||||
dp += X;
|
||||
rd.l = read(dp++);
|
||||
rd.h = read(dp++);
|
||||
regs.pc = rd;
|
||||
PC = rd;
|
||||
}
|
||||
|
||||
auto SPC700::op_jsp_dp() {
|
||||
rd = readPC();
|
||||
auto SPC700::instructionJSPDirectPage() -> void {
|
||||
rd = fetch();
|
||||
idle();
|
||||
idle();
|
||||
writeSP(regs.pc.h);
|
||||
writeSP(regs.pc.l);
|
||||
regs.pc = 0xff00 | rd;
|
||||
push(PC >> 8);
|
||||
push(PC >> 0);
|
||||
PC = 0xff00 | rd;
|
||||
}
|
||||
|
||||
auto SPC700::op_jsr_addr() {
|
||||
rd.l = readPC();
|
||||
rd.h = readPC();
|
||||
auto SPC700::instructionJSRAbsolute() -> void {
|
||||
rd.l = fetch();
|
||||
rd.h = fetch();
|
||||
idle();
|
||||
idle();
|
||||
idle();
|
||||
writeSP(regs.pc.h);
|
||||
writeSP(regs.pc.l);
|
||||
regs.pc = rd;
|
||||
push(PC >> 8);
|
||||
push(PC >> 0);
|
||||
PC = rd;
|
||||
}
|
||||
|
||||
auto SPC700::op_jst() {
|
||||
dp = 0xffde - ((opcode >> 4) << 1);
|
||||
auto SPC700::instructionJST(uint4 vector) -> void {
|
||||
dp = 0xffde - (vector << 1);
|
||||
rd.l = read(dp++);
|
||||
rd.h = read(dp++);
|
||||
idle();
|
||||
idle();
|
||||
idle();
|
||||
writeSP(regs.pc.h);
|
||||
writeSP(regs.pc.l);
|
||||
regs.pc = rd;
|
||||
push(PC >> 8);
|
||||
push(PC >> 0);
|
||||
PC = rd;
|
||||
}
|
||||
|
||||
auto SPC700::op_lda_ixinc() {
|
||||
auto SPC700::instructionLDAIndirectXIncrement() -> void {
|
||||
idle();
|
||||
regs.a = readDP(regs.x++);
|
||||
A = load(X++);
|
||||
idle();
|
||||
regs.p.n = regs.a & 0x80;
|
||||
regs.p.z = regs.a == 0;
|
||||
ZF = A == 0;
|
||||
NF = A & 0x80;
|
||||
}
|
||||
|
||||
auto SPC700::op_mul_ya() {
|
||||
auto SPC700::instructionMUL() -> void {
|
||||
idle();
|
||||
idle();
|
||||
idle();
|
||||
|
@ -448,94 +453,128 @@ auto SPC700::op_mul_ya() {
|
|||
idle();
|
||||
idle();
|
||||
idle();
|
||||
ya = regs.y * regs.a;
|
||||
regs.a = ya;
|
||||
regs.y = ya >> 8;
|
||||
uint16 ya = Y * A;
|
||||
A = ya >> 0;
|
||||
Y = ya >> 8;
|
||||
//result is set based on y (high-byte) only
|
||||
regs.p.n = (regs.y & 0x80);
|
||||
regs.p.z = (regs.y == 0);
|
||||
ZF = Y == 0;
|
||||
NF = Y & 0x80;
|
||||
}
|
||||
|
||||
auto SPC700::op_nop() {
|
||||
auto SPC700::instructionNOP() -> void {
|
||||
idle();
|
||||
}
|
||||
|
||||
auto SPC700::op_plp() {
|
||||
auto SPC700::instructionPLP() -> void {
|
||||
idle();
|
||||
idle();
|
||||
regs.p = readSP();
|
||||
P = pull();
|
||||
}
|
||||
|
||||
auto SPC700::op_rti() {
|
||||
regs.p = readSP();
|
||||
rd.l = readSP();
|
||||
rd.h = readSP();
|
||||
auto SPC700::instructionRTI() -> void {
|
||||
P = pull();
|
||||
rd.l = pull();
|
||||
rd.h = pull();
|
||||
idle();
|
||||
idle();
|
||||
regs.pc = rd;
|
||||
PC = rd;
|
||||
}
|
||||
|
||||
auto SPC700::op_rts() {
|
||||
rd.l = readSP();
|
||||
rd.h = readSP();
|
||||
auto SPC700::instructionRTS() -> void {
|
||||
rd.l = pull();
|
||||
rd.h = pull();
|
||||
idle();
|
||||
idle();
|
||||
regs.pc = rd;
|
||||
PC = rd;
|
||||
}
|
||||
|
||||
auto SPC700::op_sta_idpx() {
|
||||
sp = readPC() + regs.x;
|
||||
auto SPC700::instructionSET(uint3 bit) -> void {
|
||||
uint8 direct = fetch();
|
||||
uint8 data = load(direct);
|
||||
data.bit(bit) = 1;
|
||||
store(direct, data);
|
||||
}
|
||||
|
||||
auto SPC700::instructionSTAIndirectPageX() -> void {
|
||||
sp = fetch() + X;
|
||||
idle();
|
||||
dp.l = readDP(sp++);
|
||||
dp.h = readDP(sp++);
|
||||
dp.l = load(sp++);
|
||||
dp.h = load(sp++);
|
||||
read(dp);
|
||||
write(dp, regs.a);
|
||||
write(dp, A);
|
||||
}
|
||||
|
||||
auto SPC700::op_sta_idpy() {
|
||||
sp = readPC();
|
||||
dp.l = readDP(sp++);
|
||||
dp.h = readDP(sp++);
|
||||
auto SPC700::instructionSTAIndirectPageY() -> void {
|
||||
sp = fetch();
|
||||
dp.l = load(sp++);
|
||||
dp.h = load(sp++);
|
||||
idle();
|
||||
dp += regs.y;
|
||||
dp += Y;
|
||||
read(dp);
|
||||
write(dp, regs.a);
|
||||
write(dp, A);
|
||||
}
|
||||
|
||||
auto SPC700::op_sta_ix() {
|
||||
auto SPC700::instructionSTAIndirectX() -> void {
|
||||
idle();
|
||||
readDP(regs.x);
|
||||
writeDP(regs.x, regs.a);
|
||||
load(X);
|
||||
store(X, A);
|
||||
}
|
||||
|
||||
auto SPC700::op_sta_ixinc() {
|
||||
auto SPC700::instructionSTAIndirectXIncrement() -> void {
|
||||
idle();
|
||||
idle();
|
||||
writeDP(regs.x++, regs.a);
|
||||
store(X++, A);
|
||||
}
|
||||
|
||||
auto SPC700::op_stw_dp() {
|
||||
dp = readPC();
|
||||
readDP(dp);
|
||||
writeDP(dp++, regs.a);
|
||||
writeDP(dp++, regs.y);
|
||||
}
|
||||
|
||||
auto SPC700::op_wait() {
|
||||
auto SPC700::instructionSTP() -> void {
|
||||
while(true) {
|
||||
idle();
|
||||
idle();
|
||||
}
|
||||
}
|
||||
|
||||
auto SPC700::op_xcn() {
|
||||
idle();
|
||||
idle();
|
||||
idle();
|
||||
idle();
|
||||
regs.a = (regs.a >> 4) | (regs.a << 4);
|
||||
regs.p.n = regs.a & 0x80;
|
||||
regs.p.z = regs.a == 0;
|
||||
auto SPC700::instructionSTWDirectPage() -> void {
|
||||
dp = fetch();
|
||||
load(dp);
|
||||
store(dp++, A);
|
||||
store(dp++, Y);
|
||||
}
|
||||
|
||||
#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 {
|
||||
s.integer(regs.pc.w);
|
||||
s.integer(regs.a);
|
||||
s.integer(regs.x);
|
||||
s.integer(regs.y);
|
||||
s.integer(regs.s);
|
||||
s.integer(regs.p.data);
|
||||
s.integer(r.pc.w);
|
||||
s.integer(r.ya.w);
|
||||
s.integer(r.x);
|
||||
s.integer(r.s);
|
||||
s.integer(r.p.c);
|
||||
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(dp.w);
|
||||
|
@ -12,5 +18,4 @@ auto SPC700::serialize(serializer& s) -> void {
|
|||
s.integer(rd.w);
|
||||
s.integer(wr.w);
|
||||
s.integer(bit.w);
|
||||
s.integer(ya.w);
|
||||
}
|
||||
|
|
|
@ -3,276 +3,53 @@
|
|||
|
||||
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 "instructions.cpp"
|
||||
#include "disassembler.cpp"
|
||||
#include "instruction.cpp"
|
||||
#include "serialization.cpp"
|
||||
#include "disassembler.cpp"
|
||||
|
||||
#define op(id, name, ...) case id: return op_##name(__VA_ARGS__);
|
||||
#define fp(name) &SPC700::op_##name
|
||||
#undef PC
|
||||
#undef YA
|
||||
#undef A
|
||||
#undef X
|
||||
#undef Y
|
||||
#undef S
|
||||
#undef P
|
||||
|
||||
auto SPC700::instruction() -> void {
|
||||
switch(opcode = readPC()) {
|
||||
op(0x00, nop)
|
||||
op(0x01, jst)
|
||||
op(0x02, set_bit)
|
||||
op(0x03, branch_bit)
|
||||
op(0x04, read_dp, fp(or), regs.a)
|
||||
op(0x05, read_addr, fp(or), regs.a)
|
||||
op(0x06, read_ix, fp(or))
|
||||
op(0x07, read_idpx, fp(or))
|
||||
op(0x08, read_const, fp(or), regs.a)
|
||||
op(0x09, write_dp_dp, fp(or))
|
||||
op(0x0a, set_addr_bit)
|
||||
op(0x0b, adjust_dp, fp(asl))
|
||||
op(0x0c, adjust_addr, fp(asl))
|
||||
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 CF
|
||||
#undef ZF
|
||||
#undef IF
|
||||
#undef HF
|
||||
#undef BF
|
||||
#undef PF
|
||||
#undef VF
|
||||
#undef NF
|
||||
|
||||
auto SPC700::power() -> void {
|
||||
r.pc.w = 0x0000;
|
||||
r.ya.w = 0x0000;
|
||||
r.x = 0x00;
|
||||
r.s = 0xef;
|
||||
r.p = 0x02;
|
||||
}
|
||||
|
||||
#undef op
|
||||
#undef fp
|
||||
|
||||
}
|
||||
|
|
|
@ -8,103 +8,178 @@ struct SPC700 {
|
|||
virtual auto write(uint16 addr, uint8 data) -> void = 0;
|
||||
virtual auto readDisassembler(uint16 addr) -> uint8 = 0;
|
||||
|
||||
//spc700.cpp
|
||||
auto power() -> void;
|
||||
|
||||
//instruction.cpp
|
||||
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"
|
||||
#include "memory.hpp"
|
||||
|
||||
Registers regs;
|
||||
Register dp, sp, rd, wr, bit, ya;
|
||||
uint8 opcode;
|
||||
|
||||
protected:
|
||||
//instructions.cpp
|
||||
using fps = auto (SPC700::*)(uint8) -> uint8;
|
||||
using fpb = auto (SPC700::*)(uint8, uint8) -> uint8;
|
||||
using fpw = auto (SPC700::*)(uint16, uint16) -> uint16;
|
||||
using reg = uint8_t&;
|
||||
|
||||
auto op_adc(uint8, uint8) -> uint8;
|
||||
auto op_and(uint8, uint8) -> uint8;
|
||||
auto op_asl(uint8) -> uint8;
|
||||
auto op_cmp(uint8, uint8) -> uint8;
|
||||
auto op_dec(uint8) -> uint8;
|
||||
auto op_eor(uint8, uint8) -> uint8;
|
||||
auto op_inc(uint8) -> uint8;
|
||||
auto op_ld (uint8, uint8) -> uint8;
|
||||
auto op_lsr(uint8) -> uint8;
|
||||
auto op_or (uint8, uint8) -> uint8;
|
||||
auto op_rol(uint8) -> uint8;
|
||||
auto op_ror(uint8) -> uint8;
|
||||
auto op_sbc(uint8, uint8) -> uint8;
|
||||
auto op_st (uint8, uint8) -> uint8;
|
||||
auto op_adw(uint16, uint16) -> uint16;
|
||||
auto op_cpw(uint16, uint16) -> uint16;
|
||||
auto op_ldw(uint16, uint16) -> uint16;
|
||||
auto op_sbw(uint16, uint16) -> uint16;
|
||||
auto instructionImpliedModify(fps, uint8&) -> void;
|
||||
auto instructionAbsoluteModify(fps) -> void;
|
||||
auto instructionDirectPageModify(fps) -> void;
|
||||
auto instructionDirectPageModifyWord(int) -> void;
|
||||
auto instructionDirectPageXModify(fps) -> void;
|
||||
auto instructionBranch(bool) -> void;
|
||||
auto instructionPull(uint8&) -> void;
|
||||
auto instructionPush(uint8) -> void;
|
||||
auto instructionAbsoluteRead(fpb, uint8&) -> void;
|
||||
auto instructionAbsoluteIndexedRead(fpb, uint8&) -> void;
|
||||
auto instructionImmediateRead(fpb, uint8&) -> void;
|
||||
auto instructionDirectPageRead(fpb, uint8&) -> void;
|
||||
auto instructionDirectPageIndexedRead(fpb, uint8&, uint8&) -> void;
|
||||
auto instructionDirectPageReadWord(fpw) -> void;
|
||||
auto instructionIndirectPageXRead(fpb) -> void;
|
||||
auto instructionIndirectPageYRead(fpb) -> void;
|
||||
auto instructionIndirectXRead(fpb) -> void;
|
||||
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 op_adjust_addr(fps);
|
||||
auto op_adjust_dp(fps);
|
||||
auto op_adjust_dpw(int);
|
||||
auto op_adjust_dpx(fps);
|
||||
auto op_branch(bool);
|
||||
auto op_branch_bit();
|
||||
auto op_pull(reg);
|
||||
auto op_push(uint8);
|
||||
auto op_read_addr(fpb, reg);
|
||||
auto op_read_addri(fpb, reg);
|
||||
auto op_read_const(fpb, reg);
|
||||
auto op_read_dp(fpb, reg);
|
||||
auto op_read_dpi(fpb, reg, reg);
|
||||
auto op_read_dpw(fpw);
|
||||
auto op_read_idpx(fpb);
|
||||
auto op_read_idpy(fpb);
|
||||
auto op_read_ix(fpb);
|
||||
auto op_set_addr_bit();
|
||||
auto op_set_bit();
|
||||
auto op_set_flag(uint, bool);
|
||||
auto op_test_addr(bool);
|
||||
auto op_transfer(reg, reg);
|
||||
auto op_write_addr(reg);
|
||||
auto op_write_addri(reg);
|
||||
auto op_write_dp(reg);
|
||||
auto op_write_dpi(reg, reg);
|
||||
auto op_write_dp_const(fpb);
|
||||
auto op_write_dp_dp(fpb);
|
||||
auto op_write_ix_iy(fpb);
|
||||
auto instructionBBC(uint3) -> void;
|
||||
auto instructionBBS(uint3) -> void;
|
||||
auto instructionBNEDirectPage() -> void;
|
||||
auto instructionBNEDirectPageDecrement() -> void;
|
||||
auto instructionBNEDirectPageX() -> void;
|
||||
auto instructionBNEYDecrement() -> void;
|
||||
auto instructionBRK() -> void;
|
||||
auto instructionCLR(uint3) -> void;
|
||||
auto instructionCLV() -> void;
|
||||
auto instructionCMC() -> void;
|
||||
auto instructionDAA() -> void;
|
||||
auto instructionDAS() -> void;
|
||||
auto instructionDIV() -> void;
|
||||
auto instructionJMPAbsolute() -> void;
|
||||
auto instructionJMPIndirectAbsoluteX() -> void;
|
||||
auto instructionJSPDirectPage() -> void;
|
||||
auto instructionJSRAbsolute() -> void;
|
||||
auto instructionJST(uint4) -> void;
|
||||
auto instructionLDAIndirectXIncrement() -> void;
|
||||
auto instructionMUL() -> void;
|
||||
auto instructionNOP() -> void;
|
||||
auto instructionPLP() -> void;
|
||||
auto instructionRTI() -> void;
|
||||
auto instructionRTS() -> void;
|
||||
auto instructionSET(uint3) -> void;
|
||||
auto instructionSTAIndirectPageX() -> void;
|
||||
auto instructionSTAIndirectPageY() -> void;
|
||||
auto instructionSTAIndirectX() -> void;
|
||||
auto instructionSTAIndirectXIncrement() -> void;
|
||||
auto instructionSTP() -> void;
|
||||
auto instructionSTWDirectPage() -> void;
|
||||
auto instructionTRBAbsolute() -> void;
|
||||
auto instructionTSBAbsolute() -> void;
|
||||
auto instructionWAI() -> void;
|
||||
auto instructionXCN() -> void;
|
||||
|
||||
auto op_bne_dp();
|
||||
auto op_bne_dpdec();
|
||||
auto op_bne_dpx();
|
||||
auto op_bne_ydec();
|
||||
auto op_brk();
|
||||
auto op_clv();
|
||||
auto op_cmc();
|
||||
auto op_daa();
|
||||
auto op_das();
|
||||
auto op_div_ya_x();
|
||||
auto op_jmp_addr();
|
||||
auto op_jmp_iaddrx();
|
||||
auto op_jsp_dp();
|
||||
auto op_jsr_addr();
|
||||
auto op_jst();
|
||||
auto op_lda_ixinc();
|
||||
auto op_mul_ya();
|
||||
auto op_nop();
|
||||
auto op_plp();
|
||||
auto op_rti();
|
||||
auto op_rts();
|
||||
auto op_sta_idpx();
|
||||
auto op_sta_idpy();
|
||||
auto op_sta_ix();
|
||||
auto op_sta_ixinc();
|
||||
auto op_stw_dp();
|
||||
auto op_wait();
|
||||
auto op_xcn();
|
||||
//serialization.cpp
|
||||
auto serialize(serializer&) -> void;
|
||||
|
||||
//disassembler.cpp
|
||||
auto disassemble(uint16 addr, bool p) -> string;
|
||||
|
||||
struct Flags {
|
||||
bool c; //carry
|
||||
bool z; //zero
|
||||
bool i; //interrupt disable
|
||||
bool h; //half-carry
|
||||
bool b; //break
|
||||
bool p; //page
|
||||
bool v; //overflow
|
||||
bool n; //negative
|
||||
|
||||
inline operator uint() const {
|
||||
return c << 0 | z << 1 | i << 2 | h << 3 | b << 4 | p << 5 | v << 6 | n << 7;
|
||||
}
|
||||
|
||||
inline auto& operator=(uint8 data) {
|
||||
c = data.bit(0);
|
||||
z = data.bit(1);
|
||||
i = data.bit(2);
|
||||
h = data.bit(3);
|
||||
b = data.bit(4);
|
||||
p = data.bit(5);
|
||||
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;
|
||||
if(D && result > 0x9fff) result += 0x6000;
|
||||
if(DF && result > 0x9fff) result += 0x6000;
|
||||
CF = result > 0xffff;
|
||||
ZF = (uint16)result == 0;
|
||||
NF = result & 0x8000;
|
||||
|
@ -48,7 +48,7 @@ auto WDC65816::algorithmADC16(uint16 data) -> uint16 {
|
|||
|
||||
auto WDC65816::algorithmAND8(uint8 data) -> uint8 {
|
||||
lo(A) &= data;
|
||||
ZF = A == 0;
|
||||
ZF = lo(A) == 0;
|
||||
NF = A & 0x80;
|
||||
return data;
|
||||
}
|
||||
|
@ -148,13 +148,13 @@ auto WDC65816::algorithmDEC8(uint8 data) -> uint8 {
|
|||
auto WDC65816::algorithmDEC16(uint16 data) -> uint16 {
|
||||
data--;
|
||||
ZF = data == 0;
|
||||
NF = data & 0x80;
|
||||
NF = data & 0x8000;
|
||||
return data;
|
||||
}
|
||||
|
||||
auto WDC65816::algorithmEOR8(uint8 data) -> uint8 {
|
||||
lo(A) ^= data;
|
||||
ZF = A == 0;
|
||||
ZF = lo(A) == 0;
|
||||
NF = A & 0x80;
|
||||
return lo(A);
|
||||
}
|
||||
|
|
|
@ -171,7 +171,7 @@ L push(lo(data));
|
|||
auto WDC65816::instructionPHD() -> void {
|
||||
idle();
|
||||
pushN(hi(D));
|
||||
L pushN(hi(D));
|
||||
L pushN(lo(D));
|
||||
E hi(S) = 0x01;
|
||||
}
|
||||
|
||||
|
|
|
@ -112,7 +112,7 @@ auto WDC65816::instructionRTS() -> void {
|
|||
uint16 data = pull();
|
||||
hi(data) = pull();
|
||||
L idle();
|
||||
PC = data;
|
||||
aa(PC) = data;
|
||||
aa(PC)++;
|
||||
}
|
||||
|
||||
|
|
|
@ -50,11 +50,6 @@ auto CPU::main() -> void {
|
|||
}
|
||||
}
|
||||
|
||||
#if 1
|
||||
static uint counter = 0;
|
||||
if(++counter < 40) print(disassemble(), "\n");
|
||||
#endif
|
||||
|
||||
instruction();
|
||||
}
|
||||
|
||||
|
|
|
@ -74,7 +74,7 @@ auto SMP::readBus(uint16 addr) -> uint8 {
|
|||
auto SMP::writeBus(uint16 addr, uint8 data) -> void {
|
||||
switch(addr) {
|
||||
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.timerSpeed = (data >> 4) & 3;
|
||||
|
|
|
@ -27,15 +27,11 @@ auto SMP::load(Markup::Node node) -> bool {
|
|||
}
|
||||
|
||||
auto SMP::power() -> void {
|
||||
SPC700::power();
|
||||
create(Enter, 32040.0 * 768.0);
|
||||
|
||||
regs.pc.l = iplrom[62];
|
||||
regs.pc.h = iplrom[63];
|
||||
regs.a = 0x00;
|
||||
regs.x = 0x00;
|
||||
regs.y = 0x00;
|
||||
regs.s = 0xef;
|
||||
regs.p = 0x02;
|
||||
r.pc.byte.l = iplrom[62];
|
||||
r.pc.byte.h = iplrom[63];
|
||||
|
||||
for(auto& byte : apuram) byte = random(0x00);
|
||||
apuram[0x00f4] = 0x00;
|
||||
|
|
Loading…
Reference in New Issue