From b73d918776fda9e710a28a8f86b8de8eb3c32df5 Mon Sep 17 00:00:00 2001 From: Tim Allen Date: Thu, 15 Jun 2017 01:55:55 +1000 Subject: [PATCH] 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` 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. --- higan/emulator/emulator.hpp | 4 +- higan/processor/arm/instructions-arm.cpp | 16 + higan/processor/wdc65816/algorithms.cpp | 468 ++++++++++-------- higan/processor/wdc65816/disassembler.cpp | 43 +- higan/processor/wdc65816/instruction.cpp | 323 ++---------- higan/processor/wdc65816/instruction.hpp | 258 ++++++++++ .../processor/wdc65816/instructions-misc.cpp | 214 ++++---- .../wdc65816/instructions-modify.cpp | 198 +++----- higan/processor/wdc65816/instructions-pc.cpp | 146 +++--- .../processor/wdc65816/instructions-read.cpp | 280 +++++------ .../processor/wdc65816/instructions-write.cpp | 186 +++---- higan/processor/wdc65816/memory.cpp | 22 +- higan/processor/wdc65816/serialization.cpp | 23 +- higan/processor/wdc65816/wdc65816.cpp | 78 +-- higan/processor/wdc65816/wdc65816.hpp | 225 ++++----- higan/sfc/coprocessor/sa1/io.cpp | 5 +- higan/sfc/coprocessor/sa1/sa1.cpp | 11 +- higan/sfc/cpu/cpu.cpp | 13 +- 18 files changed, 1211 insertions(+), 1302 deletions(-) create mode 100644 higan/processor/wdc65816/instruction.hpp 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; }