diff --git a/higan/emulator/emulator.hpp b/higan/emulator/emulator.hpp index 6e403b74..20b0e3c4 100644 --- a/higan/emulator/emulator.hpp +++ b/higan/emulator/emulator.hpp @@ -6,7 +6,7 @@ using namespace nall; namespace Emulator { static const string Name = "higan"; - static const string Version = "097.31"; + static const string Version = "097.32"; static const string Author = "byuu"; static const string License = "GPLv3"; static const string Website = "http://byuu.org/"; diff --git a/higan/sfc/alt/cpu/cpu.cpp b/higan/sfc/alt/cpu/cpu.cpp index 60f9680a..eb72cfc0 100644 --- a/higan/sfc/alt/cpu/cpu.cpp +++ b/higan/sfc/alt/cpu/cpu.cpp @@ -30,7 +30,7 @@ auto CPU::synchronizeSMP() -> void { if(SMP::Threaded == true) { if(smp.clock < 0) co_switch(smp.thread); } else { - while(smp.clock < 0) smp.enter(); + while(smp.clock < 0) smp.main(); } } @@ -38,7 +38,7 @@ auto CPU::synchronizePPU() -> void { if(PPU::Threaded == true) { if(ppu.clock < 0) co_switch(ppu.thread); } else { - while(ppu.clock < 0) ppu.enter(); + while(ppu.clock < 0) ppu.main(); } } @@ -54,29 +54,24 @@ auto CPU::synchronizeDevices() -> void { if(device.controllerPort2->clock < 0) co_switch(device.controllerPort2->thread); } -auto CPU::Enter() -> void { cpu.enter(); } +auto CPU::Enter() -> void { + while(true) scheduler.synchronize(), cpu.main(); +} -auto CPU::enter() -> void { - while(true) { - if(scheduler.sync == Scheduler::SynchronizeMode::CPU) { - scheduler.sync = Scheduler::SynchronizeMode::All; - scheduler.exit(Scheduler::ExitReason::SynchronizeEvent); - } - - if(status.nmi_pending) { - status.nmi_pending = false; - regs.vector = (regs.e == false ? 0xffea : 0xfffa); - op_irq(); - } - - if(status.irq_pending) { - status.irq_pending = false; - regs.vector = (regs.e == false ? 0xffee : 0xfffe); - op_irq(); - } - - op_exec(); +auto CPU::main() -> void { + if(status.nmi_pending) { + status.nmi_pending = false; + regs.vector = (regs.e == false ? 0xffea : 0xfffa); + interrupt(); } + + if(status.irq_pending) { + status.irq_pending = false; + regs.vector = (regs.e == false ? 0xffee : 0xfffe); + interrupt(); + } + + instruction(); } auto CPU::enable() -> void { diff --git a/higan/sfc/alt/cpu/cpu.hpp b/higan/sfc/alt/cpu/cpu.hpp index 1fab7a3b..10cbef28 100644 --- a/higan/sfc/alt/cpu/cpu.hpp +++ b/higan/sfc/alt/cpu/cpu.hpp @@ -11,17 +11,19 @@ struct CPU : Processor::R65816, Thread, public PPUcounter { auto pio() -> uint8; auto joylatch() -> bool; - auto interrupt_pending() -> bool; + auto interruptPending() const -> bool; auto port_read(uint8 port) -> uint8; auto port_write(uint8 port, uint8 data) -> void; + auto dmaPortRead(uint24 addr, uint8 data) -> uint8; + auto dmaPortWrite(uint24 addr, uint8 data) -> void; auto mmio_read(uint addr, uint8 data) -> uint8; auto mmio_write(uint addr, uint8 data) -> void; - auto op_io() -> void; - auto op_read(uint addr) -> uint8; - auto op_write(uint addr, uint8 data) -> void; + auto io() -> void; + auto read(uint24 addr) -> uint8; + auto write(uint24 addr, uint8 data) -> void; - auto enter() -> void; + auto main() -> void; auto enable() -> void; auto power() -> void; auto reset() -> void; @@ -37,7 +39,7 @@ private: //timing auto queue_event(uint id) -> void; - auto last_cycle() -> void; + auto lastCycle() -> void; auto add_clocks(uint clocks) -> void; auto scanline() -> void; auto run_auto_joypad_poll() -> void; @@ -89,8 +91,8 @@ private: uint8 source_bank; union { - uint16 transfer_size; - uint16 indirect_addr; + uint16_t transfer_size; + uint16_t indirect_addr; }; uint8 indirect_bank; diff --git a/higan/sfc/alt/cpu/dma.cpp b/higan/sfc/alt/cpu/dma.cpp index 50691a01..6b7a8361 100644 --- a/higan/sfc/alt/cpu/dma.cpp +++ b/higan/sfc/alt/cpu/dma.cpp @@ -28,7 +28,7 @@ auto CPU::dma_transfer(bool direction, uint8 bbus, uint abus) -> void { add_clocks(8); dma_write(dma_transfer_valid(bbus, abus), 0x2100 | bbus, data); } else { - uint8 data = dma_transfer_valid(bbus, abus) ? bus.read(0x2100 | bbus, regs.mdr) : 0x00; + uint8 data = dma_transfer_valid(bbus, abus) ? bus.read(0x2100 | bbus, regs.mdr) : (uint8)0x00; add_clocks(8); dma_write(dma_addr_valid(abus), abus, data); } diff --git a/higan/sfc/alt/cpu/memory.cpp b/higan/sfc/alt/cpu/memory.cpp index 961043f2..92bd3ff5 100644 --- a/higan/sfc/alt/cpu/memory.cpp +++ b/higan/sfc/alt/cpu/memory.cpp @@ -6,7 +6,7 @@ auto CPU::joylatch() -> bool { return status.joypad_strobe_latch; } -auto CPU::interrupt_pending() -> bool { +auto CPU::interruptPending() const -> bool { return false; } @@ -18,17 +18,17 @@ auto CPU::port_write(uint8 port, uint8 data) -> void { port_data[port & 3] = data; } -auto CPU::op_io() -> void { +auto CPU::io() -> void { add_clocks(6); } -auto CPU::op_read(uint addr) -> uint8 { +auto CPU::read(uint24 addr) -> uint8 { regs.mdr = bus.read(addr, regs.mdr); add_clocks(speed(addr)); return regs.mdr; } -auto CPU::op_write(uint addr, uint8 data) -> void { +auto CPU::write(uint24 addr, uint8 data) -> void { add_clocks(speed(addr)); bus.write(addr, regs.mdr = data); } diff --git a/higan/sfc/alt/cpu/mmio.cpp b/higan/sfc/alt/cpu/mmio.cpp index 386019d0..d1279791 100644 --- a/higan/sfc/alt/cpu/mmio.cpp +++ b/higan/sfc/alt/cpu/mmio.cpp @@ -1,3 +1,11 @@ +auto CPU::dmaPortRead(uint24 addr, uint8 data) -> uint8 { + return mmio_read(addr, data); +} + +auto CPU::dmaPortWrite(uint24 addr, uint8 data) -> void { + return mmio_write(addr, data); +} + auto CPU::mmio_read(uint addr, uint8 data) -> uint8 { if((addr & 0xffc0) == 0x2140) { synchronizeSMP(); @@ -186,7 +194,7 @@ auto CPU::mmio_write(uint addr, uint8 data) -> void { case 0x4206: { status.wrdivb = data; status.rddiv = status.wrdivb ? status.wrdiva / status.wrdivb : 0xffff; - status.rdmpy = status.wrdivb ? status.wrdiva % status.wrdivb : status.wrdiva; + status.rdmpy = status.wrdivb ? status.wrdiva % status.wrdivb : (uint)status.wrdiva; return; } diff --git a/higan/sfc/alt/cpu/timing.cpp b/higan/sfc/alt/cpu/timing.cpp index 741e7ab1..866ab32f 100644 --- a/higan/sfc/alt/cpu/timing.cpp +++ b/higan/sfc/alt/cpu/timing.cpp @@ -5,7 +5,7 @@ auto CPU::queue_event(uint id) -> void { } } -auto CPU::last_cycle() -> void { +auto CPU::lastCycle() -> void { if(status.irq_lock) { status.irq_lock = false; return; diff --git a/higan/sfc/alt/dsp/dsp.cpp b/higan/sfc/alt/dsp/dsp.cpp index 71fa8102..26e092f1 100644 --- a/higan/sfc/alt/dsp/dsp.cpp +++ b/higan/sfc/alt/dsp/dsp.cpp @@ -2,6 +2,7 @@ namespace SuperFamicom { +#include DSP dsp; #include "serialization.cpp" @@ -17,13 +18,13 @@ auto DSP::step(uint clocks) -> void { auto DSP::synchronizeSMP() -> void { if(SMP::Threaded == true) { - if(clock >= 0 && scheduler.sync != Scheduler::SynchronizeMode::All) co_switch(smp.thread); + if(clock >= 0 && !scheduler.synchronizing()) co_switch(smp.thread); } else { - while(clock >= 0) smp.enter(); + while(clock >= 0) smp.main(); } } -auto DSP::enter() -> void { +auto DSP::main() -> void { spc_dsp.run(1); step(24); diff --git a/higan/sfc/alt/dsp/dsp.hpp b/higan/sfc/alt/dsp/dsp.hpp index 92c116e9..fe786799 100644 --- a/higan/sfc/alt/dsp/dsp.hpp +++ b/higan/sfc/alt/dsp/dsp.hpp @@ -1,3 +1,5 @@ +#include + #include "SPC_DSP.h" struct DSP : Thread { @@ -12,7 +14,7 @@ struct DSP : Thread { auto read(uint8 addr) -> uint8; auto write(uint8 addr, uint8 data) -> void; - auto enter() -> void; + auto main() -> void; auto power() -> void; auto reset() -> void; @@ -22,7 +24,7 @@ struct DSP : Thread { private: SPC_DSP spc_dsp; - int16 samplebuffer[8192]; + int16_t samplebuffer[8192]; bool channel_enabled[8]; }; diff --git a/higan/sfc/alt/ppu-balanced/ppu.cpp b/higan/sfc/alt/ppu-balanced/ppu.cpp index 43ed24e8..5e4b950c 100644 --- a/higan/sfc/alt/ppu-balanced/ppu.cpp +++ b/higan/sfc/alt/ppu-balanced/ppu.cpp @@ -2,6 +2,7 @@ namespace SuperFamicom { +#include PPU ppu; #include "memory/memory.cpp" @@ -49,55 +50,50 @@ auto PPU::step(uint clocks) -> void { auto PPU::synchronizeCPU() -> void { if(CPU::Threaded == true) { - if(clock >= 0 && scheduler.sync != Scheduler::SynchronizeMode::All) co_switch(cpu.thread); + if(clock >= 0 && !scheduler.synchronizing()) co_switch(cpu.thread); } else { - while(clock >= 0) cpu.enter(); + while(clock >= 0) cpu.main(); } } -auto PPU::Enter() -> void { ppu.enter(); } +auto PPU::Enter() -> void { + while(true) scheduler.synchronize(), ppu.main(); +} -auto PPU::enter() -> void { - while(true) { - if(scheduler.sync == Scheduler::SynchronizeMode::All) { - scheduler.exit(Scheduler::ExitReason::SynchronizeEvent); +auto PPU::main() -> void { + //H = 0 (initialize) + scanline(); + add_clocks(10); + + //H = 10 (cache mode7 registers + OAM address reset) + cache.m7_hofs = regs.m7_hofs; + cache.m7_vofs = regs.m7_vofs; + cache.m7a = regs.m7a; + cache.m7b = regs.m7b; + cache.m7c = regs.m7c; + cache.m7d = regs.m7d; + cache.m7x = regs.m7x; + cache.m7y = regs.m7y; + if(vcounter() == (!overscan() ? 225 : 240)) { + if(regs.display_disabled == false) { + regs.oam_addr = regs.oam_baseaddr << 1; + regs.oam_firstsprite = (regs.oam_priority == false) ? 0 : (regs.oam_addr >> 2) & 127; } - - //H = 0 (initialize) - scanline(); - add_clocks(10); - - //H = 10 (cache mode7 registers + OAM address reset) - cache.m7_hofs = regs.m7_hofs; - cache.m7_vofs = regs.m7_vofs; - cache.m7a = regs.m7a; - cache.m7b = regs.m7b; - cache.m7c = regs.m7c; - cache.m7d = regs.m7d; - cache.m7x = regs.m7x; - cache.m7y = regs.m7y; - if(vcounter() == (!overscan() ? 225 : 240)) { - if(regs.display_disabled == false) { - regs.oam_addr = regs.oam_baseaddr << 1; - regs.oam_firstsprite = (regs.oam_priority == false) ? 0 : (regs.oam_addr >> 2) & 127; - } - } - add_clocks(502); - - //H = 512 (render) - render_scanline(); - add_clocks(640); - - //H = 1152 (cache OBSEL) - if(cache.oam_basesize != regs.oam_basesize) { - cache.oam_basesize = regs.oam_basesize; - sprite_list_valid = false; - } - cache.oam_nameselect = regs.oam_nameselect; - cache.oam_tdaddr = regs.oam_tdaddr; - add_clocks(lineclocks() - 1152); //seek to start of next scanline - } + add_clocks(502); + + //H = 512 (render) + render_scanline(); + add_clocks(640); + + //H = 1152 (cache OBSEL) + if(cache.oam_basesize != regs.oam_basesize) { + cache.oam_basesize = regs.oam_basesize; + sprite_list_valid = false; + } + cache.oam_nameselect = regs.oam_nameselect; + cache.oam_tdaddr = regs.oam_tdaddr; + add_clocks(lineclocks() - 1152); //seek to start of next scanline } auto PPU::add_clocks(uint clocks) -> void { @@ -131,7 +127,8 @@ auto PPU::scanline() -> void { } if(line == 241) { - scheduler.exit(Scheduler::ExitReason::FrameEvent); + video.refresh(); + scheduler.exit(Scheduler::Event::Frame); } } @@ -401,6 +398,8 @@ auto PPU::reset() -> void { regs.bg_y[1] = 0; regs.bg_y[2] = 0; regs.bg_y[3] = 0; + + video.reset(); } auto PPU::layer_enable(uint layer, uint priority, bool enable) -> void { diff --git a/higan/sfc/alt/ppu-balanced/ppu.hpp b/higan/sfc/alt/ppu-balanced/ppu.hpp index 9f2305f5..60b84746 100644 --- a/higan/sfc/alt/ppu-balanced/ppu.hpp +++ b/higan/sfc/alt/ppu-balanced/ppu.hpp @@ -1,3 +1,5 @@ +#include + struct PPU : Thread, public PPUcounter { enum : bool { Threaded = true }; @@ -23,7 +25,7 @@ struct PPU : Thread, public PPUcounter { auto scanline() -> void; auto render_scanline() -> void; auto frame() -> void; - auto enter() -> void; + auto main() -> void; auto enable() -> void; auto power() -> void; auto reset() -> void; diff --git a/higan/sfc/alt/ppu-balanced/render/bg.cpp b/higan/sfc/alt/ppu-balanced/render/bg.cpp index 54ad3a41..f508fd12 100644 --- a/higan/sfc/alt/ppu-balanced/render/bg.cpp +++ b/higan/sfc/alt/ppu-balanced/render/bg.cpp @@ -5,7 +5,7 @@ auto PPU::update_bg_info() -> void { for(unsigned bg = 0; bg < 4; bg++) { bg_info[bg].th = (regs.bg_tilesize[bg] ? 4 : 3); - bg_info[bg].tw = (hires ? 4 : bg_info[bg].th); + bg_info[bg].tw = (hires ? 4 : (uint)bg_info[bg].th); bg_info[bg].mx = (bg_info[bg].th == 4 ? (width << 1) : width); bg_info[bg].my = bg_info[bg].mx; @@ -96,7 +96,7 @@ auto PPU::render_line_bg(uint8 pri0_pos, uint8 pri1_pos) -> void { bool mirror_x, mirror_y; const uint8* tile_ptr; - const uint16* mtable = mosaic_table[regs.mosaic_enabled[bg] ? regs.mosaic_size : 0]; + const uint16* mtable = mosaic_table[regs.mosaic_enabled[bg] ? (uint)regs.mosaic_size : 0]; const bool is_opt_mode = (mode == 2 || mode == 4 || mode == 6); const bool is_direct_color_mode = (regs.direct_color == true && bg == BG1 && (mode == 3 || mode == 4)); diff --git a/higan/sfc/alt/ppu-balanced/render/cache.cpp b/higan/sfc/alt/ppu-balanced/render/cache.cpp index 8bedcbe9..06dc1119 100644 --- a/higan/sfc/alt/ppu-balanced/render/cache.cpp +++ b/higan/sfc/alt/ppu-balanced/render/cache.cpp @@ -118,12 +118,12 @@ auto PPU::flush_pixel_cache() -> void { } auto PPU::alloc_tiledata_cache() -> void { - bg_tiledata[TILE_2BIT] = new uint8_t[262144](); - bg_tiledata[TILE_4BIT] = new uint8_t[131072](); - bg_tiledata[TILE_8BIT] = new uint8_t[ 65536](); - bg_tiledata_state[TILE_2BIT] = new uint8_t[ 4096](); - bg_tiledata_state[TILE_4BIT] = new uint8_t[ 2048](); - bg_tiledata_state[TILE_8BIT] = new uint8_t[ 1024](); + bg_tiledata[TILE_2BIT] = new uint8[262144](); + bg_tiledata[TILE_4BIT] = new uint8[131072](); + bg_tiledata[TILE_8BIT] = new uint8[ 65536](); + bg_tiledata_state[TILE_2BIT] = new uint8[ 4096](); + bg_tiledata_state[TILE_4BIT] = new uint8[ 2048](); + bg_tiledata_state[TILE_8BIT] = new uint8[ 1024](); } //marks all tiledata cache entries as dirty diff --git a/higan/sfc/alt/ppu-balanced/render/mode7.cpp b/higan/sfc/alt/ppu-balanced/render/mode7.cpp index f4bff7c9..5de69f27 100644 --- a/higan/sfc/alt/ppu-balanced/render/mode7.cpp +++ b/higan/sfc/alt/ppu-balanced/render/mode7.cpp @@ -44,13 +44,13 @@ auto PPU::render_line_mode7(uint8 pri0_pos, uint8 pri1_pos) -> void { uint16* mtable_x; uint16* mtable_y; if(bg == BG1) { - mtable_x = (uint16*)mosaic_table[(regs.mosaic_enabled[BG1] == true) ? regs.mosaic_size : 0]; - mtable_y = (uint16*)mosaic_table[(regs.mosaic_enabled[BG1] == true) ? regs.mosaic_size : 0]; + mtable_x = (uint16*)mosaic_table[(regs.mosaic_enabled[BG1] == true) ? (uint)regs.mosaic_size : 0]; + mtable_y = (uint16*)mosaic_table[(regs.mosaic_enabled[BG1] == true) ? (uint)regs.mosaic_size : 0]; } else { //bg == BG2 //Mode7 EXTBG BG2 uses BG1 mosaic enable to control vertical mosaic, //and BG2 mosaic enable to control horizontal mosaic... - mtable_x = (uint16*)mosaic_table[(regs.mosaic_enabled[BG2] == true) ? regs.mosaic_size : 0]; - mtable_y = (uint16*)mosaic_table[(regs.mosaic_enabled[BG1] == true) ? regs.mosaic_size : 0]; + mtable_x = (uint16*)mosaic_table[(regs.mosaic_enabled[BG2] == true) ? (uint)regs.mosaic_size : 0]; + mtable_y = (uint16*)mosaic_table[(regs.mosaic_enabled[BG1] == true) ? (uint)regs.mosaic_size : 0]; } int32 psx = ((a * CLIP(hofs - cx)) & ~63) + ((b * CLIP(vofs - cy)) & ~63) + ((b * mtable_y[y]) & ~63) + (cx << 8); @@ -108,7 +108,7 @@ auto PPU::render_line_mode7(uint8 pri0_pos, uint8 pri1_pos) -> void { if(!palette) continue; - _x = (regs.mode7_hflip == false) ? (x) : (255 - x); + _x = (regs.mode7_hflip == false) ? ((uint)x) : (255 - x); uint32 col; if(regs.direct_color == true && bg == BG1) { diff --git a/higan/sfc/alt/ppu-balanced/render/oam.cpp b/higan/sfc/alt/ppu-balanced/render/oam.cpp index b5eae808..732d0952 100644 --- a/higan/sfc/alt/ppu-balanced/render/oam.cpp +++ b/higan/sfc/alt/ppu-balanced/render/oam.cpp @@ -69,7 +69,7 @@ auto PPU::is_sprite_on_scanline() -> bool { sprite_item* spr = &sprite_list[active_sprite]; if(spr->x > 256 && (spr->x + spr->width - 1) < 512) return false; - int spr_height = (regs.oam_interlace == false) ? (spr->height) : (spr->height >> 1); + int spr_height = (regs.oam_interlace == false) ? ((uint)spr->height) : (spr->height >> 1); if(line >= spr->y && line < (spr->y + spr_height)) return true; if((spr->y + spr_height) >= 256 && line < ((spr->y + spr_height) & 255)) return true; return false; diff --git a/higan/sfc/alt/ppu-performance/background/background.cpp b/higan/sfc/alt/ppu-performance/background/background.cpp index 852a48b1..9896c9e4 100644 --- a/higan/sfc/alt/ppu-performance/background/background.cpp +++ b/higan/sfc/alt/ppu-performance/background/background.cpp @@ -111,7 +111,7 @@ auto PPU::Background::render() -> void { hscroll = regs.hoffset; vscroll = regs.voffset; - uint y = (regs.mosaic == 0 ? self.vcounter() : mosaic_voffset); + uint y = (regs.mosaic == 0 ? (uint)self.vcounter() : mosaic_voffset); if(hires) { hscroll <<= 1; if(self.regs.interlace) y = (y << 1) + self.field(); diff --git a/higan/sfc/alt/ppu-performance/background/mode7.cpp b/higan/sfc/alt/ppu-performance/background/mode7.cpp index a53dbcbb..74e66ae9 100644 --- a/higan/sfc/alt/ppu-performance/background/mode7.cpp +++ b/higan/sfc/alt/ppu-performance/background/mode7.cpp @@ -14,7 +14,7 @@ auto PPU::Background::render_mode7() -> void { int hofs = sclip<13>(self.regs.mode7_hoffset); int vofs = sclip<13>(self.regs.mode7_voffset); - int y = (self.regs.mode7_vflip == false ? self.vcounter() : 255 - self.vcounter()); + int y = (self.regs.mode7_vflip == false ? (uint)self.vcounter() : 255 - self.vcounter()); uint16* mosaic_x; uint16* mosaic_y; diff --git a/higan/sfc/alt/ppu-performance/ppu.cpp b/higan/sfc/alt/ppu-performance/ppu.cpp index a4f9e406..964343de 100644 --- a/higan/sfc/alt/ppu-performance/ppu.cpp +++ b/higan/sfc/alt/ppu-performance/ppu.cpp @@ -2,6 +2,7 @@ namespace SuperFamicom { +#include PPU ppu; #include "mmio/mmio.cpp" @@ -39,28 +40,24 @@ auto PPU::step(uint clocks) -> void { auto PPU::synchronizeCPU() -> void { if(CPU::Threaded == true) { - if(clock >= 0 && scheduler.sync != Scheduler::SynchronizeMode::All) co_switch(cpu.thread); + if(clock >= 0 && !scheduler.synchronizing()) co_switch(cpu.thread); } else { - while(clock >= 0) cpu.enter(); + while(clock >= 0) cpu.main(); } } -auto PPU::Enter() -> void { ppu.enter(); } +auto PPU::Enter() -> void { + while(true) scheduler.synchronize(), ppu.main(); +} -auto PPU::enter() -> void { - while(true) { - if(scheduler.sync == Scheduler::SynchronizeMode::All) { - scheduler.exit(Scheduler::ExitReason::SynchronizeEvent); - } - - scanline(); - if(vcounter() < display.height && vcounter()) { - add_clocks(512); - render_scanline(); - add_clocks(lineclocks() - 512); - } else { - add_clocks(lineclocks()); - } +auto PPU::main() -> void { + scanline(); + if(vcounter() < display.height && vcounter()) { + add_clocks(512); + render_scanline(); + add_clocks(lineclocks() - 512); + } else { + add_clocks(lineclocks()); } } @@ -93,7 +90,8 @@ auto PPU::scanline() -> void { if(vcounter() == display.height && regs.display_disable == false) sprite.address_reset(); if(vcounter() == 241) { - scheduler.exit(Scheduler::ExitReason::FrameEvent); + video.refresh(); + scheduler.exit(Scheduler::Event::Frame); } } @@ -126,6 +124,7 @@ auto PPU::reset() -> void { mmio_reset(); display.interlace = false; display.overscan = false; + video.reset(); } auto PPU::layer_enable(uint layer, uint priority, bool enable) -> void { diff --git a/higan/sfc/alt/ppu-performance/ppu.hpp b/higan/sfc/alt/ppu-performance/ppu.hpp index 6bb622f6..60f9538f 100644 --- a/higan/sfc/alt/ppu-performance/ppu.hpp +++ b/higan/sfc/alt/ppu-performance/ppu.hpp @@ -1,3 +1,5 @@ +#include + struct PPU : Thread, public PPUcounter { enum : bool { Threaded = true }; @@ -11,7 +13,7 @@ struct PPU : Thread, public PPUcounter { auto interlace() const -> bool; auto overscan() const -> bool; - auto enter() -> void; + auto main() -> void; auto enable() -> void; auto power() -> void; auto reset() -> void; diff --git a/higan/sfc/alt/smp/smp.cpp b/higan/sfc/alt/smp/smp.cpp index c4bf48af..7e500b5f 100644 --- a/higan/sfc/alt/smp/smp.cpp +++ b/higan/sfc/alt/smp/smp.cpp @@ -21,7 +21,7 @@ auto SMP::synchronizeCPU() -> void { if(CPU::Threaded == true) { //if(clock >= 0 && scheduler.sync != Scheduler::SynchronizeMode::All) co_switch(cpu.thread); } else { - while(clock >= 0) cpu.enter(); + while(clock >= 0) cpu.main(); } } @@ -29,11 +29,11 @@ auto SMP::synchronizeDSP() -> void { if(DSP::Threaded == true) { //if(dsp.clock < 0 && scheduler.sync != Scheduler::SynchronizeMode::All) co_switch(dsp.thread); } else { - while(dsp.clock < 0) dsp.enter(); + while(dsp.clock < 0) dsp.main(); } } -auto SMP::enter() -> void { +auto SMP::main() -> void { while(clock < 0) op_step(); } diff --git a/higan/sfc/alt/smp/smp.hpp b/higan/sfc/alt/smp/smp.hpp index 0b29459b..97613eea 100644 --- a/higan/sfc/alt/smp/smp.hpp +++ b/higan/sfc/alt/smp/smp.hpp @@ -12,7 +12,7 @@ struct SMP : Thread { auto mmio_read(uint addr) -> uint; auto mmio_write(uint addr, uint data) -> void; - auto enter() -> void; + auto main() -> void; auto power() -> void; auto reset() -> void; @@ -69,8 +69,8 @@ struct SMP : Thread { uint16 pc; uint8 sp; union { - uint16 ya; - struct { uint8 order_lsb2(a, y); }; + uint16_t ya; + struct { uint8_t order_lsb2(a, y); }; }; uint8 x; Flags p; diff --git a/higan/sfc/cpu/cpu.cpp b/higan/sfc/cpu/cpu.cpp index 8a6b7882..bfe2592e 100644 --- a/higan/sfc/cpu/cpu.cpp +++ b/higan/sfc/cpu/cpu.cpp @@ -66,16 +66,21 @@ auto CPU::main() -> void { status.interrupt_pending = false; if(status.nmi_pending) { status.nmi_pending = false; - regs.vector = (regs.e == false ? 0xffea : 0xfffa); + regs.vector = !regs.e ? 0xffea : 0xfffa; interrupt(); debugger.op_nmi(); } else if(status.irq_pending) { status.irq_pending = false; - regs.vector = (regs.e == false ? 0xffee : 0xfffe); + regs.vector = !regs.e ? 0xffee : 0xfffe; interrupt(); debugger.op_irq(); } else if(status.reset_pending) { status.reset_pending = false; + addClocks(132); + regs.vector = 0xfffc; + interrupt(); + } else if(status.power_pending) { + status.power_pending = false; addClocks(186); regs.pc.l = bus.read(0xfffc, regs.mdr); regs.pc.h = bus.read(0xfffd, regs.mdr); @@ -146,6 +151,9 @@ auto CPU::power() -> void { channel.line_counter = 0xff; channel.unknown = 0xff; } + + status.power_pending = true; + status.interrupt_pending = true; } auto CPU::reset() -> void { @@ -255,7 +263,7 @@ auto CPU::reset() -> void { status.irq_pending = false; status.irq_hold = false; - status.reset_pending = true; + status.reset_pending = !status.power_pending; status.interrupt_pending = true; status.dma_active = false; diff --git a/higan/sfc/cpu/cpu.hpp b/higan/sfc/cpu/cpu.hpp index 627b56e0..d0f12581 100644 --- a/higan/sfc/cpu/cpu.hpp +++ b/higan/sfc/cpu/cpu.hpp @@ -123,6 +123,7 @@ privileged: bool irq_pending; bool irq_hold; + bool power_pending; bool reset_pending; //DMA diff --git a/higan/sfc/cpu/serialization.cpp b/higan/sfc/cpu/serialization.cpp index e0d49192..c946b349 100644 --- a/higan/sfc/cpu/serialization.cpp +++ b/higan/sfc/cpu/serialization.cpp @@ -35,6 +35,7 @@ auto CPU::serialize(serializer& s) -> void { s.integer(status.irq_pending); s.integer(status.irq_hold); + s.integer(status.power_pending); s.integer(status.reset_pending); s.integer(status.dma_active);