Update to v102r25 release.

byuu says:

Changelog:

  - processor/arm: corrected MUL instruction timings [Jonas Quinn]
  - processor/wdc65816: finished phase two of the rewrite

I'm really pleased with the visual results of the wdc65816 core rewrite.
I was able to eliminate all of the weird `{Boolean,Natural}BitRange`
templates, as well as the need to use unions/structs. Registers are now
just simple `uint24` or `uint16` types (technically they're `Natural<T>`
types, but then all of higan uses those), flags are now just bool types.
I also eliminated all of the implicit object state inside of the core
(aa, rd, dp, sp) and instead do all computations on the stack frame with
local variables. Through using macros to reference the registers and
individual parts of them, I was able to reduce the visual tensity of all
of the instructions. And by using normal types without implicit states,
I was able to eliminate about 15% of the instructions necessary, instead
reusing existing ones.

The final third phase of the rewrite will be to recode the disassembler.
That code is probably the oldest code in all of higan right now, still
using sprintf to generate the output. So it is very long overdue for a
cleanup.

And now for the bad news ... as with any large code cleanup, regression
errors have seeped in. Currently, no games are running at all. I've left
the old disassembler in for this reason: we can compare trace logs of
v102r23 against trace logs of v102r25. The second there's any
difference, we've spotted a buggy instruction and can correct it.

With any luck, this will be the last time I ever rewrite the wdc65816
core. My style has changed wildly over the ~10 years since I wrote this
core, but it's really solidifed in recent years.
This commit is contained in:
Tim Allen 2017-06-15 01:55:55 +10:00
parent 6e8406291c
commit b73d918776
18 changed files with 1211 additions and 1302 deletions

View File

@ -12,13 +12,13 @@ using namespace nall;
namespace Emulator {
static const string Name = "higan";
static const string Version = "102.24";
static const string Version = "102.25";
static const string Author = "byuu";
static const string License = "GPLv3";
static const string Website = "http://byuu.org/";
//incremented only when serialization format changes
static const string SerializerVersion = "102.23";
static const string SerializerVersion = "102.25";
namespace Constants {
namespace Colorburst {

View File

@ -78,6 +78,8 @@ auto ARM::arm_op_multiply() {
uint4 s = instruction() >> 8;
uint4 m = instruction();
if(accumulate) idle();
r(d) = mul(accumulate ? r(n) : 0u, r(m), r(s));
}
@ -103,9 +105,23 @@ auto ARM::arm_op_multiply_long() {
uint64 rm = r(m);
uint64 rs = r(s);
idle();
idle();
//this instruction uses an 8-bit Booth algorithm for multiplication
//this supports short-circuiting, so that smaller numbers multiply faster
//for now, simulate the timing of this operation
if(signextend) {
if(rs >> 8 && (rs >> 8) != 0xffffff) idle();
if(rs >> 16 && (rs >> 16) != 0xffff) idle();
if(rs >> 24 && (rs >> 24) != 0xff) idle();
rm = (int32)rm;
rs = (int32)rs;
} else {
if(rs >> 8) idle();
if(rs >> 16) idle();
if(rs >> 24) idle();
}
uint64 rd = rm * rs;

View File

@ -1,327 +1,363 @@
auto WDC65816::algorithmADC8() -> void {
auto WDC65816::algorithmADC8(uint8 data) -> uint8 {
int result;
if(!r.p.d) {
result = r.a.l + rd.l + r.p.c;
if(!DF) {
result = lo(A) + data + CF;
} else {
result = (r.a.l & 0x0f) + (rd.l & 0x0f) + (r.p.c << 0);
result = (lo(A) & 0x0f) + (data & 0x0f) + (CF << 0);
if(result > 0x09) result += 0x06;
r.p.c = result > 0x0f;
result = (r.a.l & 0xf0) + (rd.l & 0xf0) + (r.p.c << 4) + (result & 0x0f);
CF = result > 0x0f;
result = (lo(A) & 0xf0) + (data & 0xf0) + (CF << 4) + (result & 0x0f);
}
r.p.v = ~(r.a.l ^ rd.l) & (r.a.l ^ result) & 0x80;
if(r.p.d && result > 0x9f) result += 0x60;
r.p.c = result > 0xff;
r.p.n = result & 0x80;
r.p.z = (uint8)result == 0;
VF = ~(lo(A) ^ data) & (lo(A) ^ result) & 0x80;
if(DF && result > 0x9f) result += 0x60;
CF = result > 0xff;
ZF = (uint8)result == 0;
NF = result & 0x80;
r.a.l = result;
return lo(A) = result;
}
auto WDC65816::algorithmADC16() -> void {
auto WDC65816::algorithmADC16(uint16 data) -> uint16 {
int result;
if(!r.p.d) {
result = r.a.w + rd.w + r.p.c;
if(!DF) {
result = A + data + CF;
} else {
result = (r.a.w & 0x000f) + (rd.w & 0x000f) + (r.p.c << 0);
result = (A & 0x000f) + (data & 0x000f) + (CF << 0);
if(result > 0x0009) result += 0x0006;
r.p.c = result > 0x000f;
result = (r.a.w & 0x00f0) + (rd.w & 0x00f0) + (r.p.c << 4) + (result & 0x000f);
CF = result > 0x000f;
result = (A & 0x00f0) + (data & 0x00f0) + (CF << 4) + (result & 0x000f);
if(result > 0x009f) result += 0x0060;
r.p.c = result > 0x00ff;
result = (r.a.w & 0x0f00) + (rd.w & 0x0f00) + (r.p.c << 8) + (result & 0x00ff);
CF = result > 0x00ff;
result = (A & 0x0f00) + (data & 0x0f00) + (CF << 8) + (result & 0x00ff);
if(result > 0x09ff) result += 0x0600;
r.p.c = result > 0x0fff;
result = (r.a.w & 0xf000) + (rd.w & 0xf000) + (r.p.c << 12) + (result & 0x0fff);
CF = result > 0x0fff;
result = (A & 0xf000) + (data & 0xf000) + (CF << 12) + (result & 0x0fff);
}
r.p.v = ~(r.a.w ^ rd.w) & (r.a.w ^ result) & 0x8000;
if(r.p.d && result > 0x9fff) result += 0x6000;
r.p.c = result > 0xffff;
r.p.n = result & 0x8000;
r.p.z = (uint16)result == 0;
VF = ~(A ^ data) & (A ^ result) & 0x8000;
if(D && result > 0x9fff) result += 0x6000;
CF = result > 0xffff;
ZF = (uint16)result == 0;
NF = result & 0x8000;
r.a.w = result;
return A = result;
}
auto WDC65816::algorithmAND8() -> void {
r.a.l &= rd.l;
r.p.n = r.a.l & 0x80;
r.p.z = r.a.l == 0;
auto WDC65816::algorithmAND8(uint8 data) -> uint8 {
lo(A) &= data;
ZF = A == 0;
NF = A & 0x80;
return data;
}
auto WDC65816::algorithmAND16() -> void {
r.a.w &= rd.w;
r.p.n = r.a.w & 0x8000;
r.p.z = r.a.w == 0;
auto WDC65816::algorithmAND16(uint16 data) -> uint16 {
A &= data;
ZF = A == 0;
NF = A & 0x8000;
return data;
}
auto WDC65816::algorithmASL8() -> void {
r.p.c = rd.l & 0x80;
rd.l <<= 1;
r.p.n = rd.l & 0x80;
r.p.z = rd.l == 0;
auto WDC65816::algorithmASL8(uint8 data) -> uint8 {
CF = data & 0x80;
data <<= 1;
ZF = data == 0;
NF = data & 0x80;
return data;
}
auto WDC65816::algorithmASL16() -> void {
r.p.c = rd.w & 0x8000;
rd.w <<= 1;
r.p.n = rd.w & 0x8000;
r.p.z = rd.w == 0;
auto WDC65816::algorithmASL16(uint16 data) -> uint16 {
CF = data & 0x8000;
data <<= 1;
ZF = data == 0;
NF = data & 0x8000;
return data;
}
auto WDC65816::algorithmBIT8() -> void {
r.p.n = rd.l & 0x80;
r.p.v = rd.l & 0x40;
r.p.z = (rd.l & r.a.l) == 0;
auto WDC65816::algorithmBIT8(uint8 data) -> uint8 {
ZF = (data & lo(A)) == 0;
VF = data & 0x40;
NF = data & 0x80;
return data;
}
auto WDC65816::algorithmBIT16() -> void {
r.p.n = rd.w & 0x8000;
r.p.v = rd.w & 0x4000;
r.p.z = (rd.w & r.a.w) == 0;
auto WDC65816::algorithmBIT16(uint16 data) -> uint16 {
ZF = (data & A) == 0;
VF = data & 0x4000;
NF = data & 0x8000;
return data;
}
auto WDC65816::algorithmCMP8() -> void {
int result = r.a.l - rd.l;
r.p.n = result & 0x80;
r.p.z = (uint8)result == 0;
r.p.c = result >= 0;
auto WDC65816::algorithmCMP8(uint8 data) -> uint8 {
int result = lo(A) - data;
CF = result >= 0;
ZF = (uint8)result == 0;
NF = result & 0x80;
return result;
}
auto WDC65816::algorithmCMP16() -> void {
int result = r.a.w - rd.w;
r.p.n = result & 0x8000;
r.p.z = (uint16)result == 0;
r.p.c = result >= 0;
auto WDC65816::algorithmCMP16(uint16 data) -> uint16 {
int result = A - data;
CF = result >= 0;
ZF = (uint16)result == 0;
NF = result & 0x8000;
return result;
}
auto WDC65816::algorithmCPX8() -> void {
int result = r.x.l - rd.l;
r.p.n = result & 0x80;
r.p.z = (uint8)result == 0;
r.p.c = result >= 0;
auto WDC65816::algorithmCPX8(uint8 data) -> uint8 {
int result = lo(X) - data;
CF = result >= 0;
ZF = (uint8)result == 0;
NF = result & 0x80;
return result;
}
auto WDC65816::algorithmCPX16() -> void {
int result = r.x.w - rd.w;
r.p.n = result & 0x8000;
r.p.z = (uint16)result == 0;
r.p.c = result >= 0;
auto WDC65816::algorithmCPX16(uint16 data) -> uint16 {
int result = X - data;
CF = result >= 0;
ZF = (uint16)result == 0;
NF = result & 0x8000;
return result;
}
auto WDC65816::algorithmCPY8() -> void {
int result = r.y.l - rd.l;
r.p.n = result & 0x80;
r.p.z = (uint8)result == 0;
r.p.c = result >= 0;
auto WDC65816::algorithmCPY8(uint8 data) -> uint8 {
int result = lo(Y) - data;
CF = result >= 0;
ZF = (uint8)result == 0;
NF = result & 0x80;
return result;
}
auto WDC65816::algorithmCPY16() -> void {
int result = r.y.w - rd.w;
r.p.n = result & 0x8000;
r.p.z = (uint16)result == 0;
r.p.c = result >= 0;
auto WDC65816::algorithmCPY16(uint16 data) -> uint16 {
int result = Y - data;
CF = result >= 0;
ZF = (uint16)result == 0;
NF = result & 0x8000;
return result;
}
auto WDC65816::algorithmDEC8() -> void {
rd.l--;
r.p.n = rd.l & 0x80;
r.p.z = rd.l == 0;
auto WDC65816::algorithmDEC8(uint8 data) -> uint8 {
data--;
ZF = data == 0;
NF = data & 0x80;
return data;
}
auto WDC65816::algorithmDEC16() -> void {
rd.w--;
r.p.n = rd.w & 0x8000;
r.p.z = rd.w == 0;
auto WDC65816::algorithmDEC16(uint16 data) -> uint16 {
data--;
ZF = data == 0;
NF = data & 0x80;
return data;
}
auto WDC65816::algorithmEOR8() -> void {
r.a.l ^= rd.l;
r.p.n = r.a.l & 0x80;
r.p.z = r.a.l == 0;
auto WDC65816::algorithmEOR8(uint8 data) -> uint8 {
lo(A) ^= data;
ZF = A == 0;
NF = A & 0x80;
return lo(A);
}
auto WDC65816::algorithmEOR16() -> void {
r.a.w ^= rd.w;
r.p.n = r.a.w & 0x8000;
r.p.z = r.a.w == 0;
auto WDC65816::algorithmEOR16(uint16 data) -> uint16 {
A ^= data;
ZF = A == 0;
NF = A & 0x8000;
return data;
}
auto WDC65816::algorithmINC8() -> void {
rd.l++;
r.p.n = rd.l & 0x80;
r.p.z = rd.l == 0;
auto WDC65816::algorithmINC8(uint8 data) -> uint8 {
data++;
ZF = data == 0;
NF = data & 0x80;
return data;
}
auto WDC65816::algorithmINC16() -> void {
rd.w++;
r.p.n = rd.w & 0x8000;
r.p.z = rd.w == 0;
auto WDC65816::algorithmINC16(uint16 data) -> uint16 {
data++;
ZF = data == 0;
NF = data & 0x8000;
return data;
}
auto WDC65816::algorithmLDA8() -> void {
r.a.l = rd.l;
r.p.n = r.a.l & 0x80;
r.p.z = r.a.l == 0;
auto WDC65816::algorithmLDA8(uint8 data) -> uint8 {
lo(A) = data;
ZF = lo(A) == 0;
NF = A & 0x80;
return data;
}
auto WDC65816::algorithmLDA16() -> void {
r.a.w = rd.w;
r.p.n = r.a.w & 0x8000;
r.p.z = r.a.w == 0;
auto WDC65816::algorithmLDA16(uint16 data) -> uint16 {
A = data;
ZF = A == 0;
NF = A & 0x8000;
return data;
}
auto WDC65816::algorithmLDX8() -> void {
r.x.l = rd.l;
r.p.n = r.x.l & 0x80;
r.p.z = r.x.l == 0;
auto WDC65816::algorithmLDX8(uint8 data) -> uint8 {
lo(X) = data;
ZF = lo(X) == 0;
NF = X & 0x80;
return data;
}
auto WDC65816::algorithmLDX16() -> void {
r.x.w = rd.w;
r.p.n = r.x.w & 0x8000;
r.p.z = r.x.w == 0;
auto WDC65816::algorithmLDX16(uint16 data) -> uint16 {
X = data;
ZF = X == 0;
NF = X & 0x8000;
return data;
}
auto WDC65816::algorithmLDY8() -> void {
r.y.l = rd.l;
r.p.n = r.y.l & 0x80;
r.p.z = r.y.l == 0;
auto WDC65816::algorithmLDY8(uint8 data) -> uint8 {
lo(Y) = data;
ZF = lo(Y) == 0;
NF = Y & 0x80;
return data;
}
auto WDC65816::algorithmLDY16() -> void {
r.y.w = rd.w;
r.p.n = r.y.w & 0x8000;
r.p.z = r.y.w == 0;
auto WDC65816::algorithmLDY16(uint16 data) -> uint16 {
Y = data;
ZF = Y == 0;
NF = Y & 0x8000;
return data;
}
auto WDC65816::algorithmLSR8() -> void {
r.p.c = rd.l & 1;
rd.l >>= 1;
r.p.n = rd.l & 0x80;
r.p.z = rd.l == 0;
auto WDC65816::algorithmLSR8(uint8 data) -> uint8 {
CF = data & 1;
data >>= 1;
ZF = data == 0;
NF = data & 0x80;
return data;
}
auto WDC65816::algorithmLSR16() -> void {
r.p.c = rd.w & 1;
rd.w >>= 1;
r.p.n = rd.w & 0x8000;
r.p.z = rd.w == 0;
auto WDC65816::algorithmLSR16(uint16 data) -> uint16 {
CF = data & 1;
data >>= 1;
ZF = data == 0;
NF = data & 0x8000;
return data;
}
auto WDC65816::algorithmORA8() -> void {
r.a.l |= rd.l;
r.p.n = r.a.l & 0x80;
r.p.z = r.a.l == 0;
auto WDC65816::algorithmORA8(uint8 data) -> uint8 {
lo(A) |= data;
ZF = lo(A) == 0;
NF = A & 0x80;
return lo(A);
}
auto WDC65816::algorithmORA16() -> void {
r.a.w |= rd.w;
r.p.n = r.a.w & 0x8000;
r.p.z = r.a.w == 0;
auto WDC65816::algorithmORA16(uint16 data) -> uint16 {
A |= data;
ZF = A == 0;
NF = A & 0x8000;
return A;
}
auto WDC65816::algorithmROL8() -> void {
auto carry = (uint)r.p.c;
r.p.c = rd.l & 0x80;
rd.l = (rd.l << 1) | carry;
r.p.n = rd.l & 0x80;
r.p.z = rd.l == 0;
auto WDC65816::algorithmROL8(uint8 data) -> uint8 {
bool carry = CF;
CF = data & 0x80;
data = data << 1 | carry;
ZF = data == 0;
NF = data & 0x80;
return data;
}
auto WDC65816::algorithmROL16() -> void {
auto carry = (uint)r.p.c;
r.p.c = rd.w & 0x8000;
rd.w = (rd.w << 1) | carry;
r.p.n = rd.w & 0x8000;
r.p.z = rd.w == 0;
auto WDC65816::algorithmROL16(uint16 data) -> uint16 {
bool carry = CF;
CF = data & 0x8000;
data = data << 1 | carry;
ZF = data == 0;
NF = data & 0x8000;
return data;
}
auto WDC65816::algorithmROR8() -> void {
auto carry = (uint)r.p.c << 7;
r.p.c = rd.l & 1;
rd.l = carry | (rd.l >> 1);
r.p.n = rd.l & 0x80;
r.p.z = rd.l == 0;
auto WDC65816::algorithmROR8(uint8 data) -> uint8 {
bool carry = CF;
CF = data & 1;
data = carry << 7 | data >> 1;
ZF = data == 0;
NF = data & 0x80;
return data;
}
auto WDC65816::algorithmROR16() -> void {
auto carry = (uint)r.p.c << 15;
r.p.c = rd.w & 1;
rd.w = carry | (rd.w >> 1);
r.p.n = rd.w & 0x8000;
r.p.z = rd.w == 0;
auto WDC65816::algorithmROR16(uint16 data) -> uint16 {
bool carry = CF;
CF = data & 1;
data = carry << 15 | data >> 1;
ZF = data == 0;
NF = data & 0x8000;
return data;
}
auto WDC65816::algorithmSBC8() -> void {
auto WDC65816::algorithmSBC8(uint8 data) -> uint8 {
int result;
rd.l ^= 0xff;
data = ~data;
if(!r.p.d) {
result = r.a.l + rd.l + r.p.c;
if(!DF) {
result = lo(A) + data + CF;
} else {
result = (r.a.l & 0x0f) + (rd.l & 0x0f) + (r.p.c << 0);
result = (lo(A) & 0x0f) + (data & 0x0f) + (CF << 0);
if(result <= 0x0f) result -= 0x06;
r.p.c = result > 0x0f;
result = (r.a.l & 0xf0) + (rd.l & 0xf0) + (r.p.c << 4) + (result & 0x0f);
CF = result > 0x0f;
result = (lo(A) & 0xf0) + (data & 0xf0) + (CF << 4) + (result & 0x0f);
}
r.p.v = ~(r.a.l ^ rd.l) & (r.a.l ^ result) & 0x80;
if(r.p.d && result <= 0xff) result -= 0x60;
r.p.c = result > 0xff;
r.p.n = result & 0x80;
r.p.z = (uint8_t)result == 0;
VF = ~(lo(A) ^ data) & (lo(A) ^ result) & 0x80;
if(DF && result <= 0xff) result -= 0x60;
CF = result > 0xff;
ZF = (uint8)result == 0;
NF = result & 0x80;
r.a.l = result;
return lo(A) = result;
}
auto WDC65816::algorithmSBC16() -> void {
auto WDC65816::algorithmSBC16(uint16 data) -> uint16 {
int result;
rd.w ^= 0xffff;
data = ~data;
if(!r.p.d) {
result = r.a.w + rd.w + r.p.c;
if(!DF) {
result = A + data + CF;
} else {
result = (r.a.w & 0x000f) + (rd.w & 0x000f) + (r.p.c << 0);
result = (A & 0x000f) + (data & 0x000f) + (CF << 0);
if(result <= 0x000f) result -= 0x0006;
r.p.c = result > 0x000f;
result = (r.a.w & 0x00f0) + (rd.w & 0x00f0) + (r.p.c << 4) + (result & 0x000f);
CF = result > 0x000f;
result = (A & 0x00f0) + (data & 0x00f0) + (CF << 4) + (result & 0x000f);
if(result <= 0x00ff) result -= 0x0060;
r.p.c = result > 0x00ff;
result = (r.a.w & 0x0f00) + (rd.w & 0x0f00) + (r.p.c << 8) + (result & 0x00ff);
CF = result > 0x00ff;
result = (A & 0x0f00) + (data & 0x0f00) + (CF << 8) + (result & 0x00ff);
if(result <= 0x0fff) result -= 0x0600;
r.p.c = result > 0x0fff;
result = (r.a.w & 0xf000) + (rd.w & 0xf000) + (r.p.c << 12) + (result & 0x0fff);
CF = result > 0x0fff;
result = (A & 0xf000) + (data & 0xf000) + (CF << 12) + (result & 0x0fff);
}
r.p.v = ~(r.a.w ^ rd.w) & (r.a.w ^ result) & 0x8000;
if(r.p.d && result <= 0xffff) result -= 0x6000;
r.p.c = result > 0xffff;
r.p.n = result & 0x8000;
r.p.z = (uint16_t)result == 0;
VF = ~(A ^ data) & (A ^ result) & 0x8000;
if(DF && result <= 0xffff) result -= 0x6000;
CF = result > 0xffff;
ZF = (uint16)result == 0;
NF = result & 0x8000;
r.a.w = result;
return A = result;
}
auto WDC65816::algorithmTRB8() -> void {
r.p.z = (rd.l & r.a.l) == 0;
rd.l &= ~r.a.l;
auto WDC65816::algorithmTRB8(uint8 data) -> uint8 {
ZF = (data & lo(A)) == 0;
data &= ~lo(A);
return data;
}
auto WDC65816::algorithmTRB16() -> void {
r.p.z = (rd.w & r.a.w) == 0;
rd.w &= ~r.a.w;
auto WDC65816::algorithmTRB16(uint16 data) -> uint16 {
ZF = (data & A) == 0;
data &= ~A;
return data;
}
auto WDC65816::algorithmTSB8() -> void {
r.p.z = (rd.l & r.a.l) == 0;
rd.l |= r.a.l;
auto WDC65816::algorithmTSB8(uint8 data) -> uint8 {
ZF = (data & lo(A)) == 0;
data |= lo(A);
return data;
}
auto WDC65816::algorithmTSB16() -> void {
r.p.z = (rd.w & r.a.w) == 0;
rd.w |= r.a.w;
auto WDC65816::algorithmTSB16(uint16 data) -> uint16 {
ZF = (data & A) == 0;
data |= A;
return data;
}

View File

@ -61,15 +61,15 @@ auto WDC65816::decode(uint8 mode, uint24 addr) -> uint24 {
break;
case OPTYPE_IDP:
addr = (r.d + (addr & 0xffff)) & 0xffff;
a = (r.db << 16) + dreadw(addr);
a = (r.b << 16) + dreadw(addr);
break;
case OPTYPE_IDPX:
addr = (r.d + r.x + (addr & 0xffff)) & 0xffff;
a = (r.db << 16) + dreadw(addr);
a = (r.b << 16) + dreadw(addr);
break;
case OPTYPE_IDPY:
addr = (r.d + (addr & 0xffff)) & 0xffff;
a = (r.db << 16) + dreadw(addr) + r.y;
a = (r.b << 16) + dreadw(addr) + r.y;
break;
case OPTYPE_ILDP:
addr = (r.d + (addr & 0xffff)) & 0xffff;
@ -80,22 +80,22 @@ auto WDC65816::decode(uint8 mode, uint24 addr) -> uint24 {
a = dreadl(addr) + r.y;
break;
case OPTYPE_ADDR:
a = (r.db << 16) + (addr & 0xffff);
a = (r.b << 16) + (addr & 0xffff);
break;
case OPTYPE_ADDR_PC:
a = (r.pc.b << 16) + (addr & 0xffff);
a = (r.pc & 0xff0000) + (addr & 0xffff);
break;
case OPTYPE_ADDRX:
a = (r.db << 16) + (addr & 0xffff) + r.x;
a = (r.b << 16) + (addr & 0xffff) + r.x;
break;
case OPTYPE_ADDRY:
a = (r.db << 16) + (addr & 0xffff) + r.y;
a = (r.b << 16) + (addr & 0xffff) + r.y;
break;
case OPTYPE_IADDR_PC:
a = (r.pc.b << 16) + (addr & 0xffff);
a = (r.pc & 0xff0000) + (addr & 0xffff);
break;
case OPTYPE_IADDRX:
a = (r.pc.b << 16) + ((addr + r.x) & 0xffff);
a = (r.pc & 0xff0000) + ((addr + r.x) & 0xffff);
break;
case OPTYPE_ILADDR:
a = addr;
@ -111,14 +111,14 @@ auto WDC65816::decode(uint8 mode, uint24 addr) -> uint24 {
break;
case OPTYPE_ISRY:
addr = (r.s + (addr & 0xff)) & 0xffff;
a = (r.db << 16) + dreadw(addr) + r.y;
a = (r.b << 16) + dreadw(addr) + r.y;
break;
case OPTYPE_RELB:
a = (r.pc.b << 16) + ((r.pc.w + 2) & 0xffff);
a = (r.pc & 0xff0000) + (((r.pc & 0xffff) + 2) & 0xffff);
a += int8(addr);
break;
case OPTYPE_RELW:
a = (r.pc.b << 16) + ((r.pc.w + 3) & 0xffff);
a = (r.pc & 0xff0000) + (((r.pc & 0xffff) + 3) & 0xffff);
a += (int16)addr;
break;
}
@ -127,20 +127,19 @@ auto WDC65816::decode(uint8 mode, uint24 addr) -> uint24 {
}
auto WDC65816::disassemble() -> string {
return disassemble(r.pc.d, r.e, r.p.m, r.p.x);
return disassemble(r.pc, r.e, r.p.m, r.p.x);
}
auto WDC65816::disassemble(uint24 addr, bool e, bool m, bool x) -> string {
string s;
Long pc;
pc.d = addr;
s = {hex(pc.d, 6), " "};
uint24 pc = addr;
s = {hex(pc, 6), " "};
uint8 op = dreadb(pc.d); pc.w++;
uint8 op0 = dreadb(pc.d); pc.w++;
uint8 op1 = dreadb(pc.d); pc.w++;
uint8 op2 = dreadb(pc.d);
uint8 op = dreadb(pc); pc.bits(0,15)++;
uint8 op0 = dreadb(pc); pc.bits(0,15)++;
uint8 op1 = dreadb(pc); pc.bits(0,15)++;
uint8 op2 = dreadb(pc);
#define op8 ((op0))
#define op16 ((op0) | (op1 << 8))
@ -427,8 +426,8 @@ auto WDC65816::disassemble(uint24 addr, bool e, bool m, bool x) -> string {
#undef x8
s.append(t, " A:{0} X:{1} Y:{2} S:{3} D:{4} B:{5} ", string_format{
hex(r.a.w, 4), hex(r.x.w, 4), hex(r.y.w, 4),
hex(r.s.w, 4), hex(r.d.w, 4), hex(r.db, 2)
hex(r.a, 4), hex(r.x, 4), hex(r.y, 4),
hex(r.s, 4), hex(r.d, 4), hex(r.b, 2)
});
if(r.e) {

View File

@ -1,286 +1,63 @@
auto WDC65816::interrupt() -> void {
read(PC);
idle();
N push(PCB);
push(PCH);
push(PCL);
N push(db(PC));
push(hi(PC));
push(lo(PC));
push(EF ? P & ~0x10 : P);
IF = 1;
DF = 0;
PCL = read(r.vector + 0);
PCH = read(r.vector + 1);
PCB = 0x00;
lo(PC) = read(r.vector + 0);
hi(PC) = read(r.vector + 1);
db(PC) = 0x00;
}
//both the accumulator and index registers can independently be in either 8-bit or 16-bit mode.
//controlled via the M/X flags, this changes the execution details of various instructions.
//rather than implement four instruction tables for all possible combinations of these bits,
//instead use macro abuse to generate all four tables based off of a single template table.
auto WDC65816::instruction() -> void {
//a = instructions unaffected by M/X flags
//m = instructions affected by M flag (1 = 8-bit; 0 = 16-bit)
//x = instructions affected by X flag (1 = 8-bit; 0 = 16-bit)
#define opA(id, name, ...) case id: return instruction##name(__VA_ARGS__);
#define opM(id, name, ...) case id: return MF ? instruction##name##8(__VA_ARGS__) : instruction##name##16(__VA_ARGS__);
#define opX(id, name, ...) case id: return XF ? instruction##name##8(__VA_ARGS__) : instruction##name##16(__VA_ARGS__);
#define m(name) MF ? &WDC65816::algorithm##name##8 : &WDC65816::algorithm##name##16
#define x(name) XF ? &WDC65816::algorithm##name##8 : &WDC65816::algorithm##name##16
switch(fetch()) {
opA(0x00, Interrupt, EF ? 0xfffe : 0xffe6) //emulation mode lacks BRK vector; uses IRQ vector instead
opM(0x01, IndexedIndirectRead, m(ORA))
opA(0x02, Interrupt, EF ? 0xfff4 : 0xffe4)
opM(0x03, StackRead, m(ORA))
opM(0x04, DirectModify, m(TSB))
opM(0x05, DirectRead, m(ORA))
opM(0x06, DirectModify, m(ASL))
opM(0x07, IndirectLongRead, m(ORA))
opA(0x08, PHP)
opM(0x09, ImmediateRead, m(ORA))
opM(0x0a, ASLImplied)
opA(0x0b, PHD)
opM(0x0c, BankModify, m(TSB))
opM(0x0d, BankRead, m(ORA))
opM(0x0e, BankModify, m(ASL))
opM(0x0f, LongRead, m(ORA))
opA(0x10, Branch, NF == 0)
opM(0x11, IndirectIndexedRead, m(ORA))
opM(0x12, IndirectRead, m(ORA))
opM(0x13, IndirectStackRead, m(ORA))
opM(0x14, DirectModify, m(TRB))
opM(0x15, DirectRead, m(ORA), X)
opM(0x16, DirectIndexedModify, m(ASL))
opM(0x17, IndirectLongRead, m(ORA), Y)
opA(0x18, ClearFlag, CF)
opM(0x19, BankRead, m(ORA), Y)
opM(0x1a, INCImplied, A)
opA(0x1b, TCS)
opM(0x1c, BankModify, m(TRB))
opM(0x1d, BankRead, m(ORA), X)
opM(0x1e, BankIndexedModify, m(ASL))
opM(0x1f, LongRead, m(ORA), X)
opA(0x20, JSRShort)
opM(0x21, IndexedIndirectRead, m(AND))
opA(0x22, JSRLong)
opM(0x23, StackRead, m(AND))
opM(0x24, DirectRead, m(BIT))
opM(0x25, DirectRead, m(AND))
opM(0x26, DirectModify, m(ROL))
opM(0x27, IndirectLongRead, m(AND))
opA(0x28, PLP)
opM(0x29, ImmediateRead, m(AND))
opM(0x2a, ROLImplied)
opA(0x2b, PLD)
opM(0x2c, BankRead, m(BIT))
opM(0x2d, BankRead, m(AND))
opM(0x2e, BankModify, m(ROL))
opM(0x2f, LongRead, m(AND))
opA(0x30, Branch, NF == 1)
opM(0x31, IndirectIndexedRead, m(AND))
opM(0x32, IndirectRead, m(AND))
opM(0x33, IndirectStackRead, m(AND))
opM(0x34, DirectRead, m(BIT), X)
opM(0x35, DirectRead, m(AND), X)
opM(0x36, DirectIndexedModify, m(ROL))
opM(0x37, IndirectLongRead, m(AND), Y)
opA(0x38, SetFlag, CF)
opM(0x39, BankRead, m(AND), Y)
opM(0x3a, DECImplied, A)
opA(0x3b, Transfer16, S, A)
opM(0x3c, BankRead, m(BIT), X)
opM(0x3d, BankRead, m(AND), X)
opM(0x3e, BankIndexedModify, m(ROL))
opM(0x3f, LongRead, m(AND), X)
opA(0x40, RTI)
opM(0x41, IndexedIndirectRead, m(EOR))
opA(0x42, WDM)
opM(0x43, StackRead, m(EOR))
opX(0x44, BlockMove, -1)
opM(0x45, DirectRead, m(EOR))
opM(0x46, DirectModify, m(LSR))
opM(0x47, IndirectLongRead, m(EOR))
opM(0x48, Push, A)
opM(0x49, ImmediateRead, m(EOR))
opM(0x4a, LSRImplied)
opA(0x4b, PHK)
opA(0x4c, JMPShort)
opM(0x4d, BankRead, m(EOR))
opM(0x4e, BankModify, m(LSR))
opM(0x4f, LongRead, m(EOR))
opA(0x50, Branch, VF == 0)
opM(0x51, IndirectIndexedRead, m(EOR))
opM(0x52, IndirectRead, m(EOR))
opM(0x53, IndirectStackRead, m(EOR))
opX(0x54, BlockMove, +1)
opM(0x55, DirectRead, m(EOR), X)
opM(0x56, DirectIndexedModify, m(LSR))
opM(0x57, IndirectLongRead, m(EOR), Y)
opA(0x58, ClearFlag, IF)
opM(0x59, BankRead, m(EOR), Y)
opX(0x5a, Push, Y)
opA(0x5b, Transfer16, A, D)
opA(0x5c, JMPLong)
opM(0x5d, BankRead, m(EOR), X)
opM(0x5e, BankIndexedModify, m(LSR))
opM(0x5f, LongRead, m(EOR), X)
opA(0x60, RTS)
opM(0x61, IndexedIndirectRead, m(ADC))
opA(0x62, PER)
opM(0x63, StackRead, m(ADC))
opM(0x64, DirectWrite, Z)
opM(0x65, DirectRead, m(ADC))
opM(0x66, DirectModify, m(ROR))
opM(0x67, IndirectLongRead, m(ADC))
opM(0x68, Pull, A)
opM(0x69, ImmediateRead, m(ADC))
opM(0x6a, RORImplied)
opA(0x6b, RTL)
opA(0x6c, JMPIndirect)
opM(0x6d, BankRead, m(ADC))
opM(0x6e, BankModify, m(ROR))
opM(0x6f, LongRead, m(ADC))
opA(0x70, Branch, VF == 1)
opM(0x71, IndirectIndexedRead, m(ADC))
opM(0x72, IndirectRead, m(ADC))
opM(0x73, IndirectStackRead, m(ADC))
opM(0x74, DirectWrite, Z, X)
opM(0x75, DirectRead, m(ADC), X)
opM(0x76, DirectIndexedModify, m(ROR))
opM(0x77, IndirectLongRead, m(ADC), Y)
opA(0x78, SetFlag, IF)
opM(0x79, BankRead, m(ADC), Y)
opX(0x7a, Pull, Y)
opA(0x7b, Transfer16, D, A)
opA(0x7c, JMPIndexedIndirect)
opM(0x7d, BankRead, m(ADC), X)
opM(0x7e, BankIndexedModify, m(ROR))
opM(0x7f, LongRead, m(ADC), X)
opA(0x80, Branch)
opM(0x81, IndexedIndirectWrite)
opA(0x82, BRL)
opM(0x83, StackWrite)
opX(0x84, DirectWrite, Y)
opM(0x85, DirectWrite, A)
opX(0x86, DirectWrite, X)
opM(0x87, IndirectLongWrite)
opX(0x88, DECImplied, Y)
opM(0x89, BITImmediate)
opM(0x8a, Transfer, X, A)
opA(0x8b, PHB)
opX(0x8c, BankWrite, Y)
opM(0x8d, BankWrite, A)
opX(0x8e, BankWrite, X)
opM(0x8f, LongWrite)
opA(0x90, Branch, CF == 0)
opM(0x91, IndirectIndexedWrite)
opM(0x92, IndirectWrite)
opM(0x93, IndirectStackWrite)
opX(0x94, DirectWrite, Y, X)
opM(0x95, DirectWrite, A, X)
opX(0x96, DirectWrite, X, Y)
opM(0x97, IndirectLongWrite, Y)
opM(0x98, Transfer, Y, A)
opM(0x99, BankWrite, A, Y)
opA(0x9a, TXS)
opX(0x9b, Transfer, X, Y)
opM(0x9c, BankWrite, Z)
opM(0x9d, BankWrite, A, X)
opM(0x9e, BankWrite, Z, X)
opM(0x9f, LongWrite, X)
opX(0xa0, ImmediateRead, x(LDY))
opM(0xa1, IndexedIndirectRead, m(LDA))
opX(0xa2, ImmediateRead, x(LDX))
opM(0xa3, StackRead, m(LDA))
opX(0xa4, DirectRead, x(LDY))
opM(0xa5, DirectRead, m(LDA))
opX(0xa6, DirectRead, x(LDX))
opM(0xa7, IndirectLongRead, m(LDA))
opX(0xa8, Transfer, A, Y)
opM(0xa9, ImmediateRead, m(LDA))
opX(0xaa, Transfer, A, X)
opA(0xab, PLB)
opX(0xac, BankRead, x(LDY))
opM(0xad, BankRead, m(LDA))
opX(0xae, BankRead, x(LDX))
opM(0xaf, LongRead, m(LDA))
opA(0xb0, Branch, CF == 1)
opM(0xb1, IndirectIndexedRead, m(LDA))
opM(0xb2, IndirectRead, m(LDA))
opM(0xb3, IndirectStackRead, m(LDA))
opX(0xb4, DirectRead, x(LDY), X)
opM(0xb5, DirectRead, m(LDA), X)
opX(0xb6, DirectRead, x(LDX), Y)
opM(0xb7, IndirectLongRead, m(LDA), Y)
opA(0xb8, ClearFlag, VF)
opM(0xb9, BankRead, m(LDA), Y)
opX(0xba, TSX)
opX(0xbb, Transfer, Y, X)
opX(0xbc, BankRead, x(LDY), X)
opM(0xbd, BankRead, m(LDA), X)
opX(0xbe, BankRead, x(LDX), Y)
opM(0xbf, LongRead, m(LDA), X)
opX(0xc0, ImmediateRead, x(CPY))
opM(0xc1, IndexedIndirectRead, m(CMP))
opA(0xc2, REP)
opM(0xc3, StackRead, m(CMP))
opX(0xc4, DirectRead, x(CPY))
opM(0xc5, DirectRead, m(CMP))
opM(0xc6, DirectModify, m(DEC))
opM(0xc7, IndirectLongRead, m(CMP))
opX(0xc8, INCImplied, Y)
opM(0xc9, ImmediateRead, m(CMP))
opX(0xca, DECImplied, X)
opA(0xcb, WAI)
opX(0xcc, BankRead, x(CPY))
opM(0xcd, BankRead, m(CMP))
opM(0xce, BankModify, m(DEC))
opM(0xcf, LongRead, m(CMP))
opA(0xd0, Branch, ZF == 0)
opM(0xd1, IndirectIndexedRead, m(CMP))
opM(0xd2, IndirectRead, m(CMP))
opM(0xd3, IndirectStackRead, m(CMP))
opA(0xd4, PEI)
opM(0xd5, DirectRead, m(CMP), X)
opM(0xd6, DirectIndexedModify, m(DEC))
opM(0xd7, IndirectLongRead, m(CMP), Y)
opA(0xd8, ClearFlag, DF)
opM(0xd9, BankRead, m(CMP), Y)
opX(0xda, Push, X)
opA(0xdb, STP)
opA(0xdc, JMPIndirectLong)
opM(0xdd, BankRead, m(CMP), X)
opM(0xde, BankIndexedModify, m(DEC))
opM(0xdf, LongRead, m(CMP), X)
opX(0xe0, ImmediateRead, x(CPX))
opM(0xe1, IndexedIndirectRead, m(SBC))
opA(0xe2, SEP)
opM(0xe3, StackRead, m(SBC))
opX(0xe4, DirectRead, x(CPX))
opM(0xe5, DirectRead, m(SBC))
opM(0xe6, DirectModify, m(INC))
opM(0xe7, IndirectLongRead, m(SBC))
opX(0xe8, INCImplied, X)
opM(0xe9, ImmediateRead, m(SBC))
opA(0xea, NOP)
opA(0xeb, XBA)
opX(0xec, BankRead, x(CPX))
opM(0xed, BankRead, m(SBC))
opM(0xee, BankModify, m(INC))
opM(0xef, LongRead, m(SBC))
opA(0xf0, Branch, ZF == 1)
opM(0xf1, IndirectIndexedRead, m(SBC))
opM(0xf2, IndirectRead, m(SBC))
opM(0xf3, IndirectStackRead, m(SBC))
opA(0xf4, PEA)
opM(0xf5, DirectRead, m(SBC), X)
opM(0xf6, DirectIndexedModify, m(INC))
opM(0xf7, IndirectLongRead, m(SBC), Y)
opA(0xf8, SetFlag, DF)
opM(0xf9, BankRead, m(SBC), Y)
opX(0xfa, Pull, X)
opA(0xfb, XCE)
opA(0xfc, JSRIndexedIndirect)
opM(0xfd, BankRead, m(SBC), X)
opM(0xfe, BankIndexedModify, m(INC))
opM(0xff, LongRead, m(SBC), X)
if(MF) {
#define opM(id, name, ...) case id: return instruction##name##8(__VA_ARGS__);
#define m(name) &WDC65816::algorithm##name##8
if(XF) {
#define opX(id, name, ...) case id: return instruction##name##8(__VA_ARGS__);
#define x(name) &WDC65816::algorithm##name##8
#include "instruction.hpp"
#undef opX
#undef x
} else {
#define opX(id, name, ...) case id: return instruction##name##16(__VA_ARGS__);
#define x(name) &WDC65816::algorithm##name##16
#include "instruction.hpp"
#undef opX
#undef x
}
#undef opM
#undef m
} else {
#define opM(id, name, ...) case id: return instruction##name##16(__VA_ARGS__);
#define m(name) &WDC65816::algorithm##name##16
if(XF) {
#define opX(id, name, ...) case id: return instruction##name##8(__VA_ARGS__);
#define x(name) &WDC65816::algorithm##name##8
#include "instruction.hpp"
#undef opX
#undef x
} else {
#define opX(id, name, ...) case id: return instruction##name##16(__VA_ARGS__);
#define x(name) &WDC65816::algorithm##name##16
#include "instruction.hpp"
#undef opX
#undef x
}
#undef opM
#undef m
}
#undef opA
#undef opM
#undef opX
#undef m
#undef x
}

View File

@ -0,0 +1,258 @@
switch(fetch()) {
opA(0x00, Interrupt, EF ? 0xfffe : 0xffe6) //emulation mode lacks BRK vector; uses IRQ vector instead
opM(0x01, IndexedIndirectRead, m(ORA))
opA(0x02, Interrupt, EF ? 0xfff4 : 0xffe4)
opM(0x03, StackRead, m(ORA))
opM(0x04, DirectModify, m(TSB))
opM(0x05, DirectRead, m(ORA))
opM(0x06, DirectModify, m(ASL))
opM(0x07, IndirectLongRead, m(ORA))
opA(0x08, Push8, P)
opM(0x09, ImmediateRead, m(ORA))
opM(0x0a, ImpliedModify, m(ASL), A)
opA(0x0b, PHD)
opM(0x0c, BankModify, m(TSB))
opM(0x0d, BankRead, m(ORA))
opM(0x0e, BankModify, m(ASL))
opM(0x0f, LongRead, m(ORA))
opA(0x10, Branch, NF == 0)
opM(0x11, IndirectIndexedRead, m(ORA))
opM(0x12, IndirectRead, m(ORA))
opM(0x13, IndirectStackRead, m(ORA))
opM(0x14, DirectModify, m(TRB))
opM(0x15, DirectRead, m(ORA), X)
opM(0x16, DirectIndexedModify, m(ASL))
opM(0x17, IndirectLongRead, m(ORA), Y)
opA(0x18, ClearFlag, CF)
opM(0x19, BankRead, m(ORA), Y)
opM(0x1a, ImpliedModify, m(INC), A)
opA(0x1b, TCS)
opM(0x1c, BankModify, m(TRB))
opM(0x1d, BankRead, m(ORA), X)
opM(0x1e, BankIndexedModify, m(ASL))
opM(0x1f, LongRead, m(ORA), X)
opA(0x20, JSRShort)
opM(0x21, IndexedIndirectRead, m(AND))
opA(0x22, JSRLong)
opM(0x23, StackRead, m(AND))
opM(0x24, DirectRead, m(BIT))
opM(0x25, DirectRead, m(AND))
opM(0x26, DirectModify, m(ROL))
opM(0x27, IndirectLongRead, m(AND))
opA(0x28, PLP)
opM(0x29, ImmediateRead, m(AND))
opM(0x2a, ImpliedModify, m(ROL), A)
opA(0x2b, PLD)
opM(0x2c, BankRead, m(BIT))
opM(0x2d, BankRead, m(AND))
opM(0x2e, BankModify, m(ROL))
opM(0x2f, LongRead, m(AND))
opA(0x30, Branch, NF == 1)
opM(0x31, IndirectIndexedRead, m(AND))
opM(0x32, IndirectRead, m(AND))
opM(0x33, IndirectStackRead, m(AND))
opM(0x34, DirectRead, m(BIT), X)
opM(0x35, DirectRead, m(AND), X)
opM(0x36, DirectIndexedModify, m(ROL))
opM(0x37, IndirectLongRead, m(AND), Y)
opA(0x38, SetFlag, CF)
opM(0x39, BankRead, m(AND), Y)
opM(0x3a, ImpliedModify, m(DEC), A)
opA(0x3b, Transfer16, S, A)
opM(0x3c, BankRead, m(BIT), X)
opM(0x3d, BankRead, m(AND), X)
opM(0x3e, BankIndexedModify, m(ROL))
opM(0x3f, LongRead, m(AND), X)
opA(0x40, RTI)
opM(0x41, IndexedIndirectRead, m(EOR))
opA(0x42, WDM)
opM(0x43, StackRead, m(EOR))
opX(0x44, BlockMove, -1)
opM(0x45, DirectRead, m(EOR))
opM(0x46, DirectModify, m(LSR))
opM(0x47, IndirectLongRead, m(EOR))
opM(0x48, Push, A)
opM(0x49, ImmediateRead, m(EOR))
opM(0x4a, ImpliedModify, m(LSR), A)
opA(0x4b, Push8, db(PC))
opA(0x4c, JMPShort)
opM(0x4d, BankRead, m(EOR))
opM(0x4e, BankModify, m(LSR))
opM(0x4f, LongRead, m(EOR))
opA(0x50, Branch, VF == 0)
opM(0x51, IndirectIndexedRead, m(EOR))
opM(0x52, IndirectRead, m(EOR))
opM(0x53, IndirectStackRead, m(EOR))
opX(0x54, BlockMove, +1)
opM(0x55, DirectRead, m(EOR), X)
opM(0x56, DirectIndexedModify, m(LSR))
opM(0x57, IndirectLongRead, m(EOR), Y)
opA(0x58, ClearFlag, IF)
opM(0x59, BankRead, m(EOR), Y)
opX(0x5a, Push, Y)
opA(0x5b, Transfer16, A, D)
opA(0x5c, JMPLong)
opM(0x5d, BankRead, m(EOR), X)
opM(0x5e, BankIndexedModify, m(LSR))
opM(0x5f, LongRead, m(EOR), X)
opA(0x60, RTS)
opM(0x61, IndexedIndirectRead, m(ADC))
opA(0x62, PER)
opM(0x63, StackRead, m(ADC))
opM(0x64, DirectWrite, Z)
opM(0x65, DirectRead, m(ADC))
opM(0x66, DirectModify, m(ROR))
opM(0x67, IndirectLongRead, m(ADC))
opM(0x68, Pull, A)
opM(0x69, ImmediateRead, m(ADC))
opM(0x6a, ImpliedModify, m(ROR), A)
opA(0x6b, RTL)
opA(0x6c, JMPIndirect)
opM(0x6d, BankRead, m(ADC))
opM(0x6e, BankModify, m(ROR))
opM(0x6f, LongRead, m(ADC))
opA(0x70, Branch, VF == 1)
opM(0x71, IndirectIndexedRead, m(ADC))
opM(0x72, IndirectRead, m(ADC))
opM(0x73, IndirectStackRead, m(ADC))
opM(0x74, DirectWrite, Z, X)
opM(0x75, DirectRead, m(ADC), X)
opM(0x76, DirectIndexedModify, m(ROR))
opM(0x77, IndirectLongRead, m(ADC), Y)
opA(0x78, SetFlag, IF)
opM(0x79, BankRead, m(ADC), Y)
opX(0x7a, Pull, Y)
opA(0x7b, Transfer16, D, A)
opA(0x7c, JMPIndexedIndirect)
opM(0x7d, BankRead, m(ADC), X)
opM(0x7e, BankIndexedModify, m(ROR))
opM(0x7f, LongRead, m(ADC), X)
opA(0x80, Branch)
opM(0x81, IndexedIndirectWrite)
opA(0x82, BRL)
opM(0x83, StackWrite)
opX(0x84, DirectWrite, Y)
opM(0x85, DirectWrite, A)
opX(0x86, DirectWrite, X)
opM(0x87, IndirectLongWrite)
opX(0x88, ImpliedModify, x(DEC), Y)
opM(0x89, BITImmediate)
opM(0x8a, Transfer, X, A)
opA(0x8b, Push8, B)
opX(0x8c, BankWrite, Y)
opM(0x8d, BankWrite, A)
opX(0x8e, BankWrite, X)
opM(0x8f, LongWrite)
opA(0x90, Branch, CF == 0)
opM(0x91, IndirectIndexedWrite)
opM(0x92, IndirectWrite)
opM(0x93, IndirectStackWrite)
opX(0x94, DirectWrite, Y, X)
opM(0x95, DirectWrite, A, X)
opX(0x96, DirectWrite, X, Y)
opM(0x97, IndirectLongWrite, Y)
opM(0x98, Transfer, Y, A)
opM(0x99, BankWrite, A, Y)
opA(0x9a, TXS)
opX(0x9b, Transfer, X, Y)
opM(0x9c, BankWrite, Z)
opM(0x9d, BankWrite, A, X)
opM(0x9e, BankWrite, Z, X)
opM(0x9f, LongWrite, X)
opX(0xa0, ImmediateRead, x(LDY))
opM(0xa1, IndexedIndirectRead, m(LDA))
opX(0xa2, ImmediateRead, x(LDX))
opM(0xa3, StackRead, m(LDA))
opX(0xa4, DirectRead, x(LDY))
opM(0xa5, DirectRead, m(LDA))
opX(0xa6, DirectRead, x(LDX))
opM(0xa7, IndirectLongRead, m(LDA))
opX(0xa8, Transfer, A, Y)
opM(0xa9, ImmediateRead, m(LDA))
opX(0xaa, Transfer, A, X)
opA(0xab, PLB)
opX(0xac, BankRead, x(LDY))
opM(0xad, BankRead, m(LDA))
opX(0xae, BankRead, x(LDX))
opM(0xaf, LongRead, m(LDA))
opA(0xb0, Branch, CF == 1)
opM(0xb1, IndirectIndexedRead, m(LDA))
opM(0xb2, IndirectRead, m(LDA))
opM(0xb3, IndirectStackRead, m(LDA))
opX(0xb4, DirectRead, x(LDY), X)
opM(0xb5, DirectRead, m(LDA), X)
opX(0xb6, DirectRead, x(LDX), Y)
opM(0xb7, IndirectLongRead, m(LDA), Y)
opA(0xb8, ClearFlag, VF)
opM(0xb9, BankRead, m(LDA), Y)
opX(0xba, TSX)
opX(0xbb, Transfer, Y, X)
opX(0xbc, BankRead, x(LDY), X)
opM(0xbd, BankRead, m(LDA), X)
opX(0xbe, BankRead, x(LDX), Y)
opM(0xbf, LongRead, m(LDA), X)
opX(0xc0, ImmediateRead, x(CPY))
opM(0xc1, IndexedIndirectRead, m(CMP))
opA(0xc2, REP)
opM(0xc3, StackRead, m(CMP))
opX(0xc4, DirectRead, x(CPY))
opM(0xc5, DirectRead, m(CMP))
opM(0xc6, DirectModify, m(DEC))
opM(0xc7, IndirectLongRead, m(CMP))
opX(0xc8, ImpliedModify, x(INC), Y)
opM(0xc9, ImmediateRead, m(CMP))
opX(0xca, ImpliedModify, x(DEC), X)
opA(0xcb, WAI)
opX(0xcc, BankRead, x(CPY))
opM(0xcd, BankRead, m(CMP))
opM(0xce, BankModify, m(DEC))
opM(0xcf, LongRead, m(CMP))
opA(0xd0, Branch, ZF == 0)
opM(0xd1, IndirectIndexedRead, m(CMP))
opM(0xd2, IndirectRead, m(CMP))
opM(0xd3, IndirectStackRead, m(CMP))
opA(0xd4, PEI)
opM(0xd5, DirectRead, m(CMP), X)
opM(0xd6, DirectIndexedModify, m(DEC))
opM(0xd7, IndirectLongRead, m(CMP), Y)
opA(0xd8, ClearFlag, DF)
opM(0xd9, BankRead, m(CMP), Y)
opX(0xda, Push, X)
opA(0xdb, STP)
opA(0xdc, JMPIndirectLong)
opM(0xdd, BankRead, m(CMP), X)
opM(0xde, BankIndexedModify, m(DEC))
opM(0xdf, LongRead, m(CMP), X)
opX(0xe0, ImmediateRead, x(CPX))
opM(0xe1, IndexedIndirectRead, m(SBC))
opA(0xe2, SEP)
opM(0xe3, StackRead, m(SBC))
opX(0xe4, DirectRead, x(CPX))
opM(0xe5, DirectRead, m(SBC))
opM(0xe6, DirectModify, m(INC))
opM(0xe7, IndirectLongRead, m(SBC))
opX(0xe8, ImpliedModify, x(INC), X)
opM(0xe9, ImmediateRead, m(SBC))
opA(0xea, NOP)
opA(0xeb, XBA)
opX(0xec, BankRead, x(CPX))
opM(0xed, BankRead, m(SBC))
opM(0xee, BankModify, m(INC))
opM(0xef, LongRead, m(SBC))
opA(0xf0, Branch, ZF == 1)
opM(0xf1, IndirectIndexedRead, m(SBC))
opM(0xf2, IndirectRead, m(SBC))
opM(0xf3, IndirectStackRead, m(SBC))
opA(0xf4, PEA)
opM(0xf5, DirectRead, m(SBC), X)
opM(0xf6, DirectIndexedModify, m(INC))
opM(0xf7, IndirectLongRead, m(SBC), Y)
opA(0xf8, SetFlag, DF)
opM(0xf9, BankRead, m(SBC), Y)
opX(0xfa, Pull, X)
opA(0xfb, XCE)
opA(0xfc, JSRIndexedIndirect)
opM(0xfd, BankRead, m(SBC), X)
opM(0xfe, BankIndexedModify, m(INC))
opM(0xff, LongRead, m(SBC), X)
}

View File

@ -1,12 +1,12 @@
auto WDC65816::instructionBITImmediate8() -> void {
L uint8 immediate = fetch();
ZF = (immediate & AL) == 0;
ZF = (immediate & lo(A)) == 0;
}
auto WDC65816::instructionBITImmediate16() -> void {
uint16 immediate = fetch();
L immediate |= fetch() << 8;
ZF = (immediate & AW) == 0;
ZF = (immediate & A) == 0;
}
auto WDC65816::instructionNOP() -> void {
@ -20,48 +20,48 @@ L fetch();
auto WDC65816::instructionXBA() -> void {
idle();
L idle();
r.a.w = r.a.w >> 8 | r.a.w << 8;
r.p.n = (r.a.l & 0x80);
r.p.z = (r.a.l == 0);
A = A >> 8 | A << 8;
ZF = lo(A) == 0;
NF = A & 0x80;
}
auto WDC65816::instructionBlockMove8(int adjust) -> void {
dp = fetch();
sp = fetch();
r.db = dp;
rd.l = read(sp << 16 | r.x.w);
write(dp << 16 | r.y.w, rd.l);
auto targetBank = fetch();
auto sourceBank = fetch();
B = targetBank;
auto data = read(sourceBank << 16 | X);
write(targetBank << 16 | Y, data);
idle();
r.x.l += adjust;
r.y.l += adjust;
lo(X) += adjust;
lo(Y) += adjust;
L idle();
if(r.a.w--) r.pc.w -= 3;
if(A--) aa(PC) -= 3;
}
auto WDC65816::instructionBlockMove16(int adjust) -> void {
dp = fetch();
sp = fetch();
r.db = dp;
rd.l = read(sp << 16 | r.x.w);
write(dp << 16 | r.y.w, rd.l);
auto targetBank = fetch();
auto sourceBank = fetch();
B = targetBank;
auto data = read(sourceBank << 16 | X);
write(targetBank << 16 | Y, data);
idle();
r.x.w += adjust;
r.y.w += adjust;
X += adjust;
Y += adjust;
L idle();
if(r.a.w--) r.pc.w -= 3;
if(A--) aa(PC) -= 3;
}
auto WDC65816::instructionInterrupt(uint16 vector) -> void {
fetch();
N push(PCB);
push(PCH);
push(PCL);
N push(db(PC));
push(hi(PC));
push(lo(PC));
push(P);
IF = 1;
DF = 0;
PCL = read(vector++);
L PCH = read(vector++);
PCB = 0x00;
lo(PC) = read(vector++);
L hi(PC) = read(vector++);
db(PC) = 0x00;
}
auto WDC65816::instructionSTP() -> void {
@ -81,15 +81,13 @@ L idle();
auto WDC65816::instructionXCE() -> void {
L idleIRQ();
bool carry = r.p.c;
r.p.c = r.e;
r.e = carry;
if(r.e) {
r.p.m = 1;
r.p.x = 1;
r.x.h = 0x00;
r.y.h = 0x00;
r.s.h = 0x01;
swap(CF, EF);
if(EF) {
XF = 1;
MF = 1;
hi(X) = 0x00;
hi(Y) = 0x00;
hi(S) = 0x01;
}
}
@ -108,7 +106,7 @@ auto WDC65816::instructionREP() -> void {
L idle();
P = P & ~data;
E XF = 1, MF = 1;
if(XF) XH = 0x00, YH = 0x00;
if(XF) hi(X) = 0x00, hi(Y) = 0x00;
}
auto WDC65816::instructionSEP() -> void {
@ -116,152 +114,134 @@ auto WDC65816::instructionSEP() -> void {
L idle();
P = P | data;
E XF = 1, MF = 1;
if(XF) XH = 0x00, YH = 0x00;
if(XF) hi(X) = 0x00, hi(Y) = 0x00;
}
auto WDC65816::instructionTransfer8(uint16& from, uint16& to) -> void {
L idleIRQ();
LO(to) = LO(from);
r.p.n = (LO(to) & 0x80);
r.p.z = (LO(to) == 0);
lo(to) = lo(from);
ZF = lo(to) == 0;
NF = to & 0x80;
}
auto WDC65816::instructionTransfer16(uint16& from, uint16& to) -> void {
L idleIRQ();
to = from;
r.p.n = (to & 0x8000);
r.p.z = (to == 0);
ZF = to == 0;
NF = to & 0x8000;
}
auto WDC65816::instructionTCS() -> void {
L idleIRQ();
r.s.w = r.a.w;
E r.s.h = 0x01;
S = A;
E hi(S) = 0x01;
}
auto WDC65816::instructionTSX8() -> void {
L idleIRQ();
r.x.l = r.s.l;
r.p.n = (r.x.l & 0x80);
r.p.z = (r.x.l == 0);
lo(X) = lo(S);
ZF = lo(X) == 0;
NF = X & 0x80;
}
auto WDC65816::instructionTSX16() -> void {
L idleIRQ();
r.x.w = r.s.w;
r.p.n = (r.x.w & 0x8000);
r.p.z = (r.x.w == 0);
X = S;
ZF = X == 0;
NF = X & 0x8000;
}
auto WDC65816::instructionTXS() -> void {
L idleIRQ();
E r.s.l = r.x.l;
N r.s.w = r.x.w;
E lo(S) = lo(X);
N S = X;
}
auto WDC65816::instructionPush8(uint16& reg) -> void {
auto WDC65816::instructionPush8(uint8 data) -> void {
idle();
L push(reg);
L push(data);
}
auto WDC65816::instructionPush16(uint16& reg) -> void {
auto WDC65816::instructionPush16(uint16 data) -> void {
idle();
push(reg >> 8);
L push(reg >> 0);
push(hi(data));
L push(lo(data));
}
auto WDC65816::instructionPHD() -> void {
idle();
pushN(r.d.h);
L pushN(r.d.l);
E r.s.h = 0x01;
pushN(hi(D));
L pushN(hi(D));
E hi(S) = 0x01;
}
auto WDC65816::instructionPHB() -> void {
auto WDC65816::instructionPull8(uint16& data) -> void {
idle();
L push(r.db);
idle();
L lo(data) = pull();
ZF = lo(data) == 0;
NF = data & 0x80;
}
auto WDC65816::instructionPHK() -> void {
idle();
L push(r.pc.b);
}
auto WDC65816::instructionPHP() -> void {
idle();
L push(r.p);
}
auto WDC65816::instructionPull8(uint16& reg) -> void {
auto WDC65816::instructionPull16(uint16& data) -> void {
idle();
idle();
L LO(reg) = pull();
r.p.n = (LO(reg) & 0x80);
r.p.z = (LO(reg) == 0);
}
auto WDC65816::instructionPull16(uint16& reg) -> void {
idle();
idle();
LO(reg) = pull();
L HI(reg) = pull();
r.p.n = (reg & 0x8000);
r.p.z = (reg == 0);
lo(data) = pull();
L hi(data) = pull();
ZF = data == 0;
NF = data & 0x8000;
}
auto WDC65816::instructionPLD() -> void {
idle();
idle();
r.d.l = pullN();
L r.d.h = pullN();
r.p.n = (r.d.w & 0x8000);
r.p.z = (r.d.w == 0);
E r.s.h = 0x01;
lo(D) = pullN();
L hi(D) = pullN();
ZF = D == 0;
NF = D & 0x8000;
E hi(S) = 0x01;
}
auto WDC65816::instructionPLB() -> void {
idle();
idle();
L r.db = pull();
r.p.n = (r.db & 0x80);
r.p.z = (r.db == 0);
L B = pull();
ZF = B == 0;
NF = B & 0x80;
}
auto WDC65816::instructionPLP() -> void {
idle();
idle();
L r.p = pull();
E r.p.m = 1, r.p.x = 1;
if(r.p.x) {
r.x.h = 0x00;
r.y.h = 0x00;
}
L P = pull();
E XF = 1, MF = 1;
if(XF) hi(X) = 0x00, hi(Y) = 0x00;
}
auto WDC65816::instructionPEA() -> void {
aa.l = fetch();
aa.h = fetch();
pushN(aa.h);
L pushN(aa.l);
E r.s.h = 0x01;
uint16 data = fetch();
hi(data) = fetch();
pushN(hi(data));
L pushN(lo(data));
E hi(S) = 0x01;
}
auto WDC65816::instructionPEI() -> void {
dp = fetch();
auto direct = fetch();
idle2();
aa.l = readDirectN(dp + 0);
aa.h = readDirectN(dp + 1);
pushN(aa.h);
L pushN(aa.l);
E r.s.h = 0x01;
uint16 data = readDirectN(direct + 0);
hi(data) = readDirectN(direct + 1);
pushN(hi(data));
L pushN(lo(data));
E hi(S) = 0x01;
}
auto WDC65816::instructionPER() -> void {
aa.l = fetch();
aa.h = fetch();
uint16 displacement = fetch();
hi(displacement) = fetch();
idle();
rd.w = r.pc.d + (int16)aa.w;
pushN(rd.h);
L pushN(rd.l);
E r.s.h = 0x01;
uint16 data = PC + (int16)displacement;
pushN(hi(data));
L pushN(lo(data));
E hi(S) = 0x01;
}

View File

@ -1,179 +1,93 @@
auto WDC65816::instructionINCImplied8(uint16& reg) -> void {
auto WDC65816::instructionImpliedModify8(alu8 op, uint16& data) -> void {
L idleIRQ();
LO(reg)++;
r.p.n = (LO(reg) & 0x80);
r.p.z = (LO(reg) == 0);
lo(data) = alu(lo(data));
}
auto WDC65816::instructionINCImplied16(uint16& reg) -> void {
auto WDC65816::instructionImpliedModify16(alu16 op, uint16& data) -> void {
L idleIRQ();
reg++;
r.p.n = (reg & 0x8000);
r.p.z = (reg == 0);
data = alu(data);
}
auto WDC65816::instructionDECImplied8(uint16& reg) -> void {
L idleIRQ();
LO(reg)--;
r.p.n = (LO(reg) & 0x80);
r.p.z = (LO(reg) == 0);
}
auto WDC65816::instructionDECImplied16(uint16& reg) -> void {
L idleIRQ();
reg--;
r.p.n = (reg & 0x8000);
r.p.z = (reg == 0);
}
auto WDC65816::instructionASLImplied8() -> void {
L idleIRQ();
r.p.c = (r.a.l & 0x80);
r.a.l <<= 1;
r.p.n = (r.a.l & 0x80);
r.p.z = (r.a.l == 0);
}
auto WDC65816::instructionASLImplied16() -> void {
L idleIRQ();
r.p.c = (r.a.w & 0x8000);
r.a.w <<= 1;
r.p.n = (r.a.w & 0x8000);
r.p.z = (r.a.w == 0);
}
auto WDC65816::instructionLSRImplied8() -> void {
L idleIRQ();
r.p.c = (r.a.l & 0x01);
r.a.l >>= 1;
r.p.n = (r.a.l & 0x80);
r.p.z = (r.a.l == 0);
}
auto WDC65816::instructionLSRImplied16() -> void {
L idleIRQ();
r.p.c = (r.a.w & 0x0001);
r.a.w >>= 1;
r.p.n = (r.a.w & 0x8000);
r.p.z = (r.a.w == 0);
}
auto WDC65816::instructionROLImplied8() -> void {
L idleIRQ();
bool carry = r.p.c;
r.p.c = (r.a.l & 0x80);
r.a.l = (r.a.l << 1) | carry;
r.p.n = (r.a.l & 0x80);
r.p.z = (r.a.l == 0);
}
auto WDC65816::instructionROLImplied16() -> void {
L idleIRQ();
bool carry = r.p.c;
r.p.c = (r.a.w & 0x8000);
r.a.w = (r.a.w << 1) | carry;
r.p.n = (r.a.w & 0x8000);
r.p.z = (r.a.w == 0);
}
auto WDC65816::instructionRORImplied8() -> void {
L idleIRQ();
bool carry = r.p.c;
r.p.c = (r.a.l & 0x01);
r.a.l = (carry << 7) | (r.a.l >> 1);
r.p.n = (r.a.l & 0x80);
r.p.z = (r.a.l == 0);
}
auto WDC65816::instructionRORImplied16() -> void {
L idleIRQ();
bool carry = r.p.c;
r.p.c = (r.a.w & 0x0001);
r.a.w = (carry << 15) | (r.a.w >> 1);
r.p.n = (r.a.w & 0x8000);
r.p.z = (r.a.w == 0);
}
auto WDC65816::instructionBankModify8(fp op) -> void {
aa.l = fetch();
aa.h = fetch();
rd.l = readBank(aa.w);
auto WDC65816::instructionBankModify8(alu8 op) -> void {
uint16 absolute = fetch();
hi(absolute) = fetch();
uint8 data = readBank(absolute);
idle();
call(op);
L writeBank(aa.w, rd.l);
data = alu(data);
L writeBank(absolute, data);
}
auto WDC65816::instructionBankModify16(fp op) -> void {
aa.l = fetch();
aa.h = fetch();
rd.l = readBank(aa.w + 0);
rd.h = readBank(aa.w + 1);
auto WDC65816::instructionBankModify16(alu16 op) -> void {
uint16 absolute = fetch();
hi(absolute) = fetch();
uint16 data = readBank(absolute + 0);
hi(data) = readBank(absolute + 1);
idle();
call(op);
writeBank(aa.w + 1, rd.h);
L writeBank(aa.w + 0, rd.l);
data = alu(data);
writeBank(absolute + 1, hi(data));
L writeBank(absolute + 0, lo(data));
}
auto WDC65816::instructionBankIndexedModify8(fp op) -> void {
aa.l = fetch();
aa.h = fetch();
auto WDC65816::instructionBankIndexedModify8(alu8 op) -> void {
uint16 absolute = fetch();
hi(absolute) = fetch();
idle();
rd.l = readBank(aa.w + r.x.w);
uint8 data = readBank(absolute + X);
idle();
call(op);
L writeBank(aa.w + r.x.w, rd.l);
data = alu(data);
L writeBank(absolute + X, data);
}
auto WDC65816::instructionBankIndexedModify16(fp op) -> void {
aa.l = fetch();
aa.h = fetch();
auto WDC65816::instructionBankIndexedModify16(alu16 op) -> void {
uint16 absolute = fetch();
hi(absolute) = fetch();
idle();
rd.l = readBank(aa.w + r.x.w + 0);
rd.h = readBank(aa.w + r.x.w + 1);
uint16 data = readBank(absolute + X + 0);
hi(data) = readBank(absolute + X + 1);
idle();
call(op);
writeBank(aa.w + r.x.w + 1, rd.h);
L writeBank(aa.w + r.x.w + 0, rd.l);
data = alu(data);
writeBank(absolute + X + 1, hi(data));
L writeBank(absolute + X + 0, lo(data));
}
auto WDC65816::instructionDirectModify8(fp op) -> void {
dp = fetch();
auto WDC65816::instructionDirectModify8(alu8 op) -> void {
uint8 direct = fetch();
idle2();
rd.l = readDirect(dp);
uint8 data = readDirect(direct);
idle();
call(op);
L writeDirect(dp, rd.l);
data = alu(data);
L writeDirect(direct, data);
}
auto WDC65816::instructionDirectModify16(fp op) -> void {
dp = fetch();
auto WDC65816::instructionDirectModify16(alu16 op) -> void {
uint8 direct = fetch();
idle2();
rd.l = readDirect(dp + 0);
rd.h = readDirect(dp + 1);
uint16 data = readDirect(direct + 0);
hi(data) = readDirect(direct + 1);
idle();
call(op);
writeDirect(dp + 1, rd.h);
L writeDirect(dp + 0, rd.l);
data = alu(data);
writeDirect(direct + 1, hi(data));
L writeDirect(direct + 0, lo(data));
}
auto WDC65816::instructionDirectIndexedModify8(fp op) -> void {
dp = fetch();
auto WDC65816::instructionDirectIndexedModify8(alu8 op) -> void {
uint8 direct = fetch();
idle2();
idle();
rd.l = readDirect(dp + r.x.w);
uint8 data = readDirect(direct + X);
idle();
call(op);
L writeDirect(dp + r.x.w, rd.l);
data = alu(data);
L writeDirect(direct + X, data);
}
auto WDC65816::instructionDirectIndexedModify16(fp op) -> void {
dp = fetch();
auto WDC65816::instructionDirectIndexedModify16(alu16 op) -> void {
uint8 direct = fetch();
idle2();
idle();
rd.l = readDirect(dp + r.x.w + 0);
rd.h = readDirect(dp + r.x.w + 1);
uint16 data = readDirect(direct + X + 0);
hi(data) = readDirect(direct + X + 1);
idle();
call(op);
writeDirect(dp + r.x.w + 1, rd.h);
L writeDirect(dp + r.x.w + 0, rd.l);
data = alu(data);
writeDirect(direct + X + 1, hi(data));
L writeDirect(direct + X + 0, lo(data));
}

View File

@ -1,130 +1,128 @@
auto WDC65816::instructionBranch(bool take) -> void {
if(!take) {
L rd.l = fetch();
L fetch();
} else {
rd.l = fetch();
aa.w = r.pc.d + (int8)rd.l;
idle6(aa.w);
uint8 displacement = fetch();
uint16 absolute = PC + (int8)displacement;
idle6(absolute);
L idle();
r.pc.w = aa.w;
aa(PC) = absolute;
}
}
auto WDC65816::instructionBRL() -> void {
rd.l = fetch();
rd.h = fetch();
uint16 displacement = fetch();
hi(displacement) = fetch();
L idle();
r.pc.w = r.pc.d + (int16)rd.w;
aa(PC) = PC + (int16)displacement;
}
auto WDC65816::instructionJMPShort() -> void {
rd.l = fetch();
L rd.h = fetch();
r.pc.w = rd.w;
uint16 data = fetch();
L hi(data) = fetch();
aa(PC) = data;
}
auto WDC65816::instructionJMPLong() -> void {
rd.l = fetch();
rd.h = fetch();
L rd.b = fetch();
r.pc.d = rd.d;
uint24 data = fetch();
hi(data) = fetch();
L db(data) = fetch();
PC = data;
}
auto WDC65816::instructionJMPIndirect() -> void {
aa.l = fetch();
aa.h = fetch();
rd.l = read(uint16(aa.w + 0));
L rd.h = read(uint16(aa.w + 1));
r.pc.w = rd.w;
uint16 absolute = fetch();
hi(absolute) = fetch();
uint16 data = read(uint16(absolute + 0));
L hi(data) = read(uint16(absolute + 1));
aa(PC) = data;
}
auto WDC65816::instructionJMPIndexedIndirect() -> void {
aa.l = fetch();
aa.h = fetch();
uint16 absolute = fetch();
hi(absolute) = fetch();
idle();
rd.l = read(PCB << 16 | uint16(aa.w + r.x.w + 0));
L rd.h = read(PCB << 16 | uint16(aa.w + r.x.w + 1));
r.pc.w = rd.w;
uint16 data = read(db(PC) << 16 | uint16(absolute + X + 0));
L hi(data) = read(db(PC) << 16 | uint16(absolute + X + 1));
aa(PC) = data;
}
auto WDC65816::instructionJMPIndirectLong() -> void {
aa.l = fetch();
aa.h = fetch();
rd.l = read(uint16(aa.w + 0));
rd.h = read(uint16(aa.w + 1));
L rd.b = read(uint16(aa.w + 2));
r.pc.d = rd.d;
uint16 absolute = fetch();
hi(absolute) = fetch();
uint24 data = read(uint16(absolute + 0));
hi(data) = read(uint16(absolute + 1));
L db(data) = read(uint16(absolute + 2));
PC = data;
}
auto WDC65816::instructionJSRShort() -> void {
aa.l = fetch();
aa.h = fetch();
uint16 data = fetch();
hi(data) = fetch();
idle();
r.pc.w--;
push(r.pc.h);
L push(r.pc.l);
r.pc.w = aa.w;
aa(PC)--;
push(hi(PC));
L push(lo(PC));
aa(PC) = data;
}
auto WDC65816::instructionJSRLong() -> void {
aa.l = fetch();
aa.h = fetch();
pushN(r.pc.b);
uint24 data = fetch();
hi(data) = fetch();
pushN(db(PC));
idle();
aa.b = fetch();
r.pc.w--;
pushN(r.pc.h);
L pushN(r.pc.l);
r.pc.d = aa.d;
E r.s.h = 0x01;
db(data) = fetch();
aa(PC)--;
pushN(hi(PC));
L pushN(lo(PC));
PC = data;
E hi(S) = 0x01;
}
auto WDC65816::instructionJSRIndexedIndirect() -> void {
aa.l = fetch();
pushN(r.pc.h);
pushN(r.pc.l);
aa.h = fetch();
uint16 absolute = fetch();
pushN(hi(PC));
pushN(lo(PC));
hi(absolute) = fetch();
idle();
rd.l = read(PCB << 16 | uint16(aa.w + r.x.w + 0));
L rd.h = read(PCB << 16 | uint16(aa.w + r.x.w + 1));
r.pc.w = rd.w;
E r.s.h = 0x01;
uint16 data = read(db(PC) << 16 | uint16(absolute + X + 0));
L hi(data) = read(db(PC) << 16 | uint16(absolute + X + 1));
aa(PC) = data;
E hi(S) = 0x01;
}
auto WDC65816::instructionRTI() -> void {
idle();
idle();
r.p = pull();
E r.p.m = 1, r.p.x = 1;
if(r.p.x) {
r.x.h = 0x00;
r.y.h = 0x00;
}
r.pc.l = pull();
if(r.e) {
L r.pc.h = pull();
P = pull();
E XF = 1, MF = 1;
if(XF) hi(X) = 0x00, hi(Y) = 0x00;
lo(PC) = pull();
if(EF) {
L hi(PC) = pull();
} else {
r.pc.h = pull();
L r.pc.b = pull();
hi(PC) = pull();
L db(PC) = pull();
}
}
auto WDC65816::instructionRTS() -> void {
idle();
idle();
rd.l = pull();
rd.h = pull();
uint16 data = pull();
hi(data) = pull();
L idle();
r.pc.w = ++rd.w;
PC = data;
aa(PC)++;
}
auto WDC65816::instructionRTL() -> void {
idle();
idle();
rd.l = pullN();
rd.h = pullN();
L rd.b = pullN();
r.pc.b = rd.b;
r.pc.w = ++rd.w;
E r.s.h = 0x01;
uint24 data = pullN();
hi(data) = pullN();
L db(data) = pullN();
PC = data;
aa(PC)++;
E hi(S) = 0x01;
}

View File

@ -1,209 +1,209 @@
auto WDC65816::instructionImmediateRead8(fp op) -> void {
L rd.l = fetch();
call(op);
auto WDC65816::instructionImmediateRead8(alu8 op) -> void {
L uint8 data = fetch();
alu(data);
}
auto WDC65816::instructionImmediateRead16(fp op) -> void {
rd.l = fetch();
L rd.h = fetch();
call(op);
auto WDC65816::instructionImmediateRead16(alu16 op) -> void {
uint16 data = fetch();
L hi(data) = fetch();
alu(data);
}
auto WDC65816::instructionBankRead8(fp op) -> void {
aa.l = fetch();
aa.h = fetch();
L rd.l = readBank(aa.w);
call(op);
auto WDC65816::instructionBankRead8(alu8 op) -> void {
uint16 absolute = fetch();
hi(absolute) = fetch();
L uint8 data = readBank(absolute);
alu(data);
}
auto WDC65816::instructionBankRead16(fp op) -> void {
aa.l = fetch();
aa.h = fetch();
rd.l = readBank(aa.w + 0);
L rd.h = readBank(aa.w + 1);
call(op);
auto WDC65816::instructionBankRead16(alu16 op) -> void {
uint16 absolute = fetch();
hi(absolute) = fetch();
uint16 data = readBank(absolute + 0);
L hi(data) = readBank(absolute + 1);
alu(data);
}
auto WDC65816::instructionBankRead8(fp op, uint16 index) -> void {
aa.l = fetch();
aa.h = fetch();
idle4(aa.w, aa.w + index);
L rd.l = readBank(aa.w + index);
call(op);
auto WDC65816::instructionBankRead8(alu8 op, uint16 index) -> void {
uint16 absolute = fetch();
hi(absolute) = fetch();
idle4(absolute, absolute + index);
L uint8 data = readBank(absolute + index);
alu(data);
}
auto WDC65816::instructionBankRead16(fp op, uint16 index) -> void {
aa.l = fetch();
aa.h = fetch();
idle4(aa.w, aa.w + index);
rd.l = readBank(aa.w + index + 0);
L rd.h = readBank(aa.w + index + 1);
call(op);
auto WDC65816::instructionBankRead16(alu16 op, uint16 index) -> void {
uint16 absolute = fetch();
hi(absolute) = fetch();
idle4(absolute, absolute + index);
uint16 data = readBank(absolute + index + 0);
L hi(data) = readBank(absolute + index + 1);
alu(data);
}
auto WDC65816::instructionLongRead8(fp op, uint16 index) -> void {
aa.l = fetch();
aa.h = fetch();
aa.b = fetch();
L rd.l = read(aa.d + index);
call(op);
auto WDC65816::instructionLongRead8(alu8 op, uint16 index) -> void {
uint24 address = fetch();
hi(address) = fetch();
db(address) = fetch();
L uint8 data = read(address + index);
alu(data);
}
auto WDC65816::instructionLongRead16(fp op, uint16 index) -> void {
aa.l = fetch();
aa.h = fetch();
aa.b = fetch();
rd.l = read(aa.d + index + 0);
L rd.h = read(aa.d + index + 1);
call(op);
auto WDC65816::instructionLongRead16(alu16 op, uint16 index) -> void {
uint24 address = fetch();
hi(address) = fetch();
db(address) = fetch();
uint16 data = read(address + index + 0);
L hi(data) = read(address + index + 1);
alu(data);
}
auto WDC65816::instructionDirectRead8(fp op) -> void {
dp = fetch();
auto WDC65816::instructionDirectRead8(alu8 op) -> void {
uint8 direct = fetch();
idle2();
L rd.l = readDirect(dp);
call(op);
L uint8 data = readDirect(direct);
alu(data);
}
auto WDC65816::instructionDirectRead16(fp op) -> void {
dp = fetch();
auto WDC65816::instructionDirectRead16(alu16 op) -> void {
uint8 direct = fetch();
idle2();
rd.l = readDirect(dp + 0);
L rd.h = readDirect(dp + 1);
call(op);
uint16 data = readDirect(direct + 0);
L hi(data) = readDirect(direct + 1);
alu(data);
}
auto WDC65816::instructionDirectRead8(fp op, uint16 index) -> void {
dp = fetch();
auto WDC65816::instructionDirectRead8(alu8 op, uint16 index) -> void {
uint8 direct = fetch();
idle2();
idle();
L rd.l = readDirect(dp + index);
call(op);
L uint8 data = readDirect(direct + index);
alu(data);
}
auto WDC65816::instructionDirectRead16(fp op, uint16 index) -> void {
dp = fetch();
auto WDC65816::instructionDirectRead16(alu16 op, uint16 index) -> void {
uint8 direct = fetch();
idle2();
idle();
rd.l = readDirect(dp + index + 0);
L rd.h = readDirect(dp + index + 1);
call(op);
uint16 data = readDirect(direct + index + 0);
L hi(data) = readDirect(direct + index + 1);
alu(data);
}
auto WDC65816::instructionIndirectRead8(fp op) -> void {
dp = fetch();
auto WDC65816::instructionIndirectRead8(alu8 op) -> void {
uint8 direct = fetch();
idle2();
aa.l = readDirect(dp + 0);
aa.h = readDirect(dp + 1);
L rd.l = readBank(aa.w);
call(op);
uint16 absolute = readDirect(direct + 0);
hi(absolute) = readDirect(direct + 1);
L uint8 data = readBank(absolute);
alu(data);
}
auto WDC65816::instructionIndirectRead16(fp op) -> void {
dp = fetch();
auto WDC65816::instructionIndirectRead16(alu16 op) -> void {
uint8 direct = fetch();
idle2();
aa.l = readDirect(dp + 0);
aa.h = readDirect(dp + 1);
rd.l = readBank(aa.w + 0);
L rd.h = readBank(aa.w + 1);
call(op);
uint16 absolute = readDirect(direct + 0);
hi(absolute) = readDirect(direct + 1);
uint16 data = readBank(absolute + 0);
L hi(data) = readBank(absolute + 1);
alu(data);
}
auto WDC65816::instructionIndexedIndirectRead8(fp op) -> void {
dp = fetch();
auto WDC65816::instructionIndexedIndirectRead8(alu8 op) -> void {
uint8 direct = fetch();
idle2();
idle();
aa.l = readDirect(dp + r.x.w + 0);
aa.h = readDirect(dp + r.x.w + 1);
L rd.l = readBank(aa.w);
call(op);
uint16 absolute = readDirect(direct + X + 0);
hi(absolute) = readDirect(direct + X + 1);
L uint8 data = readBank(absolute);
alu(data);
}
auto WDC65816::instructionIndexedIndirectRead16(fp op) -> void {
dp = fetch();
auto WDC65816::instructionIndexedIndirectRead16(alu16 op) -> void {
uint8 direct = fetch();
idle2();
idle();
aa.l = readDirect(dp + r.x.w + 0);
aa.h = readDirect(dp + r.x.w + 1);
rd.l = readBank(aa.w + 0);
L rd.h = readBank(aa.w + 1);
call(op);
uint16 absolute = readDirect(direct + X + 0);
hi(absolute) = readDirect(direct + X + 1);
uint16 data = readBank(absolute + 0);
L hi(data) = readBank(absolute + 1);
alu(data);
}
auto WDC65816::instructionIndirectIndexedRead8(fp op) -> void {
dp = fetch();
auto WDC65816::instructionIndirectIndexedRead8(alu8 op) -> void {
uint8 direct = fetch();
idle2();
aa.l = readDirect(dp + 0);
aa.h = readDirect(dp + 1);
idle4(aa.w, aa.w + r.y.w);
L rd.l = readBank(aa.w + r.y.w);
call(op);
uint16 absolute = readDirect(direct + 0);
hi(absolute) = readDirect(direct + 1);
idle4(absolute, absolute + Y);
L uint8 data = readBank(absolute + Y);
alu(data);
}
auto WDC65816::instructionIndirectIndexedRead16(fp op) -> void {
dp = fetch();
auto WDC65816::instructionIndirectIndexedRead16(alu16 op) -> void {
uint8 direct = fetch();
idle2();
aa.l = readDirect(dp + 0);
aa.h = readDirect(dp + 1);
idle4(aa.w, aa.w + r.y.w);
rd.l = readBank(aa.w + r.y.w + 0);
L rd.h = readBank(aa.w + r.y.w + 1);
call(op);
uint16 absolute = readDirect(direct + 0);
hi(absolute) = readDirect(direct + 1);
idle4(absolute, absolute + Y);
uint16 data = readBank(absolute + Y + 0);
L hi(data) = readBank(absolute + Y + 1);
alu(data);
}
auto WDC65816::instructionIndirectLongRead8(fp op, uint16 index) -> void {
dp = fetch();
auto WDC65816::instructionIndirectLongRead8(alu8 op, uint16 index) -> void {
uint8 direct = fetch();
idle2();
aa.l = readDirectN(dp + 0);
aa.h = readDirectN(dp + 1);
aa.b = readDirectN(dp + 2);
L rd.l = read(aa.d + index);
call(op);
uint24 address = readDirectN(direct + 0);
hi(address) = readDirectN(direct + 1);
db(address) = readDirectN(direct + 2);
L uint8 data = read(address + index);
alu(data);
}
auto WDC65816::instructionIndirectLongRead16(fp op, uint16 index) -> void {
dp = fetch();
auto WDC65816::instructionIndirectLongRead16(alu16 op, uint16 index) -> void {
uint8 direct = fetch();
idle2();
aa.l = readDirectN(dp + 0);
aa.h = readDirectN(dp + 1);
aa.b = readDirectN(dp + 2);
rd.l = read(aa.d + index + 0);
L rd.h = read(aa.d + index + 1);
call(op);
uint24 address = readDirectN(direct + 0);
hi(address) = readDirectN(direct + 1);
db(address) = readDirectN(direct + 2);
uint16 data = read(address + index + 0);
L hi(data) = read(address + index + 1);
alu(data);
}
auto WDC65816::instructionStackRead8(fp op) -> void {
sp = fetch();
auto WDC65816::instructionStackRead8(alu8 op) -> void {
uint8 stack = fetch();
idle();
L rd.l = readStack(sp);
call(op);
L uint8 data = readStack(stack);
alu(data);
}
auto WDC65816::instructionStackRead16(fp op) -> void {
sp = fetch();
auto WDC65816::instructionStackRead16(alu16 op) -> void {
uint8 stack = fetch();
idle();
rd.l = readStack(sp + 0);
L rd.h = readStack(sp + 1);
call(op);
uint16 data = readStack(stack + 0);
L hi(data) = readStack(stack + 1);
alu(data);
}
auto WDC65816::instructionIndirectStackRead8(fp op) -> void {
sp = fetch();
auto WDC65816::instructionIndirectStackRead8(alu8 op) -> void {
uint8 stack = fetch();
idle();
aa.l = readStack(sp + 0);
aa.h = readStack(sp + 1);
uint16 absolute = readStack(stack + 0);
hi(absolute) = readStack(stack + 1);
idle();
L rd.l = readBank(aa.w + r.y.w);
call(op);
L uint8 data = readBank(absolute + Y);
alu(data);
}
auto WDC65816::instructionIndirectStackRead16(fp op) -> void {
sp = fetch();
auto WDC65816::instructionIndirectStackRead16(alu16 op) -> void {
uint8 stack = fetch();
idle();
aa.l = readStack(sp + 0);
aa.h = readStack(sp + 1);
uint16 absolute = readStack(stack + 0);
hi(absolute) = readStack(stack + 1);
idle();
rd.l = readBank(aa.w + r.y.w + 0);
L rd.h = readBank(aa.w + r.y.w + 1);
call(op);
uint16 data = readBank(absolute + Y + 0);
L hi(data) = readBank(absolute + Y + 1);
alu(data);
}

View File

@ -1,176 +1,176 @@
auto WDC65816::instructionBankWrite8(uint16& reg) -> void {
aa.l = fetch();
aa.h = fetch();
L writeBank(aa.w, reg);
auto WDC65816::instructionBankWrite8(uint16& data) -> void {
uint16 absolute = fetch();
hi(absolute) = fetch();
L writeBank(absolute, data);
}
auto WDC65816::instructionBankWrite16(uint16& reg) -> void {
aa.l = fetch();
aa.h = fetch();
writeBank(aa.w + 0, reg >> 0);
L writeBank(aa.w + 1, reg >> 8);
auto WDC65816::instructionBankWrite16(uint16& data) -> void {
uint16 absolute = fetch();
hi(absolute) = fetch();
writeBank(absolute + 0, lo(data));
L writeBank(absolute + 1, hi(data));
}
auto WDC65816::instructionBankWrite8(uint16& reg, uint16 index) -> void {
aa.l = fetch();
aa.h = fetch();
auto WDC65816::instructionBankWrite8(uint16& data, uint16 index) -> void {
uint16 absolute = fetch();
hi(absolute) = fetch();
idle();
L writeBank(aa.w + index, reg);
L writeBank(absolute + index, data);
}
auto WDC65816::instructionBankWrite16(uint16& reg, uint16 index) -> void {
aa.l = fetch();
aa.h = fetch();
auto WDC65816::instructionBankWrite16(uint16& data, uint16 index) -> void {
uint16 absolute = fetch();
hi(absolute) = fetch();
idle();
writeBank(aa.w + index + 0, reg >> 0);
L writeBank(aa.w + index + 1, reg >> 8);
writeBank(absolute + index + 0, lo(data));
L writeBank(absolute + index + 1, hi(data));
}
auto WDC65816::instructionLongWrite8(uint16 index) -> void {
aa.l = fetch();
aa.h = fetch();
aa.b = fetch();
L write(aa.d + index, r.a.l);
uint24 address = fetch();
hi(address) = fetch();
db(address) = fetch();
L write(address + index, lo(A));
}
auto WDC65816::instructionLongWrite16(uint16 index) -> void {
aa.l = fetch();
aa.h = fetch();
aa.b = fetch();
write(aa.d + index + 0, r.a.l);
L write(aa.d + index + 1, r.a.h);
uint24 address = fetch();
hi(address) = fetch();
db(address) = fetch();
write(address + index + 0, lo(A));
L write(address + index + 1, hi(A));
}
auto WDC65816::instructionDirectWrite8(uint16& reg) -> void {
dp = fetch();
auto WDC65816::instructionDirectWrite8(uint16& data) -> void {
uint8 direct = fetch();
idle2();
L writeDirect(dp, reg);
L writeDirect(direct, data);
}
auto WDC65816::instructionDirectWrite16(uint16& reg) -> void {
dp = fetch();
auto WDC65816::instructionDirectWrite16(uint16& data) -> void {
uint8 direct = fetch();
idle2();
writeDirect(dp + 0, reg >> 0);
L writeDirect(dp + 1, reg >> 8);
writeDirect(direct + 0, lo(data));
L writeDirect(direct + 1, hi(data));
}
auto WDC65816::instructionDirectWrite8(uint16& reg, uint16 index) -> void {
dp = fetch();
auto WDC65816::instructionDirectWrite8(uint16& data, uint16 index) -> void {
uint8 direct = fetch();
idle2();
idle();
L writeDirect(dp + index, reg);
L writeDirect(direct + index, lo(data));
}
auto WDC65816::instructionDirectWrite16(uint16& reg, uint16 index) -> void {
dp = fetch();
auto WDC65816::instructionDirectWrite16(uint16& data, uint16 index) -> void {
uint8 direct = fetch();
idle2();
idle();
writeDirect(dp + index + 0, reg >> 0);
L writeDirect(dp + index + 1, reg >> 8);
writeDirect(direct + index + 0, lo(data));
L writeDirect(direct + index + 1, hi(data));
}
auto WDC65816::instructionIndirectWrite8() -> void {
dp = fetch();
uint8 direct = fetch();
idle2();
aa.l = readDirect(dp + 0);
aa.h = readDirect(dp + 1);
L writeBank(aa.w, r.a.l);
uint16 absolute = readDirect(direct + 0);
hi(absolute) = readDirect(direct + 1);
L writeBank(absolute, lo(A));
}
auto WDC65816::instructionIndirectWrite16() -> void {
dp = fetch();
uint8 direct = fetch();
idle2();
aa.l = readDirect(dp + 0);
aa.h = readDirect(dp + 1);
writeBank(aa.w + 0, r.a.l);
L writeBank(aa.w + 1, r.a.h);
uint16 absolute = readDirect(direct + 0);
hi(absolute) = readDirect(direct + 1);
writeBank(absolute + 0, lo(A));
L writeBank(absolute + 1, hi(A));
}
auto WDC65816::instructionIndexedIndirectWrite8() -> void {
dp = fetch();
uint8 direct = fetch();
idle2();
idle();
aa.l = readDirect(dp + r.x.w + 0);
aa.h = readDirect(dp + r.x.w + 1);
L writeBank(aa.w, r.a.l);
uint16 absolute = readDirect(direct + X + 0);
hi(absolute) = readDirect(direct + X + 1);
L writeBank(absolute, lo(A));
}
auto WDC65816::instructionIndexedIndirectWrite16() -> void {
dp = fetch();
uint8 direct = fetch();
idle2();
idle();
aa.l = readDirect(dp + r.x.w + 0);
aa.h = readDirect(dp + r.x.w + 1);
writeBank(aa.w + 0, r.a.l);
L writeBank(aa.w + 1, r.a.h);
uint16 absolute = readDirect(direct + X + 0);
hi(absolute) = readDirect(direct + X + 1);
writeBank(absolute + 0, lo(A));
L writeBank(absolute + 1, hi(A));
}
auto WDC65816::instructionIndirectIndexedWrite8() -> void {
dp = fetch();
uint8 direct = fetch();
idle2();
aa.l = readDirect(dp + 0);
aa.h = readDirect(dp + 1);
uint16 absolute = readDirect(direct + 0);
hi(absolute) = readDirect(direct + 1);
idle();
L writeBank(aa.w + r.y.w, r.a.l);
L writeBank(absolute + Y, lo(A));
}
auto WDC65816::instructionIndirectIndexedWrite16() -> void {
dp = fetch();
uint8 direct = fetch();
idle2();
aa.l = readDirect(dp + 0);
aa.h = readDirect(dp + 1);
uint16 absolute = readDirect(direct + 0);
hi(absolute) = readDirect(direct + 1);
idle();
writeBank(aa.w + r.y.w + 0, r.a.l);
L writeBank(aa.w + r.y.w + 1, r.a.h);
writeBank(absolute + Y + 0, lo(A));
L writeBank(absolute + Y + 1, hi(A));
}
auto WDC65816::instructionIndirectLongWrite8(uint16 index) -> void {
dp = fetch();
uint8 direct = fetch();
idle2();
aa.l = readDirectN(dp + 0);
aa.h = readDirectN(dp + 1);
aa.b = readDirectN(dp + 2);
L write(aa.d + index, r.a.l);
uint24 address = readDirectN(direct + 0);
hi(address) = readDirectN(direct + 1);
db(address) = readDirectN(direct + 2);
L write(address + index, lo(A));
}
auto WDC65816::instructionIndirectLongWrite16(uint16 index) -> void {
dp = fetch();
uint8 direct = fetch();
idle2();
aa.l = readDirectN(dp + 0);
aa.h = readDirectN(dp + 1);
aa.b = readDirectN(dp + 2);
write(aa.d + index + 0, r.a.l);
L write(aa.d + index + 1, r.a.h);
uint24 address = readDirectN(direct + 0);
hi(address) = readDirectN(direct + 1);
db(address) = readDirectN(direct + 2);
write(address + index + 0, lo(A));
L write(address + index + 1, hi(A));
}
auto WDC65816::instructionStackWrite8() -> void {
sp = fetch();
uint8 stack = fetch();
idle();
L writeStack(sp, r.a.l);
L writeStack(stack, lo(A));
}
auto WDC65816::instructionStackWrite16() -> void {
sp = fetch();
uint8 stack = fetch();
idle();
writeStack(sp + 0, r.a.l);
L writeStack(sp + 1, r.a.h);
writeStack(stack + 0, lo(A));
L writeStack(stack + 1, hi(A));
}
auto WDC65816::instructionIndirectStackWrite8() -> void {
sp = fetch();
uint8 stack = fetch();
idle();
aa.l = readStack(sp + 0);
aa.h = readStack(sp + 1);
uint16 absolute = readStack(stack + 0);
hi(absolute) = readStack(stack + 1);
idle();
L writeBank(aa.w + r.y.w, r.a.l);
L writeBank(absolute + Y, lo(A));
}
auto WDC65816::instructionIndirectStackWrite16() -> void {
sp = fetch();
uint8 stack = fetch();
idle();
aa.l = readStack(sp + 0);
aa.h = readStack(sp + 1);
uint16 absolute = readStack(stack + 0);
hi(absolute) = readStack(stack + 1);
idle();
writeBank(aa.w + r.y.w + 0, r.a.l);
L writeBank(aa.w + r.y.w + 1, r.a.h);
writeBank(absolute + Y + 0, lo(A));
L writeBank(absolute + Y + 1, hi(A));
}

View File

@ -16,35 +16,29 @@ auto WDC65816::idleIRQ() -> void {
}
auto WDC65816::idle2() -> void {
if(DL != 0x00) {
idle();
}
if(lo(D)) idle();
}
auto WDC65816::idle4(uint16 x, uint16 y) -> void {
if(!XF || (x & 0xff00) != (y & 0xff00)) {
idle();
}
if(!XF || hi(x) != hi(y)) idle();
}
auto WDC65816::idle6(uint16 addr) -> void {
if(EF && (PC & 0xff00) != (addr & 0xff00)) {
idle();
}
if(EF && hi(PC) != hi(addr)) idle();
}
auto WDC65816::fetch() -> uint8 {
return read(PCB << 16 | PCW++);
return read(db(PC) << 16 | aa(PC)++);
}
auto WDC65816::pull() -> uint8 {
EF ? SL++ : S++;
EF ? lo(S)++ : S++;
return read(S);
}
auto WDC65816::push(uint8 data) -> void {
write(S, data);
EF ? SL-- : S--;
EF ? lo(S)-- : S--;
}
auto WDC65816::pullN() -> uint8 {
@ -56,12 +50,12 @@ auto WDC65816::pushN(uint8 data) -> void {
}
auto WDC65816::readDirect(uint addr) -> uint8 {
if(EF && !DL) return read(D | uint8(addr));
if(EF && !lo(D)) return read(D | uint8(addr));
return read(uint16(D + addr));
}
auto WDC65816::writeDirect(uint addr, uint8 data) -> void {
if(EF && !DL) return write(D | uint8(addr), data);
if(EF && !lo(D)) return write(D | uint8(addr), data);
write(uint16(D + addr), data);
}

View File

@ -1,12 +1,13 @@
auto WDC65816::serialize(serializer& s) -> void {
s.integer(r.pc.d);
s.integer(r.pc);
s.integer(r.a.w);
s.integer(r.x.w);
s.integer(r.y.w);
s.integer(r.z.w);
s.integer(r.s.w);
s.integer(r.d.w);
s.integer(r.a);
s.integer(r.x);
s.integer(r.y);
s.integer(r.z);
s.integer(r.s);
s.integer(r.d);
s.integer(r.b);
s.integer(r.p.c);
s.integer(r.p.z);
@ -16,17 +17,11 @@ auto WDC65816::serialize(serializer& s) -> void {
s.integer(r.p.m);
s.integer(r.p.v);
s.integer(r.p.n);
s.integer(r.db);
s.integer(r.e);
s.integer(r.irq);
s.integer(r.wai);
s.integer(r.stp);
s.integer(r.mdr);
s.integer(r.vector);
s.integer(aa.d);
s.integer(rd.d);
s.integer(sp);
s.integer(dp);
}

View File

@ -3,15 +3,16 @@
namespace Processor {
#define A r.a.w
#define X r.x.w
#define Y r.y.w
#define Z r.z.w
#define S r.s.w
#define D r.d.w
#define B r.db
#define PC r.pc
#define A r.a
#define X r.x
#define Y r.y
#define Z r.z
#define S r.s
#define D r.d
#define B r.b
#define P r.p
#define PC r.pc.d
#define CF r.p.c
#define ZF r.p.z
#define IF r.p.i
@ -21,34 +22,16 @@ namespace Processor {
#define VF r.p.v
#define NF r.p.n
#define EF r.e
#define AW r.a.w
#define AH r.a.h
#define AL r.a.l
#define XW r.x.w
#define XH r.x.h
#define XL r.x.l
#define YW r.y.w
#define YH r.y.h
#define YL r.y.l
#define ZW r.x.w
#define ZH r.z.h
#define ZL r.z.l
#define SH r.s.h
#define SL r.s.l
#define DH r.d.h
#define DL r.d.l
#define PCB r.pc.b
#define PCW r.pc.w
#define PCH r.pc.h
#define PCL r.pc.l
#define E if(r.e)
#define N if(!r.e)
#define L lastCycle();
#define call(op) (this->*op)()
#define LO(n) n.byte(0)
#define HI(n) n.byte(1)
#define lo(n) n.byte(0)
#define hi(n) n.byte(1)
#define db(n) n.byte(2)
#define aa(n) n.bits(0,15)
#define alu(...) (this->*op)(__VA_ARGS__)
#include "memory.cpp"
#include "algorithms.cpp"
@ -77,6 +60,7 @@ auto WDC65816::power() -> void {
r.vector = 0xfffc; //reset vector address
}
#undef PC
#undef A
#undef X
#undef Y
@ -85,7 +69,7 @@ auto WDC65816::power() -> void {
#undef D
#undef B
#undef P
#undef PC
#undef CF
#undef ZF
#undef IF
@ -95,36 +79,18 @@ auto WDC65816::power() -> void {
#undef VF
#undef NF
#undef EF
#undef AW
#undef AH
#undef AL
#undef XW
#undef XH
#undef XL
#undef YW
#undef YH
#undef YL
#undef ZW
#undef ZH
#undef ZL
#undef SH
#undef SL
#undef DH
#undef DL
#undef PCB
#undef PCW
#undef PCH
#undef PCL
#undef E
#undef N
#undef L
#undef call
#undef LO
#undef HI
#undef lo
#undef hi
#undef db
#undef aa
#undef alu
//#include "disassembler.cpp"
#include "serialization.cpp"
#include "disassembler.cpp"
}

View File

@ -7,8 +7,6 @@
namespace Processor {
struct WDC65816 {
using fp = auto (WDC65816::*)() -> void;
virtual auto idle() -> void = 0;
virtual auto read(uint24 addr) -> uint8 = 0;
virtual auto write(uint24 addr, uint8 data) -> void = 0;
@ -41,72 +39,75 @@ struct WDC65816 {
inline auto writeStack(uint addr, uint8 data) -> void;
//algorithms.cpp
auto algorithmADC8() ->void;
auto algorithmADC16() -> void;
auto algorithmAND8() -> void;
auto algorithmAND16() -> void;
auto algorithmASL8() -> void;
auto algorithmASL16() -> void;
auto algorithmBIT8() -> void;
auto algorithmBIT16() -> void;
auto algorithmCMP8() -> void;
auto algorithmCMP16() -> void;
auto algorithmCPX8() -> void;
auto algorithmCPX16() -> void;
auto algorithmCPY8() -> void;
auto algorithmCPY16() -> void;
auto algorithmDEC8() -> void;
auto algorithmDEC16() -> void;
auto algorithmEOR8() -> void;
auto algorithmEOR16() -> void;
auto algorithmINC8() -> void;
auto algorithmINC16() -> void;
auto algorithmLDA8() -> void;
auto algorithmLDA16() -> void;
auto algorithmLDX8() -> void;
auto algorithmLDX16() -> void;
auto algorithmLDY8() -> void;
auto algorithmLDY16() -> void;
auto algorithmLSR8() -> void;
auto algorithmLSR16() -> void;
auto algorithmORA8() -> void;
auto algorithmORA16() -> void;
auto algorithmROL8() -> void;
auto algorithmROL16() -> void;
auto algorithmROR8() -> void;
auto algorithmROR16() -> void;
auto algorithmSBC8() -> void;
auto algorithmSBC16() -> void;
auto algorithmTRB8() -> void;
auto algorithmTRB16() -> void;
auto algorithmTSB8() -> void;
auto algorithmTSB16() -> void;
using alu8 = auto (WDC65816::*)(uint8) -> uint8;
using alu16 = auto (WDC65816::*)(uint16) -> uint16;
auto algorithmADC8(uint8) -> uint8;
auto algorithmADC16(uint16) -> uint16;
auto algorithmAND8(uint8) -> uint8;
auto algorithmAND16(uint16) -> uint16;
auto algorithmASL8(uint8) -> uint8;
auto algorithmASL16(uint16) -> uint16;
auto algorithmBIT8(uint8) -> uint8;
auto algorithmBIT16(uint16) -> uint16;
auto algorithmCMP8(uint8) -> uint8;
auto algorithmCMP16(uint16) -> uint16;
auto algorithmCPX8(uint8) -> uint8;
auto algorithmCPX16(uint16) -> uint16;
auto algorithmCPY8(uint8) -> uint8;
auto algorithmCPY16(uint16) -> uint16;
auto algorithmDEC8(uint8) -> uint8;
auto algorithmDEC16(uint16) -> uint16;
auto algorithmEOR8(uint8) -> uint8;
auto algorithmEOR16(uint16) -> uint16;
auto algorithmINC8(uint8) -> uint8;
auto algorithmINC16(uint16) -> uint16;
auto algorithmLDA8(uint8) -> uint8;
auto algorithmLDA16(uint16) -> uint16;
auto algorithmLDX8(uint8) -> uint8;
auto algorithmLDX16(uint16) -> uint16;
auto algorithmLDY8(uint8) -> uint8;
auto algorithmLDY16(uint16) -> uint16;
auto algorithmLSR8(uint8) -> uint8;
auto algorithmLSR16(uint16) -> uint16;
auto algorithmORA8(uint8) -> uint8;
auto algorithmORA16(uint16) -> uint16;
auto algorithmROL8(uint8) -> uint8;
auto algorithmROL16(uint16) -> uint16;
auto algorithmROR8(uint8) -> uint8;
auto algorithmROR16(uint16) -> uint16;
auto algorithmSBC8(uint8) -> uint8;
auto algorithmSBC16(uint16) -> uint16;
auto algorithmTRB8(uint8) -> uint8;
auto algorithmTRB16(uint16) -> uint16;
auto algorithmTSB8(uint8) -> uint8;
auto algorithmTSB16(uint16) -> uint16;
//instructions-read.cpp
auto instructionImmediateRead8(fp) -> void;
auto instructionImmediateRead16(fp) -> void;
auto instructionBankRead8(fp) -> void;
auto instructionBankRead16(fp) -> void;
auto instructionBankRead8(fp, uint16) -> void;
auto instructionBankRead16(fp, uint16) -> void;
auto instructionLongRead8(fp, uint16 = 0) -> void;
auto instructionLongRead16(fp, uint16 = 0) -> void;
auto instructionDirectRead8(fp) -> void;
auto instructionDirectRead16(fp) -> void;
auto instructionDirectRead8(fp, uint16) -> void;
auto instructionDirectRead16(fp, uint16) -> void;
auto instructionIndirectRead8(fp) -> void;
auto instructionIndirectRead16(fp) -> void;
auto instructionIndexedIndirectRead8(fp) -> void;
auto instructionIndexedIndirectRead16(fp) -> void;
auto instructionIndirectIndexedRead8(fp) -> void;
auto instructionIndirectIndexedRead16(fp) -> void;
auto instructionIndirectLongRead8(fp, uint16 = 0) -> void;
auto instructionIndirectLongRead16(fp, uint16 = 0) -> void;
auto instructionStackRead8(fp) -> void;
auto instructionStackRead16(fp) -> void;
auto instructionIndirectStackRead8(fp) -> void;
auto instructionIndirectStackRead16(fp) -> void;
auto instructionImmediateRead8(alu8) -> void;
auto instructionImmediateRead16(alu16) -> void;
auto instructionBankRead8(alu8) -> void;
auto instructionBankRead16(alu16) -> void;
auto instructionBankRead8(alu8, uint16) -> void;
auto instructionBankRead16(alu16, uint16) -> void;
auto instructionLongRead8(alu8, uint16 = 0) -> void;
auto instructionLongRead16(alu16, uint16 = 0) -> void;
auto instructionDirectRead8(alu8) -> void;
auto instructionDirectRead16(alu16) -> void;
auto instructionDirectRead8(alu8, uint16) -> void;
auto instructionDirectRead16(alu16, uint16) -> void;
auto instructionIndirectRead8(alu8) -> void;
auto instructionIndirectRead16(alu16) -> void;
auto instructionIndexedIndirectRead8(alu8) -> void;
auto instructionIndexedIndirectRead16(alu16) -> void;
auto instructionIndirectIndexedRead8(alu8) -> void;
auto instructionIndirectIndexedRead16(alu16) -> void;
auto instructionIndirectLongRead8(alu8, uint16 = 0) -> void;
auto instructionIndirectLongRead16(alu16, uint16 = 0) -> void;
auto instructionStackRead8(alu8) -> void;
auto instructionStackRead16(alu16) -> void;
auto instructionIndirectStackRead8(alu8) -> void;
auto instructionIndirectStackRead16(alu16) -> void;
//instructions-write.cpp
auto instructionBankWrite8(uint16&) -> void;
@ -133,29 +134,19 @@ struct WDC65816 {
auto instructionIndirectStackWrite16() -> void;
//instructions-modify.cpp
auto instructionINCImplied8(uint16&) -> void;
auto instructionINCImplied16(uint16&) -> void;
auto instructionDECImplied8(uint16&) -> void;
auto instructionDECImplied16(uint16&) -> void;
auto instructionASLImplied8() -> void;
auto instructionASLImplied16() -> void;
auto instructionLSRImplied8() -> void;
auto instructionLSRImplied16() -> void;
auto instructionROLImplied8() -> void;
auto instructionROLImplied16() -> void;
auto instructionRORImplied8() -> void;
auto instructionRORImplied16() -> void;
auto instructionBankModify8(fp op) -> void;
auto instructionBankModify16(fp op) -> void;
auto instructionBankIndexedModify8(fp op) -> void;
auto instructionBankIndexedModify16(fp op) -> void;
auto instructionDirectModify8(fp op) -> void;
auto instructionDirectModify16(fp op) -> void;
auto instructionDirectIndexedModify8(fp op) -> void;
auto instructionDirectIndexedModify16(fp op) -> void;
auto instructionImpliedModify8(alu8, uint16&) -> void;
auto instructionImpliedModify16(alu16, uint16&) -> void;
auto instructionBankModify8(alu8) -> void;
auto instructionBankModify16(alu16) -> void;
auto instructionBankIndexedModify8(alu8) -> void;
auto instructionBankIndexedModify16(alu16) -> void;
auto instructionDirectModify8(alu8) -> void;
auto instructionDirectModify16(alu16) -> void;
auto instructionDirectIndexedModify8(alu8) -> void;
auto instructionDirectIndexedModify16(alu16) -> void;
//instructions-pc.cpp
auto instructionBranch(bool take = 1) -> void;
auto instructionBranch(bool = 1) -> void;
auto instructionBRL() -> void;
auto instructionJMPShort() -> void;
auto instructionJMPLong() -> void;
@ -175,14 +166,14 @@ struct WDC65816 {
auto instructionNOP() -> void;
auto instructionWDM() -> void;
auto instructionXBA() -> void;
auto instructionBlockMove8(int adjust) -> void;
auto instructionBlockMove16(int adjust) -> void;
auto instructionBlockMove8(int) -> void;
auto instructionBlockMove16(int) -> void;
auto instructionInterrupt(uint16) -> void;
auto instructionSTP() -> void;
auto instructionWAI() -> void;
auto instructionXCE() -> void;
auto instructionSetFlag(bool& flag) -> void;
auto instructionClearFlag(bool& flag) -> void;
auto instructionSetFlag(bool&) -> void;
auto instructionClearFlag(bool&) -> void;
auto instructionREP() -> void;
auto instructionSEP() -> void;
auto instructionTransfer8(uint16&, uint16&) -> void;
@ -191,12 +182,9 @@ struct WDC65816 {
auto instructionTSX8() -> void;
auto instructionTSX16() -> void;
auto instructionTXS() -> void;
auto instructionPush8(uint16&) -> void;
auto instructionPush16(uint16&) -> void;
auto instructionPush8(uint8) -> void;
auto instructionPush16(uint16) -> void;
auto instructionPHD() -> void;
auto instructionPHB() -> void;
auto instructionPHK() -> void;
auto instructionPHP() -> void;
auto instructionPull8(uint16&) -> void;
auto instructionPull16(uint16&) -> void;
auto instructionPLD() -> void;
@ -247,41 +235,24 @@ struct WDC65816 {
}
};
union Word {
Word() : w(0) {}
uint16 w;
struct { uint8_t order_lsb2(l, h); };
};
union Long {
Long() : d(0) {}
uint32 d;
struct { uint16_t order_lsb2(w, wh); };
struct { uint8_t order_lsb4(l, h, b, bh); };
};
struct Registers {
Long pc;
Word a;
Word x;
Word y;
Word z;
Word s;
Word d;
uint24 pc;
uint16 a;
uint16 x;
uint16 y;
uint16 z;
uint16 s;
uint16 d;
uint8 b;
Flags p;
uint8 db = 0;
bool e = false;
bool irq = false; //IRQ pin (0 = low, 1 = trigger)
bool wai = false; //raised during wai, cleared after interrupt triggered
bool stp = false; //raised during stp, never cleared
uint8 mdr = 0; //memory data register
uint16 vector = 0; //interrupt vector address
};
Registers r;
Long aa, rd;
uint8 sp, dp;
bool irq = false; //IRQ pin (0 = low, 1 = trigger)
bool wai = false; //raised during wai, cleared after interrupt triggered
bool stp = false; //raised during stp, never cleared
uint8 mdr; //memory data register
uint16 vector; //interrupt vector address
} r;
};
}

View File

@ -98,9 +98,8 @@ auto SA1::writeIO(uint24 addr, uint8 data) -> void {
//(CCNT) SA-1 control
case 0x2200: {
if(mmio.sa1_resb && !(data & 0x80)) {
//reset SA-1 CPU
r.pc.w = mmio.crv;
r.pc.b = 0x00;
//reset SA-1 CPU (PC bank set to 0x00)
r.pc = mmio.crv;
}
mmio.sa1_irq = (data & 0x80);

View File

@ -35,16 +35,15 @@ auto SA1::main() -> void {
//override R65816::interrupt() to support SA-1 vector location IO registers
auto SA1::interrupt() -> void {
read(r.pc.d);
read(r.pc);
idle();
if(!r.e) push(r.pc.b);
push(r.pc.h);
push(r.pc.l);
if(!r.e) push(r.pc >> 16);
push(r.pc >> 8);
push(r.pc >> 0);
push(r.e ? r.p & ~0x10 : r.p);
r.p.i = 1;
r.p.d = 0;
r.pc.w = r.vector;
r.pc.b = 0x00;
r.pc = r.vector; //PC bank set to 0x00
}
auto SA1::lastCycle() -> void {

View File

@ -45,16 +45,23 @@ auto CPU::main() -> void {
} else if(status.powerPending) {
status.powerPending = false;
step(186);
r.pc.l = bus.read(0xfffc, r.mdr);
r.pc.h = bus.read(0xfffd, r.mdr);
r.pc.byte(0) = bus.read(0xfffc, r.mdr);
r.pc.byte(1) = bus.read(0xfffd, r.mdr);
}
}
#if 1
static uint counter = 0;
if(++counter < 40) print(disassemble(), "\n");
#endif
instruction();
}
auto CPU::load(Markup::Node node) -> bool {
version = max(1, min(2, node["cpu/version"].natural()));
version = node["cpu/version"].natural();
if(version < 1) version = 1;
if(version > 2) version = 2;
return true;
}