diff --git a/higan/emulator/emulator.hpp b/higan/emulator/emulator.hpp index 5191caaa..4c643c40 100644 --- a/higan/emulator/emulator.hpp +++ b/higan/emulator/emulator.hpp @@ -9,7 +9,7 @@ using namespace nall; namespace Emulator { static const string Name = "higan"; - static const string Version = "098.16"; + static const string Version = "098.17"; static const string Author = "byuu"; static const string License = "GPLv3"; static const string Website = "http://byuu.org/"; diff --git a/higan/gb/cpu/cpu.cpp b/higan/gb/cpu/cpu.cpp index 7f235c22..6ce35d5b 100644 --- a/higan/gb/cpu/cpu.cpp +++ b/higan/gb/cpu/cpu.cpp @@ -14,10 +14,10 @@ auto CPU::Enter() -> void { auto CPU::main() -> void { interrupt_test(); - exec(); + instruction(); } -auto CPU::interrupt_raise(CPU::Interrupt id) -> void { +auto CPU::raise(CPU::Interrupt id) -> void { if(id == Interrupt::Vblank) { status.interrupt_request_vblank = 1; if(status.interrupt_enable_vblank) r.halt = false; @@ -44,51 +44,35 @@ auto CPU::interrupt_raise(CPU::Interrupt id) -> void { } } -auto CPU::interrupt_lower(CPU::Interrupt id) -> void { - if(id == Interrupt::Stat) { - status.interrupt_request_stat = 0; - } -} - auto CPU::interrupt_test() -> void { if(!r.ime) return; if(status.interrupt_request_vblank && status.interrupt_enable_vblank) { status.interrupt_request_vblank = 0; - return interrupt_exec(0x0040); + return interrupt(0x0040); } if(status.interrupt_request_stat && status.interrupt_enable_stat) { status.interrupt_request_stat = 0; - return interrupt_exec(0x0048); + return interrupt(0x0048); } if(status.interrupt_request_timer && status.interrupt_enable_timer) { status.interrupt_request_timer = 0; - return interrupt_exec(0x0050); + return interrupt(0x0050); } if(status.interrupt_request_serial && status.interrupt_enable_serial) { status.interrupt_request_serial = 0; - return interrupt_exec(0x0058); + return interrupt(0x0058); } if(status.interrupt_request_joypad && status.interrupt_enable_joypad) { status.interrupt_request_joypad = 0; - return interrupt_exec(0x0060); + return interrupt(0x0060); } } -auto CPU::interrupt_exec(uint16 pc) -> void { - op_io(); - op_io(); - op_io(); - r.ime = 0; - op_write(--r[SP], r[PC] >> 8); - op_write(--r[SP], r[PC] >> 0); - r[PC] = pc; -} - auto CPU::stop() -> bool { if(status.speed_switch) { status.speed_switch = 0; diff --git a/higan/gb/cpu/cpu.hpp b/higan/gb/cpu/cpu.hpp index cde61a20..abae6161 100644 --- a/higan/gb/cpu/cpu.hpp +++ b/higan/gb/cpu/cpu.hpp @@ -3,10 +3,8 @@ struct CPU : Processor::LR35902, Thread, MMIO { static auto Enter() -> void; auto main() -> void; - auto interrupt_raise(Interrupt id) -> void; - auto interrupt_lower(Interrupt id) -> void; + auto raise(Interrupt id) -> void; auto interrupt_test() -> void; - auto interrupt_exec(uint16 pc) -> void; auto stop() -> bool; auto power() -> void; @@ -19,9 +17,9 @@ struct CPU : Processor::LR35902, Thread, MMIO { auto mmio_write(uint16 addr, uint8 data) -> void; //memory.cpp - auto op_io() -> void; - auto op_read(uint16 addr) -> uint8; - auto op_write(uint16 addr, uint8 data) -> void; + auto io() -> void override; + auto read(uint16 addr) -> uint8 override; + auto write(uint16 addr, uint8 data) -> void override; auto cycle_edge() -> void; auto dma_read(uint16 addr) -> uint8; auto dma_write(uint16 addr, uint8 data) -> void; diff --git a/higan/gb/cpu/memory.cpp b/higan/gb/cpu/memory.cpp index 642876a0..bb9e62fe 100644 --- a/higan/gb/cpu/memory.cpp +++ b/higan/gb/cpu/memory.cpp @@ -1,15 +1,15 @@ -auto CPU::op_io() -> void { +auto CPU::io() -> void { cycle_edge(); add_clocks(4); } -auto CPU::op_read(uint16 addr) -> uint8 { +auto CPU::read(uint16 addr) -> uint8 { cycle_edge(); add_clocks(4); return bus.read(addr); } -auto CPU::op_write(uint16 addr, uint8 data) -> void { +auto CPU::write(uint16 addr, uint8 data) -> void { cycle_edge(); add_clocks(4); bus.write(addr, data); diff --git a/higan/gb/cpu/mmio.cpp b/higan/gb/cpu/mmio.cpp index a27174ab..c470c69b 100644 --- a/higan/gb/cpu/mmio.cpp +++ b/higan/gb/cpu/mmio.cpp @@ -29,7 +29,7 @@ auto CPU::mmio_joyp_poll() -> void { if(status.p15 == 1 && status.p14 == 1) status.joyp -= status.mlt_req; if(status.p15 == 0) status.joyp &= button ^ 0x0f; if(status.p14 == 0) status.joyp &= dpad ^ 0x0f; - if(status.joyp != 0x0f) interrupt_raise(Interrupt::Joypad); + if(status.joyp != 0x0f) raise(Interrupt::Joypad); } auto CPU::mmio_read(uint16 addr) -> uint8 { diff --git a/higan/gb/cpu/timing.cpp b/higan/gb/cpu/timing.cpp index 2067676b..77af3a7c 100644 --- a/higan/gb/cpu/timing.cpp +++ b/higan/gb/cpu/timing.cpp @@ -3,9 +3,7 @@ // 154 scanlines/frame auto CPU::add_clocks(uint clocks) -> void { - if(system.sgb()) system._clocksExecuted += clocks; - - while(clocks--) { + for(auto n : range(clocks)) { if(++status.clock == 0) { cartridge.mbc3.second(); } @@ -25,14 +23,17 @@ auto CPU::add_clocks(uint clocks) -> void { if(apu.clock < 0) co_switch(apu.thread); } - if(system.sgb()) scheduler.exit(Scheduler::Event::Step); + if(system.sgb()) { + system._clocksExecuted += clocks; + scheduler.exit(Scheduler::Event::Step); + } } auto CPU::timer_262144hz() -> void { if(status.timer_enable && status.timer_clock == 1) { if(++status.tima == 0) { status.tima = status.tma; - interrupt_raise(Interrupt::Timer); + raise(Interrupt::Timer); } } } @@ -41,7 +42,7 @@ auto CPU::timer_65536hz() -> void { if(status.timer_enable && status.timer_clock == 2) { if(++status.tima == 0) { status.tima = status.tma; - interrupt_raise(Interrupt::Timer); + raise(Interrupt::Timer); } } } @@ -50,7 +51,7 @@ auto CPU::timer_16384hz() -> void { if(status.timer_enable && status.timer_clock == 3) { if(++status.tima == 0) { status.tima = status.tma; - interrupt_raise(Interrupt::Timer); + raise(Interrupt::Timer); } } } @@ -59,7 +60,7 @@ auto CPU::timer_8192hz() -> void { if(status.serial_transfer && status.serial_clock) { if(--status.serial_bits == 0) { status.serial_transfer = 0; - interrupt_raise(Interrupt::Serial); + raise(Interrupt::Serial); } } } @@ -68,7 +69,7 @@ auto CPU::timer_4096hz() -> void { if(status.timer_enable && status.timer_clock == 0) { if(++status.tima == 0) { status.tima = status.tma; - interrupt_raise(Interrupt::Timer); + raise(Interrupt::Timer); } } } diff --git a/higan/gb/ppu/cgb.cpp b/higan/gb/ppu/cgb.cpp index 8d8c0ec6..39c86d44 100644 --- a/higan/gb/ppu/cgb.cpp +++ b/higan/gb/ppu/cgb.cpp @@ -37,6 +37,7 @@ auto PPU::cgb_read_tile(bool select, uint x, uint y, uint& attr, uint& data) -> auto PPU::cgb_scanline() -> void { px = 0; + if(!enabled()) return; const uint Height = (status.ob_size == 0 ? 8 : 16); sprites = 0; @@ -68,7 +69,7 @@ auto PPU::cgb_run() -> void { ob.priority = 0; uint color = 0x7fff; - if(status.display_enable) { + if(enabled()) { cgb_run_bg(); if(status.window_display_enable) cgb_run_window(); if(status.ob_enable) cgb_run_ob(); diff --git a/higan/gb/ppu/dmg.cpp b/higan/gb/ppu/dmg.cpp index 6b239f7f..c159bb94 100644 --- a/higan/gb/ppu/dmg.cpp +++ b/higan/gb/ppu/dmg.cpp @@ -19,6 +19,7 @@ auto PPU::dmg_read_tile(bool select, uint x, uint y, uint& data) -> void { auto PPU::dmg_scanline() -> void { px = 0; + if(!enabled()) return; const uint Height = (status.ob_size == 0 ? 8 : 16); sprites = 0; @@ -59,7 +60,7 @@ auto PPU::dmg_run() -> void { ob.palette = 0; uint color = 0; - if(status.display_enable) { + if(enabled()) { if(status.bg_enable) dmg_run_bg(); if(status.window_display_enable) dmg_run_window(); if(status.ob_enable) dmg_run_ob(); diff --git a/higan/gb/ppu/ppu.cpp b/higan/gb/ppu/ppu.cpp index 3546ff10..bad9ed05 100644 --- a/higan/gb/ppu/ppu.cpp +++ b/higan/gb/ppu/ppu.cpp @@ -8,6 +8,8 @@ PPU ppu; #include "cgb.cpp" #include "serialization.cpp" +auto PPU::enabled() const -> bool { return status.display_enable; } + auto PPU::Enter() -> void { while(true) scheduler.synchronize(), ppu.main(); } @@ -16,7 +18,7 @@ auto PPU::main() -> void { status.lx = 0; interface->lcdScanline(); //Super Game Boy notification - if(status.display_enable && status.ly <= 143) { + if(status.ly <= 143) { mode(2); scanline(); wait(92); @@ -28,7 +30,7 @@ auto PPU::main() -> void { } mode(0); - cpu.hblank(); + if(enabled()) cpu.hblank(); wait(204); } else { mode(1); @@ -38,7 +40,7 @@ auto PPU::main() -> void { status.ly++; if(status.ly == 144) { - cpu.interrupt_raise(CPU::Interrupt::Vblank); + if(enabled()) cpu.raise(CPU::Interrupt::Vblank); scheduler.exit(Scheduler::Event::Frame); } @@ -48,35 +50,25 @@ auto PPU::main() -> void { } auto PPU::mode(uint mode) -> void { + if(!enabled()) mode = 1; //force blank status.mode = mode; +} + +auto PPU::stat() -> void { bool irq = status.irq; - if(status.mode == 0) { //hblank - status.irq = status.interrupt_hblank; - } + status.irq = status.interrupt_hblank && status.mode == 0; + status.irq |= status.interrupt_vblank && status.mode == 1; + status.irq |= status.interrupt_oam && status.mode == 2; + status.irq |= status.interrupt_lyc && coincidence(); - if(status.mode == 1) { //vblank - status.irq = status.interrupt_vblank || (status.interrupt_lyc && coincidence()); - } - - if(status.mode == 2) { //oam - status.irq = status.interrupt_oam || (status.interrupt_lyc && coincidence()); - } - - if(status.mode == 3) { //render - status.irq = false; - } - - if(!irq && status.irq) { - cpu.interrupt_raise(CPU::Interrupt::Stat); - } else if(!status.irq) { - cpu.interrupt_lower(CPU::Interrupt::Stat); - } + if(!irq && status.irq) cpu.raise(CPU::Interrupt::Stat); } auto PPU::coincidence() -> bool { - //LYC of zero triggers on LYC=153 - return (status.lyc && status.ly == status.lyc) || (!status.lyc && status.ly == 153); + uint ly = status.ly; + if(ly == 153 && status.lx >= 92) ly = 0; //LYC=0 triggers early during LY=153 + return ly == status.lyc; } auto PPU::refresh() -> void { @@ -85,6 +77,7 @@ auto PPU::refresh() -> void { auto PPU::wait(uint clocks) -> void { while(clocks--) { + stat(); if(status.dma_active) { uint hi = status.dma_clock++; uint lo = hi & (cpu.status.speed_double ? 1 : 3); diff --git a/higan/gb/ppu/ppu.hpp b/higan/gb/ppu/ppu.hpp index cae779ce..af143591 100644 --- a/higan/gb/ppu/ppu.hpp +++ b/higan/gb/ppu/ppu.hpp @@ -1,7 +1,10 @@ struct PPU : Thread, MMIO { + auto enabled() const -> bool; + static auto Enter() -> void; auto main() -> void; auto mode(uint) -> void; + auto stat() -> void; auto coincidence() -> bool; auto refresh() -> void; auto wait(uint clocks) -> void; diff --git a/higan/processor/gsu/disassembler.cpp b/higan/processor/gsu/disassembler.cpp index 73f31ad8..75216e34 100644 --- a/higan/processor/gsu/disassembler.cpp +++ b/higan/processor/gsu/disassembler.cpp @@ -1,21 +1,14 @@ -auto GSU::disassemble_opcode(char* output) -> void { +auto GSU::disassembleOpcode(char* output) -> void { *output = 0; - if(!regs.sfr.alt2) { - if(!regs.sfr.alt1) { - disassemble_alt0(output); - } else { - disassemble_alt1(output); - } - } else { - if(!regs.sfr.alt1) { - disassemble_alt2(output); - } else { - disassemble_alt3(output); - } + switch(regs.sfr.alt2 << 1 | regs.sfr.alt1 << 0) { + case 0: disassembleAlt0(output); break; + case 1: disassembleAlt1(output); break; + case 2: disassembleAlt2(output); break; + case 3: disassembleAlt3(output); break; } - unsigned length = strlen(output); + uint length = strlen(output); while(length++ < 20) strcat(output, " "); } @@ -34,10 +27,10 @@ auto GSU::disassemble_opcode(char* output) -> void { case id+ 8: case id+ 9: case id+10: case id+11: case id+12: case id+13: case id+14: case id+15 #define op0 regs.pipeline -#define op1 bus_read((regs.pbr << 16) + regs.r[15] + 0) -#define op2 bus_read((regs.pbr << 16) + regs.r[15] + 1) +#define op1 read((regs.pbr << 16) + regs.r[15] + 0) +#define op2 read((regs.pbr << 16) + regs.r[15] + 1) -auto GSU::disassemble_alt0(char* output) -> void { +auto GSU::disassembleAlt0(char* output) -> void { char t[256] = ""; switch(op0) { case (0x00): sprintf(t, "stop"); break; @@ -94,7 +87,7 @@ auto GSU::disassemble_alt0(char* output) -> void { strcat(output, t); } -auto GSU::disassemble_alt1(char* output) -> void { +auto GSU::disassembleAlt1(char* output) -> void { char t[256] = ""; switch(op0) { case (0x00): sprintf(t, "stop"); break; @@ -151,7 +144,7 @@ auto GSU::disassemble_alt1(char* output) -> void { strcat(output, t); } -auto GSU::disassemble_alt2(char* output) -> void { +auto GSU::disassembleAlt2(char* output) -> void { char t[256] = ""; switch(op0) { case (0x00): sprintf(t, "stop"); break; @@ -208,7 +201,7 @@ auto GSU::disassemble_alt2(char* output) -> void { strcat(output, t); } -auto GSU::disassemble_alt3(char* output) -> void { +auto GSU::disassembleAlt3(char* output) -> void { char t[256] = ""; switch(op0) { case (0x00): sprintf(t, "stop"); break; diff --git a/higan/processor/gsu/gsu.cpp b/higan/processor/gsu/gsu.cpp index 6210ba79..49199c66 100644 --- a/higan/processor/gsu/gsu.cpp +++ b/higan/processor/gsu/gsu.cpp @@ -16,7 +16,11 @@ auto GSU::power() -> void { } auto GSU::reset() -> void { - for(auto& r : regs.r) r = 0x0000; + for(auto& r : regs.r) { + r.data = 0x0000; + r.modified = false; + } + regs.sfr = 0x0000; regs.pbr = 0x00; regs.rombr = 0x00; diff --git a/higan/processor/gsu/gsu.hpp b/higan/processor/gsu/gsu.hpp index 47e7601c..6023d948 100644 --- a/higan/processor/gsu/gsu.hpp +++ b/higan/processor/gsu/gsu.hpp @@ -13,15 +13,15 @@ struct GSU { virtual auto rpix(uint8 x, uint8 y) -> uint8 = 0; virtual auto pipe() -> uint8 = 0; - virtual auto rombuffer_sync() -> void = 0; - virtual auto rombuffer_read() -> uint8 = 0; - virtual auto rambuffer_sync() -> void = 0; - virtual auto rambuffer_read(uint16 addr) -> uint8 = 0; - virtual auto rambuffer_write(uint16 addr, uint8 data) -> void = 0; - virtual auto cache_flush() -> void = 0; + virtual auto syncROMBuffer() -> void = 0; + virtual auto readROMBuffer() -> uint8 = 0; + virtual auto syncRAMBuffer() -> void = 0; + virtual auto readRAMBuffer(uint16 addr) -> uint8 = 0; + virtual auto writeRAMBuffer(uint16 addr, uint8 data) -> void = 0; + virtual auto flushCache() -> void = 0; - virtual auto bus_read(uint24 addr, uint8 data = 0x00) -> uint8 = 0; - virtual auto bus_write(uint24 addr, uint8 data) -> void = 0; + virtual auto read(uint24 addr, uint8 data = 0x00) -> uint8 = 0; + virtual auto write(uint24 addr, uint8 data) -> void = 0; //gsu.cpp auto power() -> void; @@ -76,11 +76,11 @@ struct GSU { auto serialize(serializer&) -> void; //disassembler.cpp - auto disassemble_opcode(char* output) -> void; - auto disassemble_alt0(char* output) -> void; - auto disassemble_alt1(char* output) -> void; - auto disassemble_alt2(char* output) -> void; - auto disassemble_alt3(char* output) -> void; + auto disassembleOpcode(char* output) -> void; + auto disassembleAlt0(char* output) -> void; + auto disassembleAlt1(char* output) -> void; + auto disassembleAlt2(char* output) -> void; + auto disassembleAlt3(char* output) -> void; }; } diff --git a/higan/processor/gsu/instructions.cpp b/higan/processor/gsu/instructions.cpp index caa5ba8d..f022641e 100644 --- a/higan/processor/gsu/instructions.cpp +++ b/higan/processor/gsu/instructions.cpp @@ -18,7 +18,7 @@ auto GSU::op_nop() { auto GSU::op_cache() { if(regs.cbr != (regs.r[15] & 0xfff0)) { regs.cbr = regs.r[15] & 0xfff0; - cache_flush(); + flushCache(); } regs.reset(); } @@ -80,8 +80,8 @@ auto GSU::op_with(uint n) { //$30-3b(alt1) stb (rN) auto GSU::op_store(uint n) { regs.ramaddr = regs.r[n]; - rambuffer_write(regs.ramaddr, regs.sr()); - if(!regs.sfr.alt1) rambuffer_write(regs.ramaddr ^ 1, regs.sr() >> 8); + writeRAMBuffer(regs.ramaddr, regs.sr()); + if(!regs.sfr.alt1) writeRAMBuffer(regs.ramaddr ^ 1, regs.sr() >> 8); regs.reset(); } @@ -117,8 +117,8 @@ auto GSU::op_alt3() { //$40-4b(alt1) ldb (rN) auto GSU::op_load(uint n) { regs.ramaddr = regs.r[n]; - regs.dr() = rambuffer_read(regs.ramaddr); - if(!regs.sfr.alt1) regs.dr() |= rambuffer_read(regs.ramaddr ^ 1) << 8; + regs.dr() = readRAMBuffer(regs.ramaddr); + if(!regs.sfr.alt1) regs.dr() |= readRAMBuffer(regs.ramaddr ^ 1) << 8; regs.reset(); } @@ -230,8 +230,8 @@ auto GSU::op_mult_umult(uint n) { //$90 sbk auto GSU::op_sbk() { - rambuffer_write(regs.ramaddr ^ 0, regs.sr() >> 0); - rambuffer_write(regs.ramaddr ^ 1, regs.sr() >> 8); + writeRAMBuffer(regs.ramaddr ^ 0, regs.sr() >> 0); + writeRAMBuffer(regs.ramaddr ^ 1, regs.sr() >> 8); regs.reset(); } @@ -278,7 +278,7 @@ auto GSU::op_jmp_ljmp(uint n) { regs.pbr = regs.r[n] & 0x7f; regs.r[15] = regs.sr(); regs.cbr = regs.r[15] & 0xfff0; - cache_flush(); + flushCache(); } regs.reset(); } @@ -310,12 +310,12 @@ auto GSU::op_fmult_lmult() { auto GSU::op_ibt_lms_sms(uint n) { if(regs.sfr.alt1) { regs.ramaddr = pipe() << 1; - uint8 lo = rambuffer_read(regs.ramaddr ^ 0) << 0; - regs.r[n] = rambuffer_read(regs.ramaddr ^ 1) << 8 | lo; + uint8 lo = readRAMBuffer(regs.ramaddr ^ 0) << 0; + regs.r[n] = readRAMBuffer(regs.ramaddr ^ 1) << 8 | lo; } else if(regs.sfr.alt2) { regs.ramaddr = pipe() << 1; - rambuffer_write(regs.ramaddr ^ 0, regs.r[n] >> 0); - rambuffer_write(regs.ramaddr ^ 1, regs.r[n] >> 8); + writeRAMBuffer(regs.ramaddr ^ 0, regs.r[n] >> 0); + writeRAMBuffer(regs.ramaddr ^ 1, regs.r[n] >> 8); } else { regs.r[n] = (int8)pipe(); } @@ -369,12 +369,12 @@ auto GSU::op_inc(uint n) { //$df(alt3) romb auto GSU::op_getc_ramb_romb() { if(!regs.sfr.alt2) { - regs.colr = color(rombuffer_read()); + regs.colr = color(readROMBuffer()); } else if(!regs.sfr.alt1) { - rambuffer_sync(); + syncRAMBuffer(); regs.rambr = regs.sr() & 0x01; } else { - rombuffer_sync(); + syncROMBuffer(); regs.rombr = regs.sr() & 0x7f; } regs.reset(); @@ -394,10 +394,10 @@ auto GSU::op_dec(uint n) { //$ef(alt3) getbs auto GSU::op_getb() { switch(regs.sfr.alt2 << 1 | regs.sfr.alt1 << 0) { - case 0: regs.dr() = rombuffer_read(); break; - case 1: regs.dr() = rombuffer_read() << 8 | (uint8)regs.sr(); break; - case 2: regs.dr() = (regs.sr() & 0xff00) | rombuffer_read(); break; - case 3: regs.dr() = (int8)rombuffer_read(); break; + case 0: regs.dr() = readROMBuffer(); break; + case 1: regs.dr() = readROMBuffer() << 8 | (uint8)regs.sr(); break; + case 2: regs.dr() = (regs.sr() & 0xff00) | readROMBuffer(); break; + case 3: regs.dr() = (int8)readROMBuffer(); break; } regs.reset(); } @@ -409,13 +409,13 @@ auto GSU::op_iwt_lm_sm(uint n) { if(regs.sfr.alt1) { regs.ramaddr = pipe() << 0; regs.ramaddr |= pipe() << 8; - uint8 lo = rambuffer_read(regs.ramaddr ^ 0) << 0; - regs.r[n] = rambuffer_read(regs.ramaddr ^ 1) << 8 | lo; + uint8 lo = readRAMBuffer(regs.ramaddr ^ 0) << 0; + regs.r[n] = readRAMBuffer(regs.ramaddr ^ 1) << 8 | lo; } else if(regs.sfr.alt2) { regs.ramaddr = pipe() << 0; regs.ramaddr |= pipe() << 8; - rambuffer_write(regs.ramaddr ^ 0, regs.r[n] >> 0); - rambuffer_write(regs.ramaddr ^ 1, regs.r[n] >> 8); + writeRAMBuffer(regs.ramaddr ^ 0, regs.r[n] >> 0); + writeRAMBuffer(regs.ramaddr ^ 1, regs.r[n] >> 8); } else { uint8 lo = pipe(); regs.r[n] = pipe() << 8 | lo; diff --git a/higan/processor/gsu/registers.hpp b/higan/processor/gsu/registers.hpp index 29268787..bc904e83 100644 --- a/higan/processor/gsu/registers.hpp +++ b/higan/processor/gsu/registers.hpp @@ -1,41 +1,39 @@ -//accepts a callback binding so r14 writes can trigger ROM buffering transparently -struct reg16_t { +struct Register { uint16 data = 0; - function void> modify; + bool modified = false; - inline operator unsigned() const { + inline operator uint() const { return data; } - inline auto assign(uint16 i) -> uint16 { - if(modify) modify(i); - else data = i; - return data; + inline auto assign(uint value) -> uint16 { + modified = true; + return data = value; } inline auto operator++() { return assign(data + 1); } inline auto operator--() { return assign(data - 1); } - inline auto operator++(int) { unsigned r = data; assign(data + 1); return r; } - inline auto operator--(int) { unsigned r = data; assign(data - 1); return r; } - inline auto operator = (unsigned i) { return assign(i); } - inline auto operator |= (unsigned i) { return assign(data | i); } - inline auto operator ^= (unsigned i) { return assign(data ^ i); } - inline auto operator &= (unsigned i) { return assign(data & i); } - inline auto operator <<= (unsigned i) { return assign(data << i); } - inline auto operator >>= (unsigned i) { return assign(data >> i); } - inline auto operator += (unsigned i) { return assign(data + i); } - inline auto operator -= (unsigned i) { return assign(data - i); } - inline auto operator *= (unsigned i) { return assign(data * i); } - inline auto operator /= (unsigned i) { return assign(data / i); } - inline auto operator %= (unsigned i) { return assign(data % i); } + inline auto operator++(int) { uint r = data; assign(data + 1); return r; } + inline auto operator--(int) { uint r = data; assign(data - 1); return r; } + inline auto operator = (uint i) { return assign(i); } + inline auto operator |= (uint i) { return assign(data | i); } + inline auto operator ^= (uint i) { return assign(data ^ i); } + inline auto operator &= (uint i) { return assign(data & i); } + inline auto operator <<= (uint i) { return assign(data << i); } + inline auto operator >>= (uint i) { return assign(data >> i); } + inline auto operator += (uint i) { return assign(data + i); } + inline auto operator -= (uint i) { return assign(data - i); } + inline auto operator *= (uint i) { return assign(data * i); } + inline auto operator /= (uint i) { return assign(data / i); } + inline auto operator %= (uint i) { return assign(data % i); } - inline auto operator = (const reg16_t& i) { return assign(i); } + inline auto operator = (const Register& value) { return assign(value); } - reg16_t() = default; - reg16_t(const reg16_t&) = delete; + Register() = default; + Register(const Register&) = delete; }; -struct sfr_t { +struct SFR { bool irq; //interrupt flag bool b; //WITH flag bool ih; //immediate higher 8-bit flag @@ -49,12 +47,12 @@ struct sfr_t { bool cy; //carry flag bool z; //zero flag - operator unsigned() const { + operator uint() const { return (irq << 15) | (b << 12) | (ih << 11) | (il << 10) | (alt2 << 9) | (alt1 << 8) | (r << 6) | (g << 5) | (ov << 4) | (s << 3) | (cy << 2) | (z << 1); } - auto& operator=(uint16_t data) { + auto& operator=(uint data) { irq = data & 0x8000; b = data & 0x1000; ih = data & 0x0800; @@ -71,17 +69,17 @@ struct sfr_t { } }; -struct scmr_t { - unsigned ht; +struct SCMR { + uint ht; bool ron; bool ran; - unsigned md; + uint md; - operator unsigned() const { + operator uint() const { return ((ht >> 1) << 5) | (ron << 4) | (ran << 3) | ((ht & 1) << 2) | (md); } - auto& operator=(uint8 data) { + auto& operator=(uint data) { ht = (bool)(data & 0x20) << 1; ht |= (bool)(data & 0x04) << 0; ron = data & 0x10; @@ -91,18 +89,18 @@ struct scmr_t { } }; -struct por_t { +struct POR { bool obj; bool freezehigh; bool highnibble; bool dither; bool transparent; - operator unsigned() const { + operator uint() const { return (obj << 4) | (freezehigh << 3) | (highnibble << 2) | (dither << 1) | (transparent); } - auto& operator=(uint8 data) { + auto& operator=(uint data) { obj = data & 0x10; freezehigh = data & 0x08; highnibble = data & 0x04; @@ -112,48 +110,49 @@ struct por_t { } }; -struct cfgr_t { +struct CFGR { bool irq; bool ms0; - operator unsigned() const { + operator uint() const { return (irq << 7) | (ms0 << 5); } - auto& operator=(uint8 data) { + auto& operator=(uint data) { irq = data & 0x80; ms0 = data & 0x20; return *this; } }; -struct regs_t { +struct Registers { uint8 pipeline; uint16 ramaddr; - reg16_t r[16]; //general purpose registers - sfr_t sfr; //status flag register + Register r[16]; //general purpose registers + SFR sfr; //status flag register uint8 pbr; //program bank register uint8 rombr; //game pack ROM bank register bool rambr; //game pack RAM bank register uint16 cbr; //cache base register uint8 scbr; //screen base register - scmr_t scmr; //screen mode register + SCMR scmr; //screen mode register uint8 colr; //color register - por_t por; //plot option register + POR por; //plot option register bool bramr; //back-up RAM register uint8 vcr; //version code register - cfgr_t cfgr; //config register + CFGR cfgr; //config register bool clsr; //clock select register - unsigned romcl; //clock ticks until romdr is valid + uint romcl; //clock ticks until romdr is valid uint8 romdr; //ROM buffer data register - unsigned ramcl; //clock ticks until ramdr is valid + uint ramcl; //clock ticks until ramdr is valid uint16 ramar; //RAM buffer address register uint8 ramdr; //RAM buffer data register - unsigned sreg, dreg; + uint sreg; + uint dreg; auto& sr() { return r[sreg]; } //source register (from) auto& dr() { return r[dreg]; } //destination register (to) @@ -167,12 +166,12 @@ struct regs_t { } } regs; -struct cache_t { +struct Cache { uint8 buffer[512]; bool valid[32]; } cache; -struct pixelcache_t { +struct PixelCache { uint16 offset; uint8 bitpend; uint8 data[8]; diff --git a/higan/processor/gsu/serialization.cpp b/higan/processor/gsu/serialization.cpp index e688231e..d1025b80 100644 --- a/higan/processor/gsu/serialization.cpp +++ b/higan/processor/gsu/serialization.cpp @@ -2,22 +2,10 @@ auto GSU::serialize(serializer& s) -> void { s.integer(regs.pipeline); s.integer(regs.ramaddr); - s.integer(regs.r[ 0].data); - s.integer(regs.r[ 1].data); - s.integer(regs.r[ 2].data); - s.integer(regs.r[ 3].data); - s.integer(regs.r[ 4].data); - s.integer(regs.r[ 5].data); - s.integer(regs.r[ 6].data); - s.integer(regs.r[ 7].data); - s.integer(regs.r[ 8].data); - s.integer(regs.r[ 9].data); - s.integer(regs.r[10].data); - s.integer(regs.r[11].data); - s.integer(regs.r[12].data); - s.integer(regs.r[13].data); - s.integer(regs.r[14].data); - s.integer(regs.r[15].data); + for(auto n : range(16)) { + s.integer(regs.r[n].data); + s.integer(regs.r[n].modified); + } s.integer(regs.sfr.irq); s.integer(regs.sfr.b); @@ -72,9 +60,9 @@ auto GSU::serialize(serializer& s) -> void { s.array(cache.buffer); s.array(cache.valid); - for(unsigned i = 0; i < 2; i++) { - s.integer(pixelcache[i].offset); - s.integer(pixelcache[i].bitpend); - s.array(pixelcache[i].data); + for(uint n : range(2)) { + s.integer(pixelcache[n].offset); + s.integer(pixelcache[n].bitpend); + s.array(pixelcache[n].data); } } diff --git a/higan/processor/lr35902/disassembler.cpp b/higan/processor/lr35902/disassembler.cpp index c4286a3a..8cc962f8 100644 --- a/higan/processor/lr35902/disassembler.cpp +++ b/higan/processor/lr35902/disassembler.cpp @@ -20,10 +20,10 @@ auto LR35902::disassemble(uint16 pc) -> string { } auto LR35902::disassembleOpcode(uint16 pc) -> string { - uint8 opcode = debugger_read(pc); - uint8 p0 = debugger_read(pc + 1); - uint8 p1 = debugger_read(pc + 2); - uint8 p2 = debugger_read(pc + 3); + uint8 opcode = debuggerRead(pc); + uint8 p0 = debuggerRead(pc + 1); + uint8 p1 = debuggerRead(pc + 2); + uint8 p2 = debuggerRead(pc + 3); switch(opcode) { case 0x00: return { "nop" }; @@ -288,10 +288,10 @@ auto LR35902::disassembleOpcode(uint16 pc) -> string { } auto LR35902::disassembleOpcodeCB(uint16 pc) -> string { - uint8 opcode = debugger_read(pc); - uint8 p0 = debugger_read(pc + 1); - uint8 p1 = debugger_read(pc + 2); - uint8 p2 = debugger_read(pc + 3); + uint8 opcode = debuggerRead(pc); + uint8 p0 = debuggerRead(pc + 1); + uint8 p1 = debuggerRead(pc + 2); + uint8 p2 = debuggerRead(pc + 3); switch(opcode) { case 0x00: return { "rlc b" }; diff --git a/higan/processor/lr35902/instructions.cpp b/higan/processor/lr35902/instructions.cpp index 0137f8d2..8f636218 100644 --- a/higan/processor/lr35902/instructions.cpp +++ b/higan/processor/lr35902/instructions.cpp @@ -2,7 +2,7 @@ auto LR35902::op_xx() { } auto LR35902::op_cb() { - execCB(); + instructionCB(); } //8-bit load commands @@ -12,105 +12,105 @@ auto LR35902::op_ld_r_r(uint x, uint y) { } auto LR35902::op_ld_r_n(uint x) { - r[x] = op_read(r[PC]++); + r[x] = read(r[PC]++); } auto LR35902::op_ld_r_hl(uint x) { - r[x] = op_read(r[HL]); + r[x] = read(r[HL]); } auto LR35902::op_ld_hl_r(uint x) { - op_write(r[HL], r[x]); + write(r[HL], r[x]); } auto LR35902::op_ld_hl_n() { - op_write(r[HL], op_read(r[PC]++)); + write(r[HL], read(r[PC]++)); } auto LR35902::op_ld_a_rr(uint x) { - r[A] = op_read(r[x]); + r[A] = read(r[x]); } auto LR35902::op_ld_a_nn() { - uint8 lo = op_read(r[PC]++); - uint8 hi = op_read(r[PC]++); - r[A] = op_read((hi << 8) | (lo << 0)); + 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) { - op_write(r[x], r[A]); + write(r[x], r[A]); } auto LR35902::op_ld_nn_a() { - uint8 lo = op_read(r[PC]++); - uint8 hi = op_read(r[PC]++); - op_write((hi << 8) | (lo << 0), r[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] = op_read(0xff00 + op_read(r[PC]++)); + r[A] = read(0xff00 + read(r[PC]++)); } auto LR35902::op_ld_ffn_a() { - op_write(0xff00 + op_read(r[PC]++), r[A]); + write(0xff00 + read(r[PC]++), r[A]); } auto LR35902::op_ld_a_ffc() { - r[A] = op_read(0xff00 + r[C]); + r[A] = read(0xff00 + r[C]); } auto LR35902::op_ld_ffc_a() { - op_write(0xff00 + r[C], r[A]); + write(0xff00 + r[C], r[A]); } auto LR35902::op_ldi_hl_a() { - op_write(r[HL], r[A]); + write(r[HL], r[A]); r[HL]++; } auto LR35902::op_ldi_a_hl() { - r[A] = op_read(r[HL]); + r[A] = read(r[HL]); r[HL]++; } auto LR35902::op_ldd_hl_a() { - op_write(r[HL], r[A]); + write(r[HL], r[A]); r[HL]--; } auto LR35902::op_ldd_a_hl() { - r[A] = op_read(r[HL]); + r[A] = read(r[HL]); r[HL]--; } //16-bit load commands auto LR35902::op_ld_rr_nn(uint x) { - r[x] = op_read(r[PC]++) << 0; - r[x] |= op_read(r[PC]++) << 8; + r[x] = read(r[PC]++) << 0; + r[x] |= read(r[PC]++) << 8; } auto LR35902::op_ld_nn_sp() { - uint16 addr = op_read(r[PC]++) << 0; - addr |= op_read(r[PC]++) << 8; - op_write(addr + 0, r[SP] >> 0); - op_write(addr + 1, r[SP] >> 8); + 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]; - op_io(); + io(); } auto LR35902::op_push_rr(uint x) { - op_io(); - op_write(--r[SP], r[x] >> 8); - op_write(--r[SP], r[x] >> 0); + io(); + write(--r[SP], r[x] >> 8); + write(--r[SP], r[x] >> 0); } auto LR35902::op_pop_rr(uint x) { - r[x] = op_read(r[SP]++) << 0; - r[x] |= op_read(r[SP]++) << 8; + r[x] = read(r[SP]++) << 0; + r[x] |= read(r[SP]++) << 8; } //8-bit arithmetic commands @@ -126,8 +126,8 @@ auto LR35902::opi_add_a(uint8 x) { } auto LR35902::op_add_a_r(uint x) { opi_add_a(r[x]); } -auto LR35902::op_add_a_n() { opi_add_a(op_read(r[PC]++)); } -auto LR35902::op_add_a_hl() { opi_add_a(op_read(r[HL])); } +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; @@ -140,8 +140,8 @@ auto LR35902::opi_adc_a(uint8 x) { } auto LR35902::op_adc_a_r(uint x) { opi_adc_a(r[x]); } -auto LR35902::op_adc_a_n() { opi_adc_a(op_read(r[PC]++)); } -auto LR35902::op_adc_a_hl() { opi_adc_a(op_read(r[HL])); } +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; @@ -154,8 +154,8 @@ auto LR35902::opi_sub_a(uint8 x) { } auto LR35902::op_sub_a_r(uint x) { opi_sub_a(r[x]); } -auto LR35902::op_sub_a_n() { opi_sub_a(op_read(r[PC]++)); } -auto LR35902::op_sub_a_hl() { opi_sub_a(op_read(r[HL])); } +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; @@ -168,8 +168,8 @@ auto LR35902::opi_sbc_a(uint8 x) { } auto LR35902::op_sbc_a_r(uint x) { opi_sbc_a(r[x]); } -auto LR35902::op_sbc_a_n() { opi_sbc_a(op_read(r[PC]++)); } -auto LR35902::op_sbc_a_hl() { opi_sbc_a(op_read(r[HL])); } +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; @@ -180,8 +180,8 @@ auto LR35902::opi_and_a(uint8 x) { } auto LR35902::op_and_a_r(uint x) { opi_and_a(r[x]); } -auto LR35902::op_and_a_n() { opi_and_a(op_read(r[PC]++)); } -auto LR35902::op_and_a_hl() { opi_and_a(op_read(r[HL])); } +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; @@ -192,8 +192,8 @@ auto LR35902::opi_xor_a(uint8 x) { } auto LR35902::op_xor_a_r(uint x) { opi_xor_a(r[x]); } -auto LR35902::op_xor_a_n() { opi_xor_a(op_read(r[PC]++)); } -auto LR35902::op_xor_a_hl() { opi_xor_a(op_read(r[HL])); } +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; @@ -204,8 +204,8 @@ auto LR35902::opi_or_a(uint8 x) { } auto LR35902::op_or_a_r(uint x) { opi_or_a(r[x]); } -auto LR35902::op_or_a_n() { opi_or_a(op_read(r[PC]++)); } -auto LR35902::op_or_a_hl() { opi_or_a(op_read(r[HL])); } +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; @@ -217,8 +217,8 @@ auto LR35902::opi_cp_a(uint8 x) { } auto LR35902::op_cp_a_r(uint x) { opi_cp_a(r[x]); } -auto LR35902::op_cp_a_n() { opi_cp_a(op_read(r[PC]++)); } -auto LR35902::op_cp_a_hl() { opi_cp_a(op_read(r[HL])); } +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]++; @@ -228,8 +228,8 @@ auto LR35902::op_inc_r(uint x) { } auto LR35902::op_inc_hl() { - uint8 n = op_read(r[HL]); - op_write(r[HL], ++n); + uint8 n = read(r[HL]); + write(r[HL], ++n); r.f.z = n == 0; r.f.n = 0; r.f.h = (n & 0x0f) == 0x00; @@ -243,8 +243,8 @@ auto LR35902::op_dec_r(uint x) { } auto LR35902::op_dec_hl() { - uint8 n = op_read(r[HL]); - op_write(r[HL], --n); + uint8 n = read(r[HL]); + write(r[HL], --n); r.f.z = n == 0; r.f.n = 1; r.f.h = (n & 0x0f) == 0x0f; @@ -277,7 +277,7 @@ auto LR35902::op_cpl() { //16-bit arithmetic commands auto LR35902::op_add_hl_rr(uint x) { - op_io(); + io(); uint32 rb = (r[HL] + r[x]); uint32 rn = (r[HL] & 0xfff) + (r[x] & 0xfff); r[HL] = rb; @@ -287,34 +287,34 @@ auto LR35902::op_add_hl_rr(uint x) { } auto LR35902::op_inc_rr(uint x) { - op_io(); + io(); r[x]++; } auto LR35902::op_dec_rr(uint x) { - op_io(); + io(); r[x]--; } auto LR35902::op_add_sp_n() { - int n = (int8)op_read(r[PC]++); + 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; - op_io(); - op_io(); + io(); + io(); } auto LR35902::op_ld_hl_sp_n() { - int n = (int8)op_read(r[PC]++); + 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; - op_io(); + io(); } //rotate/shift commands @@ -362,9 +362,9 @@ auto LR35902::op_rlc_r(uint x) { } auto LR35902::op_rlc_hl() { - uint8 n = op_read(r[HL]); + uint8 n = read(r[HL]); n = (n << 1) | (n >> 7); - op_write(r[HL], n); + write(r[HL], n); r.f.z = n == 0; r.f.n = 0; r.f.h = 0; @@ -381,10 +381,10 @@ auto LR35902::op_rl_r(uint x) { } auto LR35902::op_rl_hl() { - uint8 n = op_read(r[HL]); + uint8 n = read(r[HL]); bool c = n & 0x80; n = (n << 1) | (r.f.c << 0); - op_write(r[HL], n); + write(r[HL], n); r.f.z = n == 0; r.f.n = 0; r.f.h = 0; @@ -400,9 +400,9 @@ auto LR35902::op_rrc_r(uint x) { } auto LR35902::op_rrc_hl() { - uint8 n = op_read(r[HL]); + uint8 n = read(r[HL]); n = (n >> 1) | (n << 7); - op_write(r[HL], n); + write(r[HL], n); r.f.z = n == 0; r.f.n = 0; r.f.h = 0; @@ -419,10 +419,10 @@ auto LR35902::op_rr_r(uint x) { } auto LR35902::op_rr_hl() { - uint8 n = op_read(r[HL]); + uint8 n = read(r[HL]); bool c = n & 0x01; n = (n >> 1) | (r.f.c << 7); - op_write(r[HL], n); + write(r[HL], n); r.f.z = n == 0; r.f.n = 0; r.f.h = 0; @@ -439,10 +439,10 @@ auto LR35902::op_sla_r(uint x) { } auto LR35902::op_sla_hl() { - uint8 n = op_read(r[HL]); + uint8 n = read(r[HL]); bool c = n & 0x80; n <<= 1; - op_write(r[HL], n); + write(r[HL], n); r.f.z = n == 0; r.f.n = 0; r.f.h = 0; @@ -458,9 +458,9 @@ auto LR35902::op_swap_r(uint x) { } auto LR35902::op_swap_hl() { - uint8 n = op_read(r[HL]); + uint8 n = read(r[HL]); n = (n << 4) | (n >> 4); - op_write(r[HL], n); + write(r[HL], n); r.f.z = n == 0; r.f.n = 0; r.f.h = 0; @@ -477,10 +477,10 @@ auto LR35902::op_sra_r(uint x) { } auto LR35902::op_sra_hl() { - uint8 n = op_read(r[HL]); + uint8 n = read(r[HL]); bool c = n & 0x01; n = (int8)n >> 1; - op_write(r[HL], n); + write(r[HL], n); r.f.z = n == 0; r.f.n = 0; r.f.h = 0; @@ -497,10 +497,10 @@ auto LR35902::op_srl_r(uint x) { } auto LR35902::op_srl_hl() { - uint8 n = op_read(r[HL]); + uint8 n = read(r[HL]); bool c = n & 0x01; n >>= 1; - op_write(r[HL], n); + write(r[HL], n); r.f.z = n == 0; r.f.n = 0; r.f.h = 0; @@ -516,7 +516,7 @@ auto LR35902::op_bit_n_r(uint b, uint x) { } auto LR35902::op_bit_n_hl(uint b) { - uint8 n = op_read(r[HL]); + uint8 n = read(r[HL]); r.f.z = (n & (1 << b)) == 0; r.f.n = 0; r.f.h = 1; @@ -527,9 +527,9 @@ auto LR35902::op_set_n_r(uint b, uint x) { } auto LR35902::op_set_n_hl(uint b) { - uint8 n = op_read(r[HL]); + uint8 n = read(r[HL]); n |= 1 << b; - op_write(r[HL], n); + write(r[HL], n); } auto LR35902::op_res_n_r(uint b, uint x) { @@ -537,9 +537,9 @@ auto LR35902::op_res_n_r(uint b, uint x) { } auto LR35902::op_res_n_hl(uint b) { - uint n = op_read(r[HL]); + uint n = read(r[HL]); n &= ~(1 << b); - op_write(r[HL], n); + write(r[HL], n); } //control commands @@ -561,13 +561,13 @@ auto LR35902::op_nop() { auto LR35902::op_halt() { r.halt = true; - while(r.halt == true) op_io(); + while(r.halt) io(); } auto LR35902::op_stop() { if(stop()) return; r.stop = true; - while(r.stop == true) op_io(); + while(r.stop) io(); } auto LR35902::op_di() { @@ -582,10 +582,10 @@ auto LR35902::op_ei() { //jump commands auto LR35902::op_jp_nn() { - uint8 lo = op_read(r[PC]++); - uint8 hi = op_read(r[PC]++); + uint8 lo = read(r[PC]++); + uint8 hi = read(r[PC]++); r[PC] = (hi << 8) | (lo << 0); - op_io(); + io(); } auto LR35902::op_jp_hl() { @@ -593,76 +593,76 @@ auto LR35902::op_jp_hl() { } auto LR35902::op_jp_f_nn(uint x, bool y) { - uint8 lo = op_read(r[PC]++); - uint8 hi = op_read(r[PC]++); + uint8 lo = read(r[PC]++); + uint8 hi = read(r[PC]++); if(r.f[x] == y) { r[PC] = (hi << 8) | (lo << 0); - op_io(); + io(); } } auto LR35902::op_jr_n() { - int8 n = op_read(r[PC]++); + int8 n = read(r[PC]++); r[PC] += n; - op_io(); + io(); } auto LR35902::op_jr_f_n(uint x, bool y) { - int8 n = op_read(r[PC]++); + int8 n = read(r[PC]++); if(r.f[x] == y) { r[PC] += n; - op_io(); + io(); } } auto LR35902::op_call_nn() { - uint8 lo = op_read(r[PC]++); - uint8 hi = op_read(r[PC]++); - op_io(); - op_write(--r[SP], r[PC] >> 8); - op_write(--r[SP], r[PC] >> 0); + 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 = op_read(r[PC]++); - uint8 hi = op_read(r[PC]++); + uint8 lo = read(r[PC]++); + uint8 hi = read(r[PC]++); if(r.f[x] == y) { - op_io(); - op_write(--r[SP], r[PC] >> 8); - op_write(--r[SP], r[PC] >> 0); + 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 = op_read(r[SP]++); - uint8 hi = op_read(r[SP]++); + uint8 lo = read(r[SP]++); + uint8 hi = read(r[SP]++); r[PC] = (hi << 8) | (lo << 0); - op_io(); + io(); } auto LR35902::op_ret_f(uint x, bool y) { - op_io(); + io(); if(r.f[x] == y) { - uint8 lo = op_read(r[SP]++); - uint8 hi = op_read(r[SP]++); + uint8 lo = read(r[SP]++); + uint8 hi = read(r[SP]++); r[PC] = (hi << 8) | (lo << 0); - op_io(); + io(); } } auto LR35902::op_reti() { - uint8 lo = op_read(r[SP]++); - uint8 hi = op_read(r[SP]++); + uint8 lo = read(r[SP]++); + uint8 hi = read(r[SP]++); r[PC] = (hi << 8) | (lo << 0); - op_io(); + io(); r.ime = 1; } auto LR35902::op_rst_n(uint n) { - op_io(); - op_write(--r[SP], r[PC] >> 8); - op_write(--r[SP], r[PC] >> 0); + io(); + write(--r[SP], r[PC] >> 8); + write(--r[SP], r[PC] >> 0); r[PC] = n; } diff --git a/higan/processor/lr35902/lr35902.cpp b/higan/processor/lr35902/lr35902.cpp index dc0f5a8b..969a4235 100644 --- a/higan/processor/lr35902/lr35902.cpp +++ b/higan/processor/lr35902/lr35902.cpp @@ -14,9 +14,18 @@ auto LR35902::power() -> void { r.ime = false; } -auto LR35902::exec() -> void { - uint8 opcode = op_read(r[PC]++); - switch(opcode) { +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); @@ -276,9 +285,8 @@ auto LR35902::exec() -> void { } } -auto LR35902::execCB() -> void { - uint8 opcode = op_read(r[PC]++); - switch(opcode) { +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); diff --git a/higan/processor/lr35902/lr35902.hpp b/higan/processor/lr35902/lr35902.hpp index 40e70b25..5a548953 100644 --- a/higan/processor/lr35902/lr35902.hpp +++ b/higan/processor/lr35902/lr35902.hpp @@ -5,15 +5,16 @@ namespace Processor { struct LR35902 { - virtual auto op_io() -> void = 0; - virtual auto op_read(uint16 addr) -> uint8 = 0; - virtual auto op_write(uint16 addr, uint8 data) -> void = 0; + virtual auto io() -> void = 0; + virtual auto read(uint16 addr) -> uint8 = 0; + virtual auto write(uint16 addr, uint8 data) -> void = 0; virtual auto stop() -> bool = 0; - virtual auto debugger_read(uint16 addr) -> uint8 { return 0; } + virtual auto debuggerRead(uint16 addr) -> uint8 { return 0; } auto power() -> void; - auto exec() -> void; - auto execCB() -> void; + auto interrupt(uint16 vector) -> void; + auto instruction() -> void; + auto instructionCB() -> void; auto serialize(serializer&) -> void; diff --git a/higan/processor/spc700/instructions.cpp b/higan/processor/spc700/instructions.cpp index a5a8b88f..398a5bb1 100644 --- a/higan/processor/spc700/instructions.cpp +++ b/higan/processor/spc700/instructions.cpp @@ -1,11 +1,11 @@ #define call (this->*op) -auto SPC700::op_adjust(fps op, uint8_t& r) -> void { +auto SPC700::op_adjust(fps op, uint8_t& r) { io(); r = call(r); } -auto SPC700::op_adjust_addr(fps op) -> void { +auto SPC700::op_adjust_addr(fps op) { dp.l = readPC(); dp.h = readPC(); rd = read(dp); @@ -13,14 +13,14 @@ auto SPC700::op_adjust_addr(fps op) -> void { write(dp, rd); } -auto SPC700::op_adjust_dp(fps op) -> void { +auto SPC700::op_adjust_dp(fps op) { dp = readPC(); rd = readDP(dp); rd = call(rd); writeDP(dp, rd); } -auto SPC700::op_adjust_dpw(int n) -> void { +auto SPC700::op_adjust_dpw(int n) { dp = readPC(); rd.w = readDP(dp) + n; writeDP(dp++, rd.l); @@ -30,7 +30,7 @@ auto SPC700::op_adjust_dpw(int n) -> void { regs.p.z = rd == 0; } -auto SPC700::op_adjust_dpx(fps op) -> void { +auto SPC700::op_adjust_dpx(fps op) { dp = readPC(); io(); rd = readDP(dp + regs.x); @@ -38,7 +38,7 @@ auto SPC700::op_adjust_dpx(fps op) -> void { writeDP(dp + regs.x, rd); } -auto SPC700::op_branch(bool condition) -> void { +auto SPC700::op_branch(bool condition) { rd = readPC(); if(!condition) return; io(); @@ -46,7 +46,7 @@ auto SPC700::op_branch(bool condition) -> void { regs.pc += (int8)rd; } -auto SPC700::op_branch_bit() -> void { +auto SPC700::op_branch_bit() { dp = readPC(); sp = readDP(dp); rd = readPC(); @@ -57,26 +57,26 @@ auto SPC700::op_branch_bit() -> void { regs.pc += (int8)rd; } -auto SPC700::op_pull(uint8_t& r) -> void { +auto SPC700::op_pull(uint8_t& r) { io(); io(); r = readSP(); } -auto SPC700::op_push(uint8 r) -> void { +auto SPC700::op_push(uint8 r) { io(); io(); writeSP(r); } -auto SPC700::op_read_addr(fpb op, uint8_t& r) -> void { +auto SPC700::op_read_addr(fpb op, uint8_t& r) { dp.l = readPC(); dp.h = readPC(); rd = read(dp); r = call(r, rd); } -auto SPC700::op_read_addri(fpb op, uint8_t& r) -> void { +auto SPC700::op_read_addri(fpb op, uint8_t& r) { dp.l = readPC(); dp.h = readPC(); io(); @@ -84,25 +84,25 @@ auto SPC700::op_read_addri(fpb op, uint8_t& r) -> void { regs.a = call(regs.a, rd); } -auto SPC700::op_read_const(fpb op, uint8_t& r) -> void { +auto SPC700::op_read_const(fpb op, uint8_t& r) { rd = readPC(); r = call(r, rd); } -auto SPC700::op_read_dp(fpb op, uint8_t& r) -> void { +auto SPC700::op_read_dp(fpb op, uint8_t& r) { dp = readPC(); rd = readDP(dp); r = call(r, rd); } -auto SPC700::op_read_dpi(fpb op, uint8_t& r, uint8_t& i) -> void { +auto SPC700::op_read_dpi(fpb op, uint8_t& r, uint8_t& i) { dp = readPC(); io(); rd = readDP(dp + i); r = call(r, rd); } -auto SPC700::op_read_dpw(fpw op) -> void { +auto SPC700::op_read_dpw(fpw op) { dp = readPC(); rd.l = readDP(dp++); if(op != &SPC700::op_cpw) io(); @@ -110,7 +110,7 @@ auto SPC700::op_read_dpw(fpw op) -> void { regs.ya = call(regs.ya, rd); } -auto SPC700::op_read_idpx(fpb op) -> void { +auto SPC700::op_read_idpx(fpb op) { dp = readPC() + regs.x; io(); sp.l = readDP(dp++); @@ -119,7 +119,7 @@ auto SPC700::op_read_idpx(fpb op) -> void { regs.a = call(regs.a, rd); } -auto SPC700::op_read_idpy(fpb op) -> void { +auto SPC700::op_read_idpy(fpb op) { dp = readPC(); io(); sp.l = readDP(dp++); @@ -128,13 +128,13 @@ auto SPC700::op_read_idpy(fpb op) -> void { regs.a = call(regs.a, rd); } -auto SPC700::op_read_ix(fpb op) -> void { +auto SPC700::op_read_ix(fpb op) { io(); rd = readDP(regs.x); regs.a = call(regs.a, rd); } -auto SPC700::op_set_addr_bit() -> void { +auto SPC700::op_set_addr_bit() { dp.l = readPC(); dp.h = readPC(); bit = dp >> 13; @@ -169,19 +169,19 @@ auto SPC700::op_set_addr_bit() -> void { } } -auto SPC700::op_set_bit() -> void { +auto SPC700::op_set_bit() { dp = readPC(); rd = readDP(dp) & ~(1 << (opcode >> 5)); writeDP(dp, rd | (!(opcode & 0x10) << (opcode >> 5))); } -auto SPC700::op_set_flag(bool& flag, bool data) -> void { +auto SPC700::op_set_flag(bool& flag, bool data) { io(); if(&flag == ®s.p.i) io(); flag = data; } -auto SPC700::op_test_addr(bool set) -> void { +auto SPC700::op_test_addr(bool set) { dp.l = readPC(); dp.h = readPC(); rd = read(dp); @@ -191,7 +191,7 @@ auto SPC700::op_test_addr(bool set) -> void { write(dp, set ? rd | regs.a : rd & ~regs.a); } -auto SPC700::op_transfer(uint8_t& from, uint8_t& to) -> void { +auto SPC700::op_transfer(uint8_t& from, uint8_t& to) { io(); to = from; if(&to == ®s.s) return; @@ -199,14 +199,14 @@ auto SPC700::op_transfer(uint8_t& from, uint8_t& to) -> void { regs.p.z = (to == 0); } -auto SPC700::op_write_addr(uint8_t& r) -> void { +auto SPC700::op_write_addr(uint8_t& r) { dp.l = readPC(); dp.h = readPC(); read(dp); write(dp, r); } -auto SPC700::op_write_addri(uint8_t& i) -> void { +auto SPC700::op_write_addri(uint8_t& i) { dp.l = readPC(); dp.h = readPC(); io(); @@ -215,20 +215,20 @@ auto SPC700::op_write_addri(uint8_t& i) -> void { write(dp, regs.a); } -auto SPC700::op_write_dp(uint8_t& r) -> void { +auto SPC700::op_write_dp(uint8_t& r) { dp = readPC(); readDP(dp); writeDP(dp, r); } -auto SPC700::op_write_dpi(uint8_t& r, uint8_t& i) -> void { +auto SPC700::op_write_dpi(uint8_t& r, uint8_t& i) { dp = readPC() + i; io(); readDP(dp); writeDP(dp, r); } -auto SPC700::op_write_dp_const(fpb op) -> void { +auto SPC700::op_write_dp_const(fpb op) { rd = readPC(); dp = readPC(); wr = readDP(dp); @@ -236,7 +236,7 @@ auto SPC700::op_write_dp_const(fpb op) -> void { op != &SPC700::op_cmp ? writeDP(dp, wr) : io(); } -auto SPC700::op_write_dp_dp(fpb op) -> void { +auto SPC700::op_write_dp_dp(fpb op) { sp = readPC(); rd = readDP(sp); dp = readPC(); @@ -245,7 +245,7 @@ auto SPC700::op_write_dp_dp(fpb op) -> void { op != &SPC700::op_cmp ? writeDP(dp, wr) : io(); } -auto SPC700::op_write_ix_iy(fpb op) -> void { +auto SPC700::op_write_ix_iy(fpb op) { io(); rd = readDP(regs.y); wr = readDP(regs.x); @@ -255,7 +255,7 @@ auto SPC700::op_write_ix_iy(fpb op) -> void { // -auto SPC700::op_bne_dp() -> void { +auto SPC700::op_bne_dp() { dp = readPC(); sp = readDP(dp); rd = readPC(); @@ -266,7 +266,7 @@ auto SPC700::op_bne_dp() -> void { regs.pc += (int8)rd; } -auto SPC700::op_bne_dpdec() -> void { +auto SPC700::op_bne_dpdec() { dp = readPC(); wr = readDP(dp); writeDP(dp, --wr); @@ -277,7 +277,7 @@ auto SPC700::op_bne_dpdec() -> void { regs.pc += (int8)rd; } -auto SPC700::op_bne_dpx() -> void { +auto SPC700::op_bne_dpx() { dp = readPC(); io(); sp = readDP(dp + regs.x); @@ -289,7 +289,7 @@ auto SPC700::op_bne_dpx() -> void { regs.pc += (int8)rd; } -auto SPC700::op_bne_ydec() -> void { +auto SPC700::op_bne_ydec() { rd = readPC(); io(); io(); @@ -299,7 +299,7 @@ auto SPC700::op_bne_ydec() -> void { regs.pc += (int8)rd; } -auto SPC700::op_brk() -> void { +auto SPC700::op_brk() { rd.l = read(0xffde); rd.h = read(0xffdf); io(); @@ -312,19 +312,19 @@ auto SPC700::op_brk() -> void { regs.p.i = 0; } -auto SPC700::op_clv() -> void { +auto SPC700::op_clv() { io(); regs.p.v = 0; regs.p.h = 0; } -auto SPC700::op_cmc() -> void { +auto SPC700::op_cmc() { io(); io(); regs.p.c = !regs.p.c; } -auto SPC700::op_daa() -> void { +auto SPC700::op_daa() { io(); io(); if(regs.p.c || (regs.a) > 0x99) { @@ -338,7 +338,7 @@ auto SPC700::op_daa() -> void { regs.p.z = (regs.a == 0); } -auto SPC700::op_das() -> void { +auto SPC700::op_das() { io(); io(); if(!regs.p.c || (regs.a) > 0x99) { @@ -352,7 +352,7 @@ auto SPC700::op_das() -> void { regs.p.z = (regs.a == 0); } -auto SPC700::op_div_ya_x() -> void { +auto SPC700::op_div_ya_x() { io(); io(); io(); @@ -383,13 +383,13 @@ auto SPC700::op_div_ya_x() -> void { regs.p.z = (regs.a == 0); } -auto SPC700::op_jmp_addr() -> void { +auto SPC700::op_jmp_addr() { rd.l = readPC(); rd.h = readPC(); regs.pc = rd; } -auto SPC700::op_jmp_iaddrx() -> void { +auto SPC700::op_jmp_iaddrx() { dp.l = readPC(); dp.h = readPC(); io(); @@ -399,7 +399,7 @@ auto SPC700::op_jmp_iaddrx() -> void { regs.pc = rd; } -auto SPC700::op_jsp_dp() -> void { +auto SPC700::op_jsp_dp() { rd = readPC(); io(); io(); @@ -408,7 +408,7 @@ auto SPC700::op_jsp_dp() -> void { regs.pc = 0xff00 | rd; } -auto SPC700::op_jsr_addr() -> void { +auto SPC700::op_jsr_addr() { rd.l = readPC(); rd.h = readPC(); io(); @@ -419,7 +419,7 @@ auto SPC700::op_jsr_addr() -> void { regs.pc = rd; } -auto SPC700::op_jst() -> void { +auto SPC700::op_jst() { dp = 0xffde - ((opcode >> 4) << 1); rd.l = read(dp++); rd.h = read(dp++); @@ -431,7 +431,7 @@ auto SPC700::op_jst() -> void { regs.pc = rd; } -auto SPC700::op_lda_ixinc() -> void { +auto SPC700::op_lda_ixinc() { io(); regs.a = readDP(regs.x++); io(); @@ -439,7 +439,7 @@ auto SPC700::op_lda_ixinc() -> void { regs.p.z = regs.a == 0; } -auto SPC700::op_mul_ya() -> void { +auto SPC700::op_mul_ya() { io(); io(); io(); @@ -456,17 +456,17 @@ auto SPC700::op_mul_ya() -> void { regs.p.z = (regs.y == 0); } -auto SPC700::op_nop() -> void { +auto SPC700::op_nop() { io(); } -auto SPC700::op_plp() -> void { +auto SPC700::op_plp() { io(); io(); regs.p = readSP(); } -auto SPC700::op_rti() -> void { +auto SPC700::op_rti() { regs.p = readSP(); rd.l = readSP(); rd.h = readSP(); @@ -475,7 +475,7 @@ auto SPC700::op_rti() -> void { regs.pc = rd; } -auto SPC700::op_rts() -> void { +auto SPC700::op_rts() { rd.l = readSP(); rd.h = readSP(); io(); @@ -483,7 +483,7 @@ auto SPC700::op_rts() -> void { regs.pc = rd; } -auto SPC700::op_sta_idpx() -> void { +auto SPC700::op_sta_idpx() { sp = readPC() + regs.x; io(); dp.l = readDP(sp++); @@ -492,7 +492,7 @@ auto SPC700::op_sta_idpx() -> void { write(dp, regs.a); } -auto SPC700::op_sta_idpy() -> void { +auto SPC700::op_sta_idpy() { sp = readPC(); dp.l = readDP(sp++); dp.h = readDP(sp++); @@ -502,33 +502,33 @@ auto SPC700::op_sta_idpy() -> void { write(dp, regs.a); } -auto SPC700::op_sta_ix() -> void { +auto SPC700::op_sta_ix() { io(); readDP(regs.x); writeDP(regs.x, regs.a); } -auto SPC700::op_sta_ixinc() -> void { +auto SPC700::op_sta_ixinc() { io(); io(); writeDP(regs.x++, regs.a); } -auto SPC700::op_stw_dp() -> void { +auto SPC700::op_stw_dp() { dp = readPC(); readDP(dp); writeDP(dp++, regs.a); writeDP(dp++, regs.y); } -auto SPC700::op_wait() -> void { +auto SPC700::op_wait() { while(true) { io(); io(); } } -auto SPC700::op_xcn() -> void { +auto SPC700::op_xcn() { io(); io(); io(); diff --git a/higan/processor/spc700/spc700.hpp b/higan/processor/spc700/spc700.hpp index c59f73e9..6a540643 100644 --- a/higan/processor/spc700/spc700.hpp +++ b/higan/processor/spc700/spc700.hpp @@ -45,65 +45,65 @@ protected: auto op_ldw(uint16, uint16) -> uint16; auto op_sbw(uint16, uint16) -> uint16; - auto op_adjust(fps, uint8_t&) -> void; - auto op_adjust_addr(fps) -> void; - auto op_adjust_dp(fps) -> void; - auto op_adjust_dpw(int) -> void; - auto op_adjust_dpx(fps) -> void; - auto op_branch(bool) -> void; - auto op_branch_bit() -> void; - auto op_pull(uint8_t&) -> void; - auto op_push(uint8) -> void; - auto op_read_addr(fpb, uint8_t&) -> void; - auto op_read_addri(fpb, uint8_t&) -> void; - auto op_read_const(fpb, uint8_t&) -> void; - auto op_read_dp(fpb, uint8_t&) -> void; - auto op_read_dpi(fpb, uint8_t&, uint8_t&) -> void; - auto op_read_dpw(fpw) -> void; - auto op_read_idpx(fpb) -> void; - auto op_read_idpy(fpb) -> void; - auto op_read_ix(fpb) -> void; - auto op_set_addr_bit() -> void; - auto op_set_bit() -> void; - auto op_set_flag(bool&, bool) -> void; - auto op_test_addr(bool) -> void; - auto op_transfer(uint8_t&, uint8_t&) -> void; - auto op_write_addr(uint8_t&) -> void; - auto op_write_addri(uint8_t&) -> void; - auto op_write_dp(uint8_t&) -> void; - auto op_write_dpi(uint8_t&, uint8_t&) -> void; - auto op_write_dp_const(fpb) -> void; - auto op_write_dp_dp(fpb) -> void; - auto op_write_ix_iy(fpb) -> void; + auto op_adjust(fps, uint8_t&); + auto op_adjust_addr(fps); + auto op_adjust_dp(fps); + auto op_adjust_dpw(int); + auto op_adjust_dpx(fps); + auto op_branch(bool); + auto op_branch_bit(); + auto op_pull(uint8_t&); + auto op_push(uint8); + auto op_read_addr(fpb, uint8_t&); + auto op_read_addri(fpb, uint8_t&); + auto op_read_const(fpb, uint8_t&); + auto op_read_dp(fpb, uint8_t&); + auto op_read_dpi(fpb, uint8_t&, uint8_t&); + auto op_read_dpw(fpw); + auto op_read_idpx(fpb); + auto op_read_idpy(fpb); + auto op_read_ix(fpb); + auto op_set_addr_bit(); + auto op_set_bit(); + auto op_set_flag(bool&, bool); + auto op_test_addr(bool); + auto op_transfer(uint8_t&, uint8_t&); + auto op_write_addr(uint8_t&); + auto op_write_addri(uint8_t&); + auto op_write_dp(uint8_t&); + auto op_write_dpi(uint8_t&, uint8_t&); + auto op_write_dp_const(fpb); + auto op_write_dp_dp(fpb); + auto op_write_ix_iy(fpb); - auto op_bne_dp() -> void; - auto op_bne_dpdec() -> void; - auto op_bne_dpx() -> void; - auto op_bne_ydec() -> void; - auto op_brk() -> void; - auto op_clv() -> void; - auto op_cmc() -> void; - auto op_daa() -> void; - auto op_das() -> void; - auto op_div_ya_x() -> void; - auto op_jmp_addr() -> void; - auto op_jmp_iaddrx() -> void; - auto op_jsp_dp() -> void; - auto op_jsr_addr() -> void; - auto op_jst() -> void; - auto op_lda_ixinc() -> void; - auto op_mul_ya() -> void; - auto op_nop() -> void; - auto op_plp() -> void; - auto op_rti() -> void; - auto op_rts() -> void; - auto op_sta_idpx() -> void; - auto op_sta_idpy() -> void; - auto op_sta_ix() -> void; - auto op_sta_ixinc() -> void; - auto op_stw_dp() -> void; - auto op_wait() -> void; - auto op_xcn() -> void; + auto op_bne_dp(); + auto op_bne_dpdec(); + auto op_bne_dpx(); + auto op_bne_ydec(); + auto op_brk(); + auto op_clv(); + auto op_cmc(); + auto op_daa(); + auto op_das(); + auto op_div_ya_x(); + auto op_jmp_addr(); + auto op_jmp_iaddrx(); + auto op_jsp_dp(); + auto op_jsr_addr(); + auto op_jst(); + auto op_lda_ixinc(); + auto op_mul_ya(); + auto op_nop(); + auto op_plp(); + auto op_rti(); + auto op_rts(); + auto op_sta_idpx(); + auto op_sta_idpy(); + auto op_sta_ix(); + auto op_sta_ixinc(); + auto op_stw_dp(); + auto op_wait(); + auto op_xcn(); }; } diff --git a/higan/sfc/coprocessor/superfx/core.cpp b/higan/sfc/coprocessor/superfx/core.cpp index 87302cbf..9c2b241a 100644 --- a/higan/sfc/coprocessor/superfx/core.cpp +++ b/higan/sfc/coprocessor/superfx/core.cpp @@ -30,7 +30,7 @@ auto SuperFX::plot(uint8 x, uint8 y) -> void { uint16 offset = (y << 5) + (x >> 3); if(offset != pixelcache[0].offset) { - pixelcache_flush(pixelcache[1]); + flushPixelCache(pixelcache[1]); pixelcache[1] = pixelcache[0]; pixelcache[0].bitpend = 0x00; pixelcache[0].offset = offset; @@ -40,64 +40,64 @@ auto SuperFX::plot(uint8 x, uint8 y) -> void { pixelcache[0].data[x] = color; pixelcache[0].bitpend |= 1 << x; if(pixelcache[0].bitpend == 0xff) { - pixelcache_flush(pixelcache[1]); + flushPixelCache(pixelcache[1]); pixelcache[1] = pixelcache[0]; pixelcache[0].bitpend = 0x00; } } auto SuperFX::rpix(uint8 x, uint8 y) -> uint8 { - pixelcache_flush(pixelcache[1]); - pixelcache_flush(pixelcache[0]); + flushPixelCache(pixelcache[1]); + flushPixelCache(pixelcache[0]); - unsigned cn; //character number + uint cn; //character number switch(regs.por.obj ? 3 : regs.scmr.ht) { case 0: cn = ((x & 0xf8) << 1) + ((y & 0xf8) >> 3); break; case 1: cn = ((x & 0xf8) << 1) + ((x & 0xf8) >> 1) + ((y & 0xf8) >> 3); break; case 2: cn = ((x & 0xf8) << 1) + ((x & 0xf8) << 0) + ((y & 0xf8) >> 3); break; case 3: cn = ((y & 0x80) << 2) + ((x & 0x80) << 1) + ((y & 0x78) << 1) + ((x & 0x78) >> 3); break; } - unsigned bpp = 2 << (regs.scmr.md - (regs.scmr.md >> 1)); // = [regs.scmr.md]{ 2, 4, 4, 8 }; - unsigned addr = 0x700000 + (cn * (bpp << 3)) + (regs.scbr << 10) + ((y & 0x07) * 2); + uint bpp = 2 << (regs.scmr.md - (regs.scmr.md >> 1)); // = [regs.scmr.md]{ 2, 4, 4, 8 }; + uint addr = 0x700000 + (cn * (bpp << 3)) + (regs.scbr << 10) + ((y & 0x07) * 2); uint8 data = 0x00; x = (x & 7) ^ 7; - for(unsigned n = 0; n < bpp; n++) { - unsigned byte = ((n >> 1) << 4) + (n & 1); // = [n]{ 0, 1, 16, 17, 32, 33, 48, 49 }; + for(uint n : range(bpp)) { + uint byte = ((n >> 1) << 4) + (n & 1); // = [n]{ 0, 1, 16, 17, 32, 33, 48, 49 }; step(regs.clsr ? 5 : 6); - data |= ((bus_read(addr + byte) >> x) & 1) << n; + data |= ((read(addr + byte) >> x) & 1) << n; } return data; } -auto SuperFX::pixelcache_flush(pixelcache_t& cache) -> void { +auto SuperFX::flushPixelCache(PixelCache& cache) -> void { if(cache.bitpend == 0x00) return; uint8 x = cache.offset << 3; uint8 y = cache.offset >> 5; - unsigned cn; //character number + uint cn; //character number switch(regs.por.obj ? 3 : regs.scmr.ht) { case 0: cn = ((x & 0xf8) << 1) + ((y & 0xf8) >> 3); break; case 1: cn = ((x & 0xf8) << 1) + ((x & 0xf8) >> 1) + ((y & 0xf8) >> 3); break; case 2: cn = ((x & 0xf8) << 1) + ((x & 0xf8) << 0) + ((y & 0xf8) >> 3); break; case 3: cn = ((y & 0x80) << 2) + ((x & 0x80) << 1) + ((y & 0x78) << 1) + ((x & 0x78) >> 3); break; } - unsigned bpp = 2 << (regs.scmr.md - (regs.scmr.md >> 1)); // = [regs.scmr.md]{ 2, 4, 4, 8 }; - unsigned addr = 0x700000 + (cn * (bpp << 3)) + (regs.scbr << 10) + ((y & 0x07) * 2); + uint bpp = 2 << (regs.scmr.md - (regs.scmr.md >> 1)); // = [regs.scmr.md]{ 2, 4, 4, 8 }; + uint addr = 0x700000 + (cn * (bpp << 3)) + (regs.scbr << 10) + ((y & 0x07) * 2); - for(unsigned n = 0; n < bpp; n++) { - unsigned byte = ((n >> 1) << 4) + (n & 1); // = [n]{ 0, 1, 16, 17, 32, 33, 48, 49 }; + for(uint n : range(bpp)) { + uint byte = ((n >> 1) << 4) + (n & 1); // = [n]{ 0, 1, 16, 17, 32, 33, 48, 49 }; uint8 data = 0x00; - for(unsigned x = 0; x < 8; x++) data |= ((cache.data[x] >> n) & 1) << x; + for(uint x : range(8)) data |= ((cache.data[x] >> n) & 1) << x; if(cache.bitpend != 0xff) { step(regs.clsr ? 5 : 6); data &= cache.bitpend; - data |= bus_read(addr + byte) & ~cache.bitpend; + data |= read(addr + byte) & ~cache.bitpend; } step(regs.clsr ? 5 : 6); - bus_write(addr + byte, data); + write(addr + byte, data); } cache.bitpend = 0x00; diff --git a/higan/sfc/coprocessor/superfx/memory.cpp b/higan/sfc/coprocessor/superfx/memory.cpp index 5fcc6cff..5ada9ddd 100644 --- a/higan/sfc/coprocessor/superfx/memory.cpp +++ b/higan/sfc/coprocessor/superfx/memory.cpp @@ -1,10 +1,10 @@ -auto SuperFX::bus_read(uint24 addr, uint8 data) -> uint8 { - if((addr & 0xc00000) == 0x000000) { //$00-3f:0000-7fff, $00-3f:8000-ffff +auto SuperFX::read(uint24 addr, uint8 data) -> uint8 { + if((addr & 0xc00000) == 0x000000) { //$00-3f:0000-7fff,:8000-ffff while(!regs.scmr.ron && !scheduler.synchronizing()) { step(6); synchronizeCPU(); } - return rom.read((((addr & 0x3f0000) >> 1) | (addr & 0x7fff)) & rom_mask); + return rom.read((((addr & 0x3f0000) >> 1) | (addr & 0x7fff)) & romMask); } if((addr & 0xe00000) == 0x400000) { //$40-5f:0000-ffff @@ -12,7 +12,7 @@ auto SuperFX::bus_read(uint24 addr, uint8 data) -> uint8 { step(6); synchronizeCPU(); } - return rom.read(addr & rom_mask); + return rom.read(addr & romMask); } if((addr & 0xe00000) == 0x600000) { //$60-7f:0000-ffff @@ -20,31 +20,31 @@ auto SuperFX::bus_read(uint24 addr, uint8 data) -> uint8 { step(6); synchronizeCPU(); } - return ram.read(addr & ram_mask); + return ram.read(addr & ramMask); } return data; } -auto SuperFX::bus_write(uint24 addr, uint8 data) -> void { +auto SuperFX::write(uint24 addr, uint8 data) -> void { if((addr & 0xe00000) == 0x600000) { //$60-7f:0000-ffff while(!regs.scmr.ran && !scheduler.synchronizing()) { step(6); synchronizeCPU(); } - return ram.write(addr & ram_mask, data); + return ram.write(addr & ramMask, data); } } -auto SuperFX::op_read(uint16 addr) -> uint8 { +auto SuperFX::readOpcode(uint16 addr) -> uint8 { uint16 offset = addr - regs.cbr; if(offset < 512) { if(cache.valid[offset >> 4] == false) { - unsigned dp = offset & 0xfff0; - unsigned sp = (regs.pbr << 16) + ((regs.cbr + dp) & 0xfff0); - for(unsigned n = 0; n < 16; n++) { + uint dp = offset & 0xfff0; + uint sp = (regs.pbr << 16) + ((regs.cbr + dp) & 0xfff0); + for(uint n : range(16)) { step(regs.clsr ? 5 : 6); - cache.buffer[dp++] = bus_read(sp++); + cache.buffer[dp++] = read(sp++); } cache.valid[offset >> 4] = true; } else { @@ -54,55 +54,43 @@ auto SuperFX::op_read(uint16 addr) -> uint8 { } if(regs.pbr <= 0x5f) { - //$[00-5f]:[0000-ffff] ROM - rombuffer_sync(); + //$00-5f:0000-ffff ROM + syncROMBuffer(); step(regs.clsr ? 5 : 6); - return bus_read((regs.pbr << 16) + addr); + return read(regs.pbr << 16 | addr); } else { - //$[60-7f]:[0000-ffff] RAM - rambuffer_sync(); + //$60-7f:0000-ffff RAM + syncRAMBuffer(); step(regs.clsr ? 5 : 6); - return bus_read((regs.pbr << 16) + addr); + return read(regs.pbr << 16 | addr); } } auto SuperFX::peekpipe() -> uint8 { uint8 result = regs.pipeline; - regs.pipeline = op_read(regs.r[15]); - r15_modified = false; + regs.pipeline = readOpcode(regs.r[15]); + regs.r[15].modified = false; return result; } auto SuperFX::pipe() -> uint8 { uint8 result = regs.pipeline; - regs.pipeline = op_read(++regs.r[15]); - r15_modified = false; + regs.pipeline = readOpcode(++regs.r[15]); + regs.r[15].modified = false; return result; } -auto SuperFX::cache_flush() -> void { - for(unsigned n = 0; n < 32; n++) cache.valid[n] = false; +auto SuperFX::flushCache() -> void { + for(uint n : range(32)) cache.valid[n] = false; } -auto SuperFX::cache_mmio_read(uint16 addr) -> uint8 { +auto SuperFX::readCache(uint16 addr) -> uint8 { addr = (addr + regs.cbr) & 511; return cache.buffer[addr]; } -auto SuperFX::cache_mmio_write(uint16 addr, uint8 data) -> void { +auto SuperFX::writeCache(uint16 addr, uint8 data) -> void { addr = (addr + regs.cbr) & 511; cache.buffer[addr] = data; if((addr & 15) == 15) cache.valid[addr >> 4] = true; } - -auto SuperFX::memory_reset() -> void { - rom_mask = rom.size() - 1; - ram_mask = ram.size() - 1; - - for(unsigned n = 0; n < 512; n++) cache.buffer[n] = 0x00; - for(unsigned n = 0; n < 32; n++) cache.valid[n] = false; - for(unsigned n = 0; n < 2; n++) { - pixelcache[n].offset = ~0; - pixelcache[n].bitpend = 0x00; - } -} diff --git a/higan/sfc/coprocessor/superfx/mmio.cpp b/higan/sfc/coprocessor/superfx/mmio.cpp index 29da30df..d2174a4c 100644 --- a/higan/sfc/coprocessor/superfx/mmio.cpp +++ b/higan/sfc/coprocessor/superfx/mmio.cpp @@ -3,7 +3,7 @@ auto SuperFX::readIO(uint24 addr, uint8) -> uint8 { addr = 0x3000 | addr.bits(0,9); if(addr >= 0x3100 && addr <= 0x32ff) { - return cache_mmio_read(addr - 0x3100); + return readCache(addr - 0x3100); } if(addr >= 0x3000 && addr <= 0x301f) { @@ -55,7 +55,7 @@ auto SuperFX::writeIO(uint24 addr, uint8 data) -> void { addr = 0x3000 | addr.bits(0,9); if(addr >= 0x3100 && addr <= 0x32ff) { - return cache_mmio_write(addr - 0x3100, data); + return writeCache(addr - 0x3100, data); } if(addr >= 0x3000 && addr <= 0x301f) { @@ -65,6 +65,7 @@ auto SuperFX::writeIO(uint24 addr, uint8 data) -> void { } else { regs.r[n] = (data << 8) | (regs.r[n] & 0xff); } + if(n == 14) updateROMBuffer(); if(addr == 0x301f) regs.sfr.g = 1; return; @@ -76,7 +77,7 @@ auto SuperFX::writeIO(uint24 addr, uint8 data) -> void { regs.sfr = (regs.sfr & 0xff00) | (data << 0); if(g == 1 && regs.sfr.g == 0) { regs.cbr = 0x0000; - cache_flush(); + flushCache(); } } break; @@ -90,7 +91,7 @@ auto SuperFX::writeIO(uint24 addr, uint8 data) -> void { case 0x3034: { regs.pbr = data & 0x7f; - cache_flush(); + flushCache(); } break; case 0x3037: { diff --git a/higan/sfc/coprocessor/superfx/serialization.cpp b/higan/sfc/coprocessor/superfx/serialization.cpp index ad3ace66..214f5dd3 100644 --- a/higan/sfc/coprocessor/superfx/serialization.cpp +++ b/higan/sfc/coprocessor/superfx/serialization.cpp @@ -3,5 +3,4 @@ auto SuperFX::serialize(serializer& s) -> void { Thread::serialize(s); s.array(ram.data(), ram.size()); - s.integer(r15_modified); } diff --git a/higan/sfc/coprocessor/superfx/superfx.cpp b/higan/sfc/coprocessor/superfx/superfx.cpp index 91efafa1..2980976d 100644 --- a/higan/sfc/coprocessor/superfx/superfx.cpp +++ b/higan/sfc/coprocessor/superfx/superfx.cpp @@ -16,13 +16,22 @@ auto SuperFX::Enter() -> void { auto SuperFX::main() -> void { if(regs.sfr.g == 0) return step(6); + instruction(peekpipe()); - if(!r15_modified) regs.r[15]++; + + if(regs.r[14].modified) { + regs.r[14].modified = false; + updateROMBuffer(); + } + + if(regs.r[15].modified) { + regs.r[15].modified = false; + } else { + regs.r[15]++; + } } auto SuperFX::init() -> void { - regs.r[14].modify = {&SuperFX::r14_modify, this}; - regs.r[15].modify = {&SuperFX::r15_modify, this}; } auto SuperFX::load() -> void { @@ -40,8 +49,23 @@ auto SuperFX::power() -> void { auto SuperFX::reset() -> void { GSU::reset(); create(SuperFX::Enter, system.cpuFrequency()); - memory_reset(); - timing_reset(); + + romMask = rom.size() - 1; + ramMask = ram.size() - 1; + + for(uint n : range(512)) cache.buffer[n] = 0x00; + for(uint n : range(32)) cache.valid[n] = false; + for(uint n : range(2)) { + pixelcache[n].offset = ~0; + pixelcache[n].bitpend = 0x00; + } + + regs.romcl = 0; + regs.romdr = 0; + + regs.ramcl = 0; + regs.ramar = 0; + regs.ramdr = 0; } } diff --git a/higan/sfc/coprocessor/superfx/superfx.hpp b/higan/sfc/coprocessor/superfx/superfx.hpp index 4f5de86b..502bd56f 100644 --- a/higan/sfc/coprocessor/superfx/superfx.hpp +++ b/higan/sfc/coprocessor/superfx/superfx.hpp @@ -25,45 +25,39 @@ struct SuperFX : Processor::GSU, Cothread { }; //core.cpp - auto stop() -> void; - auto color(uint8 source) -> uint8; - auto plot(uint8 x, uint8 y) -> void; - auto rpix(uint8 x, uint8 y) -> uint8; - auto pixelcache_flush(pixelcache_t& cache) -> void; + auto stop() -> void override; + auto color(uint8 source) -> uint8 override; + auto plot(uint8 x, uint8 y) -> void override; + auto rpix(uint8 x, uint8 y) -> uint8 override; + + auto flushPixelCache(PixelCache& cache) -> void; //memory.cpp - auto bus_read(uint24 addr, uint8 data = 0x00) -> uint8 override; - auto bus_write(uint24 addr, uint8 data) -> void override; + auto read(uint24 addr, uint8 data = 0x00) -> uint8 override; + auto write(uint24 addr, uint8 data) -> void override; - auto op_read(uint16 addr) -> uint8; + auto readOpcode(uint16 addr) -> uint8; alwaysinline auto peekpipe() -> uint8; - alwaysinline auto pipe() -> uint8; + alwaysinline auto pipe() -> uint8 override; - auto cache_flush() -> void; - auto cache_mmio_read(uint16 addr) -> uint8; - auto cache_mmio_write(uint16 addr, uint8 data) -> void; - - auto memory_reset() -> void; + auto flushCache() -> void override; + auto readCache(uint16 addr) -> uint8; + auto writeCache(uint16 addr, uint8 data) -> void; //mmio.cpp auto readIO(uint24 addr, uint8 data) -> uint8; auto writeIO(uint24 addr, uint8 data) -> void; //timing.cpp - auto step(uint clocks) -> void; + auto step(uint clocks) -> void override; - auto rombuffer_sync() -> void; - auto rombuffer_update() -> void; - auto rombuffer_read() -> uint8; + auto syncROMBuffer() -> void override; + auto readROMBuffer() -> uint8 override; + auto updateROMBuffer() -> void; - auto rambuffer_sync() -> void; - auto rambuffer_read(uint16 addr) -> uint8; - auto rambuffer_write(uint16 addr, uint8 data) -> void; - - auto r14_modify(uint16) -> void; - auto r15_modify(uint16) -> void; - - auto timing_reset() -> void; + auto syncRAMBuffer() -> void override; + auto readRAMBuffer(uint16 addr) -> uint8 override; + auto writeRAMBuffer(uint16 addr, uint8 data) -> void override; //serialization.cpp auto serialize(serializer&) -> void; @@ -72,10 +66,8 @@ struct SuperFX : Processor::GSU, Cothread { CPURAM cpuram; private: - uint rom_mask; //rom_size - 1 - uint ram_mask; //ram_size - 1 - - bool r15_modified = false; + uint romMask; + uint ramMask; }; extern SuperFX superfx; diff --git a/higan/sfc/coprocessor/superfx/timing.cpp b/higan/sfc/coprocessor/superfx/timing.cpp index 858bccd9..0cf59ac2 100644 --- a/higan/sfc/coprocessor/superfx/timing.cpp +++ b/higan/sfc/coprocessor/superfx/timing.cpp @@ -3,14 +3,14 @@ auto SuperFX::step(uint clocks) -> void { regs.romcl -= min(clocks, regs.romcl); if(regs.romcl == 0) { regs.sfr.r = 0; - regs.romdr = bus_read((regs.rombr << 16) + regs.r[14]); + regs.romdr = read((regs.rombr << 16) + regs.r[14]); } } if(regs.ramcl) { regs.ramcl -= min(clocks, regs.ramcl); if(regs.ramcl == 0) { - bus_write(0x700000 + (regs.rambr << 16) + regs.ramar, regs.ramdr); + write(0x700000 + (regs.rambr << 16) + regs.ramar, regs.ramdr); } } @@ -18,53 +18,32 @@ auto SuperFX::step(uint clocks) -> void { synchronizeCPU(); } -auto SuperFX::rombuffer_sync() -> void { +auto SuperFX::syncROMBuffer() -> void { if(regs.romcl) step(regs.romcl); } -auto SuperFX::rombuffer_update() -> void { +auto SuperFX::readROMBuffer() -> uint8 { + syncROMBuffer(); + return regs.romdr; +} + +auto SuperFX::updateROMBuffer() -> void { regs.sfr.r = 1; regs.romcl = regs.clsr ? 5 : 6; } -auto SuperFX::rombuffer_read() -> uint8 { - rombuffer_sync(); - return regs.romdr; -} - -auto SuperFX::rambuffer_sync() -> void { +auto SuperFX::syncRAMBuffer() -> void { if(regs.ramcl) step(regs.ramcl); } -auto SuperFX::rambuffer_read(uint16 addr) -> uint8 { - rambuffer_sync(); - return bus_read(0x700000 + (regs.rambr << 16) + addr); +auto SuperFX::readRAMBuffer(uint16 addr) -> uint8 { + syncRAMBuffer(); + return read(0x700000 + (regs.rambr << 16) + addr); } -auto SuperFX::rambuffer_write(uint16 addr, uint8 data) -> void { - rambuffer_sync(); +auto SuperFX::writeRAMBuffer(uint16 addr, uint8 data) -> void { + syncRAMBuffer(); regs.ramcl = regs.clsr ? 5 : 6; regs.ramar = addr; regs.ramdr = data; } - -auto SuperFX::r14_modify(uint16 data) -> void { - regs.r[14].data = data; - rombuffer_update(); -} - -auto SuperFX::r15_modify(uint16 data) -> void { - regs.r[15].data = data; - r15_modified = true; -} - -auto SuperFX::timing_reset() -> void { - r15_modified = false; - - regs.romcl = 0; - regs.romdr = 0; - - regs.ramcl = 0; - regs.ramar = 0; - regs.ramdr = 0; -}