diff --git a/higan/data/higan.Manifest b/higan/data/higan.Manifest
index 2796a434..095d34fa 100644
--- a/higan/data/higan.Manifest
+++ b/higan/data/higan.Manifest
@@ -6,4 +6,9 @@
+
+
+ false
+
+
diff --git a/higan/data/higan.plist b/higan/data/higan.plist
index 53d81b52..6d59f131 100644
--- a/higan/data/higan.plist
+++ b/higan/data/higan.plist
@@ -11,7 +11,7 @@
CFBundleIconFile
higan.icns
NSHighResolutionCapable
-
+
NSSupportsAutomaticGraphicsSwitching
diff --git a/higan/emulator/emulator.hpp b/higan/emulator/emulator.hpp
index d1a2855a..c13bff9e 100644
--- a/higan/emulator/emulator.hpp
+++ b/higan/emulator/emulator.hpp
@@ -12,7 +12,7 @@ using namespace nall;
namespace Emulator {
static const string Name = "higan";
- static const string Version = "103.26";
+ static const string Version = "103.27";
static const string Author = "byuu";
static const string License = "GPLv3";
static const string Website = "http://byuu.org/";
diff --git a/higan/gba/GNUmakefile b/higan/gba/GNUmakefile
index 31c9c3e8..df590008 100644
--- a/higan/gba/GNUmakefile
+++ b/higan/gba/GNUmakefile
@@ -1,4 +1,4 @@
-processors += arm
+processors += arm arm7tdmi
objects += gba-memory gba-interface gba-system
objects += gba-cartridge gba-player
diff --git a/higan/gba/cpu/bus.cpp b/higan/gba/cpu/bus.cpp
index 962e4637..fb6b8d96 100644
--- a/higan/gba/cpu/bus.cpp
+++ b/higan/gba/cpu/bus.cpp
@@ -1,8 +1,8 @@
-auto CPU::_idle() -> void {
+auto CPU::sleep() -> void {
prefetchStep(1);
}
-auto CPU::_read(uint mode, uint32 addr) -> uint32 {
+auto CPU::get(uint mode, uint32 addr) -> uint32 {
uint clocks = _wait(mode, addr);
uint word = pipeline.fetch.instruction;
@@ -35,7 +35,7 @@ auto CPU::_read(uint mode, uint32 addr) -> uint32 {
return word;
}
-auto CPU::_write(uint mode, uint32 addr, uint32 word) -> void {
+auto CPU::set(uint mode, uint32 addr, uint32 word) -> void {
uint clocks = _wait(mode, addr);
if(addr >= 0x1000'0000) {
diff --git a/higan/gba/cpu/cpu.hpp b/higan/gba/cpu/cpu.hpp
index 8d3e3870..344e7756 100644
--- a/higan/gba/cpu/cpu.hpp
+++ b/higan/gba/cpu/cpu.hpp
@@ -38,9 +38,9 @@ struct CPU : Processor::ARM, Thread, IO {
auto prefetchRead() -> uint16;
//bus.cpp
- auto _idle() -> void override;
- auto _read(uint mode, uint32 addr) -> uint32 override;
- auto _write(uint mode, uint32 addr, uint32 word) -> void override;
+ auto sleep() -> void override;
+ auto get(uint mode, uint32 addr) -> uint32 override;
+ auto set(uint mode, uint32 addr, uint32 word) -> void override;
auto _wait(uint mode, uint32 addr) -> uint;
//io.cpp
diff --git a/higan/gba/cpu/dma.cpp b/higan/gba/cpu/dma.cpp
index 25dc6f18..2fe7a8e2 100644
--- a/higan/gba/cpu/dma.cpp
+++ b/higan/gba/cpu/dma.cpp
@@ -27,7 +27,7 @@ auto CPU::DMA::transfer() -> void {
uint32 addr = latch.source;
if(mode & Word) addr &= ~3;
if(mode & Half) addr &= ~1;
- data = cpu._read(mode, addr);
+ data = cpu.get(mode, addr);
}
if(latch.target < 0x0200'0000) {
@@ -36,7 +36,7 @@ auto CPU::DMA::transfer() -> void {
uint32 addr = latch.target;
if(mode & Word) addr &= ~3;
if(mode & Half) addr &= ~1;
- cpu._write(mode, addr, data);
+ cpu.set(mode, addr, data);
}
switch(sourceMode) {
diff --git a/higan/gba/gba.hpp b/higan/gba/gba.hpp
index dab846e6..287e9d62 100644
--- a/higan/gba/gba.hpp
+++ b/higan/gba/gba.hpp
@@ -8,6 +8,7 @@
#include
#include
+#include
namespace GameBoyAdvance {
#define platform Emulator::platform
diff --git a/higan/processor/GNUmakefile b/higan/processor/GNUmakefile
index aa3da06c..6e961afd 100644
--- a/higan/processor/GNUmakefile
+++ b/higan/processor/GNUmakefile
@@ -1,6 +1,7 @@
processors := $(call unique,$(processors))
objects += $(if $(findstring arm,$(processors)),processor-arm)
+objects += $(if $(findstring arm7tdmi,$(processors)),processor-arm7tdmi)
objects += $(if $(findstring gsu,$(processors)),processor-gsu)
objects += $(if $(findstring hg51b,$(processors)),processor-hg51b)
objects += $(if $(findstring huc6280,$(processors)),processor-huc6280)
@@ -13,15 +14,16 @@ objects += $(if $(findstring v30mz,$(processors)),processor-v30mz)
objects += $(if $(findstring wdc65816,$(processors)),processor-wdc65816)
objects += $(if $(findstring z80,$(processors)),processor-z80)
-obj/processor-arm.o: processor/arm/arm.cpp $(call rwildcard,processor/arm)
-obj/processor-gsu.o: processor/gsu/gsu.cpp $(call rwildcard,processor/gsu)
-obj/processor-hg51b.o: processor/hg51b/hg51b.cpp $(call rwildcard,processor/hg51b)
-obj/processor-huc6280.o: processor/huc6280/huc6280.cpp $(call rwildcard,processor/huc6280)
-obj/processor-lr35902.o: processor/lr35902/lr35902.cpp $(call rwildcard,processor/lr35902)
-obj/processor-m68k.o: processor/m68k/m68k.cpp $(call rwildcard,processor/m68k)
-obj/processor-mos6502.o: processor/mos6502/mos6502.cpp $(call rwildcard,processor/mos6502)
-obj/processor-spc700.o: processor/spc700/spc700.cpp $(call rwildcard,processor/spc700)
-obj/processor-upd96050.o: processor/upd96050/upd96050.cpp $(call rwildcard,processor/upd96050)
-obj/processor-v30mz.o: processor/v30mz/v30mz.cpp $(call rwildcard,processor/v30mz)
-obj/processor-wdc65816.o: processor/wdc65816/wdc65816.cpp $(call rwildcard,processor/wdc65816)
-obj/processor-z80.o: processor/z80/z80.cpp $(call rwildcard,processor/z80)
+obj/processor-arm.o: processor/arm/arm.cpp $(call rwildcard,processor/arm/)
+obj/processor-arm7tdmi.o: processor/arm7tdmi/arm7tdmi.cpp $(call rwildcard,processor/arm7tdmi/)
+obj/processor-gsu.o: processor/gsu/gsu.cpp $(call rwildcard,processor/gsu/)
+obj/processor-hg51b.o: processor/hg51b/hg51b.cpp $(call rwildcard,processor/hg51b/)
+obj/processor-huc6280.o: processor/huc6280/huc6280.cpp $(call rwildcard,processor/huc6280/)
+obj/processor-lr35902.o: processor/lr35902/lr35902.cpp $(call rwildcard,processor/lr35902/)
+obj/processor-m68k.o: processor/m68k/m68k.cpp $(call rwildcard,processor/m68k/)
+obj/processor-mos6502.o: processor/mos6502/mos6502.cpp $(call rwildcard,processor/mos6502/)
+obj/processor-spc700.o: processor/spc700/spc700.cpp $(call rwildcard,processor/spc700/)
+obj/processor-upd96050.o: processor/upd96050/upd96050.cpp $(call rwildcard,processor/upd96050/)
+obj/processor-v30mz.o: processor/v30mz/v30mz.cpp $(call rwildcard,processor/v30mz/)
+obj/processor-wdc65816.o: processor/wdc65816/wdc65816.cpp $(call rwildcard,processor/wdc65816/)
+obj/processor-z80.o: processor/z80/z80.cpp $(call rwildcard,processor/z80/)
diff --git a/higan/processor/arm/arm.cpp b/higan/processor/arm/arm.cpp
index 9727929c..346497f5 100644
--- a/higan/processor/arm/arm.cpp
+++ b/higan/processor/arm/arm.cpp
@@ -13,7 +13,7 @@ namespace Processor {
auto ARM::power() -> void {
processor.power();
- vector(0x00000000, Processor::Mode::SVC);
+ interrupt(Processor::Mode::SVC, 0x00);
pipeline.reload = true;
pipeline.nonsequential = true;
crash = false;
@@ -31,16 +31,16 @@ auto ARM::exec() -> void {
auto ARM::idle() -> void {
pipeline.nonsequential = true;
- return _idle();
+ return sleep();
}
auto ARM::read(uint mode, uint32 addr) -> uint32 {
- return _read(mode, addr);
+ return get(mode, addr);
}
auto ARM::load(uint mode, uint32 addr) -> uint32 {
pipeline.nonsequential = true;
- uint32 word = _read(Load | mode, addr);
+ uint32 word = get(Load | mode, addr);
if(mode & Half) {
addr &= 1;
@@ -64,7 +64,7 @@ auto ARM::load(uint mode, uint32 addr) -> uint32 {
auto ARM::write(uint mode, uint32 addr, uint32 word) -> void {
pipeline.nonsequential = true;
- return _write(mode, addr, word);
+ return set(mode, addr, word);
}
auto ARM::store(uint mode, uint32 addr, uint32 word) -> void {
@@ -73,10 +73,10 @@ auto ARM::store(uint mode, uint32 addr, uint32 word) -> void {
if(mode & Half) { word &= 0xffff; word |= word << 16; }
if(mode & Byte) { word &= 0xff; word |= word << 8; word |= word << 16; }
- return _write(Store | mode, addr, word);
+ return set(Store | mode, addr, word);
}
-auto ARM::vector(uint32 addr, Processor::Mode mode) -> void {
+auto ARM::interrupt(Processor::Mode mode, uint32 addr) -> void {
auto psr = cpsr();
processor.setMode(mode);
spsr() = psr;
diff --git a/higan/processor/arm/arm.hpp b/higan/processor/arm/arm.hpp
index 7538d1aa..7f531041 100644
--- a/higan/processor/arm/arm.hpp
+++ b/higan/processor/arm/arm.hpp
@@ -25,9 +25,9 @@ struct ARM {
#include "disassembler.hpp"
virtual auto step(uint clocks) -> void = 0;
- virtual auto _idle() -> void = 0;
- virtual auto _read(uint mode, uint32 addr) -> uint32 = 0;
- virtual auto _write(uint mode, uint32 addr, uint32 word) -> void = 0;
+ virtual auto sleep() -> void = 0;
+ virtual auto get(uint mode, uint32 addr) -> uint32 = 0;
+ virtual auto set(uint mode, uint32 addr, uint32 word) -> void = 0;
//arm.cpp
auto power() -> void;
@@ -37,7 +37,7 @@ struct ARM {
auto load(uint mode, uint32 addr) -> uint32;
auto write(uint mode, uint32 addr, uint32 word) -> void;
auto store(uint mode, uint32 addr, uint32 word) -> void;
- auto vector(uint32 addr, Processor::Mode mode) -> void;
+ auto interrupt(Processor::Mode mode, uint32 addr) -> void;
//algorithms.cpp
auto condition(uint4 condition) -> bool;
diff --git a/higan/processor/arm/instructions-arm.cpp b/higan/processor/arm/instructions-arm.cpp
index 7697a1d6..df17e33f 100644
--- a/higan/processor/arm/instructions-arm.cpp
+++ b/higan/processor/arm/instructions-arm.cpp
@@ -598,5 +598,5 @@ auto ARM::arm_op_branch() {
auto ARM::arm_op_software_interrupt() {
uint24 immediate = instruction();
- vector(0x00000008, Processor::Mode::SVC);
+ interrupt(Processor::Mode::SVC, 0x08);
}
diff --git a/higan/processor/arm/instructions-thumb.cpp b/higan/processor/arm/instructions-thumb.cpp
index f012b825..b22a445a 100644
--- a/higan/processor/arm/instructions-thumb.cpp
+++ b/higan/processor/arm/instructions-thumb.cpp
@@ -328,7 +328,7 @@ auto ARM::thumb_op_move_multiple() {
auto ARM::thumb_op_software_interrupt() {
uint8 immediate = instruction();
- vector(0x00000008, Processor::Mode::SVC);
+ interrupt(Processor::Mode::SVC, 0x08);
}
//b{condition}
diff --git a/higan/processor/arm/registers.hpp b/higan/processor/arm/registers.hpp
index 724f9682..8b1ed074 100644
--- a/higan/processor/arm/registers.hpp
+++ b/higan/processor/arm/registers.hpp
@@ -55,13 +55,18 @@ struct Pipeline {
struct Processor {
enum class Mode : uint {
- USR = 0x10, //user
- FIQ = 0x11, //fast interrupt request
- IRQ = 0x12, //interrupt request
- SVC = 0x13, //supervisor (software interrupt)
- ABT = 0x17, //abort
- UND = 0x1b, //undefined
- SYS = 0x1f, //system
+ USR26 = 0x00, //26-bit user
+ FIQ26 = 0x01, //26-bit fast-interrupt
+ IRQ26 = 0x02, //26-bit interrupt
+ SVC26 = 0x03, //26-bit service
+
+ USR = 0x10, //user
+ FIQ = 0x11, //fast-interrupt
+ IRQ = 0x12, //interrupt
+ SVC = 0x13, //service
+ ABT = 0x17, //abort
+ UND = 0x1b, //undefined
+ SYS = 0x1f, //system
};
GPR r0, r1, r2, r3, r4, r5, r6, r7;
diff --git a/higan/processor/arm/step.cpp b/higan/processor/arm/step.cpp
index b6d4eb28..acbef5a9 100644
--- a/higan/processor/arm/step.cpp
+++ b/higan/processor/arm/step.cpp
@@ -33,7 +33,7 @@ auto ARM::stepARM() -> void {
stepPipeline();
if(processor.irqline && cpsr().i == 0) {
- vector(0x00000018, Processor::Mode::IRQ);
+ interrupt(Processor::Mode::IRQ, 0x18);
return;
}
@@ -90,8 +90,8 @@ auto ARM::stepTHUMB() -> void {
stepPipeline();
if(processor.irqline && cpsr().i == 0) {
- vector(0x00000018, Processor::Mode::IRQ);
- r(14) += 2;
+ interrupt(Processor::Mode::IRQ, 0x18);
+ r(14).data += 2;
return;
}
diff --git a/higan/processor/arm7tdmi/algorithms.cpp b/higan/processor/arm7tdmi/algorithms.cpp
new file mode 100644
index 00000000..c97bbbec
--- /dev/null
+++ b/higan/processor/arm7tdmi/algorithms.cpp
@@ -0,0 +1,96 @@
+auto ARM7TDMI::ADD(uint32 source, uint32 modify, bool carry, bool updateFlags) -> uint32 {
+ uint32 result = source + modify + carry;
+ if(updateFlags) {
+ uint32 overflow = ~(source ^ modify) & (source ^ result);
+ cpsr().v = 1 << 31 & (overflow);
+ cpsr().c = 1 << 31 & (overflow ^ source ^ modify ^ result);
+ cpsr().z = result == 0;
+ cpsr().n = result.bit(31);
+ }
+ return result;
+}
+
+auto ARM7TDMI::ASR(uint32 source, uint8 shift) -> uint32 {
+ carry = cpsr().c;
+ if(shift == 0) return source;
+ carry = shift > 32 ? source & 1 << 31 : source & 1 << shift - 1;
+ source = shift > 31 ? (int32)source >> 31 : (int32)source >> shift;
+ return source;
+}
+
+auto ARM7TDMI::BIT(uint32 result, bool updateFlags) -> uint32 {
+ if(updateFlags) {
+ cpsr().c = carry;
+ cpsr().z = result == 0;
+ cpsr().n = result.bit(31);
+ }
+ return result;
+}
+
+auto ARM7TDMI::LSL(uint32 source, uint8 shift) -> uint32 {
+ carry = cpsr().c;
+ if(shift == 0) return source;
+ carry = shift > 32 ? 0 : source & 1 << 32 - shift;
+ source = shift > 31 ? 0 : source << shift;
+ return source;
+}
+
+auto ARM7TDMI::LSR(uint32 source, uint8 shift) -> uint32 {
+ carry = cpsr().c;
+ if(shift == 0) return source;
+ carry = shift > 32 ? 0 : source & 1 << shift - 1;
+ source = shift > 31 ? 0 : source >> shift;
+ return source;
+}
+
+auto ARM7TDMI::MUL(uint32 product, uint32 multiplicand, uint32 multiplier, bool updateFlags) -> uint32 {
+ idle();
+ if(multiplier >> 8 && multiplier >> 8 != 0xffffff) idle();
+ if(multiplier >> 16 && multiplier >> 16 != 0xffff) idle();
+ if(multiplier >> 24 && multiplier >> 24 != 0xff) idle();
+ product += multiplicand * multiplier;
+ if(updateFlags) {
+ cpsr().z = product == 0;
+ cpsr().n = product.bit(31);
+ }
+ return product;
+}
+
+auto ARM7TDMI::ROR(uint32 source, uint8 shift) -> uint32 {
+ carry = cpsr().c;
+ if(shift == 0) return source;
+ if(shift &= 31) source = source << 32 - shift | source >> shift;
+ carry = source & 1 << 31;
+ return source;
+}
+
+auto ARM7TDMI::RRX(uint32 source) -> uint32 {
+ carry = source.bit(0);
+ return cpsr().c << 31 | source >> 1;
+}
+
+auto ARM7TDMI::SUB(uint32 source, uint32 modify, bool carry, bool updateFlags) -> uint32 {
+ return ADD(source, ~modify, carry, updateFlags);
+}
+
+auto ARM7TDMI::TST(uint4 mode) -> bool {
+ switch(mode) {
+ case 0: return cpsr().z == 1; //EQ (equal)
+ case 1: return cpsr().z == 0; //NE (not equal)
+ case 2: return cpsr().c == 1; //CS (carry set)
+ case 3: return cpsr().c == 0; //CC (carry clear)
+ case 4: return cpsr().n == 1; //MI (negative)
+ case 5: return cpsr().n == 0; //PL (positive)
+ case 6: return cpsr().v == 1; //VS (overflow)
+ case 7: return cpsr().v == 0; //VC (no overflow)
+ case 8: return cpsr().c == 1 && cpsr().z == 0; //HI (unsigned higher)
+ case 9: return cpsr().c == 0 || cpsr().z == 1; //LS (unsigned lower or same)
+ case 10: return cpsr().n == cpsr().v; //GE (signed greater than or equal)
+ case 11: return cpsr().n != cpsr().v; //LT (signed less than)
+ case 12: return cpsr().z == 0 && cpsr().n == cpsr().v; //GT (signed greater than)
+ case 13: return cpsr().z == 1 || cpsr().n != cpsr().v; //LE (signed less than or equal)
+ case 14: return true; //AL (always)
+ case 15: return false; //NV (never)
+ }
+ unreachable;
+}
diff --git a/higan/processor/arm7tdmi/arm7tdmi.cpp b/higan/processor/arm7tdmi/arm7tdmi.cpp
new file mode 100644
index 00000000..e4532f49
--- /dev/null
+++ b/higan/processor/arm7tdmi/arm7tdmi.cpp
@@ -0,0 +1,23 @@
+#include
+#include "arm7tdmi.hpp"
+
+namespace Processor {
+
+#include "registers.cpp"
+#include "memory.cpp"
+#include "algorithms.cpp"
+#include "instruction.cpp"
+#include "instructions-arm.cpp"
+#include "instructions-thumb.cpp"
+#include "serialization.cpp"
+
+auto ARM7TDMI::power() -> void {
+ processor = {};
+ interrupt(PSR::SVC, 0x00);
+ processor.r15.modify = [&] { pipeline.reload = true; };
+ pipeline = {};
+ carry = 0;
+ irq = 0;
+}
+
+}
diff --git a/higan/processor/arm7tdmi/arm7tdmi.hpp b/higan/processor/arm7tdmi/arm7tdmi.hpp
new file mode 100644
index 00000000..e92aa535
--- /dev/null
+++ b/higan/processor/arm7tdmi/arm7tdmi.hpp
@@ -0,0 +1,180 @@
+//ARMv3 (ARM60)
+//ARMv4 (ARM7TDMI)
+
+#pragma once
+
+namespace Processor {
+
+struct ARM7TDMI {
+ enum : uint {
+ Nonsequential = 1 << 0, //N cycle
+ Sequential = 1 << 1, //S cycle
+ Prefetch = 1 << 2, //instruction fetch
+ Byte = 1 << 3, // 8-bit access
+ Half = 1 << 4, //16-bit access
+ Word = 1 << 5, //32-bit access
+ Load = 1 << 6, //load operation
+ Store = 1 << 7, //store operation
+ Signed = 1 << 8, //sign-extend
+ };
+
+ virtual auto step(uint clocks) -> void = 0;
+ virtual auto sleep() -> void = 0;
+ virtual auto get(uint mode, uint32 address) -> uint32 = 0;
+ virtual auto set(uint mode, uint32 address, uint32 word) -> void = 0;
+
+ //arm7tdmi.cpp
+ auto power() -> void;
+
+ //registers.cpp
+ struct GPR;
+ struct PSR;
+ inline auto r(uint4) -> GPR&;
+ inline auto u(uint4) -> GPR&;
+ inline auto cpsr() -> PSR&;
+ inline auto spsr() -> PSR&;
+ inline auto privileged() const -> bool;
+ inline auto exception() const -> bool;
+
+ //memory.cpp
+ auto idle() -> void;
+ auto read(uint mode, uint32 address) -> uint32;
+ auto load(uint mode, uint32 address) -> uint32;
+ auto write(uint mode, uint32 address, uint32 word) -> void;
+ auto store(uint mode, uint32 address, uint32 word) -> void;
+
+ //algorithms.cpp
+ auto ADD(uint32, uint32, bool, bool = true) -> uint32;
+ auto ASR(uint32, uint8) -> uint32;
+ auto BIT(uint32, bool = true) -> uint32;
+ auto LSL(uint32, uint8) -> uint32;
+ auto LSR(uint32, uint8) -> uint32;
+ auto MUL(uint32, uint32, uint32, bool = true) -> uint32;
+ auto ROR(uint32, uint8) -> uint32;
+ auto RRX(uint32) -> uint32;
+ auto SUB(uint32, uint32, bool, bool = true) -> uint32;
+ auto TST(uint4) -> bool;
+
+ //instruction.cpp
+ auto fetch() -> void;
+ auto instruction() -> void;
+ auto interrupt(uint mode, uint32 address) -> void;
+
+ //instructions-arm.cpp
+ auto armALU(uint4 mode, uint4 target, uint4 source, uint32 data, bool save) -> void;
+
+ //instructions-thumb.cpp
+ auto thumbALU(uint4 mode, uint4 target, uint4 source) -> void;
+
+ //serialization.cpp
+ auto serialize(serializer&) -> void;
+
+ struct GPR {
+ inline operator uint32_t() const {
+ return data;
+ }
+
+ inline auto operator=(uint32 value) -> GPR& {
+ data = value;
+ if(modify) modify();
+ return *this;
+ }
+
+ uint32 data;
+ function void> modify;
+ };
+
+ struct PSR {
+ enum : uint {
+ USR = 0x10, //user
+ FIQ = 0x11, //fast interrupt request
+ IRQ = 0x12, //interrupt request
+ SVC = 0x13, //supervisor (software interrupt)
+ ABT = 0x17, //abort
+ UND = 0x1b, //undefined
+ SYS = 0x1f, //system
+ };
+
+ inline operator uint32_t() const {
+ return m << 0 | t << 5 | f << 6 | i << 7 | v << 28 | c << 29 | z << 30 | n << 31;
+ }
+
+ inline auto operator=(uint32 data) -> PSR& {
+ m = data.bits(0,4);
+ t = data.bit(5);
+ f = data.bit(6);
+ i = data.bit(7);
+ v = data.bit(28);
+ c = data.bit(29);
+ z = data.bit(30);
+ n = data.bit(31);
+ return *this;
+ }
+
+ //serialization.cpp
+ auto serialize(serializer&) -> void;
+
+ uint5 m; //mode
+ uint1 t; //thumb
+ uint1 f; //fiq
+ uint1 i; //irq
+ uint1 v; //overflow
+ uint1 c; //carry
+ uint1 z; //zero
+ uint1 n; //negative
+ };
+
+ struct Processor {
+ //serialization.cpp
+ auto serialize(serializer&) -> void;
+
+ GPR r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15;
+ PSR cpsr;
+
+ struct FIQ {
+ GPR r8, r9, r10, r11, r12, r13, r14;
+ PSR spsr;
+ } fiq;
+
+ struct IRQ {
+ GPR r13, r14;
+ PSR spsr;
+ } irq;
+
+ struct SVC {
+ GPR r13, r14;
+ PSR spsr;
+ } svc;
+
+ struct ABT {
+ GPR r13, r14;
+ PSR spsr;
+ } abt;
+
+ struct UND {
+ GPR r13, r14;
+ PSR spsr;
+ } und;
+ } processor;
+
+ struct Pipeline {
+ //serialization.cpp
+ auto serialize(serializer&) -> void;
+
+ struct Instruction {
+ uint32 address;
+ uint32 instruction;
+ };
+
+ uint1 reload = 1;
+ uint1 nonsequential = 1;
+ Instruction fetch;
+ Instruction decode;
+ Instruction execute;
+ } pipeline;
+
+ boolean carry;
+ boolean irq;
+};
+
+}
diff --git a/higan/processor/arm7tdmi/instruction.cpp b/higan/processor/arm7tdmi/instruction.cpp
new file mode 100644
index 00000000..fabbb47e
--- /dev/null
+++ b/higan/processor/arm7tdmi/instruction.cpp
@@ -0,0 +1,53 @@
+auto ARM7TDMI::fetch() -> void {
+ pipeline.execute = pipeline.decode;
+ pipeline.decode = pipeline.fetch;
+
+ uint sequential = Sequential;
+ if(pipeline.nonsequential) {
+ pipeline.nonsequential = false;
+ sequential = Nonsequential;
+ }
+
+ uint mask = !cpsr().t ? 3 : 1;
+ uint size = !cpsr().t ? Word : Half;
+
+ r(15).data += size >> 3;
+ pipeline.fetch.address = r(15) & ~mask;
+ pipeline.fetch.instruction = read(Prefetch | size | sequential, pipeline.fetch.address);
+}
+
+auto ARM7TDMI::instruction() -> void {
+ uint mask = !cpsr().t ? 3 : 1;
+ uint size = !cpsr().t ? Word : Half;
+
+ if(pipeline.reload) {
+ pipeline.reload = false;
+ r(15).data &= ~mask;
+ pipeline.fetch.address = r(15) & ~mask;
+ pipeline.fetch.instruction = read(Prefetch | size | Nonsequential, pipeline.fetch.address);
+ fetch();
+ }
+ fetch();
+
+ if(irq && !cpsr().i) {
+ interrupt(PSR::IRQ, 0x18);
+ if(cpsr().t) r(14).data += 2;
+ return;
+ }
+
+ if(!cpsr().t) {
+ if(!TST(pipeline.execute.instruction.bits(28,31))) return;
+ } else {
+ }
+}
+
+auto ARM7TDMI::interrupt(uint mode, uint32 address) -> void {
+ auto psr = cpsr();
+ cpsr().m = 0x10 | mode;
+ spsr() = psr;
+ cpsr().t = 0;
+ if(cpsr().m == PSR::FIQ) cpsr().f = 1;
+ cpsr().i = 1;
+ r(14) = pipeline.decode.address;
+ r(15) = address;
+}
diff --git a/higan/processor/arm7tdmi/instructions-arm.cpp b/higan/processor/arm7tdmi/instructions-arm.cpp
new file mode 100644
index 00000000..38813a4f
--- /dev/null
+++ b/higan/processor/arm7tdmi/instructions-arm.cpp
@@ -0,0 +1,24 @@
+auto ARM7TDMI::armALU(uint4 mode, uint4 target, uint4 source, uint32 data, bool save) -> void {
+ switch(mode) {
+ case 0: r(target) = BIT(r(source) & data, save); break; //AND
+ case 1: r(target) = BIT(r(source) ^ data, save); break; //EOR
+ case 2: r(target) = SUB(r(source), data, 1, save); break; //SUB
+ case 3: r(target) = SUB(data, r(source), 1, save); break; //RSB
+ case 4: r(target) = ADD(r(source), data, 0, save); break; //ADD
+ case 5: r(target) = ADD(r(source), data, cpsr().c, save); break; //ADC
+ case 6: r(target) = SUB(r(source), data, cpsr().c, save); break; //SBC
+ case 7: r(target) = SUB(data, r(source), cpsr().c, save); break; //RSC
+ case 8: BIT(r(source) & data, save); break; //TST
+ case 9: BIT(r(source) ^ data, save); break; //TEQ
+ case 10: SUB(r(source), data, 1, save); break; //CMP
+ case 11: ADD(r(source), data, 0, save); break; //CMN
+ case 12: r(target) = BIT(r(source) | data, save); break; //ORR
+ case 13: r(target) = BIT(data, save); break; //MOV
+ case 14: r(target) = BIT(r(source) & ~data, save); break; //BIC
+ case 15: r(target) = BIT(~data, save); break; //MVN
+ }
+
+ if(exception() && target == 15 && save) {
+ cpsr() = spsr();
+ }
+}
diff --git a/higan/processor/arm7tdmi/instructions-thumb.cpp b/higan/processor/arm7tdmi/instructions-thumb.cpp
new file mode 100644
index 00000000..cad99109
--- /dev/null
+++ b/higan/processor/arm7tdmi/instructions-thumb.cpp
@@ -0,0 +1,20 @@
+auto ARM7TDMI::thumbALU(uint4 mode, uint4 target, uint4 source) -> void {
+ switch(mode) {
+ case 0: r(target) = BIT(r(target) & r(source)); break; //AND
+ case 1: r(target) = BIT(r(target) ^ r(source)); break; //EOR
+ case 2: r(target) = BIT(LSL(r(target), r(source))); break; //LSL
+ case 3: r(target) = BIT(LSR(r(target), r(source))); break; //LSR
+ case 4: r(target) = BIT(ASR(r(target), r(source))); break; //ASR
+ case 5: r(target) = ADD(r(target), r(source), cpsr().c); break; //ADC
+ case 6: r(target) = SUB(r(target), r(source), cpsr().c); break; //SBC
+ case 7: r(target) = BIT(ROR(r(target), r(source))); break; //ROR
+ case 8: BIT(r(target) & r(source)); break; //TST
+ case 9: r(target) = SUB(0, r(source), 1); break; //NEG
+ case 10: SUB(r(target), r(source), 1); break; //CMP
+ case 11: ADD(r(target), r(source), 0); break; //CMN
+ case 12: r(target) = BIT(r(target) | r(source)); break; //ORR
+ case 13: r(target) = MUL(0, r(source), r(target)); break; //MUL
+ case 14: r(target) = BIT(r(target) & ~r(source)); break; //BIC
+ case 15: r(target) = BIT(~r(source)); break; //MVN
+ }
+}
diff --git a/higan/processor/arm7tdmi/memory.cpp b/higan/processor/arm7tdmi/memory.cpp
new file mode 100644
index 00000000..267d2d8b
--- /dev/null
+++ b/higan/processor/arm7tdmi/memory.cpp
@@ -0,0 +1,40 @@
+auto ARM7TDMI::idle() -> void {
+ pipeline.nonsequential = true;
+ sleep();
+}
+
+auto ARM7TDMI::read(uint mode, uint32 address) -> uint32 {
+ return get(mode, address);
+}
+
+auto ARM7TDMI::load(uint mode, uint32 address) -> uint32 {
+ pipeline.nonsequential = true;
+ auto word = get(Load | mode, address);
+ if(mode & Half) {
+ address &= 1;
+ word = mode & Signed ? (uint16)(int16)word : (uint16)word;
+ }
+ if(mode & Byte) {
+ address &= 0;
+ word = mode & Signed ? (uint8)(int8)word : (uint8)word;
+ }
+ if(mode & Signed) {
+ word = ASR(word, address.bits(0,1) << 3);
+ } else {
+ word = ROR(word, address.bits(0,1) << 3);
+ }
+ idle();
+ return word;
+}
+
+auto ARM7TDMI::write(uint mode, uint32 address, uint32 word) -> void {
+ pipeline.nonsequential = true;
+ return set(mode, address, word);
+}
+
+auto ARM7TDMI::store(uint mode, uint32 address, uint32 word) -> void {
+ pipeline.nonsequential = true;
+ if(mode & Half) { word &= 0xffff; word |= word << 16; }
+ if(mode & Byte) { word &= 0xff; word |= word << 8; word |= word << 16; }
+ return set(Store | mode, address, word);
+}
diff --git a/higan/processor/arm7tdmi/registers.cpp b/higan/processor/arm7tdmi/registers.cpp
new file mode 100644
index 00000000..24af3793
--- /dev/null
+++ b/higan/processor/arm7tdmi/registers.cpp
@@ -0,0 +1,80 @@
+auto ARM7TDMI::r(uint4 index) -> GPR& {
+ switch(index) {
+ case 0: return processor.r0;
+ case 1: return processor.r1;
+ case 2: return processor.r2;
+ case 3: return processor.r3;
+ case 4: return processor.r4;
+ case 5: return processor.r5;
+ case 6: return processor.r6;
+ case 7: return processor.r7;
+ case 8: return processor.cpsr.m == PSR::FIQ ? processor.fiq.r8 : processor.r8;
+ case 9: return processor.cpsr.m == PSR::FIQ ? processor.fiq.r9 : processor.r9;
+ case 10: return processor.cpsr.m == PSR::FIQ ? processor.fiq.r10 : processor.r10;
+ case 11: return processor.cpsr.m == PSR::FIQ ? processor.fiq.r11 : processor.r11;
+ case 12: return processor.cpsr.m == PSR::FIQ ? processor.fiq.r12 : processor.r12;
+ case 13: switch(processor.cpsr.m) {
+ case PSR::FIQ: return processor.fiq.r13;
+ case PSR::IRQ: return processor.irq.r13;
+ case PSR::SVC: return processor.svc.r13;
+ case PSR::ABT: return processor.abt.r13;
+ case PSR::UND: return processor.und.r13;
+ default: return processor.r13;
+ }
+ case 14: switch(processor.cpsr.m) {
+ case PSR::FIQ: return processor.fiq.r14;
+ case PSR::IRQ: return processor.irq.r14;
+ case PSR::SVC: return processor.svc.r14;
+ case PSR::ABT: return processor.abt.r14;
+ case PSR::UND: return processor.und.r14;
+ default: return processor.r14;
+ }
+ case 15: return processor.r15;
+ }
+ unreachable;
+}
+
+auto ARM7TDMI::u(uint4 index) -> GPR& {
+ switch(index) {
+ case 0: return processor.r0;
+ case 1: return processor.r1;
+ case 2: return processor.r2;
+ case 3: return processor.r3;
+ case 4: return processor.r4;
+ case 5: return processor.r5;
+ case 6: return processor.r6;
+ case 7: return processor.r7;
+ case 8: return processor.r8;
+ case 9: return processor.r9;
+ case 10: return processor.r10;
+ case 11: return processor.r11;
+ case 12: return processor.r12;
+ case 13: return processor.r13;
+ case 14: return processor.r14;
+ case 15: return processor.r15;
+ }
+ unreachable;
+}
+
+auto ARM7TDMI::cpsr() -> PSR& {
+ return processor.cpsr;
+}
+
+auto ARM7TDMI::spsr() -> PSR& {
+ switch(processor.cpsr.m) {
+ case PSR::FIQ: return processor.fiq.spsr;
+ case PSR::IRQ: return processor.irq.spsr;
+ case PSR::SVC: return processor.svc.spsr;
+ case PSR::ABT: return processor.abt.spsr;
+ case PSR::UND: return processor.und.spsr;
+ }
+ throw;
+}
+
+auto ARM7TDMI::privileged() const -> bool {
+ return processor.cpsr.m != PSR::USR;
+}
+
+auto ARM7TDMI::exception() const -> bool {
+ return privileged() && processor.cpsr.m != PSR::SYS;
+}
diff --git a/higan/processor/arm7tdmi/serialization.cpp b/higan/processor/arm7tdmi/serialization.cpp
new file mode 100644
index 00000000..b623c274
--- /dev/null
+++ b/higan/processor/arm7tdmi/serialization.cpp
@@ -0,0 +1,68 @@
+auto ARM7TDMI::serialize(serializer& s) -> void {
+ processor.serialize(s);
+ pipeline.serialize(s);
+ s.boolean(carry);
+ s.boolean(irq);
+}
+
+auto ARM7TDMI::Processor::serialize(serializer& s) -> void {
+ s.integer(r0.data);
+ s.integer(r1.data);
+ s.integer(r2.data);
+ s.integer(r3.data);
+ s.integer(r4.data);
+ s.integer(r5.data);
+ s.integer(r6.data);
+ s.integer(r7.data);
+ s.integer(r8.data);
+ s.integer(r9.data);
+ s.integer(r10.data);
+ s.integer(r11.data);
+ s.integer(r12.data);
+ s.integer(r13.data);
+ s.integer(r14.data);
+ s.integer(r15.data);
+ cpsr.serialize(s);
+ s.integer(fiq.r8.data);
+ s.integer(fiq.r9.data);
+ s.integer(fiq.r10.data);
+ s.integer(fiq.r11.data);
+ s.integer(fiq.r12.data);
+ s.integer(fiq.r13.data);
+ s.integer(fiq.r14.data);
+ fiq.spsr.serialize(s);
+ s.integer(irq.r13.data);
+ s.integer(irq.r14.data);
+ irq.spsr.serialize(s);
+ s.integer(svc.r13.data);
+ s.integer(svc.r14.data);
+ svc.spsr.serialize(s);
+ s.integer(abt.r13.data);
+ s.integer(abt.r14.data);
+ abt.spsr.serialize(s);
+ s.integer(und.r13.data);
+ s.integer(und.r14.data);
+ und.spsr.serialize(s);
+}
+
+auto ARM7TDMI::PSR::serialize(serializer& s) -> void {
+ s.integer(m);
+ s.integer(t);
+ s.integer(f);
+ s.integer(i);
+ s.integer(v);
+ s.integer(c);
+ s.integer(z);
+ s.integer(n);
+}
+
+auto ARM7TDMI::Pipeline::serialize(serializer& s) -> void {
+ s.integer(reload);
+ s.integer(nonsequential);
+ s.integer(fetch.address);
+ s.integer(fetch.instruction);
+ s.integer(decode.address);
+ s.integer(decode.instruction);
+ s.integer(execute.address);
+ s.integer(execute.instruction);
+}
diff --git a/higan/processor/lr35902-legacy/disassembler.cpp b/higan/processor/lr35902-legacy/disassembler.cpp
deleted file mode 100644
index c59f998e..00000000
--- a/higan/processor/lr35902-legacy/disassembler.cpp
+++ /dev/null
@@ -1,533 +0,0 @@
-auto LR35902::disassemble(uint16 pc) -> string {
- return {
- hex(pc, 4L), " ",
- pad(disassembleOpcode(pc), -16, ' '), " ",
- " AF:", hex(r[AF], 4L),
- " BC:", hex(r[BC], 4L),
- " DE:", hex(r[DE], 4L),
- " HL:", hex(r[HL], 4L),
- " SP:", hex(r[SP], 4L)
- };
-}
-
-auto LR35902::disassembleOpcode(uint16 pc) -> string {
- auto opcode = readDebugger(pc);
- auto lo = readDebugger(pc + 1);
- auto hi = readDebugger(pc + 2);
- auto word = hi << 8 | lo << 0;
-
- switch(opcode) {
- case 0x00: return {"nop"};
- case 0x01: return {"ld bc,$", hex(word, 4L)};
- case 0x02: return {"ld (bc),a"};
- case 0x03: return {"inc bc"};
- case 0x04: return {"inc b"};
- case 0x05: return {"dec b"};
- case 0x06: return {"ld b,$", hex(lo, 2L)};
- case 0x07: return {"rlca"};
- case 0x08: return {"ld ($", hex(word, 4L), "),sp"};
- case 0x09: return {"add hl,bc"};
- case 0x0a: return {"ld a,(bc)"};
- case 0x0b: return {"dec bc"};
- case 0x0c: return {"inc c"};
- case 0x0d: return {"dec c"};
- case 0x0e: return {"ld c,$", hex(lo, 2L)};
- case 0x0f: return {"rrca"};
- case 0x10: return {"stop"};
- case 0x11: return {"ld de,$", hex(word, 4L)};
- case 0x12: return {"ld (de),a"};
- case 0x13: return {"inc de"};
- case 0x14: return {"inc d"};
- case 0x15: return {"dec d"};
- case 0x16: return {"ld d,$", hex(lo, 2L)};
- case 0x17: return {"rla"};
- case 0x18: return {"jr $", hex(pc + 2 + (int8)lo, 4L)};
- case 0x19: return {"add hl,de"};
- case 0x1a: return {"ld a,(de)"};
- case 0x1b: return {"dec de"};
- case 0x1c: return {"inc e"};
- case 0x1d: return {"dec e"};
- case 0x1e: return {"ld e,$", hex(lo, 2L)};
- case 0x1f: return {"rra"};
- case 0x20: return {"jr nz,$", hex(pc + 2 + (int8)lo, 4L)};
- case 0x21: return {"ld hl,$", hex(word, 4L)};
- case 0x22: return {"ldi (hl),a"};
- case 0x23: return {"inc hl"};
- case 0x24: return {"inc h"};
- case 0x25: return {"dec h"};
- case 0x26: return {"ld h,$", hex(lo, 2L)};
- case 0x27: return {"daa"};
- case 0x28: return {"jr z,$", hex(pc + 2 + (int8)lo, 4L)};
- case 0x29: return {"add hl,hl"};
- case 0x2a: return {"ldi a,(hl)"};
- case 0x2b: return {"dec hl"};
- case 0x2c: return {"inc l"};
- case 0x2d: return {"dec l"};
- case 0x2e: return {"ld l,$", hex(lo, 2L)};
- case 0x2f: return {"cpl"};
- case 0x30: return {"jr nc,$", hex(pc + 2 + (int8)lo, 4L)};
- case 0x31: return {"ld sp,$", hex(word, 4L)};
- case 0x32: return {"ldd (hl),a"};
- case 0x33: return {"inc sp"};
- case 0x34: return {"inc (hl)"};
- case 0x35: return {"dec (hl)"};
- case 0x36: return {"ld (hl),$", hex(lo, 2L)};
- case 0x37: return {"scf"};
- case 0x38: return {"jr c,$", hex(pc + 2 + (int8)lo, 4L)};
- case 0x39: return {"add hl,sp"};
- case 0x3a: return {"ldd a,(hl)"};
- case 0x3b: return {"dec sp"};
- case 0x3c: return {"inc a"};
- case 0x3d: return {"dec a"};
- case 0x3e: return {"ld a,$", hex(lo, 2L)};
- case 0x3f: return {"ccf"};
- case 0x40: return {"ld b,b"};
- case 0x41: return {"ld b,c"};
- case 0x42: return {"ld b,d"};
- case 0x43: return {"ld b,e"};
- case 0x44: return {"ld b,h"};
- case 0x45: return {"ld b,l"};
- case 0x46: return {"ld b,(hl)"};
- case 0x47: return {"ld b,a"};
- case 0x48: return {"ld c,b"};
- case 0x49: return {"ld c,c"};
- case 0x4a: return {"ld c,d"};
- case 0x4b: return {"ld c,e"};
- case 0x4c: return {"ld c,h"};
- case 0x4d: return {"ld c,l"};
- case 0x4e: return {"ld c,(hl)"};
- case 0x4f: return {"ld c,a"};
- case 0x50: return {"ld d,b"};
- case 0x51: return {"ld d,c"};
- case 0x52: return {"ld d,d"};
- case 0x53: return {"ld d,e"};
- case 0x54: return {"ld d,h"};
- case 0x55: return {"ld d,l"};
- case 0x56: return {"ld d,(hl)"};
- case 0x57: return {"ld d,a"};
- case 0x58: return {"ld e,b"};
- case 0x59: return {"ld e,c"};
- case 0x5a: return {"ld e,d"};
- case 0x5b: return {"ld e,e"};
- case 0x5c: return {"ld e,h"};
- case 0x5d: return {"ld e,l"};
- case 0x5e: return {"ld e,(hl)"};
- case 0x5f: return {"ld e,a"};
- case 0x60: return {"ld h,b"};
- case 0x61: return {"ld h,c"};
- case 0x62: return {"ld h,d"};
- case 0x63: return {"ld h,e"};
- case 0x64: return {"ld h,h"};
- case 0x65: return {"ld h,l"};
- case 0x66: return {"ld h,(hl)"};
- case 0x67: return {"ld h,a"};
- case 0x68: return {"ld l,b"};
- case 0x69: return {"ld l,c"};
- case 0x6a: return {"ld l,d"};
- case 0x6b: return {"ld l,e"};
- case 0x6c: return {"ld l,h"};
- case 0x6d: return {"ld l,l"};
- case 0x6e: return {"ld l,(hl)"};
- case 0x6f: return {"ld l,a"};
- case 0x70: return {"ld (hl),b"};
- case 0x71: return {"ld (hl),c"};
- case 0x72: return {"ld (hl),d"};
- case 0x73: return {"ld (hl),e"};
- case 0x74: return {"ld (hl),h"};
- case 0x75: return {"ld (hl),l"};
- case 0x76: return {"halt"};
- case 0x77: return {"ld (hl),a"};
- case 0x78: return {"ld a,b"};
- case 0x79: return {"ld a,c"};
- case 0x7a: return {"ld a,d"};
- case 0x7b: return {"ld a,e"};
- case 0x7c: return {"ld a,h"};
- case 0x7d: return {"ld a,l"};
- case 0x7e: return {"ld a,(hl)"};
- case 0x7f: return {"ld a,a"};
- case 0x80: return {"add a,b"};
- case 0x81: return {"add a,c"};
- case 0x82: return {"add a,d"};
- case 0x83: return {"add a,e"};
- case 0x84: return {"add a,h"};
- case 0x85: return {"add a,l"};
- case 0x86: return {"add a,(hl)"};
- case 0x87: return {"add a,a"};
- case 0x88: return {"adc a,b"};
- case 0x89: return {"adc a,c"};
- case 0x8a: return {"adc a,d"};
- case 0x8b: return {"adc a,e"};
- case 0x8c: return {"adc a,h"};
- case 0x8d: return {"adc a,l"};
- case 0x8e: return {"adc a,(hl)"};
- case 0x8f: return {"adc a,a"};
- case 0x90: return {"sub a,b"};
- case 0x91: return {"sub a,c"};
- case 0x92: return {"sub a,d"};
- case 0x93: return {"sub a,e"};
- case 0x94: return {"sub a,h"};
- case 0x95: return {"sub a,l"};
- case 0x96: return {"sub a,(hl)"};
- case 0x97: return {"sub a,a"};
- case 0x98: return {"sbc a,b"};
- case 0x99: return {"sbc a,c"};
- case 0x9a: return {"sbc a,d"};
- case 0x9b: return {"sbc a,e"};
- case 0x9c: return {"sbc a,h"};
- case 0x9d: return {"sbc a,l"};
- case 0x9e: return {"sbc a,(hl)"};
- case 0x9f: return {"sbc a,a"};
- case 0xa0: return {"and a,b"};
- case 0xa1: return {"and a,c"};
- case 0xa2: return {"and a,d"};
- case 0xa3: return {"and a,e"};
- case 0xa4: return {"and a,h"};
- case 0xa5: return {"and a,l"};
- case 0xa6: return {"and a,(hl)"};
- case 0xa7: return {"and a,a"};
- case 0xa8: return {"xor a,b"};
- case 0xa9: return {"xor a,c"};
- case 0xaa: return {"xor a,d"};
- case 0xab: return {"xor a,e"};
- case 0xac: return {"xor a,h"};
- case 0xad: return {"xor a,l"};
- case 0xae: return {"xor a,(hl)"};
- case 0xaf: return {"xor a,a"};
- case 0xb0: return {"or a,b"};
- case 0xb1: return {"or a,c"};
- case 0xb2: return {"or a,d"};
- case 0xb3: return {"or a,e"};
- case 0xb4: return {"or a,h"};
- case 0xb5: return {"or a,l"};
- case 0xb6: return {"or a,(hl)"};
- case 0xb7: return {"or a,a"};
- case 0xb8: return {"cp a,b"};
- case 0xb9: return {"cp a,c"};
- case 0xba: return {"cp a,d"};
- case 0xbb: return {"cp a,e"};
- case 0xbc: return {"cp a,h"};
- case 0xbd: return {"cp a,l"};
- case 0xbe: return {"cp a,(hl)"};
- case 0xbf: return {"cp a,a"};
- case 0xc0: return {"ret nz"};
- case 0xc1: return {"pop bc"};
- case 0xc2: return {"jp nz,$", hex(word, 4L)};
- case 0xc3: return {"jp $", hex(word, 4L)};
- case 0xc4: return {"call nz,$", hex(word, 4L)};
- case 0xc5: return {"push bc"};
- case 0xc6: return {"add a,$", hex(lo, 2L)};
- case 0xc7: return {"rst $0000"};
- case 0xc8: return {"ret z"};
- case 0xc9: return {"ret"};
- case 0xca: return {"jp z,$", hex(word, 4L)};
- case 0xcb: return disassembleOpcodeCB(pc + 1);
- case 0xcc: return {"call z,$", hex(word, 4L)};
- case 0xcd: return {"call $", hex(word, 4L)};
- case 0xce: return {"adc a,$", hex(lo, 2L)};
- case 0xcf: return {"rst $0008"};
- case 0xd0: return {"ret nc"};
- case 0xd1: return {"pop de"};
- case 0xd2: return {"jp nc,$", hex(word, 4L)};
- case 0xd4: return {"call nc,$", hex(word, 4L)};
- case 0xd5: return {"push de"};
- case 0xd6: return {"sub a,$", hex(lo, 2L)};
- case 0xd7: return {"rst $0010"};
- case 0xd8: return {"ret c"};
- case 0xd9: return {"reti"};
- case 0xda: return {"jp c,$", hex(word, 4L)};
- case 0xdc: return {"call c,$", hex(word, 4L)};
- case 0xde: return {"sbc a,$", hex(lo, 2L)};
- case 0xdf: return {"rst $0018"};
- case 0xe0: return {"ldh ($ff", hex(lo, 2L), "),a"};
- case 0xe1: return {"pop hl"};
- case 0xe2: return {"ldh ($ff00+c),a"};
- case 0xe5: return {"push hl"};
- case 0xe6: return {"and a,$", hex(lo, 2L)};
- case 0xe7: return {"rst $0020"};
- case 0xe8: return {"add sp,$", hex((int8)lo, 4L)};
- case 0xe9: return {"jp hl"};
- case 0xea: return {"ld ($", hex(word, 4L), "),a"};
- case 0xee: return {"xor a,$", hex(lo, 2L)};
- case 0xef: return {"rst $0028"};
- case 0xf0: return {"ldh a,($ff", hex(lo, 2L), ")"};
- case 0xf1: return {"pop af"};
- case 0xf2: return {"ldh a,($ff00+c)"};
- case 0xf3: return {"di"};
- case 0xf5: return {"push af"};
- case 0xf6: return {"or a,$", hex(lo, 2L)};
- case 0xf7: return {"rst $0030"};
- case 0xf8: return {"ld hl,sp+$", hex((int8)lo, 4L)};
- case 0xf9: return {"ld sp,hl"};
- case 0xfa: return {"ld a,($", hex(word, 4L), ")"};
- case 0xfb: return {"ei"};
- case 0xfe: return {"cp a,$", hex(lo, 2L)};
- case 0xff: return {"rst $0038"};
- }
-
- return "xx";
-}
-
-auto LR35902::disassembleOpcodeCB(uint16 pc) -> string {
- auto opcode = readDebugger(pc);
-
- switch(opcode) {
- case 0x00: return {"rlc b"};
- case 0x01: return {"rlc c"};
- case 0x02: return {"rlc d"};
- case 0x03: return {"rlc e"};
- case 0x04: return {"rlc h"};
- case 0x05: return {"rlc l"};
- case 0x06: return {"rlc (hl)"};
- case 0x07: return {"rlc a"};
- case 0x08: return {"rrc b"};
- case 0x09: return {"rrc c"};
- case 0x0a: return {"rrc d"};
- case 0x0b: return {"rrc e"};
- case 0x0c: return {"rrc h"};
- case 0x0d: return {"rrc l"};
- case 0x0e: return {"rrc (hl)"};
- case 0x0f: return {"rrc a"};
- case 0x10: return {"rl b"};
- case 0x11: return {"rl c"};
- case 0x12: return {"rl d"};
- case 0x13: return {"rl e"};
- case 0x14: return {"rl h"};
- case 0x15: return {"rl l"};
- case 0x16: return {"rl (hl)"};
- case 0x17: return {"rl a"};
- case 0x18: return {"rr b"};
- case 0x19: return {"rr c"};
- case 0x1a: return {"rr d"};
- case 0x1b: return {"rr e"};
- case 0x1c: return {"rr h"};
- case 0x1d: return {"rr l"};
- case 0x1e: return {"rr (hl)"};
- case 0x1f: return {"rr a"};
- case 0x20: return {"sla b"};
- case 0x21: return {"sla c"};
- case 0x22: return {"sla d"};
- case 0x23: return {"sla e"};
- case 0x24: return {"sla h"};
- case 0x25: return {"sla l"};
- case 0x26: return {"sla (hl)"};
- case 0x27: return {"sla a"};
- case 0x28: return {"sra b"};
- case 0x29: return {"sra c"};
- case 0x2a: return {"sra d"};
- case 0x2b: return {"sra e"};
- case 0x2c: return {"sra h"};
- case 0x2d: return {"sra l"};
- case 0x2e: return {"sra (hl)"};
- case 0x2f: return {"sra a"};
- case 0x30: return {"swap b"};
- case 0x31: return {"swap c"};
- case 0x32: return {"swap d"};
- case 0x33: return {"swap e"};
- case 0x34: return {"swap h"};
- case 0x35: return {"swap l"};
- case 0x36: return {"swap (hl)"};
- case 0x37: return {"swap a"};
- case 0x38: return {"srl b"};
- case 0x39: return {"srl c"};
- case 0x3a: return {"srl d"};
- case 0x3b: return {"srl e"};
- case 0x3c: return {"srl h"};
- case 0x3d: return {"srl l"};
- case 0x3e: return {"srl (hl)"};
- case 0x3f: return {"srl a"};
- case 0x40: return {"bit 0,b"};
- case 0x41: return {"bit 0,c"};
- case 0x42: return {"bit 0,d"};
- case 0x43: return {"bit 0,e"};
- case 0x44: return {"bit 0,h"};
- case 0x45: return {"bit 0,l"};
- case 0x46: return {"bit 0,(hl)"};
- case 0x47: return {"bit 0,a"};
- case 0x48: return {"bit 1,b"};
- case 0x49: return {"bit 1,c"};
- case 0x4a: return {"bit 1,d"};
- case 0x4b: return {"bit 1,e"};
- case 0x4c: return {"bit 1,h"};
- case 0x4d: return {"bit 1,l"};
- case 0x4e: return {"bit 1,(hl)"};
- case 0x4f: return {"bit 1,a"};
- case 0x50: return {"bit 2,b"};
- case 0x51: return {"bit 2,c"};
- case 0x52: return {"bit 2,d"};
- case 0x53: return {"bit 2,e"};
- case 0x54: return {"bit 2,h"};
- case 0x55: return {"bit 2,l"};
- case 0x56: return {"bit 2,(hl)"};
- case 0x57: return {"bit 2,a"};
- case 0x58: return {"bit 3,b"};
- case 0x59: return {"bit 3,c"};
- case 0x5a: return {"bit 3,d"};
- case 0x5b: return {"bit 3,e"};
- case 0x5c: return {"bit 3,h"};
- case 0x5d: return {"bit 3,l"};
- case 0x5e: return {"bit 3,(hl)"};
- case 0x5f: return {"bit 3,a"};
- case 0x60: return {"bit 4,b"};
- case 0x61: return {"bit 4,c"};
- case 0x62: return {"bit 4,d"};
- case 0x63: return {"bit 4,e"};
- case 0x64: return {"bit 4,h"};
- case 0x65: return {"bit 4,l"};
- case 0x66: return {"bit 4,(hl)"};
- case 0x67: return {"bit 4,a"};
- case 0x68: return {"bit 5,b"};
- case 0x69: return {"bit 5,c"};
- case 0x6a: return {"bit 5,d"};
- case 0x6b: return {"bit 5,e"};
- case 0x6c: return {"bit 5,h"};
- case 0x6d: return {"bit 5,l"};
- case 0x6e: return {"bit 5,(hl)"};
- case 0x6f: return {"bit 5,a"};
- case 0x70: return {"bit 6,b"};
- case 0x71: return {"bit 6,c"};
- case 0x72: return {"bit 6,d"};
- case 0x73: return {"bit 6,e"};
- case 0x74: return {"bit 6,h"};
- case 0x75: return {"bit 6,l"};
- case 0x76: return {"bit 6,(hl)"};
- case 0x77: return {"bit 6,a"};
- case 0x78: return {"bit 7,b"};
- case 0x79: return {"bit 7,c"};
- case 0x7a: return {"bit 7,d"};
- case 0x7b: return {"bit 7,e"};
- case 0x7c: return {"bit 7,h"};
- case 0x7d: return {"bit 7,l"};
- case 0x7e: return {"bit 7,(hl)"};
- case 0x7f: return {"bit 7,a"};
- case 0x80: return {"res 0,b"};
- case 0x81: return {"res 0,c"};
- case 0x82: return {"res 0,d"};
- case 0x83: return {"res 0,e"};
- case 0x84: return {"res 0,h"};
- case 0x85: return {"res 0,l"};
- case 0x86: return {"res 0,(hl)"};
- case 0x87: return {"res 0,a"};
- case 0x88: return {"res 1,b"};
- case 0x89: return {"res 1,c"};
- case 0x8a: return {"res 1,d"};
- case 0x8b: return {"res 1,e"};
- case 0x8c: return {"res 1,h"};
- case 0x8d: return {"res 1,l"};
- case 0x8e: return {"res 1,(hl)"};
- case 0x8f: return {"res 1,a"};
- case 0x90: return {"res 2,b"};
- case 0x91: return {"res 2,c"};
- case 0x92: return {"res 2,d"};
- case 0x93: return {"res 2,e"};
- case 0x94: return {"res 2,h"};
- case 0x95: return {"res 2,l"};
- case 0x96: return {"res 2,(hl)"};
- case 0x97: return {"res 2,a"};
- case 0x98: return {"res 3,b"};
- case 0x99: return {"res 3,c"};
- case 0x9a: return {"res 3,d"};
- case 0x9b: return {"res 3,e"};
- case 0x9c: return {"res 3,h"};
- case 0x9d: return {"res 3,l"};
- case 0x9e: return {"res 3,(hl)"};
- case 0x9f: return {"res 3,a"};
- case 0xa0: return {"res 4,b"};
- case 0xa1: return {"res 4,c"};
- case 0xa2: return {"res 4,d"};
- case 0xa3: return {"res 4,e"};
- case 0xa4: return {"res 4,h"};
- case 0xa5: return {"res 4,l"};
- case 0xa6: return {"res 4,(hl)"};
- case 0xa7: return {"res 4,a"};
- case 0xa8: return {"res 5,b"};
- case 0xa9: return {"res 5,c"};
- case 0xaa: return {"res 5,d"};
- case 0xab: return {"res 5,e"};
- case 0xac: return {"res 5,h"};
- case 0xad: return {"res 5,l"};
- case 0xae: return {"res 5,(hl)"};
- case 0xaf: return {"res 5,a"};
- case 0xb0: return {"res 6,b"};
- case 0xb1: return {"res 6,c"};
- case 0xb2: return {"res 6,d"};
- case 0xb3: return {"res 6,e"};
- case 0xb4: return {"res 6,h"};
- case 0xb5: return {"res 6,l"};
- case 0xb6: return {"res 6,(hl)"};
- case 0xb7: return {"res 6,a"};
- case 0xb8: return {"res 7,b"};
- case 0xb9: return {"res 7,c"};
- case 0xba: return {"res 7,d"};
- case 0xbb: return {"res 7,e"};
- case 0xbc: return {"res 7,h"};
- case 0xbd: return {"res 7,l"};
- case 0xbe: return {"res 7,(hl)"};
- case 0xbf: return {"res 7,a"};
- case 0xc0: return {"set 0,b"};
- case 0xc1: return {"set 0,c"};
- case 0xc2: return {"set 0,d"};
- case 0xc3: return {"set 0,e"};
- case 0xc4: return {"set 0,h"};
- case 0xc5: return {"set 0,l"};
- case 0xc6: return {"set 0,(hl)"};
- case 0xc7: return {"set 0,a"};
- case 0xc8: return {"set 1,b"};
- case 0xc9: return {"set 1,c"};
- case 0xca: return {"set 1,d"};
- case 0xcb: return {"set 1,e"};
- case 0xcc: return {"set 1,h"};
- case 0xcd: return {"set 1,l"};
- case 0xce: return {"set 1,(hl)"};
- case 0xcf: return {"set 1,a"};
- case 0xd0: return {"set 2,b"};
- case 0xd1: return {"set 2,c"};
- case 0xd2: return {"set 2,d"};
- case 0xd3: return {"set 2,e"};
- case 0xd4: return {"set 2,h"};
- case 0xd5: return {"set 2,l"};
- case 0xd6: return {"set 2,(hl)"};
- case 0xd7: return {"set 2,a"};
- case 0xd8: return {"set 3,b"};
- case 0xd9: return {"set 3,c"};
- case 0xda: return {"set 3,d"};
- case 0xdb: return {"set 3,e"};
- case 0xdc: return {"set 3,h"};
- case 0xdd: return {"set 3,l"};
- case 0xde: return {"set 3,(hl)"};
- case 0xdf: return {"set 3,a"};
- case 0xe0: return {"set 4,b"};
- case 0xe1: return {"set 4,c"};
- case 0xe2: return {"set 4,d"};
- case 0xe3: return {"set 4,e"};
- case 0xe4: return {"set 4,h"};
- case 0xe5: return {"set 4,l"};
- case 0xe6: return {"set 4,(hl)"};
- case 0xe7: return {"set 4,a"};
- case 0xe8: return {"set 5,b"};
- case 0xe9: return {"set 5,c"};
- case 0xea: return {"set 5,d"};
- case 0xeb: return {"set 5,e"};
- case 0xec: return {"set 5,h"};
- case 0xed: return {"set 5,l"};
- case 0xee: return {"set 5,(hl)"};
- case 0xef: return {"set 5,a"};
- case 0xf0: return {"set 6,b"};
- case 0xf1: return {"set 6,c"};
- case 0xf2: return {"set 6,d"};
- case 0xf3: return {"set 6,e"};
- case 0xf4: return {"set 6,h"};
- case 0xf5: return {"set 6,l"};
- case 0xf6: return {"set 6,(hl)"};
- case 0xf7: return {"set 6,a"};
- case 0xf8: return {"set 7,b"};
- case 0xf9: return {"set 7,c"};
- case 0xfa: return {"set 7,d"};
- case 0xfb: return {"set 7,e"};
- case 0xfc: return {"set 7,h"};
- case 0xfd: return {"set 7,l"};
- case 0xfe: return {"set 7,(hl)"};
- case 0xff: return {"set 7,a"};
- }
-
- unreachable;
-}
diff --git a/higan/processor/lr35902-legacy/instruction.cpp b/higan/processor/lr35902-legacy/instruction.cpp
deleted file mode 100644
index 7856eedf..00000000
--- a/higan/processor/lr35902-legacy/instruction.cpp
+++ /dev/null
@@ -1,531 +0,0 @@
-auto LR35902::interrupt(uint16 vector) -> void {
- io();
- io();
- io();
- r.ime = 0;
- write(--r[SP], r[PC] >> 8);
- write(--r[SP], r[PC] >> 0);
- r[PC] = vector;
-}
-
-auto LR35902::instruction() -> void {
- switch(auto opcode = read(r[PC]++)) {
- case 0x00: return op_nop();
- case 0x01: return op_ld_rr_nn(BC);
- case 0x02: return op_ld_rr_a(BC);
- case 0x03: return op_inc_rr(BC);
- case 0x04: return op_inc_r(B);
- case 0x05: return op_dec_r(B);
- case 0x06: return op_ld_r_n(B);
- case 0x07: return op_rlca();
- case 0x08: return op_ld_nn_sp();
- case 0x09: return op_add_hl_rr(BC);
- case 0x0a: return op_ld_a_rr(BC);
- case 0x0b: return op_dec_rr(BC);
- case 0x0c: return op_inc_r(C);
- case 0x0d: return op_dec_r(C);
- case 0x0e: return op_ld_r_n(C);
- case 0x0f: return op_rrca();
- case 0x10: return op_stop();
- case 0x11: return op_ld_rr_nn(DE);
- case 0x12: return op_ld_rr_a(DE);
- case 0x13: return op_inc_rr(DE);
- case 0x14: return op_inc_r(D);
- case 0x15: return op_dec_r(D);
- case 0x16: return op_ld_r_n(D);
- case 0x17: return op_rla();
- case 0x18: return op_jr_n();
- case 0x19: return op_add_hl_rr(DE);
- case 0x1a: return op_ld_a_rr(DE);
- case 0x1b: return op_dec_rr(DE);
- case 0x1c: return op_inc_r(E);
- case 0x1d: return op_dec_r(E);
- case 0x1e: return op_ld_r_n(E);
- case 0x1f: return op_rra();
- case 0x20: return op_jr_f_n(ZF, 0);
- case 0x21: return op_ld_rr_nn(HL);
- case 0x22: return op_ldi_hl_a();
- case 0x23: return op_inc_rr(HL);
- case 0x24: return op_inc_r(H);
- case 0x25: return op_dec_r(H);
- case 0x26: return op_ld_r_n(H);
- case 0x27: return op_daa();
- case 0x28: return op_jr_f_n(ZF, 1);
- case 0x29: return op_add_hl_rr(HL);
- case 0x2a: return op_ldi_a_hl();
- case 0x2b: return op_dec_rr(HL);
- case 0x2c: return op_inc_r(L);
- case 0x2d: return op_dec_r(L);
- case 0x2e: return op_ld_r_n(L);
- case 0x2f: return op_cpl();
- case 0x30: return op_jr_f_n(CF, 0);
- case 0x31: return op_ld_rr_nn(SP);
- case 0x32: return op_ldd_hl_a();
- case 0x33: return op_inc_rr(SP);
- case 0x34: return op_inc_hl();
- case 0x35: return op_dec_hl();
- case 0x36: return op_ld_hl_n();
- case 0x37: return op_scf();
- case 0x38: return op_jr_f_n(CF, 1);
- case 0x39: return op_add_hl_rr(SP);
- case 0x3a: return op_ldd_a_hl();
- case 0x3b: return op_dec_rr(SP);
- case 0x3c: return op_inc_r(A);
- case 0x3d: return op_dec_r(A);
- case 0x3e: return op_ld_r_n(A);
- case 0x3f: return op_ccf();
- case 0x40: return op_ld_r_r(B, B);
- case 0x41: return op_ld_r_r(B, C);
- case 0x42: return op_ld_r_r(B, D);
- case 0x43: return op_ld_r_r(B, E);
- case 0x44: return op_ld_r_r(B, H);
- case 0x45: return op_ld_r_r(B, L);
- case 0x46: return op_ld_r_hl(B);
- case 0x47: return op_ld_r_r(B, A);
- case 0x48: return op_ld_r_r(C, B);
- case 0x49: return op_ld_r_r(C, C);
- case 0x4a: return op_ld_r_r(C, D);
- case 0x4b: return op_ld_r_r(C, E);
- case 0x4c: return op_ld_r_r(C, H);
- case 0x4d: return op_ld_r_r(C, L);
- case 0x4e: return op_ld_r_hl(C);
- case 0x4f: return op_ld_r_r(C, A);
- case 0x50: return op_ld_r_r(D, B);
- case 0x51: return op_ld_r_r(D, C);
- case 0x52: return op_ld_r_r(D, D);
- case 0x53: return op_ld_r_r(D, E);
- case 0x54: return op_ld_r_r(D, H);
- case 0x55: return op_ld_r_r(D, L);
- case 0x56: return op_ld_r_hl(D);
- case 0x57: return op_ld_r_r(D, A);
- case 0x58: return op_ld_r_r(E, B);
- case 0x59: return op_ld_r_r(E, C);
- case 0x5a: return op_ld_r_r(E, D);
- case 0x5b: return op_ld_r_r(E, E);
- case 0x5c: return op_ld_r_r(E, H);
- case 0x5d: return op_ld_r_r(E, L);
- case 0x5e: return op_ld_r_hl(E);
- case 0x5f: return op_ld_r_r(E, A);
- case 0x60: return op_ld_r_r(H, B);
- case 0x61: return op_ld_r_r(H, C);
- case 0x62: return op_ld_r_r(H, D);
- case 0x63: return op_ld_r_r(H, E);
- case 0x64: return op_ld_r_r(H, H);
- case 0x65: return op_ld_r_r(H, L);
- case 0x66: return op_ld_r_hl(H);
- case 0x67: return op_ld_r_r(H, A);
- case 0x68: return op_ld_r_r(L, B);
- case 0x69: return op_ld_r_r(L, C);
- case 0x6a: return op_ld_r_r(L, D);
- case 0x6b: return op_ld_r_r(L, E);
- case 0x6c: return op_ld_r_r(L, H);
- case 0x6d: return op_ld_r_r(L, L);
- case 0x6e: return op_ld_r_hl(L);
- case 0x6f: return op_ld_r_r(L, A);
- case 0x70: return op_ld_hl_r(B);
- case 0x71: return op_ld_hl_r(C);
- case 0x72: return op_ld_hl_r(D);
- case 0x73: return op_ld_hl_r(E);
- case 0x74: return op_ld_hl_r(H);
- case 0x75: return op_ld_hl_r(L);
- case 0x76: return op_halt();
- case 0x77: return op_ld_hl_r(A);
- case 0x78: return op_ld_r_r(A, B);
- case 0x79: return op_ld_r_r(A, C);
- case 0x7a: return op_ld_r_r(A, D);
- case 0x7b: return op_ld_r_r(A, E);
- case 0x7c: return op_ld_r_r(A, H);
- case 0x7d: return op_ld_r_r(A, L);
- case 0x7e: return op_ld_r_hl(A);
- case 0x7f: return op_ld_r_r(A, A);
- case 0x80: return op_add_a_r(B);
- case 0x81: return op_add_a_r(C);
- case 0x82: return op_add_a_r(D);
- case 0x83: return op_add_a_r(E);
- case 0x84: return op_add_a_r(H);
- case 0x85: return op_add_a_r(L);
- case 0x86: return op_add_a_hl();
- case 0x87: return op_add_a_r(A);
- case 0x88: return op_adc_a_r(B);
- case 0x89: return op_adc_a_r(C);
- case 0x8a: return op_adc_a_r(D);
- case 0x8b: return op_adc_a_r(E);
- case 0x8c: return op_adc_a_r(H);
- case 0x8d: return op_adc_a_r(L);
- case 0x8e: return op_adc_a_hl();
- case 0x8f: return op_adc_a_r(A);
- case 0x90: return op_sub_a_r(B);
- case 0x91: return op_sub_a_r(C);
- case 0x92: return op_sub_a_r(D);
- case 0x93: return op_sub_a_r(E);
- case 0x94: return op_sub_a_r(H);
- case 0x95: return op_sub_a_r(L);
- case 0x96: return op_sub_a_hl();
- case 0x97: return op_sub_a_r(A);
- case 0x98: return op_sbc_a_r(B);
- case 0x99: return op_sbc_a_r(C);
- case 0x9a: return op_sbc_a_r(D);
- case 0x9b: return op_sbc_a_r(E);
- case 0x9c: return op_sbc_a_r(H);
- case 0x9d: return op_sbc_a_r(L);
- case 0x9e: return op_sbc_a_hl();
- case 0x9f: return op_sbc_a_r(A);
- case 0xa0: return op_and_a_r(B);
- case 0xa1: return op_and_a_r(C);
- case 0xa2: return op_and_a_r(D);
- case 0xa3: return op_and_a_r(E);
- case 0xa4: return op_and_a_r(H);
- case 0xa5: return op_and_a_r(L);
- case 0xa6: return op_and_a_hl();
- case 0xa7: return op_and_a_r(A);
- case 0xa8: return op_xor_a_r(B);
- case 0xa9: return op_xor_a_r(C);
- case 0xaa: return op_xor_a_r(D);
- case 0xab: return op_xor_a_r(E);
- case 0xac: return op_xor_a_r(H);
- case 0xad: return op_xor_a_r(L);
- case 0xae: return op_xor_a_hl();
- case 0xaf: return op_xor_a_r(A);
- case 0xb0: return op_or_a_r(B);
- case 0xb1: return op_or_a_r(C);
- case 0xb2: return op_or_a_r(D);
- case 0xb3: return op_or_a_r(E);
- case 0xb4: return op_or_a_r(H);
- case 0xb5: return op_or_a_r(L);
- case 0xb6: return op_or_a_hl();
- case 0xb7: return op_or_a_r(A);
- case 0xb8: return op_cp_a_r(B);
- case 0xb9: return op_cp_a_r(C);
- case 0xba: return op_cp_a_r(D);
- case 0xbb: return op_cp_a_r(E);
- case 0xbc: return op_cp_a_r(H);
- case 0xbd: return op_cp_a_r(L);
- case 0xbe: return op_cp_a_hl();
- case 0xbf: return op_cp_a_r(A);
- case 0xc0: return op_ret_f(ZF, 0);
- case 0xc1: return op_pop_rr(BC);
- case 0xc2: return op_jp_f_nn(ZF, 0);
- case 0xc3: return op_jp_nn();
- case 0xc4: return op_call_f_nn(ZF, 0);
- case 0xc5: return op_push_rr(BC);
- case 0xc6: return op_add_a_n();
- case 0xc7: return op_rst_n(0x00);
- case 0xc8: return op_ret_f(ZF, 1);
- case 0xc9: return op_ret();
- case 0xca: return op_jp_f_nn(ZF, 1);
- case 0xcb: return op_cb();
- case 0xcc: return op_call_f_nn(ZF, 1);
- case 0xcd: return op_call_nn();
- case 0xce: return op_adc_a_n();
- case 0xcf: return op_rst_n(0x08);
- case 0xd0: return op_ret_f(CF, 0);
- case 0xd1: return op_pop_rr(DE);
- case 0xd2: return op_jp_f_nn(CF, 0);
- case 0xd3: return op_xx();
- case 0xd4: return op_call_f_nn(CF, 0);
- case 0xd5: return op_push_rr(DE);
- case 0xd6: return op_sub_a_n();
- case 0xd7: return op_rst_n(0x10);
- case 0xd8: return op_ret_f(CF, 1);
- case 0xd9: return op_reti();
- case 0xda: return op_jp_f_nn(CF, 1);
- case 0xdb: return op_xx();
- case 0xdc: return op_call_f_nn(CF, 1);
- case 0xdd: return op_xx();
- case 0xde: return op_sbc_a_n();
- case 0xdf: return op_rst_n(0x18);
- case 0xe0: return op_ld_ffn_a();
- case 0xe1: return op_pop_rr(HL);
- case 0xe2: return op_ld_ffc_a();
- case 0xe3: return op_xx();
- case 0xe4: return op_xx();
- case 0xe5: return op_push_rr(HL);
- case 0xe6: return op_and_a_n();
- case 0xe7: return op_rst_n(0x20);
- case 0xe8: return op_add_sp_n();
- case 0xe9: return op_jp_hl();
- case 0xea: return op_ld_nn_a();
- case 0xeb: return op_xx();
- case 0xec: return op_xx();
- case 0xed: return op_xx();
- case 0xee: return op_xor_a_n();
- case 0xef: return op_rst_n(0x28);
- case 0xf0: return op_ld_a_ffn();
- case 0xf1: return op_pop_rr(AF);
- case 0xf2: return op_ld_a_ffc();
- case 0xf3: return op_di();
- case 0xf4: return op_xx();
- case 0xf5: return op_push_rr(AF);
- case 0xf6: return op_or_a_n();
- case 0xf7: return op_rst_n(0x30);
- case 0xf8: return op_ld_hl_sp_n();
- case 0xf9: return op_ld_sp_hl();
- case 0xfa: return op_ld_a_nn();
- case 0xfb: return op_ei();
- case 0xfc: return op_xx();
- case 0xfd: return op_xx();
- case 0xfe: return op_cp_a_n();
- case 0xff: return op_rst_n(0x38);
- }
-}
-
-auto LR35902::instructionCB() -> void {
- switch(auto opcode = read(r[PC]++)) {
- case 0x00: return op_rlc_r(B);
- case 0x01: return op_rlc_r(C);
- case 0x02: return op_rlc_r(D);
- case 0x03: return op_rlc_r(E);
- case 0x04: return op_rlc_r(H);
- case 0x05: return op_rlc_r(L);
- case 0x06: return op_rlc_hl();
- case 0x07: return op_rlc_r(A);
- case 0x08: return op_rrc_r(B);
- case 0x09: return op_rrc_r(C);
- case 0x0a: return op_rrc_r(D);
- case 0x0b: return op_rrc_r(E);
- case 0x0c: return op_rrc_r(H);
- case 0x0d: return op_rrc_r(L);
- case 0x0e: return op_rrc_hl();
- case 0x0f: return op_rrc_r(A);
- case 0x10: return op_rl_r(B);
- case 0x11: return op_rl_r(C);
- case 0x12: return op_rl_r(D);
- case 0x13: return op_rl_r(E);
- case 0x14: return op_rl_r(H);
- case 0x15: return op_rl_r(L);
- case 0x16: return op_rl_hl();
- case 0x17: return op_rl_r(A);
- case 0x18: return op_rr_r(B);
- case 0x19: return op_rr_r(C);
- case 0x1a: return op_rr_r(D);
- case 0x1b: return op_rr_r(E);
- case 0x1c: return op_rr_r(H);
- case 0x1d: return op_rr_r(L);
- case 0x1e: return op_rr_hl();
- case 0x1f: return op_rr_r(A);
- case 0x20: return op_sla_r(B);
- case 0x21: return op_sla_r(C);
- case 0x22: return op_sla_r(D);
- case 0x23: return op_sla_r(E);
- case 0x24: return op_sla_r(H);
- case 0x25: return op_sla_r(L);
- case 0x26: return op_sla_hl();
- case 0x27: return op_sla_r(A);
- case 0x28: return op_sra_r(B);
- case 0x29: return op_sra_r(C);
- case 0x2a: return op_sra_r(D);
- case 0x2b: return op_sra_r(E);
- case 0x2c: return op_sra_r(H);
- case 0x2d: return op_sra_r(L);
- case 0x2e: return op_sra_hl();
- case 0x2f: return op_sra_r(A);
- case 0x30: return op_swap_r(B);
- case 0x31: return op_swap_r(C);
- case 0x32: return op_swap_r(D);
- case 0x33: return op_swap_r(E);
- case 0x34: return op_swap_r(H);
- case 0x35: return op_swap_r(L);
- case 0x36: return op_swap_hl();
- case 0x37: return op_swap_r(A);
- case 0x38: return op_srl_r(B);
- case 0x39: return op_srl_r(C);
- case 0x3a: return op_srl_r(D);
- case 0x3b: return op_srl_r(E);
- case 0x3c: return op_srl_r(H);
- case 0x3d: return op_srl_r(L);
- case 0x3e: return op_srl_hl();
- case 0x3f: return op_srl_r(A);
- case 0x40: return op_bit_n_r(0, B);
- case 0x41: return op_bit_n_r(0, C);
- case 0x42: return op_bit_n_r(0, D);
- case 0x43: return op_bit_n_r(0, E);
- case 0x44: return op_bit_n_r(0, H);
- case 0x45: return op_bit_n_r(0, L);
- case 0x46: return op_bit_n_hl(0);
- case 0x47: return op_bit_n_r(0, A);
- case 0x48: return op_bit_n_r(1, B);
- case 0x49: return op_bit_n_r(1, C);
- case 0x4a: return op_bit_n_r(1, D);
- case 0x4b: return op_bit_n_r(1, E);
- case 0x4c: return op_bit_n_r(1, H);
- case 0x4d: return op_bit_n_r(1, L);
- case 0x4e: return op_bit_n_hl(1);
- case 0x4f: return op_bit_n_r(1, A);
- case 0x50: return op_bit_n_r(2, B);
- case 0x51: return op_bit_n_r(2, C);
- case 0x52: return op_bit_n_r(2, D);
- case 0x53: return op_bit_n_r(2, E);
- case 0x54: return op_bit_n_r(2, H);
- case 0x55: return op_bit_n_r(2, L);
- case 0x56: return op_bit_n_hl(2);
- case 0x57: return op_bit_n_r(2, A);
- case 0x58: return op_bit_n_r(3, B);
- case 0x59: return op_bit_n_r(3, C);
- case 0x5a: return op_bit_n_r(3, D);
- case 0x5b: return op_bit_n_r(3, E);
- case 0x5c: return op_bit_n_r(3, H);
- case 0x5d: return op_bit_n_r(3, L);
- case 0x5e: return op_bit_n_hl(3);
- case 0x5f: return op_bit_n_r(3, A);
- case 0x60: return op_bit_n_r(4, B);
- case 0x61: return op_bit_n_r(4, C);
- case 0x62: return op_bit_n_r(4, D);
- case 0x63: return op_bit_n_r(4, E);
- case 0x64: return op_bit_n_r(4, H);
- case 0x65: return op_bit_n_r(4, L);
- case 0x66: return op_bit_n_hl(4);
- case 0x67: return op_bit_n_r(4, A);
- case 0x68: return op_bit_n_r(5, B);
- case 0x69: return op_bit_n_r(5, C);
- case 0x6a: return op_bit_n_r(5, D);
- case 0x6b: return op_bit_n_r(5, E);
- case 0x6c: return op_bit_n_r(5, H);
- case 0x6d: return op_bit_n_r(5, L);
- case 0x6e: return op_bit_n_hl(5);
- case 0x6f: return op_bit_n_r(5, A);
- case 0x70: return op_bit_n_r(6, B);
- case 0x71: return op_bit_n_r(6, C);
- case 0x72: return op_bit_n_r(6, D);
- case 0x73: return op_bit_n_r(6, E);
- case 0x74: return op_bit_n_r(6, H);
- case 0x75: return op_bit_n_r(6, L);
- case 0x76: return op_bit_n_hl(6);
- case 0x77: return op_bit_n_r(6, A);
- case 0x78: return op_bit_n_r(7, B);
- case 0x79: return op_bit_n_r(7, C);
- case 0x7a: return op_bit_n_r(7, D);
- case 0x7b: return op_bit_n_r(7, E);
- case 0x7c: return op_bit_n_r(7, H);
- case 0x7d: return op_bit_n_r(7, L);
- case 0x7e: return op_bit_n_hl(7);
- case 0x7f: return op_bit_n_r(7, A);
- case 0x80: return op_res_n_r(0, B);
- case 0x81: return op_res_n_r(0, C);
- case 0x82: return op_res_n_r(0, D);
- case 0x83: return op_res_n_r(0, E);
- case 0x84: return op_res_n_r(0, H);
- case 0x85: return op_res_n_r(0, L);
- case 0x86: return op_res_n_hl(0);
- case 0x87: return op_res_n_r(0, A);
- case 0x88: return op_res_n_r(1, B);
- case 0x89: return op_res_n_r(1, C);
- case 0x8a: return op_res_n_r(1, D);
- case 0x8b: return op_res_n_r(1, E);
- case 0x8c: return op_res_n_r(1, H);
- case 0x8d: return op_res_n_r(1, L);
- case 0x8e: return op_res_n_hl(1);
- case 0x8f: return op_res_n_r(1, A);
- case 0x90: return op_res_n_r(2, B);
- case 0x91: return op_res_n_r(2, C);
- case 0x92: return op_res_n_r(2, D);
- case 0x93: return op_res_n_r(2, E);
- case 0x94: return op_res_n_r(2, H);
- case 0x95: return op_res_n_r(2, L);
- case 0x96: return op_res_n_hl(2);
- case 0x97: return op_res_n_r(2, A);
- case 0x98: return op_res_n_r(3, B);
- case 0x99: return op_res_n_r(3, C);
- case 0x9a: return op_res_n_r(3, D);
- case 0x9b: return op_res_n_r(3, E);
- case 0x9c: return op_res_n_r(3, H);
- case 0x9d: return op_res_n_r(3, L);
- case 0x9e: return op_res_n_hl(3);
- case 0x9f: return op_res_n_r(3, A);
- case 0xa0: return op_res_n_r(4, B);
- case 0xa1: return op_res_n_r(4, C);
- case 0xa2: return op_res_n_r(4, D);
- case 0xa3: return op_res_n_r(4, E);
- case 0xa4: return op_res_n_r(4, H);
- case 0xa5: return op_res_n_r(4, L);
- case 0xa6: return op_res_n_hl(4);
- case 0xa7: return op_res_n_r(4, A);
- case 0xa8: return op_res_n_r(5, B);
- case 0xa9: return op_res_n_r(5, C);
- case 0xaa: return op_res_n_r(5, D);
- case 0xab: return op_res_n_r(5, E);
- case 0xac: return op_res_n_r(5, H);
- case 0xad: return op_res_n_r(5, L);
- case 0xae: return op_res_n_hl(5);
- case 0xaf: return op_res_n_r(5, A);
- case 0xb0: return op_res_n_r(6, B);
- case 0xb1: return op_res_n_r(6, C);
- case 0xb2: return op_res_n_r(6, D);
- case 0xb3: return op_res_n_r(6, E);
- case 0xb4: return op_res_n_r(6, H);
- case 0xb5: return op_res_n_r(6, L);
- case 0xb6: return op_res_n_hl(6);
- case 0xb7: return op_res_n_r(6, A);
- case 0xb8: return op_res_n_r(7, B);
- case 0xb9: return op_res_n_r(7, C);
- case 0xba: return op_res_n_r(7, D);
- case 0xbb: return op_res_n_r(7, E);
- case 0xbc: return op_res_n_r(7, H);
- case 0xbd: return op_res_n_r(7, L);
- case 0xbe: return op_res_n_hl(7);
- case 0xbf: return op_res_n_r(7, A);
- case 0xc0: return op_set_n_r(0, B);
- case 0xc1: return op_set_n_r(0, C);
- case 0xc2: return op_set_n_r(0, D);
- case 0xc3: return op_set_n_r(0, E);
- case 0xc4: return op_set_n_r(0, H);
- case 0xc5: return op_set_n_r(0, L);
- case 0xc6: return op_set_n_hl(0);
- case 0xc7: return op_set_n_r(0, A);
- case 0xc8: return op_set_n_r(1, B);
- case 0xc9: return op_set_n_r(1, C);
- case 0xca: return op_set_n_r(1, D);
- case 0xcb: return op_set_n_r(1, E);
- case 0xcc: return op_set_n_r(1, H);
- case 0xcd: return op_set_n_r(1, L);
- case 0xce: return op_set_n_hl(1);
- case 0xcf: return op_set_n_r(1, A);
- case 0xd0: return op_set_n_r(2, B);
- case 0xd1: return op_set_n_r(2, C);
- case 0xd2: return op_set_n_r(2, D);
- case 0xd3: return op_set_n_r(2, E);
- case 0xd4: return op_set_n_r(2, H);
- case 0xd5: return op_set_n_r(2, L);
- case 0xd6: return op_set_n_hl(2);
- case 0xd7: return op_set_n_r(2, A);
- case 0xd8: return op_set_n_r(3, B);
- case 0xd9: return op_set_n_r(3, C);
- case 0xda: return op_set_n_r(3, D);
- case 0xdb: return op_set_n_r(3, E);
- case 0xdc: return op_set_n_r(3, H);
- case 0xdd: return op_set_n_r(3, L);
- case 0xde: return op_set_n_hl(3);
- case 0xdf: return op_set_n_r(3, A);
- case 0xe0: return op_set_n_r(4, B);
- case 0xe1: return op_set_n_r(4, C);
- case 0xe2: return op_set_n_r(4, D);
- case 0xe3: return op_set_n_r(4, E);
- case 0xe4: return op_set_n_r(4, H);
- case 0xe5: return op_set_n_r(4, L);
- case 0xe6: return op_set_n_hl(4);
- case 0xe7: return op_set_n_r(4, A);
- case 0xe8: return op_set_n_r(5, B);
- case 0xe9: return op_set_n_r(5, C);
- case 0xea: return op_set_n_r(5, D);
- case 0xeb: return op_set_n_r(5, E);
- case 0xec: return op_set_n_r(5, H);
- case 0xed: return op_set_n_r(5, L);
- case 0xee: return op_set_n_hl(5);
- case 0xef: return op_set_n_r(5, A);
- case 0xf0: return op_set_n_r(6, B);
- case 0xf1: return op_set_n_r(6, C);
- case 0xf2: return op_set_n_r(6, D);
- case 0xf3: return op_set_n_r(6, E);
- case 0xf4: return op_set_n_r(6, H);
- case 0xf5: return op_set_n_r(6, L);
- case 0xf6: return op_set_n_hl(6);
- case 0xf7: return op_set_n_r(6, A);
- case 0xf8: return op_set_n_r(7, B);
- case 0xf9: return op_set_n_r(7, C);
- case 0xfa: return op_set_n_r(7, D);
- case 0xfb: return op_set_n_r(7, E);
- case 0xfc: return op_set_n_r(7, H);
- case 0xfd: return op_set_n_r(7, L);
- case 0xfe: return op_set_n_hl(7);
- case 0xff: return op_set_n_r(7, A);
- }
-}
diff --git a/higan/processor/lr35902-legacy/instructions.cpp b/higan/processor/lr35902-legacy/instructions.cpp
deleted file mode 100644
index 8f636218..00000000
--- a/higan/processor/lr35902-legacy/instructions.cpp
+++ /dev/null
@@ -1,668 +0,0 @@
-auto LR35902::op_xx() {
-}
-
-auto LR35902::op_cb() {
- instructionCB();
-}
-
-//8-bit load commands
-
-auto LR35902::op_ld_r_r(uint x, uint y) {
- r[x] = r[y];
-}
-
-auto LR35902::op_ld_r_n(uint x) {
- r[x] = read(r[PC]++);
-}
-
-auto LR35902::op_ld_r_hl(uint x) {
- r[x] = read(r[HL]);
-}
-
-auto LR35902::op_ld_hl_r(uint x) {
- write(r[HL], r[x]);
-}
-
-auto LR35902::op_ld_hl_n() {
- write(r[HL], read(r[PC]++));
-}
-
-auto LR35902::op_ld_a_rr(uint x) {
- r[A] = read(r[x]);
-}
-
-auto LR35902::op_ld_a_nn() {
- uint8 lo = read(r[PC]++);
- uint8 hi = read(r[PC]++);
- r[A] = read((hi << 8) | (lo << 0));
-}
-
-auto LR35902::op_ld_rr_a(uint x) {
- write(r[x], r[A]);
-}
-
-auto LR35902::op_ld_nn_a() {
- uint8 lo = read(r[PC]++);
- uint8 hi = read(r[PC]++);
- write((hi << 8) | (lo << 0), r[A]);
-}
-
-auto LR35902::op_ld_a_ffn() {
- r[A] = read(0xff00 + read(r[PC]++));
-}
-
-auto LR35902::op_ld_ffn_a() {
- write(0xff00 + read(r[PC]++), r[A]);
-}
-
-auto LR35902::op_ld_a_ffc() {
- r[A] = read(0xff00 + r[C]);
-}
-
-auto LR35902::op_ld_ffc_a() {
- write(0xff00 + r[C], r[A]);
-}
-
-auto LR35902::op_ldi_hl_a() {
- write(r[HL], r[A]);
- r[HL]++;
-}
-
-auto LR35902::op_ldi_a_hl() {
- r[A] = read(r[HL]);
- r[HL]++;
-}
-
-auto LR35902::op_ldd_hl_a() {
- write(r[HL], r[A]);
- r[HL]--;
-}
-
-auto LR35902::op_ldd_a_hl() {
- r[A] = read(r[HL]);
- r[HL]--;
-}
-
-//16-bit load commands
-
-auto LR35902::op_ld_rr_nn(uint x) {
- r[x] = read(r[PC]++) << 0;
- r[x] |= read(r[PC]++) << 8;
-}
-
-auto LR35902::op_ld_nn_sp() {
- uint16 addr = read(r[PC]++) << 0;
- addr |= read(r[PC]++) << 8;
- write(addr + 0, r[SP] >> 0);
- write(addr + 1, r[SP] >> 8);
-}
-
-auto LR35902::op_ld_sp_hl() {
- r[SP] = r[HL];
- io();
-}
-
-auto LR35902::op_push_rr(uint x) {
- io();
- write(--r[SP], r[x] >> 8);
- write(--r[SP], r[x] >> 0);
-}
-
-auto LR35902::op_pop_rr(uint x) {
- r[x] = read(r[SP]++) << 0;
- r[x] |= read(r[SP]++) << 8;
-}
-
-//8-bit arithmetic commands
-
-auto LR35902::opi_add_a(uint8 x) {
- uint16 rh = r[A] + x;
- uint16 rl = (r[A] & 0x0f) + (x & 0x0f);
- r[A] = rh;
- r.f.z = (uint8)rh == 0;
- r.f.n = 0;
- r.f.h = rl > 0x0f;
- r.f.c = rh > 0xff;
-}
-
-auto LR35902::op_add_a_r(uint x) { opi_add_a(r[x]); }
-auto LR35902::op_add_a_n() { opi_add_a(read(r[PC]++)); }
-auto LR35902::op_add_a_hl() { opi_add_a(read(r[HL])); }
-
-auto LR35902::opi_adc_a(uint8 x) {
- uint16 rh = r[A] + x + r.f.c;
- uint16 rl = (r[A] & 0x0f) + (x & 0x0f) + r.f.c;
- r[A] = rh;
- r.f.z = (uint8)rh == 0;
- r.f.n = 0;
- r.f.h = rl > 0x0f;
- r.f.c = rh > 0xff;
-}
-
-auto LR35902::op_adc_a_r(uint x) { opi_adc_a(r[x]); }
-auto LR35902::op_adc_a_n() { opi_adc_a(read(r[PC]++)); }
-auto LR35902::op_adc_a_hl() { opi_adc_a(read(r[HL])); }
-
-auto LR35902::opi_sub_a(uint8 x) {
- uint16 rh = r[A] - x;
- uint16 rl = (r[A] & 0x0f) - (x & 0x0f);
- r[A] = rh;
- r.f.z = (uint8)rh == 0;
- r.f.n = 1;
- r.f.h = rl > 0x0f;
- r.f.c = rh > 0xff;
-}
-
-auto LR35902::op_sub_a_r(uint x) { opi_sub_a(r[x]); }
-auto LR35902::op_sub_a_n() { opi_sub_a(read(r[PC]++)); }
-auto LR35902::op_sub_a_hl() { opi_sub_a(read(r[HL])); }
-
-auto LR35902::opi_sbc_a(uint8 x) {
- uint16 rh = r[A] - x - r.f.c;
- uint16 rl = (r[A] & 0x0f) - (x & 0x0f) - r.f.c;
- r[A] = rh;
- r.f.z = (uint8)rh == 0;
- r.f.n = 1;
- r.f.h = rl > 0x0f;
- r.f.c = rh > 0xff;
-}
-
-auto LR35902::op_sbc_a_r(uint x) { opi_sbc_a(r[x]); }
-auto LR35902::op_sbc_a_n() { opi_sbc_a(read(r[PC]++)); }
-auto LR35902::op_sbc_a_hl() { opi_sbc_a(read(r[HL])); }
-
-auto LR35902::opi_and_a(uint8 x) {
- r[A] &= x;
- r.f.z = r[A] == 0;
- r.f.n = 0;
- r.f.h = 1;
- r.f.c = 0;
-}
-
-auto LR35902::op_and_a_r(uint x) { opi_and_a(r[x]); }
-auto LR35902::op_and_a_n() { opi_and_a(read(r[PC]++)); }
-auto LR35902::op_and_a_hl() { opi_and_a(read(r[HL])); }
-
-auto LR35902::opi_xor_a(uint8 x) {
- r[A] ^= x;
- r.f.z = r[A] == 0;
- r.f.n = 0;
- r.f.h = 0;
- r.f.c = 0;
-}
-
-auto LR35902::op_xor_a_r(uint x) { opi_xor_a(r[x]); }
-auto LR35902::op_xor_a_n() { opi_xor_a(read(r[PC]++)); }
-auto LR35902::op_xor_a_hl() { opi_xor_a(read(r[HL])); }
-
-auto LR35902::opi_or_a(uint8 x) {
- r[A] |= x;
- r.f.z = r[A] == 0;
- r.f.n = 0;
- r.f.h = 0;
- r.f.c = 0;
-}
-
-auto LR35902::op_or_a_r(uint x) { opi_or_a(r[x]); }
-auto LR35902::op_or_a_n() { opi_or_a(read(r[PC]++)); }
-auto LR35902::op_or_a_hl() { opi_or_a(read(r[HL])); }
-
-auto LR35902::opi_cp_a(uint8 x) {
- uint16 rh = r[A] - x;
- uint16 rl = (r[A] & 0x0f) - (x & 0x0f);
- r.f.z = (uint8)rh == 0;
- r.f.n = 1;
- r.f.h = rl > 0x0f;
- r.f.c = rh > 0xff;
-}
-
-auto LR35902::op_cp_a_r(uint x) { opi_cp_a(r[x]); }
-auto LR35902::op_cp_a_n() { opi_cp_a(read(r[PC]++)); }
-auto LR35902::op_cp_a_hl() { opi_cp_a(read(r[HL])); }
-
-auto LR35902::op_inc_r(uint x) {
- r[x]++;
- r.f.z = r[x] == 0;
- r.f.n = 0;
- r.f.h = (r[x] & 0x0f) == 0x00;
-}
-
-auto LR35902::op_inc_hl() {
- uint8 n = read(r[HL]);
- write(r[HL], ++n);
- r.f.z = n == 0;
- r.f.n = 0;
- r.f.h = (n & 0x0f) == 0x00;
-}
-
-auto LR35902::op_dec_r(uint x) {
- r[x]--;
- r.f.z = r[x] == 0;
- r.f.n = 1;
- r.f.h = (r[x] & 0x0f) == 0x0f;
-}
-
-auto LR35902::op_dec_hl() {
- uint8 n = read(r[HL]);
- write(r[HL], --n);
- r.f.z = n == 0;
- r.f.n = 1;
- r.f.h = (n & 0x0f) == 0x0f;
-}
-
-auto LR35902::op_daa() {
- uint16 a = r[A];
- if(r.f.n == 0) {
- if(r.f.h || (a & 0x0f) > 0x09) a += 0x06;
- if(r.f.c || (a ) > 0x9f) a += 0x60;
- } else {
- if(r.f.h) {
- a -= 0x06;
- if(r.f.c == 0) a &= 0xff;
- }
- if(r.f.c) a -= 0x60;
- }
- r[A] = a;
- r.f.z = r[A] == 0;
- r.f.h = 0;
- r.f.c |= a & 0x100;
-}
-
-auto LR35902::op_cpl() {
- r[A] ^= 0xff;
- r.f.n = 1;
- r.f.h = 1;
-}
-
-//16-bit arithmetic commands
-
-auto LR35902::op_add_hl_rr(uint x) {
- io();
- uint32 rb = (r[HL] + r[x]);
- uint32 rn = (r[HL] & 0xfff) + (r[x] & 0xfff);
- r[HL] = rb;
- r.f.n = 0;
- r.f.h = rn > 0x0fff;
- r.f.c = rb > 0xffff;
-}
-
-auto LR35902::op_inc_rr(uint x) {
- io();
- r[x]++;
-}
-
-auto LR35902::op_dec_rr(uint x) {
- io();
- r[x]--;
-}
-
-auto LR35902::op_add_sp_n() {
- int n = (int8)read(r[PC]++);
- r.f.z = 0;
- r.f.n = 0;
- r.f.h = ((r[SP] & 0x0f) + (n & 0x0f)) > 0x0f;
- r.f.c = ((r[SP] & 0xff) + (n & 0xff)) > 0xff;
- r[SP] += n;
- io();
- io();
-}
-
-auto LR35902::op_ld_hl_sp_n() {
- int n = (int8)read(r[PC]++);
- r.f.z = 0;
- r.f.n = 0;
- r.f.h = ((r[SP] & 0x0f) + (n & 0x0f)) > 0x0f;
- r.f.c = ((r[SP] & 0xff) + (n & 0xff)) > 0xff;
- r[HL] = r[SP] + n;
- io();
-}
-
-//rotate/shift commands
-
-auto LR35902::op_rlca() {
- r[A] = (r[A] << 1) | (r[A] >> 7);
- r.f.z = 0;
- r.f.n = 0;
- r.f.h = 0;
- r.f.c = r[A] & 0x01;
-}
-
-auto LR35902::op_rla() {
- bool c = r[A] & 0x80;
- r[A] = (r[A] << 1) | (r.f.c << 0);
- r.f.z = 0;
- r.f.n = 0;
- r.f.h = 0;
- r.f.c = c;
-}
-
-auto LR35902::op_rrca() {
- r[A] = (r[A] >> 1) | (r[A] << 7);
- r.f.z = 0;
- r.f.n = 0;
- r.f.h = 0;
- r.f.c = r[A] & 0x80;
-}
-
-auto LR35902::op_rra() {
- bool c = r[A] & 0x01;
- r[A] = (r[A] >> 1) | (r.f.c << 7);
- r.f.z = 0;
- r.f.n = 0;
- r.f.h = 0;
- r.f.c = c;
-}
-
-auto LR35902::op_rlc_r(uint x) {
- r[x] = (r[x] << 1) | (r[x] >> 7);
- r.f.z = r[x] == 0;
- r.f.n = 0;
- r.f.h = 0;
- r.f.c = r[x] & 0x01;
-}
-
-auto LR35902::op_rlc_hl() {
- uint8 n = read(r[HL]);
- n = (n << 1) | (n >> 7);
- write(r[HL], n);
- r.f.z = n == 0;
- r.f.n = 0;
- r.f.h = 0;
- r.f.c = n & 0x01;
-}
-
-auto LR35902::op_rl_r(uint x) {
- bool c = r[x] & 0x80;
- r[x] = (r[x] << 1) | (r.f.c << 0);
- r.f.z = r[x] == 0;
- r.f.n = 0;
- r.f.h = 0;
- r.f.c = c;
-}
-
-auto LR35902::op_rl_hl() {
- uint8 n = read(r[HL]);
- bool c = n & 0x80;
- n = (n << 1) | (r.f.c << 0);
- write(r[HL], n);
- r.f.z = n == 0;
- r.f.n = 0;
- r.f.h = 0;
- r.f.c = c;
-}
-
-auto LR35902::op_rrc_r(uint x) {
- r[x] = (r[x] >> 1) | (r[x] << 7);
- r.f.z = r[x] == 0;
- r.f.n = 0;
- r.f.h = 0;
- r.f.c = r[x] & 0x80;
-}
-
-auto LR35902::op_rrc_hl() {
- uint8 n = read(r[HL]);
- n = (n >> 1) | (n << 7);
- write(r[HL], n);
- r.f.z = n == 0;
- r.f.n = 0;
- r.f.h = 0;
- r.f.c = n & 0x80;
-}
-
-auto LR35902::op_rr_r(uint x) {
- bool c = r[x] & 0x01;
- r[x] = (r[x] >> 1) | (r.f.c << 7);
- r.f.z = r[x] == 0;
- r.f.n = 0;
- r.f.h = 0;
- r.f.c = c;
-}
-
-auto LR35902::op_rr_hl() {
- uint8 n = read(r[HL]);
- bool c = n & 0x01;
- n = (n >> 1) | (r.f.c << 7);
- write(r[HL], n);
- r.f.z = n == 0;
- r.f.n = 0;
- r.f.h = 0;
- r.f.c = c;
-}
-
-auto LR35902::op_sla_r(uint x) {
- bool c = r[x] & 0x80;
- r[x] <<= 1;
- r.f.z = r[x] == 0;
- r.f.n = 0;
- r.f.h = 0;
- r.f.c = c;
-}
-
-auto LR35902::op_sla_hl() {
- uint8 n = read(r[HL]);
- bool c = n & 0x80;
- n <<= 1;
- write(r[HL], n);
- r.f.z = n == 0;
- r.f.n = 0;
- r.f.h = 0;
- r.f.c = c;
-}
-
-auto LR35902::op_swap_r(uint x) {
- r[x] = (r[x] << 4) | (r[x] >> 4);
- r.f.z = r[x] == 0;
- r.f.n = 0;
- r.f.h = 0;
- r.f.c = 0;
-}
-
-auto LR35902::op_swap_hl() {
- uint8 n = read(r[HL]);
- n = (n << 4) | (n >> 4);
- write(r[HL], n);
- r.f.z = n == 0;
- r.f.n = 0;
- r.f.h = 0;
- r.f.c = 0;
-}
-
-auto LR35902::op_sra_r(uint x) {
- bool c = r[x] & 0x01;
- r[x] = (int8)r[x] >> 1;
- r.f.z = r[x] == 0;
- r.f.n = 0;
- r.f.h = 0;
- r.f.c = c;
-}
-
-auto LR35902::op_sra_hl() {
- uint8 n = read(r[HL]);
- bool c = n & 0x01;
- n = (int8)n >> 1;
- write(r[HL], n);
- r.f.z = n == 0;
- r.f.n = 0;
- r.f.h = 0;
- r.f.c = c;
-}
-
-auto LR35902::op_srl_r(uint x) {
- bool c = r[x] & 0x01;
- r[x] >>= 1;
- r.f.z = r[x] == 0;
- r.f.n = 0;
- r.f.h = 0;
- r.f.c = c;
-}
-
-auto LR35902::op_srl_hl() {
- uint8 n = read(r[HL]);
- bool c = n & 0x01;
- n >>= 1;
- write(r[HL], n);
- r.f.z = n == 0;
- r.f.n = 0;
- r.f.h = 0;
- r.f.c = c;
-}
-
-//single-bit commands
-
-auto LR35902::op_bit_n_r(uint b, uint x) {
- r.f.z = (r[x] & (1 << b)) == 0;
- r.f.n = 0;
- r.f.h = 1;
-}
-
-auto LR35902::op_bit_n_hl(uint b) {
- uint8 n = read(r[HL]);
- r.f.z = (n & (1 << b)) == 0;
- r.f.n = 0;
- r.f.h = 1;
-}
-
-auto LR35902::op_set_n_r(uint b, uint x) {
- r[x] |= 1 << b;
-}
-
-auto LR35902::op_set_n_hl(uint b) {
- uint8 n = read(r[HL]);
- n |= 1 << b;
- write(r[HL], n);
-}
-
-auto LR35902::op_res_n_r(uint b, uint x) {
- r[x] &= ~(1 << b);
-}
-
-auto LR35902::op_res_n_hl(uint b) {
- uint n = read(r[HL]);
- n &= ~(1 << b);
- write(r[HL], n);
-}
-
-//control commands
-
-auto LR35902::op_ccf() {
- r.f.n = 0;
- r.f.h = 0;
- r.f.c = !r.f.c;
-}
-
-auto LR35902::op_scf() {
- r.f.n = 0;
- r.f.h = 0;
- r.f.c = 1;
-}
-
-auto LR35902::op_nop() {
-}
-
-auto LR35902::op_halt() {
- r.halt = true;
- while(r.halt) io();
-}
-
-auto LR35902::op_stop() {
- if(stop()) return;
- r.stop = true;
- while(r.stop) io();
-}
-
-auto LR35902::op_di() {
- r.ime = 0;
-}
-
-auto LR35902::op_ei() {
- r.ei = true;
-//r.ime = 1;
-}
-
-//jump commands
-
-auto LR35902::op_jp_nn() {
- uint8 lo = read(r[PC]++);
- uint8 hi = read(r[PC]++);
- r[PC] = (hi << 8) | (lo << 0);
- io();
-}
-
-auto LR35902::op_jp_hl() {
- r[PC] = r[HL];
-}
-
-auto LR35902::op_jp_f_nn(uint x, bool y) {
- uint8 lo = read(r[PC]++);
- uint8 hi = read(r[PC]++);
- if(r.f[x] == y) {
- r[PC] = (hi << 8) | (lo << 0);
- io();
- }
-}
-
-auto LR35902::op_jr_n() {
- int8 n = read(r[PC]++);
- r[PC] += n;
- io();
-}
-
-auto LR35902::op_jr_f_n(uint x, bool y) {
- int8 n = read(r[PC]++);
- if(r.f[x] == y) {
- r[PC] += n;
- io();
- }
-}
-
-auto LR35902::op_call_nn() {
- uint8 lo = read(r[PC]++);
- uint8 hi = read(r[PC]++);
- io();
- write(--r[SP], r[PC] >> 8);
- write(--r[SP], r[PC] >> 0);
- r[PC] = (hi << 8) | (lo << 0);
-}
-
-auto LR35902::op_call_f_nn(uint x, bool y) {
- uint8 lo = read(r[PC]++);
- uint8 hi = read(r[PC]++);
- if(r.f[x] == y) {
- io();
- write(--r[SP], r[PC] >> 8);
- write(--r[SP], r[PC] >> 0);
- r[PC] = (hi << 8) | (lo << 0);
- }
-}
-
-auto LR35902::op_ret() {
- uint8 lo = read(r[SP]++);
- uint8 hi = read(r[SP]++);
- r[PC] = (hi << 8) | (lo << 0);
- io();
-}
-
-auto LR35902::op_ret_f(uint x, bool y) {
- io();
- if(r.f[x] == y) {
- uint8 lo = read(r[SP]++);
- uint8 hi = read(r[SP]++);
- r[PC] = (hi << 8) | (lo << 0);
- io();
- }
-}
-
-auto LR35902::op_reti() {
- uint8 lo = read(r[SP]++);
- uint8 hi = read(r[SP]++);
- r[PC] = (hi << 8) | (lo << 0);
- io();
- r.ime = 1;
-}
-
-auto LR35902::op_rst_n(uint n) {
- io();
- write(--r[SP], r[PC] >> 8);
- write(--r[SP], r[PC] >> 0);
- r[PC] = n;
-}
diff --git a/higan/processor/lr35902-legacy/lr35902.cpp b/higan/processor/lr35902-legacy/lr35902.cpp
deleted file mode 100644
index c37e705c..00000000
--- a/higan/processor/lr35902-legacy/lr35902.cpp
+++ /dev/null
@@ -1,25 +0,0 @@
-#include
-#include "lr35902.hpp"
-
-namespace Processor {
-
-#include "instructions.cpp"
-#include "instruction.cpp"
-#include "serialization.cpp"
-#include "disassembler.cpp"
-
-auto LR35902::power() -> void {
- r[AF] = 0x0000;
- r[BC] = 0x0000;
- r[DE] = 0x0000;
- r[HL] = 0x0000;
- r[SP] = 0x0000;
- r[PC] = 0x0000;
-
- r.halt = false;
- r.stop = false;
- r.ei = false;
- r.ime = false;
-}
-
-}
diff --git a/higan/processor/lr35902-legacy/lr35902.hpp b/higan/processor/lr35902-legacy/lr35902.hpp
deleted file mode 100644
index 0535d1ef..00000000
--- a/higan/processor/lr35902-legacy/lr35902.hpp
+++ /dev/null
@@ -1,174 +0,0 @@
-//Sharp LR35902 (Game Boy Z80-derivative)
-
-#pragma once
-
-namespace Processor {
-
-struct LR35902 {
- virtual auto idle() -> void = 0;
- virtual auto read(uint16 addr) -> uint8 = 0;
- virtual auto write(uint16 addr, uint8 data) -> void = 0;
- virtual auto stop() -> bool = 0;
-
- auto io() -> void { idle(); }
-
- //lr35902.cpp
- auto power() -> void;
-
- //instruction.cpp
- auto interrupt(uint16 vector) -> void;
- auto instruction() -> void;
- auto instructionCB() -> void;
-
- //serialization.cpp
- auto serialize(serializer&) -> void;
-
- //disassembler.cpp
- virtual auto readDebugger(uint16 addr) -> uint8 { return 0; }
- auto disassemble(uint16 pc) -> string;
-
- #include "registers.hpp"
-
-private:
- auto op_xx();
- auto op_cb();
-
- //8-bit load commands
- auto op_ld_r_r(uint x, uint y);
- auto op_ld_r_n(uint x);
- auto op_ld_r_hl(uint x);
- auto op_ld_hl_r(uint x);
- auto op_ld_hl_n();
- auto op_ld_a_rr(uint x);
- auto op_ld_a_nn();
- auto op_ld_rr_a(uint x);
- auto op_ld_nn_a();
- auto op_ld_a_ffn();
- auto op_ld_ffn_a();
- auto op_ld_a_ffc();
- auto op_ld_ffc_a();
- auto op_ldi_hl_a();
- auto op_ldi_a_hl();
- auto op_ldd_hl_a();
- auto op_ldd_a_hl();
-
- //16-bit load commands
- auto op_ld_rr_nn(uint x);
- auto op_ld_nn_sp();
- auto op_ld_sp_hl();
- auto op_push_rr(uint x);
- auto op_pop_rr(uint x);
-
- //8-bit arithmetic commands
- auto opi_add_a(uint8 x);
- auto op_add_a_r(uint x);
- auto op_add_a_n();
- auto op_add_a_hl();
-
- auto opi_adc_a(uint8 x);
- auto op_adc_a_r(uint x);
- auto op_adc_a_n();
- auto op_adc_a_hl();
-
- auto opi_sub_a(uint8 x);
- auto op_sub_a_r(uint x);
- auto op_sub_a_n();
- auto op_sub_a_hl();
-
- auto opi_sbc_a(uint8 x);
- auto op_sbc_a_r(uint x);
- auto op_sbc_a_n();
- auto op_sbc_a_hl();
-
- auto opi_and_a(uint8 x);
- auto op_and_a_r(uint x);
- auto op_and_a_n();
- auto op_and_a_hl();
-
- auto opi_xor_a(uint8 x);
- auto op_xor_a_r(uint x);
- auto op_xor_a_n();
- auto op_xor_a_hl();
-
- auto opi_or_a(uint8 x);
- auto op_or_a_r(uint x);
- auto op_or_a_n();
- auto op_or_a_hl();
-
- auto opi_cp_a(uint8 x);
- auto op_cp_a_r(uint x);
- auto op_cp_a_n();
- auto op_cp_a_hl();
-
- auto op_inc_r(uint x);
- auto op_inc_hl();
- auto op_dec_r(uint x);
- auto op_dec_hl();
- auto op_daa();
- auto op_cpl();
-
- //16-bit arithmetic commands
- auto op_add_hl_rr(uint x);
- auto op_inc_rr(uint x);
- auto op_dec_rr(uint x);
- auto op_add_sp_n();
- auto op_ld_hl_sp_n();
-
- //rotate/shift commands
- auto op_rlca();
- auto op_rla();
- auto op_rrca();
- auto op_rra();
- auto op_rlc_r(uint x);
- auto op_rlc_hl();
- auto op_rl_r(uint x);
- auto op_rl_hl();
- auto op_rrc_r(uint x);
- auto op_rrc_hl();
- auto op_rr_r(uint x);
- auto op_rr_hl();
- auto op_sla_r(uint x);
- auto op_sla_hl();
- auto op_swap_r(uint x);
- auto op_swap_hl();
- auto op_sra_r(uint x);
- auto op_sra_hl();
- auto op_srl_r(uint x);
- auto op_srl_hl();
-
- //single-bit commands
- auto op_bit_n_r(uint b, uint x);
- auto op_bit_n_hl(uint b);
- auto op_set_n_r(uint b, uint x);
- auto op_set_n_hl(uint b);
- auto op_res_n_r(uint b, uint x);
- auto op_res_n_hl(uint b);
-
- //control commands
- auto op_ccf();
- auto op_scf();
- auto op_nop();
- auto op_halt();
- auto op_stop();
- auto op_di();
- auto op_ei();
-
- //jump commands
- auto op_jp_nn();
- auto op_jp_hl();
- auto op_jp_f_nn(uint x, bool y);
- auto op_jr_n();
- auto op_jr_f_n(uint x, bool y);
- auto op_call_nn();
- auto op_call_f_nn(uint x, bool y);
- auto op_ret();
- auto op_ret_f(uint x, bool y);
- auto op_reti();
- auto op_rst_n(uint n);
-
- //disassembler.cpp
- auto disassembleOpcode(uint16 pc) -> string;
- auto disassembleOpcodeCB(uint16 pc) -> string;
-};
-
-}
diff --git a/higan/processor/lr35902-legacy/registers.hpp b/higan/processor/lr35902-legacy/registers.hpp
deleted file mode 100644
index 785ce77b..00000000
--- a/higan/processor/lr35902-legacy/registers.hpp
+++ /dev/null
@@ -1,107 +0,0 @@
-enum {
- A, F, AF,
- B, C, BC,
- D, E, DE,
- H, L, HL,
- SP, PC,
-};
-
-enum {
- ZF, NF, HF, CF,
-};
-
-//register base class
-//the idea here is to have all registers derive from a single base class.
-//this allows construction of opcodes that can take any register as input or output,
-//despite the fact that behind-the-scenes, special handling is done for eg: F, AF, HL, etc.
-//registers can also be chained together: eg af = 0x0000 writes both a and f.
-struct Register {
- virtual operator uint() const = 0;
- virtual auto operator=(uint x) -> uint = 0;
- auto operator=(const Register& x) -> Register& { operator=((uint)x); return *this; }
-
- auto operator++(int) -> uint { uint r = *this; operator=(*this + 1); return r; }
- auto operator--(int) -> uint { uint r = *this; operator=(*this - 1); return r; }
- auto operator++() -> uint { return operator=(*this + 1); }
- auto operator--() -> uint { return operator=(*this - 1); }
-
- auto operator |=(uint x) -> uint { return operator=(*this | x); }
- auto operator ^=(uint x) -> uint { return operator=(*this ^ x); }
- auto operator &=(uint x) -> uint { return operator=(*this & x); }
-
- auto operator<<=(uint x) -> uint { return operator=(*this << x); }
- auto operator>>=(uint x) -> uint { return operator=(*this >> x); }
-
- auto operator +=(uint x) -> uint { return operator=(*this + x); }
- auto operator -=(uint x) -> uint { return operator=(*this - x); }
- auto operator *=(uint x) -> uint { return operator=(*this * x); }
- auto operator /=(uint x) -> uint { return operator=(*this / x); }
- auto operator %=(uint x) -> uint { return operator=(*this % x); }
-};
-
-struct Register8 : Register {
- uint8 data;
- operator uint() const { return data; }
- auto operator=(uint x) -> uint { return data = x; }
-};
-
-struct RegisterF : Register {
- bool z, n, h, c;
- operator uint() const { return (z << 7) | (n << 6) | (h << 5) | (c << 4); }
- auto operator=(uint x) -> uint { z = x & 0x80; n = x & 0x40; h = x & 0x20; c = x & 0x10; return *this; }
- bool& operator[](uint r) {
- static bool* table[] = {&z, &n, &h, &c};
- return *table[r];
- }
-};
-
-struct Register16 : Register {
- uint16 data;
- operator uint() const { return data; }
- auto operator=(uint x) -> uint { return data = x; }
-};
-
-struct RegisterAF : Register {
- Register8& hi;
- RegisterF& lo;
- operator uint() const { return (hi << 8) | (lo << 0); }
- auto operator=(uint x) -> uint { hi = x >> 8; lo = x >> 0; return *this; }
- RegisterAF(Register8& hi, RegisterF& lo) : hi(hi), lo(lo) {}
-};
-
-struct RegisterW : Register {
- Register8& hi;
- Register8& lo;
- operator uint() const { return (hi << 8) | (lo << 0); }
- auto operator=(uint x) -> uint { hi = x >> 8; lo = x >> 0; return *this; }
- RegisterW(Register8& hi, Register8& lo) : hi(hi), lo(lo) {}
-};
-
-struct Registers {
- Register8 a;
- RegisterF f;
- RegisterAF af;
- Register8 b;
- Register8 c;
- RegisterW bc;
- Register8 d;
- Register8 e;
- RegisterW de;
- Register8 h;
- Register8 l;
- RegisterW hl;
- Register16 sp;
- Register16 pc;
-
- bool halt;
- bool stop;
- bool ei;
- bool ime;
-
- auto operator[](uint r) -> Register& {
- static Register* const table[] = {&a, &f, &af, &b, &c, &bc, &d, &e, &de, &h, &l, &hl, &sp, &pc};
- return *table[r];
- }
-
- Registers() : af(a, f), bc(b, c), de(d, e), hl(h, l) {}
-} r;
diff --git a/higan/processor/lr35902-legacy/serialization.cpp b/higan/processor/lr35902-legacy/serialization.cpp
deleted file mode 100644
index 63beee28..00000000
--- a/higan/processor/lr35902-legacy/serialization.cpp
+++ /dev/null
@@ -1,20 +0,0 @@
-auto LR35902::serialize(serializer& s) -> void {
- s.integer(r.a.data);
- s.integer(r.f.z);
- s.integer(r.f.n);
- s.integer(r.f.h);
- s.integer(r.f.c);
- s.integer(r.b.data);
- s.integer(r.c.data);
- s.integer(r.d.data);
- s.integer(r.e.data);
- s.integer(r.h.data);
- s.integer(r.l.data);
- s.integer(r.sp.data);
- s.integer(r.pc.data);
-
- s.integer(r.halt);
- s.integer(r.stop);
- s.integer(r.ei);
- s.integer(r.ime);
-}
diff --git a/higan/sfc/coprocessor/armdsp/armdsp.hpp b/higan/sfc/coprocessor/armdsp/armdsp.hpp
index 8786caed..b5cbd6c0 100644
--- a/higan/sfc/coprocessor/armdsp/armdsp.hpp
+++ b/higan/sfc/coprocessor/armdsp/armdsp.hpp
@@ -11,9 +11,9 @@ struct ArmDSP : Processor::ARM, Thread {
auto main() -> void;
auto step(uint clocks) -> void override;
- auto _idle() -> void override;
- auto _read(uint mode, uint32 addr) -> uint32 override;
- auto _write(uint mode, uint32 addr, uint32 word) -> void override;
+ auto sleep() -> void override;
+ auto get(uint mode, uint32 addr) -> uint32 override;
+ auto set(uint mode, uint32 addr, uint32 word) -> void override;
auto read(uint24 addr, uint8 data) -> uint8;
auto write(uint24 addr, uint8 data) -> void;
diff --git a/higan/sfc/coprocessor/armdsp/memory.cpp b/higan/sfc/coprocessor/armdsp/memory.cpp
index ceb0d4ee..48e237f8 100644
--- a/higan/sfc/coprocessor/armdsp/memory.cpp
+++ b/higan/sfc/coprocessor/armdsp/memory.cpp
@@ -1,11 +1,11 @@
//note: timings are completely unverified
//due to the ST018 chip design (on-die ROM), testing is nearly impossible
-auto ArmDSP::_idle() -> void {
+auto ArmDSP::sleep() -> void {
step(1);
}
-auto ArmDSP::_read(uint mode, uint32 addr) -> uint32 {
+auto ArmDSP::get(uint mode, uint32 addr) -> uint32 {
step(1);
static auto memory = [&](const uint8* memory, uint mode, uint32 addr) -> uint32 {
@@ -46,7 +46,7 @@ auto ArmDSP::_read(uint mode, uint32 addr) -> uint32 {
return 0;
}
-auto ArmDSP::_write(uint mode, uint32 addr, uint32 word) -> void {
+auto ArmDSP::set(uint mode, uint32 addr, uint32 word) -> void {
step(1);
static auto memory = [](uint8* memory, uint mode, uint32 addr, uint32 word) {
diff --git a/hiro/windows/hiro.Manifest b/hiro/windows/hiro.Manifest
index a7e39c8d..5f6ac40d 100644
--- a/hiro/windows/hiro.Manifest
+++ b/hiro/windows/hiro.Manifest
@@ -8,7 +8,7 @@
- true
+ false
diff --git a/icarus/icarus.plist b/icarus/icarus.plist
index 5caaab81..67833d77 100644
--- a/icarus/icarus.plist
+++ b/icarus/icarus.plist
@@ -13,7 +13,7 @@
icarus.icns
-->
NSHighResolutionCapable
-
+
NSSupportsAutomaticGraphicsSwitching
diff --git a/ruby/video/cgl.cpp b/ruby/video/cgl.cpp
index c6b63c8b..d7f705b7 100644
--- a/ruby/video/cgl.cpp
+++ b/ruby/video/cgl.cpp
@@ -78,7 +78,7 @@ struct VideoCGL : Video, OpenGL {
if(!ready()) return;
@autoreleasepool {
if([view lockFocusIfCanDraw]) {
- auto area = [view frame];
+ auto area = [view convertRectToBacking:[view bounds]];
OpenGL::outputWidth = area.size.width;
OpenGL::outputHeight = area.size.height;
OpenGL::output();
@@ -110,6 +110,7 @@ private:
[view setOpenGLContext:context];
[view setFrame:NSMakeRect(0, 0, size.width, size.height)];
[view setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
+ [view setWantsBestResolutionOpenGLSurface:YES];
[_context addSubview:view];
[context setView:view];