diff --git a/higan/emulator/emulator.hpp b/higan/emulator/emulator.hpp index 8c167655..1b7e9a53 100644 --- a/higan/emulator/emulator.hpp +++ b/higan/emulator/emulator.hpp @@ -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 { diff --git a/higan/processor/arm/instructions-arm.cpp b/higan/processor/arm/instructions-arm.cpp index 0346a3f5..d4af7bfc 100644 --- a/higan/processor/arm/instructions-arm.cpp +++ b/higan/processor/arm/instructions-arm.cpp @@ -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; diff --git a/higan/processor/wdc65816/algorithms.cpp b/higan/processor/wdc65816/algorithms.cpp index b9bbb604..df41d35a 100644 --- a/higan/processor/wdc65816/algorithms.cpp +++ b/higan/processor/wdc65816/algorithms.cpp @@ -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; } diff --git a/higan/processor/wdc65816/disassembler.cpp b/higan/processor/wdc65816/disassembler.cpp index fc66d3ed..4dfdca26 100644 --- a/higan/processor/wdc65816/disassembler.cpp +++ b/higan/processor/wdc65816/disassembler.cpp @@ -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) { diff --git a/higan/processor/wdc65816/instruction.cpp b/higan/processor/wdc65816/instruction.cpp index 5a3973a4..75ac81d8 100644 --- a/higan/processor/wdc65816/instruction.cpp +++ b/higan/processor/wdc65816/instruction.cpp @@ -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 } diff --git a/higan/processor/wdc65816/instruction.hpp b/higan/processor/wdc65816/instruction.hpp new file mode 100644 index 00000000..27b3246b --- /dev/null +++ b/higan/processor/wdc65816/instruction.hpp @@ -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) + } diff --git a/higan/processor/wdc65816/instructions-misc.cpp b/higan/processor/wdc65816/instructions-misc.cpp index e6443b67..7a20111c 100644 --- a/higan/processor/wdc65816/instructions-misc.cpp +++ b/higan/processor/wdc65816/instructions-misc.cpp @@ -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; } diff --git a/higan/processor/wdc65816/instructions-modify.cpp b/higan/processor/wdc65816/instructions-modify.cpp index 18f5370d..0f3160b8 100644 --- a/higan/processor/wdc65816/instructions-modify.cpp +++ b/higan/processor/wdc65816/instructions-modify.cpp @@ -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)); } diff --git a/higan/processor/wdc65816/instructions-pc.cpp b/higan/processor/wdc65816/instructions-pc.cpp index e1c4ea18..506f12d2 100644 --- a/higan/processor/wdc65816/instructions-pc.cpp +++ b/higan/processor/wdc65816/instructions-pc.cpp @@ -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; } diff --git a/higan/processor/wdc65816/instructions-read.cpp b/higan/processor/wdc65816/instructions-read.cpp index 3fd9a5c5..7ae05a7a 100644 --- a/higan/processor/wdc65816/instructions-read.cpp +++ b/higan/processor/wdc65816/instructions-read.cpp @@ -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); } diff --git a/higan/processor/wdc65816/instructions-write.cpp b/higan/processor/wdc65816/instructions-write.cpp index cce3ca0d..663b4d31 100644 --- a/higan/processor/wdc65816/instructions-write.cpp +++ b/higan/processor/wdc65816/instructions-write.cpp @@ -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)); } diff --git a/higan/processor/wdc65816/memory.cpp b/higan/processor/wdc65816/memory.cpp index 75b80b0c..b6b3fd7e 100644 --- a/higan/processor/wdc65816/memory.cpp +++ b/higan/processor/wdc65816/memory.cpp @@ -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); } diff --git a/higan/processor/wdc65816/serialization.cpp b/higan/processor/wdc65816/serialization.cpp index 22410cb8..6ce48002 100644 --- a/higan/processor/wdc65816/serialization.cpp +++ b/higan/processor/wdc65816/serialization.cpp @@ -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); } diff --git a/higan/processor/wdc65816/wdc65816.cpp b/higan/processor/wdc65816/wdc65816.cpp index 2a49c4bf..68618969 100644 --- a/higan/processor/wdc65816/wdc65816.cpp +++ b/higan/processor/wdc65816/wdc65816.cpp @@ -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" } diff --git a/higan/processor/wdc65816/wdc65816.hpp b/higan/processor/wdc65816/wdc65816.hpp index de8e7779..7ecbdd89 100644 --- a/higan/processor/wdc65816/wdc65816.hpp +++ b/higan/processor/wdc65816/wdc65816.hpp @@ -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; }; } diff --git a/higan/sfc/coprocessor/sa1/io.cpp b/higan/sfc/coprocessor/sa1/io.cpp index 7cfe6e41..2ba39f85 100644 --- a/higan/sfc/coprocessor/sa1/io.cpp +++ b/higan/sfc/coprocessor/sa1/io.cpp @@ -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); diff --git a/higan/sfc/coprocessor/sa1/sa1.cpp b/higan/sfc/coprocessor/sa1/sa1.cpp index 756160c9..9053ba45 100644 --- a/higan/sfc/coprocessor/sa1/sa1.cpp +++ b/higan/sfc/coprocessor/sa1/sa1.cpp @@ -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 { diff --git a/higan/sfc/cpu/cpu.cpp b/higan/sfc/cpu/cpu.cpp index 1bbb6f95..c34da70d 100644 --- a/higan/sfc/cpu/cpu.cpp +++ b/higan/sfc/cpu/cpu.cpp @@ -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; }