From 8c2b99b53742ae0b4d7e4a654f6e450b428e04de Mon Sep 17 00:00:00 2001 From: rdanbrook <1869094+rdanbrook@users.noreply.github.com> Date: Wed, 17 Mar 2021 16:21:51 -0400 Subject: [PATCH] Update core to 1.51.0 --- NstDatabase.xml | 95 ++++++ libretro/Makefile.common | 1 + libretro/libretro.cpp | 4 +- {extras => palettes}/BMFFINR2.pal | Bin {extras => palettes}/BMFFINR3.pal | Bin {extras => palettes}/CXA2025AS-1536.pal | Bin .../Composite Direct (FBX).pal | Bin {extras => palettes}/NES Classic (FBX-FS).pal | Bin {extras => palettes}/NES_Classic-FBX.pal | Bin {extras => palettes}/Nostalgia-FBX.pal | Bin .../Original Hardware (FBX).pal | Bin {extras => palettes}/PVM Style (FBX).pal | Bin {extras => palettes}/PVM Style D93 (FBX).pal | Bin {extras => palettes}/SONY_CXA2025AS_US.pal | Bin {extras => palettes}/Smooth (FBX).pal | Bin {extras => palettes}/Unsaturated-Final.pal | Bin {extras => palettes}/Unsaturated-V5.pal | Bin {extras => palettes}/Unsaturated-V6.pal | Bin {extras => palettes}/Wavebeam.pal | Bin {extras => palettes}/YUV-V3.pal | Bin {extras => palettes}/hybrid.pal | Bin {extras => palettes}/nescap.pal | Bin {extras => palettes}/ntsc.pal | Bin source/core/NstApu.cpp | 24 +- source/core/NstApu.hpp | 16 +- source/core/NstCartridgeInes.cpp | 2 +- source/core/NstCpu.cpp | 70 ++-- source/core/NstCpu.hpp | 12 +- source/core/NstFds.cpp | 67 ++-- source/core/NstFds.hpp | 4 +- source/core/NstPpu.cpp | 183 ++++------ source/core/NstPpu.hpp | 25 +- source/core/NstVideoRenderer.cpp | 2 - source/core/api/NstApiVideo.cpp | 14 - source/core/api/NstApiVideo.hpp | 5 - source/core/board/NstBoard.cpp | 195 ++++++++++- source/core/board/NstBoard.hpp | 55 +-- source/core/board/NstBoardCamerica.cpp | 6 + source/core/board/NstBoardCamerica.hpp | 4 + source/core/board/NstBoardKaiser.cpp | 315 +++++++++++++++--- source/core/board/NstBoardKaiser.hpp | 100 ++++-- source/core/board/NstBoardKonamiVrc2.cpp | 7 +- source/core/board/NstBoardMmc1.cpp | 15 + source/core/board/NstBoardMmc1.hpp | 3 + source/core/board/NstBoardMmc5.cpp | 3 +- source/core/board/NstBoardNamcot.hpp | 1 + source/core/board/NstBoardNamcot175.cpp | 155 +-------- source/core/board/NstBoardNamcot175.hpp | 31 +- source/core/board/NstBoardNamcot340.cpp | 89 +++++ source/core/board/NstBoardNamcot340.hpp | 58 ++++ source/core/board/NstBoardOpenCorp.cpp | 140 +++++++- source/core/board/NstBoardOpenCorp.hpp | 11 + source/core/board/NstBoardSunsoft5b.cpp | 2 +- source/core/board/NstBoardTengenRambo1.cpp | 75 ++--- source/core/board/NstBoardTengenRambo1.hpp | 2 + source/core/board/NstBoardUnlCc21.cpp | 3 +- .../board/NstBoardUnlKingOfFighters97.cpp | 13 +- .../board/NstBoardUnlKingOfFighters97.hpp | 2 + 58 files changed, 1230 insertions(+), 579 deletions(-) rename {extras => palettes}/BMFFINR2.pal (100%) rename {extras => palettes}/BMFFINR3.pal (100%) rename {extras => palettes}/CXA2025AS-1536.pal (100%) rename {extras => palettes}/Composite Direct (FBX).pal (100%) rename {extras => palettes}/NES Classic (FBX-FS).pal (100%) rename {extras => palettes}/NES_Classic-FBX.pal (100%) rename {extras => palettes}/Nostalgia-FBX.pal (100%) rename {extras => palettes}/Original Hardware (FBX).pal (100%) rename {extras => palettes}/PVM Style (FBX).pal (100%) rename {extras => palettes}/PVM Style D93 (FBX).pal (100%) rename {extras => palettes}/SONY_CXA2025AS_US.pal (100%) rename {extras => palettes}/Smooth (FBX).pal (100%) rename {extras => palettes}/Unsaturated-Final.pal (100%) rename {extras => palettes}/Unsaturated-V5.pal (100%) rename {extras => palettes}/Unsaturated-V6.pal (100%) rename {extras => palettes}/Wavebeam.pal (100%) rename {extras => palettes}/YUV-V3.pal (100%) rename {extras => palettes}/hybrid.pal (100%) rename {extras => palettes}/nescap.pal (100%) rename {extras => palettes}/ntsc.pal (100%) create mode 100644 source/core/board/NstBoardNamcot340.cpp create mode 100644 source/core/board/NstBoardNamcot340.hpp diff --git a/NstDatabase.xml b/NstDatabase.xml index d724eee..cee76b8 100644 --- a/NstDatabase.xml +++ b/NstDatabase.xml @@ -26916,4 +26916,99 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libretro/Makefile.common b/libretro/Makefile.common index 07f6678..56b1578 100644 --- a/libretro/Makefile.common +++ b/libretro/Makefile.common @@ -204,6 +204,7 @@ SOURCES_CXX += $(CORE_DIR)/source/core/board/NstBoardMmc5.cpp SOURCES_CXX += $(CORE_DIR)/source/core/board/NstBoardMmc6.cpp SOURCES_CXX += $(CORE_DIR)/source/core/board/NstBoardNamcot163.cpp SOURCES_CXX += $(CORE_DIR)/source/core/board/NstBoardNamcot175.cpp +SOURCES_CXX += $(CORE_DIR)/source/core/board/NstBoardNamcot340.cpp SOURCES_CXX += $(CORE_DIR)/source/core/board/NstBoardNamcot34xx.cpp SOURCES_CXX += $(CORE_DIR)/source/core/board/NstBoardNanjing.cpp SOURCES_CXX += $(CORE_DIR)/source/core/board/NstBoardNihon.cpp diff --git a/libretro/libretro.cpp b/libretro/libretro.cpp index fcdbeae..55f3362 100644 --- a/libretro/libretro.cpp +++ b/libretro/libretro.cpp @@ -863,7 +863,7 @@ static void check_variables(void) video.EnableUnlimSprites(true); } - var.key = "nestopia_overclock"; +/* var.key = "nestopia_overclock"; if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var)) { @@ -872,7 +872,7 @@ static void check_variables(void) else if (strcmp(var.value, "2x") == 0) video.EnableOverclocking(true); } - +*/ var.key = "nestopia_fds_auto_insert"; if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var)) diff --git a/extras/BMFFINR2.pal b/palettes/BMFFINR2.pal similarity index 100% rename from extras/BMFFINR2.pal rename to palettes/BMFFINR2.pal diff --git a/extras/BMFFINR3.pal b/palettes/BMFFINR3.pal similarity index 100% rename from extras/BMFFINR3.pal rename to palettes/BMFFINR3.pal diff --git a/extras/CXA2025AS-1536.pal b/palettes/CXA2025AS-1536.pal similarity index 100% rename from extras/CXA2025AS-1536.pal rename to palettes/CXA2025AS-1536.pal diff --git a/extras/Composite Direct (FBX).pal b/palettes/Composite Direct (FBX).pal similarity index 100% rename from extras/Composite Direct (FBX).pal rename to palettes/Composite Direct (FBX).pal diff --git a/extras/NES Classic (FBX-FS).pal b/palettes/NES Classic (FBX-FS).pal similarity index 100% rename from extras/NES Classic (FBX-FS).pal rename to palettes/NES Classic (FBX-FS).pal diff --git a/extras/NES_Classic-FBX.pal b/palettes/NES_Classic-FBX.pal similarity index 100% rename from extras/NES_Classic-FBX.pal rename to palettes/NES_Classic-FBX.pal diff --git a/extras/Nostalgia-FBX.pal b/palettes/Nostalgia-FBX.pal similarity index 100% rename from extras/Nostalgia-FBX.pal rename to palettes/Nostalgia-FBX.pal diff --git a/extras/Original Hardware (FBX).pal b/palettes/Original Hardware (FBX).pal similarity index 100% rename from extras/Original Hardware (FBX).pal rename to palettes/Original Hardware (FBX).pal diff --git a/extras/PVM Style (FBX).pal b/palettes/PVM Style (FBX).pal similarity index 100% rename from extras/PVM Style (FBX).pal rename to palettes/PVM Style (FBX).pal diff --git a/extras/PVM Style D93 (FBX).pal b/palettes/PVM Style D93 (FBX).pal similarity index 100% rename from extras/PVM Style D93 (FBX).pal rename to palettes/PVM Style D93 (FBX).pal diff --git a/extras/SONY_CXA2025AS_US.pal b/palettes/SONY_CXA2025AS_US.pal similarity index 100% rename from extras/SONY_CXA2025AS_US.pal rename to palettes/SONY_CXA2025AS_US.pal diff --git a/extras/Smooth (FBX).pal b/palettes/Smooth (FBX).pal similarity index 100% rename from extras/Smooth (FBX).pal rename to palettes/Smooth (FBX).pal diff --git a/extras/Unsaturated-Final.pal b/palettes/Unsaturated-Final.pal similarity index 100% rename from extras/Unsaturated-Final.pal rename to palettes/Unsaturated-Final.pal diff --git a/extras/Unsaturated-V5.pal b/palettes/Unsaturated-V5.pal similarity index 100% rename from extras/Unsaturated-V5.pal rename to palettes/Unsaturated-V5.pal diff --git a/extras/Unsaturated-V6.pal b/palettes/Unsaturated-V6.pal similarity index 100% rename from extras/Unsaturated-V6.pal rename to palettes/Unsaturated-V6.pal diff --git a/extras/Wavebeam.pal b/palettes/Wavebeam.pal similarity index 100% rename from extras/Wavebeam.pal rename to palettes/Wavebeam.pal diff --git a/extras/YUV-V3.pal b/palettes/YUV-V3.pal similarity index 100% rename from extras/YUV-V3.pal rename to palettes/YUV-V3.pal diff --git a/extras/hybrid.pal b/palettes/hybrid.pal similarity index 100% rename from extras/hybrid.pal rename to palettes/hybrid.pal diff --git a/extras/nescap.pal b/palettes/nescap.pal similarity index 100% rename from extras/nescap.pal rename to palettes/nescap.pal diff --git a/extras/ntsc.pal b/palettes/ntsc.pal similarity index 100% rename from extras/ntsc.pal rename to palettes/ntsc.pal diff --git a/source/core/NstApu.cpp b/source/core/NstApu.cpp index 19e4388..746096d 100644 --- a/source/core/NstApu.cpp +++ b/source/core/NstApu.cpp @@ -361,6 +361,11 @@ namespace Nes return 0; } + uint Apu::GetCtrl() + { + return ctrl; + } + Result Apu::SetSpeed(const uint speed) { if (settings.speed == speed) @@ -1670,7 +1675,7 @@ namespace Nes step = 0x7; status = STATUS_COUNTING; waveLength = 0; - linearCtrl = 0; + //linearCtrl = 0; linearCounter = 0; lengthCounter.Reset(); @@ -1870,7 +1875,6 @@ namespace Nes amp = (sum * outputVolume + rate/2) / rate * 3; } } - // Disabling these blocks fixes scratchy audio in many games /*else if (amp < Channel::OUTPUT_DECAY) { return 0; @@ -2121,7 +2125,6 @@ namespace Nes dma.buffered = false; dma.address = 0xC000; dma.buffer = 0x00; - overclockingIsSafe = true; } Cycle Apu::Dmc::GetResetFrequency(CpuModel model) @@ -2362,31 +2365,16 @@ namespace Nes { out.dac = data & 0x7F; curSample = out.dac * outputVolume; - - if (out.dac != 0) - { - overclockingIsSafe = false; - } } NST_SINGLE_CALL void Apu::Dmc::WriteReg2(const uint data) { regs.address = 0xC000 | (data << 6); - - if (regs.address != 0) - { - overclockingIsSafe = true; - } } NST_SINGLE_CALL void Apu::Dmc::WriteReg3(const uint data) { regs.lengthCounter = (data << 4) + 1; - - if (regs.lengthCounter != 0) - { - overclockingIsSafe = true; - } } NST_SINGLE_CALL bool Apu::Dmc::ClockDAC() diff --git a/source/core/NstApu.hpp b/source/core/NstApu.hpp index 9af2f8d..9820108 100644 --- a/source/core/NstApu.hpp +++ b/source/core/NstApu.hpp @@ -50,7 +50,6 @@ namespace Nes public: explicit Apu(Cpu&); - void Reset(bool); void PowerOff(); void ClearBuffers(); @@ -65,6 +64,7 @@ namespace Nes Result SetSpeed(uint); Result SetVolume(uint,uint); uint GetVolume(uint) const; + uint GetCtrl(); void Mute(bool); void SetAutoTranspose(bool); void SetGenie(bool); @@ -461,7 +461,7 @@ namespace Nes enum { MIN_FRQ = 2 + 1, - STEP_CHECK = 0x00, // >= 0x1F is technically correct but will produce clicks/pops + STEP_CHECK = 0x1F, REG0_LINEAR_COUNTER_LOAD = 0x7F, REG0_LINEAR_COUNTER_START = 0x80, REG2_WAVE_LENGTH_LOW = 0x00FF, @@ -529,8 +529,6 @@ namespace Nes Dmc(); - bool overclockingIsSafe; - void Reset(CpuModel); void UpdateSettings(uint); void LoadState(State::Loader&,const Cpu&,CpuModel,Cycle&); @@ -628,16 +626,6 @@ namespace Nes public: - void SetOverclockSafety(bool safe) - { - dmc.overclockingIsSafe = safe; - } - - bool GetOverclockSafety() - { - return dmc.overclockingIsSafe; - } - dword GetSampleRate() const { return settings.rate; diff --git a/source/core/NstCartridgeInes.cpp b/source/core/NstCartridgeInes.cpp index 37e6789..7c72b9b 100644 --- a/source/core/NstCartridgeInes.cpp +++ b/source/core/NstCartridgeInes.cpp @@ -674,7 +674,7 @@ namespace Nes if (setup.version) { - setup.mapper |= uint(header[8]) << 8 & 0x100; + setup.mapper |= uint(header[8]) << 8 & 0x300; setup.subMapper = header[8] >> 4; } diff --git a/source/core/NstCpu.cpp b/source/core/NstCpu.cpp index 820aad6..f02f53a 100644 --- a/source/core/NstCpu.cpp +++ b/source/core/NstCpu.cpp @@ -204,8 +204,6 @@ namespace Nes ticks = 0; logged = 0; - cpuOverclocking = false; - pc = RESET_VECTOR; cycles.count = 0; @@ -247,7 +245,12 @@ namespace Nes if (hard) { Poke(0x4017, 0x00); - cycles.count = cycles.clock[RESET_CYCLES-1]; + cycles.count = cycles.clock[RESET_CYCLES] + cycles.clock[0]; + } + else + { + Poke(0x4017, apu.GetCtrl()); + cycles.count = cycles.clock[RESET_CYCLES] + cycles.clock[0]; } } @@ -1723,18 +1726,42 @@ namespace Nes return address; } - NST_SINGLE_CALL uint Cpu::Shx(uint address) + NST_SINGLE_CALL void Cpu::Shx(uint address) { - address = x & ((address >> 8) + 1); + uint newaddress = (address + y); + uint data = x & ((address >> 8) + 1); + Peek((address & 0xFF00) | (newaddress & 0x00FF)); // Dummy read + + if ((address ^ newaddress) & 0x100) + { + address = (newaddress & (x << 8)) | (newaddress & 0x00FF); + } + else + { + address = newaddress; + } + NotifyOp("SHX",1UL << 15); - return address; + StoreMem(address, data); } - NST_SINGLE_CALL uint Cpu::Shy(uint address) + NST_SINGLE_CALL void Cpu::Shy(uint address) { - address = y & ((address >> 8) + 1); + uint newaddress = (address + x); + uint data = y & ((address >> 8) + 1); + Peek((address & 0xFF00) | (newaddress & 0x00FF)); // Dummy read + + if ((address ^ newaddress) & 0x100) + { + address = (newaddress & (y << 8)) | (newaddress & 0x00FF); + } + else + { + address = newaddress; + } + NotifyOp("SHY",1UL << 16); - return address; + StoreMem(address, data); } NST_NO_INLINE uint Cpu::Slo(uint data) @@ -1901,18 +1928,6 @@ namespace Nes if (interrupt.irqClock != CYCLE_MAX) interrupt.irqClock = (interrupt.irqClock > cycles.frame ? interrupt.irqClock - cycles.frame : 0); - - if (cpuOverclocking) - { - uint startCycle = cycles.count; - uint lastCycle = cycles.count + extraCycles; - do - { - ExecuteOp(); - } - while (cycles.count < extraCycles); - cycles.count = startCycle; - } } void Cpu::Clock() @@ -2095,6 +2110,15 @@ namespace Nes Store##addr_( dst, instr_(dst) ); \ } + // Unofficial Opcodes SHX/SHY are edge cases + #define NES_I_W_U(instr_,addr_,hex_) \ + \ + void Cpu::op##hex_() \ + { \ + const uint dst = addr_##_W(); \ + instr_(dst); \ + } + #define NES_IP_C_(instr_,ops_,ticks_,hex_) \ \ void Cpu::op##hex_() \ @@ -2352,8 +2376,8 @@ namespace Nes NES_I_W_A( Sha, AbsY, 0x9F ) NES_I_W_A( Sha, IndY, 0x93 ) NES_I_W_A( Shs, AbsY, 0x9B ) - NES_I_W_A( Shx, AbsY, 0x9E ) - NES_I_W_A( Shy, AbsX, 0x9C ) + NES_I_W_U( Shx, Abs, 0x9E ) // Edge case: AbsY done internally + NES_I_W_U( Shy, Abs, 0x9C ) // Edge case: AbsX done internally NES_IRW__( Slo, Zpg, 0x07 ) NES_IRW__( Slo, ZpgX, 0x17 ) NES_IRW__( Slo, Abs, 0x0F ) diff --git a/source/core/NstCpu.hpp b/source/core/NstCpu.hpp index 6dcae70..0523b19 100644 --- a/source/core/NstCpu.hpp +++ b/source/core/NstCpu.hpp @@ -260,8 +260,8 @@ namespace Nes NST_SINGLE_CALL void Lxa (uint); NST_SINGLE_CALL void Sbx (uint); NST_SINGLE_CALL uint Shs (uint); - NST_SINGLE_CALL uint Shx (uint); - NST_SINGLE_CALL uint Shy (uint); + NST_SINGLE_CALL void Shx (uint); + NST_SINGLE_CALL void Shy (uint); NST_NO_INLINE void Anc (uint); NST_NO_INLINE uint Dcp (uint); @@ -487,8 +487,6 @@ namespace Nes Ram ram; Apu apu; IoMap map; - bool cpuOverclocking; - uint extraCycles; static dword logged; static void (Cpu::*const opcodes[0x100])(); @@ -501,12 +499,6 @@ namespace Nes return apu; } - void SetOverclocking(bool overclocking,uint newCycles) - { - cpuOverclocking = overclocking; - extraCycles = newCycles; - } - Cycle Update(uint readAddress=0) { apu.ClockDMA( readAddress ); diff --git a/source/core/NstFds.cpp b/source/core/NstFds.cpp index c4cb00d..ccbebd3 100644 --- a/source/core/NstFds.cpp +++ b/source/core/NstFds.cpp @@ -373,7 +373,7 @@ namespace Nes { State::Loader::Data<4> data( state ); - io.ctrl = data[0]; + io.ctrl = adapter.ctrl = data[0]; io.port = data[1]; break; } @@ -550,7 +550,13 @@ namespace Nes NES_POKE_D(Fds,4023) { - io.ctrl = data; + io.ctrl = adapter.ctrl = data; + + if (!(io.ctrl & Io::CTRL0_DISK_ENABLED)) + { + cpu.ClearIRQ(); + adapter.DisableIRQ(); + } } NES_POKE_D(Fds,4026) @@ -783,21 +789,25 @@ namespace Nes #pragma optimize("", on) #endif - void Fds::Unit::Timer::Advance(uint& timer) + bool Fds::Unit::Timer::Clock() { - timer |= STATUS_PENDING_IRQ; + bool retval = false; - if (ctrl & CTRL_REPEAT) - count = latch; - else - ctrl &= ~uint(CTRL_ENABLED); - - latch = 0; // Fixes Kaettekita Mario Bros - FHorse/dragon2snow - } + if (ctrl & CTRL_ENABLED) + { + if (count == 0) + { + retval = true; + count = latch; - NST_SINGLE_CALL bool Fds::Unit::Timer::Clock() - { - return !(ctrl & CTRL_ENABLED) || !count || --count; + if (!(ctrl & CTRL_REPEAT)) + ctrl &= ~uint(CTRL_ENABLED); + } + else + count--; + } + + return retval; } #ifdef NST_MSVC_OPTIMIZE @@ -1202,11 +1212,15 @@ namespace Nes ibool Fds::Unit::Clock() { - return - ( - (timer.Clock() ? 0 : (timer.Advance(status), 1)) | - (drive.Clock() ? 0 : drive.Advance(status)) - ); + bool retval = false; + + if (timer.Clock()) + { + status |= STATUS_PENDING_IRQ; + retval = true; + } + + return (retval | (drive.Clock() ? 0 : drive.Advance(status))); } #ifdef NST_MSVC_OPTIMIZE @@ -1216,6 +1230,12 @@ namespace Nes Fds::Adapter::Adapter(Cpu& c,const Disks::Sides& s) : Timer::M2(c,s) {} + void Fds::Adapter::DisableIRQ() + { + unit.status &= ~uint(Unit::STATUS_PENDING_IRQ); + unit.timer.ctrl &= ~uint(Unit::Timer::CTRL_ENABLED); + } + void Fds::Adapter::Reset(Cpu& cpu,byte* const io,bool protect) { Timer::M2::Reset( true, true ); @@ -1379,12 +1399,17 @@ namespace Nes { Update(); + if (!(ctrl & Io::CTRL0_DISK_ENABLED)) + return; + unit.timer.ctrl = data; unit.timer.count = unit.timer.latch; unit.status &= Unit::STATUS_TRANSFERED; - if (!unit.status) - ClearIRQ(); + if (data & Unit::Timer::CTRL_ENABLED) + return; + + ClearIRQ(); } NES_POKE_D(Fds::Adapter,4024) diff --git a/source/core/NstFds.hpp b/source/core/NstFds.hpp index eb7b0b6..07d6506 100644 --- a/source/core/NstFds.hpp +++ b/source/core/NstFds.hpp @@ -340,7 +340,6 @@ namespace Nes Timer(); void Reset(); - void Advance(uint&); NST_SINGLE_CALL bool Clock(); @@ -435,6 +434,7 @@ namespace Nes Adapter(Cpu&,const Disks::Sides&); + void DisableIRQ(); void Reset(Cpu&,byte*,bool=false); void LoadState(State::Loader&,dword,Ppu&); void SaveState(State::Saver&) const; @@ -447,6 +447,8 @@ namespace Nes NST_SINGLE_CALL uint Activity() const; using Timer::M2::VSync; + + byte ctrl; }; struct Io diff --git a/source/core/NstPpu.cpp b/source/core/NstPpu.cpp index 5b6707b..d4d3251 100644 --- a/source/core/NstPpu.cpp +++ b/source/core/NstPpu.cpp @@ -108,7 +108,6 @@ namespace Nes yuvMap (NULL) { cycles.one = PPU_RP2C02_CC; - overclocked = false; PowerOff(); } @@ -169,7 +168,7 @@ namespace Nes { static const byte powerUpPalette[] = { - 0x3F,0x01,0x00,0x01,0x00,0x02,0x02,0x0D, + 0x09,0x01,0x00,0x01,0x00,0x02,0x02,0x0D, 0x08,0x10,0x08,0x24,0x00,0x00,0x04,0x2C, 0x09,0x01,0x34,0x03,0x00,0x04,0x00,0x14, 0x08,0x3A,0x00,0x02,0x00,0x20,0x2C,0x08 @@ -240,8 +239,7 @@ namespace Nes cycles.count = Cpu::CYCLE_MAX; scanline = SCANLINE_VBLANK; - scanline_sleep = -1; - ssleep = -1; + scanline_sleep = 0; io.address = 0; io.pattern = 0; @@ -493,8 +491,6 @@ namespace Nes Cycle frame; - scanline_sleep = -1; - switch (model) { case PPU_RP2C02: @@ -503,8 +499,6 @@ namespace Nes default: - ssleep = PPU_RP2C02_VSLEEP - 2; - if (cycles.hClock == HCLOCK_DUMMY) { cycles.vClock = PPU_RP2C02_HVINT / PPU_RP2C02_CC - HCLOCK_DUMMY; @@ -521,8 +515,6 @@ namespace Nes case PPU_RP2C07: - ssleep = PPU_RP2C07_VSLEEP - 2; - if (cycles.hClock == HCLOCK_DUMMY) { cycles.vClock = PPU_RP2C07_HVINT / PPU_RP2C07_CC - HCLOCK_DUMMY; @@ -539,8 +531,6 @@ namespace Nes case PPU_DENDY: - ssleep = PPU_DENDY_VSLEEP - 2; - if (cycles.hClock == HCLOCK_DUMMY) { cycles.vClock = PPU_DENDY_HVINT / PPU_DENDY_CC - HCLOCK_DUMMY; @@ -556,44 +546,6 @@ namespace Nes break; } - if (overclocked) - { - Apu& audioSafeOverclock = cpu.GetApu(); - if (audioSafeOverclock.GetOverclockSafety()) - { - switch (model) - { - case PPU_RP2C02: - default: - - cpu.SetOverclocking(true,PPU_RP2C02_HSYNC * PPU_RP2C02_VACTIVE); - break; - - case PPU_RP2C07: - - cpu.SetOverclocking(true,PPU_RP2C07_HSYNC * PPU_RP2C07_VACTIVE); - break; - - case PPU_DENDY: - - cpu.SetOverclocking(true,PPU_DENDY_HSYNC * PPU_DENDY_VACTIVE); - break; - } - } - else - { - cpu.SetOverclocking(false,0); - } - - audioSafeOverclock.SetOverclockSafety(true);//overclocking is only safe if direct pcm audio has not been written for one frame - } - else - { - cpu.SetOverclocking(false,0); - Apu& audioSafeOverclock = cpu.GetApu(); - audioSafeOverclock.SetOverclockSafety(false); - } - cpu.SetFrameCycles( frame ); } @@ -698,6 +650,12 @@ namespace Nes io.line.Toggle( io.address, GetCycles() ); } + NST_FORCE_INLINE void Ppu::UpdateScrollAddressLine() + { + if (io.line) + io.line.Toggle( scroll.address & 0x3FFF, cpu.GetCycles() ); + } + NST_FORCE_INLINE void Ppu::UpdateVramAddress() { if ((scanline != SCANLINE_VBLANK ) && (regs.ctrl[1] & Regs::CTRL1_BG_SP_ENABLED)) @@ -824,7 +782,7 @@ namespace Nes oam.mask = oam.show[pos]; if ((regs.ctrl[1] & Regs::CTRL1_BG_SP_ENABLED) && !(data & Regs::CTRL1_BG_SP_ENABLED)) - UpdateAddressLine(scroll.address & 0x3fff); + UpdateScrollAddressLine(); } io.latch = data; @@ -968,10 +926,7 @@ namespace Nes { scroll.latch = (scroll.latch & 0x7F00) | data; scroll.address = scroll.latch; - if (!(regs.ctrl[1] & Regs::CTRL1_BG_SP_ENABLED) || - (scanline == SCANLINE_VBLANK)) { - UpdateAddressLine(scroll.address & 0x3fff); - } + UpdateScrollAddressLine(); } } } @@ -983,13 +938,11 @@ namespace Nes uint address = scroll.address; UpdateVramAddress(); - if (!(regs.ctrl[1] & Regs::CTRL1_BG_SP_ENABLED) || - (scanline == SCANLINE_VBLANK)) { + + if (!(regs.ctrl[1] & Regs::CTRL1_BG_SP_ENABLED) || (scanline == SCANLINE_VBLANK)) UpdateAddressLine(scroll.address & 0x3fff); - } - else { + else return; - } io.latch = data; @@ -1027,10 +980,9 @@ namespace Nes address = scroll.address & 0x3FFF; UpdateVramAddress(); - if (!(regs.ctrl[1] & Regs::CTRL1_BG_SP_ENABLED) || - (scanline == SCANLINE_VBLANK)) { + + if (!(regs.ctrl[1] & Regs::CTRL1_BG_SP_ENABLED) || (scanline == SCANLINE_VBLANK)) UpdateAddressLine(scroll.address & 0x3fff); - } io.latch = (address & 0x3F00) != 0x3F00 ? io.buffer : palette.ram[address & 0x1F] & Coloring(); io.buffer = (address >= 0x2000 ? nmt.FetchName( address ) : chr.FetchPattern( address )); @@ -1458,7 +1410,7 @@ namespace Nes { NST_VERIFY( cycles.count != cycles.hClock ); - if (scanline_sleep >= 0) + if (scanline_sleep) // Extra lines between VBLANK and NMI in Dendy mode { switch (cycles.hClock) { @@ -1807,15 +1759,15 @@ namespace Nes case 338: - if (scanline_sleep++ != ssleep) + if (++scanline_sleep < PPU_DENDY_VSLEEP) { cycles.hClock = 0; - cycles.vClock += 341; + cycles.vClock += HCLOCK_DUMMY; - if (cycles.count <= 341) + if (cycles.count <= HCLOCK_DUMMY) break; - cycles.count -= 341; + cycles.count -= HCLOCK_DUMMY; goto HActiveSleep; } @@ -1828,37 +1780,13 @@ namespace Nes } case HCLOCK_VBLANK_0: - VBlank0: - - regs.status |= Regs::STATUS_VBLANKING; - cycles.hClock = HCLOCK_VBLANK_1; - - if (cycles.count <= HCLOCK_VBLANK_1) - break; + goto VBlank0; case HCLOCK_VBLANK_1: - VBlank1: - - regs.status = (regs.status & 0xFF) | (regs.status >> 1 & Regs::STATUS_VBLANK); - oam.visible = oam.output; - cycles.hClock = HCLOCK_VBLANK_2; - - if (cycles.count <= HCLOCK_VBLANK_2) - break; + goto VBlank1; case HCLOCK_VBLANK_2: - VBlank2: - - scanline_sleep = -1; - - cycles.hClock = HCLOCK_DUMMY; - cycles.count = Cpu::CYCLE_MAX; - cycles.reset = 0; - - if (regs.ctrl[0] & regs.status & Regs::CTRL0_NMI) - cpu.DoNMI( cpu.GetFrameCycles() ); - - return; + goto VBlank2; } } else if (regs.ctrl[1] & Regs::CTRL1_BG_SP_ENABLED) @@ -2519,7 +2447,7 @@ namespace Nes if (scanline++ != 239) { - const uint line = (scanline != 0 || model != PPU_RP2C02 || !regs.frame ? 341 : 340); + const uint line = (scanline != 0 || model != PPU_RP2C02 || !regs.frame ? HCLOCK_DUMMY : (HCLOCK_DUMMY - 1)); cycles.hClock = 0; cycles.vClock += line; @@ -2533,16 +2461,17 @@ namespace Nes } else { - if (ssleep >= 0) + if (model == PPU_DENDY) { - scanline_sleep = 0; - cycles.hClock = 0; - cycles.vClock += 341; + scanline_sleep = 1; - if (cycles.count <= 341) + cycles.hClock = 0; + cycles.vClock += HCLOCK_DUMMY; + + if (cycles.count <= HCLOCK_DUMMY) break; - cycles.count -= 341; + cycles.count -= HCLOCK_DUMMY; goto HActiveSleep; } @@ -2556,13 +2485,37 @@ namespace Nes } case HCLOCK_VBLANK_0: - goto VBlank0; + VBlank0: + + regs.status |= Regs::STATUS_VBLANKING; + cycles.hClock = HCLOCK_VBLANK_1; + + if (cycles.count <= HCLOCK_VBLANK_1) + break; case HCLOCK_VBLANK_1: - goto VBlank1; + VBlank1: + + regs.status = (regs.status & 0xFF) | (regs.status >> 1 & Regs::STATUS_VBLANK); + oam.visible = oam.output; + cycles.hClock = HCLOCK_VBLANK_2; + + if (cycles.count <= HCLOCK_VBLANK_2) + break; case HCLOCK_VBLANK_2: - goto VBlank2; + VBlank2: + + scanline_sleep = 0; + + cycles.hClock = HCLOCK_DUMMY; + cycles.count = Cpu::CYCLE_MAX; + cycles.reset = 0; + + if (regs.ctrl[0] & regs.status & Regs::CTRL0_NMI) + cpu.DoNMI( cpu.GetFrameCycles() ); + + return; case HCLOCK_BOOT: goto Boot; @@ -3227,29 +3180,29 @@ namespace Nes if (scanline == 0 && model == PPU_RP2C02) output.burstPhase = (output.burstPhase + 1) % 3; - cycles.vClock += 341; + cycles.vClock += HCLOCK_DUMMY; cycles.hClock = 0; - if (cycles.count <= 341) + if (cycles.count <= HCLOCK_DUMMY) break; - cycles.count -= 341; + cycles.count -= HCLOCK_DUMMY; goto HActiveOff; } - else - { - if (ssleep >= 0) + else + { + if (model == PPU_DENDY) { - scanline_sleep = 0; + scanline_sleep = 1; - cycles.vClock += 341; + cycles.vClock += HCLOCK_DUMMY; cycles.hClock = 0; - if (cycles.count <= 341) + if (cycles.count <= HCLOCK_DUMMY) break; - cycles.count -= 341; + cycles.count -= HCLOCK_DUMMY; goto HActiveSleep; } diff --git a/source/core/NstPpu.hpp b/source/core/NstPpu.hpp index ee4c25e..a4c1078 100644 --- a/source/core/NstPpu.hpp +++ b/source/core/NstPpu.hpp @@ -139,7 +139,6 @@ namespace Nes enum { - HCLOCK_POSTRENDER = 340, HCLOCK_DUMMY = 341, HCLOCK_VBLANK_0 = 681, HCLOCK_VBLANK_1 = 682, @@ -176,6 +175,7 @@ namespace Nes NST_FORCE_INLINE uint Emphasis() const; NST_FORCE_INLINE void UpdateAddressLine(uint); + NST_FORCE_INLINE void UpdateScrollAddressLine(); NST_FORCE_INLINE void UpdateVramAddress(); NST_FORCE_INLINE void OpenName(); @@ -345,9 +345,6 @@ namespace Nes typedef void (Ppu::*Phase)(); - byte ram[0x100]; - byte buffer[MAX_LINE_SPRITES * 4]; - const byte* limit; Output* visible; Phase phase; @@ -361,6 +358,9 @@ namespace Nes bool spriteZeroInLine; bool spriteLimit; + byte ram[0x100]; + byte buffer[MAX_LINE_SPRITES*4]; + Output output[MAX_LINE_SPRITES]; }; @@ -415,9 +415,9 @@ namespace Nes Nmt nmt; int scanline; int scanline_sleep; - int ssleep; - bool overclocked; - + public: + Output output; + private: PpuModel model; Hook hActiveHook; Hook hBlankHook; @@ -432,7 +432,6 @@ namespace Nes static const byte yuvMaps[4][0x40]; public: - Output output; void Update() { @@ -543,16 +542,6 @@ namespace Nes { return oam.spriteLimit; } - - bool GetOverclockState() const - { - return overclocked; - } - - void SetOverclockState(bool overclock2x) - { - overclocked = overclock2x; - } }; } } diff --git a/source/core/NstVideoRenderer.cpp b/source/core/NstVideoRenderer.cpp index 9070b5a..83077dc 100644 --- a/source/core/NstVideoRenderer.cpp +++ b/source/core/NstVideoRenderer.cpp @@ -22,12 +22,10 @@ // //////////////////////////////////////////////////////////////////////////////////////// -#ifdef __LIBRETRO__ #define NST_NO_SCALEX 1 #define NST_NO_HQ2X 1 #define NST_NO_2XSAI 1 #define NST_NO_XBR 1 -#endif #include #include diff --git a/source/core/api/NstApiVideo.cpp b/source/core/api/NstApiVideo.cpp index 92c8cb9..3668413 100644 --- a/source/core/api/NstApiVideo.cpp +++ b/source/core/api/NstApiVideo.cpp @@ -58,20 +58,6 @@ namespace Nes return RESULT_NOP; } - Result Video::EnableOverclocking(bool state) throw() - { - if (emulator.tracker.IsLocked( true )) - return RESULT_ERR_NOT_READY; - - if (emulator.ppu.GetOverclockState() != state) - { - emulator.ppu.SetOverclockState( state ); - return RESULT_OK; - } - - return RESULT_NOP; - } - bool Video::AreUnlimSpritesEnabled() const throw() { return !emulator.ppu.HasSpriteLimit(); diff --git a/source/core/api/NstApiVideo.hpp b/source/core/api/NstApiVideo.hpp index d623947..4b137ae 100644 --- a/source/core/api/NstApiVideo.hpp +++ b/source/core/api/NstApiVideo.hpp @@ -223,11 +223,6 @@ namespace Nes * @return result code */ Result EnableUnlimSprites(bool state) throw(); - - /** - * Adds extra scanlines to fix lag - */ - Result EnableOverclocking(bool state) throw(); /** * Checks if the PPU sprite software extension is enabled. diff --git a/source/core/board/NstBoard.cpp b/source/core/board/NstBoard.cpp index 86d30c4..06f949f 100644 --- a/source/core/board/NstBoard.cpp +++ b/source/core/board/NstBoard.cpp @@ -97,13 +97,13 @@ #include "NstBoardWaixing.hpp" #include "NstBoardWhirlwind.hpp" #include "NstBoardBenshengBs5.hpp" -#include "NstBoardUnlN625092.hpp" #include "NstBoardUnlA9746.hpp" #include "NstBoardUnlCc21.hpp" #include "NstBoardUnlEdu2000.hpp" #include "NstBoardUnlKingOfFighters96.hpp" #include "NstBoardUnlKingOfFighters97.hpp" #include "NstBoardUnlMortalKombat2.hpp" +#include "NstBoardUnlN625092.hpp" #include "NstBoardUnlSuperFighter3.hpp" #include "NstBoardUnlTf1201.hpp" #include "NstBoardUnlWorldHero.hpp" @@ -397,7 +397,16 @@ namespace Nes { wrk.Source().SetSecurity( true, board.GetWram() > 0 ); - for (uint i=board.GetSavableWram(), n=board.GetWram(); i < n; ++i) + uint i = board.GetSavableWram(); + uint n = board.GetWram(); + + if (board.GetMapper() == 1 && board.GetWram() == SIZE_16K) + { + i = 0; + n = SIZE_8K; + } + + for (; i < n; ++i) *wrk.Source().Mem(i) = (board.IsAutoWram() && i < SIZE_8K) ? (0x6000 + i) >> 8 : 0x00; vram.Fill( 0x00 ); @@ -815,7 +824,7 @@ namespace Nes { "CAMERICA-BF9097", Type::CAMERICA_BF9097 }, { "CAMERICA-GAMEGENIE", Type::STD_NROM }, { "COLORDREAMS-74*377", Type::DISCRETE_74_377 }, - { "DREAMTECH01", Type::DREAMTECH_01 }, + { "DREAMTECH01", Type::DREAMTECH01 }, { "HVC-AMROM", Type::STD_AMROM }, { "HVC-AN1ROM", Type::STD_AN1ROM }, { "HVC-ANROM", Type::STD_ANROM }, @@ -1096,8 +1105,11 @@ namespace Nes { "UNL-EDU2000", Type::UNL_EDU2000 }, { "UNL-H2288", Type::KAY_H2288 }, { "UNL-KOF97", Type::UNL_KINGOFFIGHTERS97 }, + { "UNL-KS7013B", Type::KAISER_KS7013B }, + { "UNL-KS7016", Type::KAISER_KS7016 }, { "UNL-KS7031", Type::KAISER_KS7031 }, { "UNL-KS7032", Type::KAISER_KS7032 }, + { "UNL-KS7037", Type::KAISER_KS7037 }, { "UNL-N625092", Type::UNL_N625092 }, { "UNL-SA-0036", Type::SACHEN_SA0036 }, { "UNL-SA-0037", Type::SACHEN_SA0037 }, @@ -1110,7 +1122,7 @@ namespace Nes { "UNL-SACHEN-8259B", Type::SACHEN_8259B }, { "UNL-SACHEN-8259C", Type::SACHEN_8259C }, { "UNL-SACHEN-8259D", Type::SACHEN_8259D }, - { "UNL-SHERO", Type::SACHEN_STREETHEROES }, + { "UNL-SHERO", Type::UNL_SHERO }, { "UNL-SL1632", Type::REXSOFT_SL1632 }, { "UNL-SMB2J", Type::BTL_SMB2_C }, { "UNL-T-230", Type::BTL_T230 }, @@ -1218,7 +1230,7 @@ namespace Nes return true; } - bool Board::Context::DetectBoard(const byte mapper,const byte submapper,const dword chrRam,const dword wram,bool wramAuto) + bool Board::Context::DetectBoard(const word mapper,const byte submapper,const dword chrRam,const dword wram,bool wramAuto) { Type::Id id; @@ -1241,7 +1253,12 @@ namespace Nes { case 0: - if ((prg < SIZE_32K && prg != SIZE_16K) || !chr || wram >= SIZE_8K || (nmt != Type::NMT_HORIZONTAL && nmt != Type::NMT_VERTICAL)) + if (prg == SIZE_8K && chr == SIZE_8K) + { + name = "NAMCOT-3301"; + id = Type::STD_NROM; + } + else if ((prg < SIZE_32K && prg != SIZE_16K) || !chr || wram >= SIZE_8K || (nmt != Type::NMT_HORIZONTAL && nmt != Type::NMT_VERTICAL)) { name = "NROM (non-standard)"; id = Type::UNL_NROM; @@ -1921,8 +1938,16 @@ namespace Nes case 27: - name = "UNL WORLDHERO"; - id = Type::UNL_WORLDHERO; + if (prg >= SIZE_128K) + { + name = "UNL WORLDHERO"; + id = Type::UNL_WORLDHERO; + } + else + { + name = "UNL-CC-21"; + id = Type::UNL_CC21; + } break; case 28: @@ -2833,8 +2858,21 @@ namespace Nes case 176: - name = "XIAO ZHUAN YUAN"; - id = Type::UNL_XZY; + if (prg >= SIZE_2048K) + { + name = "BMC-SUPER24IN1SC03"; + id = Type::BMC_SUPER_24IN1; + } + else if (prg > SIZE_128K) + { + name = "BMC-FK23C"; + id = Type::BMC_FKC23C; + } + else + { + name = "XIAO ZHUAN YUAN"; + id = Type::UNL_XZY; + } break; case 177: @@ -3170,11 +3208,16 @@ namespace Nes name = "BMC SUPER 42-IN-1"; id = Type::BMC_SUPER_42IN1; } - else + else if (prg == SIZE_2048K) { name = "BMC 76-IN-1"; id = Type::BMC_76IN1; } + else + { + name = "BMC-GHOSTBUSTERS63IN1"; + id = Type::BMC_CTC65; + } break; case 227: @@ -3334,6 +3377,127 @@ namespace Nes id = Type::BMC_110IN1; break; + case 262: + + name = "UNL-SHERO"; + id = Type::UNL_SHERO; + break; + + case 263: + + name = "UNL-KOF97"; + id = Type::UNL_KINGOFFIGHTERS97; + break; + + case 265: + + name = "BMC-T-262"; + id = Type::BMC_T262; + break; + + case 283: + if (prg > SIZE_256K) + { + name = "BMC-GS-2013"; + id = Type::RCM_GS2013; + } + else + { + name = "BMC-GS-2004"; + id = Type::RCM_GS2004; + } + break; + + case 285: + + name = "BMC-A65AS"; + id = Type::BMC_A65AS; + break; + + case 286: + + name = "BMC-BS-5"; + id = Type::BENSHENG_BS5; + break; + + case 298: + + name = "UNL-TF1201"; + id = Type::UNL_TF1201; + break; + + case 300: + + name = "BMC-190IN1"; + id = Type::BMC_GOLDEN_190IN1; + break; + + case 301: + + name = "BMC-8157"; + id = Type::BMC_8157; + break; + + case 305: + + name = "UNL-KS7031"; + id = Type::KAISER_KS7031; + break; + + case 306: + + name = "UNL-KS7016"; + id = Type::KAISER_KS7016; + break; + + case 307: + + name = "UNL-KS7037"; + id = Type::KAISER_KS7037; + break; + + case 312: + + name = "UNL-KS7013B"; + id = Type::KAISER_KS7013B; + break; + + case 314: + + name = "BMC-64IN1NOREPEAT"; + id = Type::BMC_Y2K_64IN1; + break; + + case 329: + + name = "UNL-EDU2000"; + id = Type::UNL_EDU2000; + break; + + case 332: + + name = "BMC-WS"; + id = Type::BMC_SUPER_40IN1; + break; + + case 521: + + name = "DREAMTECH01"; + id = Type::DREAMTECH01; + break; + + case 529: + + name = "UNL-T-230"; + id = Type::BTL_T230; + break; + + case 530: + + name = "UNL-AX5705"; + id = Type::BTL_AX5705; + break; + default: return false; @@ -3537,7 +3701,7 @@ namespace Nes case Type::CNE_DECATHLON : return new Cne::Decathlon(c); case Type::CNE_PSB : return new Cne::Psb(c); case Type::CONY_STD : return new Cony::Standard(c); - case Type::DREAMTECH_01 : return new DreamTech::D01(c); + case Type::DREAMTECH01 : return new DreamTech::D01(c); case Type::FUTUREMEDIA_STD : return new FutureMedia::Standard(c); case Type::FUJIYA_STD : return new Fujiya::Standard(c); case Type::FUKUTAKE_SBX : return new Fukutake::Sbx(c); @@ -3602,9 +3766,12 @@ namespace Nes case Type::JYCOMPANY_TYPE_B : case Type::JYCOMPANY_TYPE_C : return new JyCompany::Standard(c); case Type::KAISER_KS202 : return new Kaiser::Ks202(c); + case Type::KAISER_KS7013B : return new Kaiser::Ks7013b(c); + case Type::KAISER_KS7016 : return new Kaiser::Ks7016(c); case Type::KAISER_KS7022 : return new Kaiser::Ks7022(c); case Type::KAISER_KS7031 : return new Kaiser::Ks7031(c); case Type::KAISER_KS7032 : return new Kaiser::Ks7032(c); + case Type::KAISER_KS7037 : return new Kaiser::Ks7037(c); case Type::KAISER_KS7058 : return new Kaiser::Ks7058(c); case Type::KASING_STD : return new Kasing::Standard(c); case Type::KAY_H2288 : return new Kay::H2288(c); @@ -3631,8 +3798,8 @@ namespace Nes case Type::NAMCOT_163_1 : case Type::NAMCOT_163_S_0 : case Type::NAMCOT_163_S_1 : return new Namcot::N163(c); - case Type::NAMCOT_340 : case Type::NAMCOT_175 : return new Namcot::N175(c); + case Type::NAMCOT_340 : return new Namcot::N340(c); case Type::NANJING_STD : return new Nanjing::Standard(c); case Type::UNL_UXROM_M5 : case Type::NIHON_UNROM_M5 : return new Nihon::UnRomM5(c); @@ -3662,7 +3829,6 @@ namespace Nes case Type::SACHEN_SA72008 : return new Sachen::Sa72008(c); case Type::SACHEN_74_374A : return new Sachen::S74x374a(c); case Type::SACHEN_74_374B : return new Sachen::S74x374b(c); - case Type::SACHEN_STREETHEROES : return new Sachen::StreetHeroes(c); case Type::SOMERITEAM_SL12 : return new SomeriTeam::Sl12(c); case Type::SUBOR_TYPE0 : return new Subor::Type0(c); case Type::SUBOR_TYPE1 : return new Subor::Type1(c); @@ -3707,6 +3873,7 @@ namespace Nes case Type::UNL_MORTALKOMBAT2 : return new Unlicensed::MortalKombat2(c); case Type::UNL_N625092 : return new Unlicensed::N625092(c); case Type::UNL_SUPERFIGHTER3 : return new Unlicensed::SuperFighter3(c); + case Type::UNL_SHERO : return new Sachen::StreetHeroes(c); case Type::UNL_TF1201 : return new Unlicensed::Tf1201(c); case Type::UNL_WORLDHERO : return new Unlicensed::WorldHero(c); case Type::UNL_XZY : return new Unlicensed::Xzy(c); diff --git a/source/core/board/NstBoard.hpp b/source/core/board/NstBoard.hpp index 2e7ffea..bc455ee 100644 --- a/source/core/board/NstBoard.hpp +++ b/source/core/board/NstBoard.hpp @@ -94,7 +94,7 @@ namespace Nes CRM_32 }; - template + template struct MakeId { NST_COMPILE_ASSERT @@ -258,7 +258,7 @@ namespace Nes BANDAI_AEROBICSSTUDIO = MakeId< 3, 32, 32, 0, 0, CRM_0, NMT_X, 2 >::ID, BANDAI_OEKAKIDS = MakeId< 96, 128, 0, 0, 0, CRM_32, NMT_1, 0 >::ID, // Bensheng - BENSHENG_BS5 = MakeId< NMPR, 128, 64, 0, 0, CRM_0, NMT_V, 2 >::ID, + BENSHENG_BS5 = MakeId< 286, 128, 64, 0, 0, CRM_0, NMT_V, 2 >::ID, // Bootleg multicarts BMC_110IN1 = MakeId< 255, 2048, 1024, 0, 0, CRM_0, NMT_V, 0 >::ID, BMC_150IN1 = MakeId< 202, 128, 64, 0, 0, CRM_0, NMT_V, 0 >::ID, @@ -273,16 +273,16 @@ namespace Nes BMC_64IN1 = MakeId< 204, 128, 64, 0, 0, CRM_0, NMT_V, 0 >::ID, BMC_72IN1 = MakeId< 225, 1024, 512, 0, 0, CRM_0, NMT_V, 0 >::ID, BMC_76IN1 = MakeId< 226, 2048, 0, 0, 0, CRM_8, NMT_H, 0 >::ID, - BMC_8157 = MakeId< NMPR, 512, 0, 0, 0, CRM_8, NMT_V, 0 >::ID, + BMC_8157 = MakeId< 301, 512, 0, 0, 0, CRM_8, NMT_V, 0 >::ID, BMC_9999999IN1 = MakeId< 213, 128, 64, 0, 0, CRM_0, NMT_X, 0 >::ID, - BMC_A65AS = MakeId< NMPR, 512, 0, 0, 0, CRM_8, NMT_V, 1 >::ID, + BMC_A65AS = MakeId< 285, 512, 0, 0, 0, CRM_8, NMT_V, 1 >::ID, BMC_BALLGAMES_11IN1 = MakeId< 51, 512, 0, 0, 0, CRM_8, NMT_V, 0 >::ID, - BMC_CTC65 = MakeId< NMPR, 2048, 0, 0, 0, CRM_8, NMT_H, 0 >::ID, + BMC_CTC65 = MakeId< 226, 2048, 0, 0, 0, CRM_8, NMT_H, 1 >::ID, BMC_DRAGONBOLLPARTY = MakeId< 83, 1024, 1024, 8, 0, CRM_0, NMT_V, 0 >::ID, BMC_FAMILY_4646B = MakeId< 134, 512, 512, 0, 0, CRM_0, NMT_X, 0 >::ID, - BMC_FKC23C = MakeId< NMPR, 1024, 1024, 0, 0, CRM_0, NMT_X, 0 >::ID, + BMC_FKC23C = MakeId< 176, 1024, 1024, 0, 0, CRM_0, NMT_X, 0 >::ID, BMC_GAME_800IN1 = MakeId< 236, 512, 64, 0, 0, CRM_8, NMT_V, 0 >::ID, - BMC_GOLDEN_190IN1 = MakeId< NMPR, 128, 64, 0, 0, CRM_0, NMT_V, 0 >::ID, + BMC_GOLDEN_190IN1 = MakeId< 300, 128, 64, 0, 0, CRM_0, NMT_V, 0 >::ID, BMC_GOLDENGAME_150IN1 = MakeId< 235, 2048, 0, 0, 0, CRM_8, NMT_V, 0 >::ID, BMC_GOLDENGAME_260IN1 = MakeId< 235, 4096, 0, 0, 0, CRM_8, NMT_V, 0 >::ID, BMC_GKA = MakeId< 57, 128, 128, 0, 0, CRM_0, NMT_V, 0 >::ID, @@ -294,9 +294,9 @@ namespace Nes BMC_CH001 = MakeId< 63, 4096, 0, 0, 0, CRM_8, NMT_V, 0 >::ID, BMC_POWERJOY_84IN1 = MakeId< 126, 2048, 1024, 0, 0, CRM_0, NMT_X, 0 >::ID, BMC_RESETBASED_4IN1 = MakeId< 60, 64, 32, 0, 0, CRM_0, NMT_X, 0 >::ID, - BMC_SUPER_24IN1 = MakeId< NMPR, 4096, 2048, 8, 0, CRM_8, NMT_X, 0 >::ID, + BMC_SUPER_24IN1 = MakeId< 176, 4096, 2048, 0, 0, CRM_8, NMT_X, 0 >::ID, BMC_SUPER_22GAMES = MakeId< 233, 1024, 0, 0, 0, CRM_8, NMT_Z, 0 >::ID, - BMC_SUPER_40IN1 = MakeId< NMPR, 128, 64, 0, 0, CRM_0, NMT_V, 1 >::ID, + BMC_SUPER_40IN1 = MakeId< 332, 128, 64, 0, 0, CRM_0, NMT_V, 1 >::ID, BMC_SUPER_42IN1 = MakeId< 226, 1024, 0, 0, 0, CRM_8, NMT_H, 0 >::ID, BMC_SUPER_700IN1 = MakeId< 62, 2048, 1024, 0, 0, CRM_0, NMT_V, 0 >::ID, BMC_SUPERBIG_7IN1 = MakeId< 44, 1024, 1024, 0, 0, CRM_0, NMT_X, 0 >::ID, @@ -304,15 +304,15 @@ namespace Nes BMC_SUPERHIK_4IN1 = MakeId< 49, 512, 512, 0, 0, CRM_0, NMT_X, 0 >::ID, BMC_SUPERHIK_300IN1 = MakeId< 212, 128, 64, 0, 0, CRM_0, NMT_V, 0 >::ID, BMC_SUPERVISION_16IN1 = MakeId< 53, 4096, 0, 0, 0, CRM_8, NMT_V, 0 >::ID, - BMC_T262 = MakeId< NMPR, 1024, 0, 0, 0, CRM_8, NMT_V, 0 >::ID, + BMC_T262 = MakeId< 265, 1024, 0, 0, 0, CRM_8, NMT_V, 0 >::ID, BMC_VRC4 = MakeId< 23, 512, 0, 8, 0, CRM_8, NMT_V, 0 >::ID, BMC_VT5201 = MakeId< 60, 128, 64, 0, 0, CRM_0, NMT_V, 0 >::ID, - BMC_Y2K_64IN1 = MakeId< NMPR, 1024, 512, 0, 0, CRM_0, NMT_V, 0 >::ID, + BMC_Y2K_64IN1 = MakeId< 314, 1024, 512, 0, 0, CRM_0, NMT_V, 0 >::ID, // Bootlegs BTL_2708 = MakeId< 103, 128, 0, 0, 16, CRM_8, NMT_V, 0 >::ID, BTL_6035052 = MakeId< 238, 512, 256, 0, 0, CRM_0, NMT_X, 0 >::ID, BTL_AISENSHINICOL = MakeId< 42, 128, 0, 0, 0, CRM_8, NMT_X, 0 >::ID, - BTL_AX5705 = MakeId< NMPR, 128, 256, 0, 0, CRM_0, NMT_X, 0 >::ID, + BTL_AX5705 = MakeId< 530, 128, 256, 0, 0, CRM_0, NMT_X, 0 >::ID, BTL_DRAGONNINJA = MakeId< 222, 128, 256, 0, 0, CRM_0, NMT_X, 0 >::ID, BTL_GENIUSMERIOBROS = MakeId< 55, 64, 8, 2, 0, CRM_0, NMT_X, 0 >::ID, BTL_MARIOBABY = MakeId< 42, 128, 128, 0, 0, CRM_0, NMT_X, 0 >::ID, @@ -323,7 +323,7 @@ namespace Nes BTL_SMB2_C = MakeId< 43, 128, 8, 0, 0, CRM_0, NMT_X, 0 >::ID, BTL_SMB3 = MakeId< 106, 256, 128, 8, 0, CRM_0, NMT_H, 0 >::ID, BTL_SUPERBROS11 = MakeId< 196, 512, 128, 0, 0, CRM_0, NMT_V, 0 >::ID, - BTL_T230 = MakeId< NMPR, 256, 0, 0, 0, CRM_8, NMT_V, 0 >::ID, + BTL_T230 = MakeId< 529, 256, 0, 0, 0, CRM_8, NMT_V, 0 >::ID, BTL_TOBIDASEDAISAKUSEN = MakeId< 120, 128, 8, 0, 0, CRM_0, NMT_X, 0 >::ID, // Camerica CAMERICA_BF9093 = MakeId< 71, 256, 0, 0, 0, CRM_8, NMT_X, 0 >::ID, @@ -342,7 +342,7 @@ namespace Nes // Cony CONY_STD = MakeId< 83, 256, 512, 0, 0, CRM_0, NMT_V, 0 >::ID, // Dreamtech - DREAMTECH_01 = MakeId< NMPR, 256, 0, 0, 0, CRM_8, NMT_X, 0 >::ID, + DREAMTECH01 = MakeId< 521, 256, 0, 0, 0, CRM_8, NMT_X, 0 >::ID, // Fujiya FUJIYA_STD = MakeId< 170, 32, 8, 0, 0, CRM_0, NMT_X, 0 >::ID, // Fukutake @@ -418,9 +418,12 @@ namespace Nes JYCOMPANY_TYPE_C = MakeId< 211, 2048, 2048, 0, 0, CRM_0, NMT_X, 0 >::ID, // Kaiser KAISER_KS202 = MakeId< 56, 256, 128, 8, 0, CRM_0, NMT_V, 0 >::ID, + KAISER_KS7013B = MakeId< 312, 128, 0, 0, 0, CRM_8, NMT_X, 0 >::ID, + KAISER_KS7016 = MakeId< 306, 128, 0, 0, 0, CRM_8, NMT_V, 0 >::ID, KAISER_KS7022 = MakeId< 175, 256, 128, 0, 0, CRM_0, NMT_V, 0 >::ID, - KAISER_KS7031 = MakeId< NMPR, 128, 0, 0, 16, CRM_8, NMT_V, 0 >::ID, + KAISER_KS7031 = MakeId< 305, 128, 0, 0, 0, CRM_8, NMT_V, 0 >::ID, KAISER_KS7032 = MakeId< 142, 128, 0, 0, 0, CRM_8, NMT_X, 0 >::ID, + KAISER_KS7037 = MakeId< 307, 128, 0, 0, 8, CRM_8, NMT_X, 0 >::ID, KAISER_KS7058 = MakeId< 171, 32, 32, 0, 0, CRM_0, NMT_X, 0 >::ID, // Kasing KASING_STD = MakeId< 115, 512, 512, 0, 0, CRM_0, NMT_V, 0 >::ID, @@ -454,8 +457,7 @@ namespace Nes NAMCOT_163_S_0 = MakeId< 19, 512, 256, 0, 0, CRM_0, NMT_X, 1 >::ID, NAMCOT_163_S_1 = MakeId< 19, 512, 256, 8, 0, CRM_0, NMT_X, 1 >::ID, NAMCOT_175 = MakeId< 210, 512, 128, 8, 0, CRM_0, NMT_V, 0 >::ID, - // FIXME: Setting NMT_4 is incorrect but makes things work - NAMCOT_340 = MakeId< 210, 256, 256, 0, 0, CRM_0, NMT_4, 0 >::ID, + NAMCOT_340 = MakeId< 210, 256, 256, 0, 0, CRM_0, NMT_X, 0 >::ID, // Nitra NITRA_TDA = MakeId< 250, 512, 256, 0, 0, CRM_0, NMT_V, 0 >::ID, // NTDEC @@ -468,10 +470,10 @@ namespace Nes // Nihon Bussan NIHON_UNROM_M5 = MakeId< 180, 128, 0, 0, 0, CRM_8, NMT_X, 0 >::ID, // Open Corp - OPENCORP_DAOU306 = MakeId< 156, 256, 256, 8, 0, CRM_0, NMT_1, 0 >::ID, + OPENCORP_DAOU306 = MakeId< 156, 256, 512, 8, 0, CRM_0, NMT_1, 0 >::ID, // RCM - RCM_GS2004 = MakeId< NMPR, 512, 0, 0, 0, CRM_8, NMT_X, 0 >::ID, - RCM_GS2013 = MakeId< NMPR, 512, 0, 0, 0, CRM_8, NMT_X, 1 >::ID, + RCM_GS2004 = MakeId< 283, 256, 0, 0, 0, CRM_8, NMT_X, 0 >::ID, + RCM_GS2013 = MakeId< 283, 512, 0, 0, 0, CRM_8, NMT_X, 1 >::ID, RCM_GS2015 = MakeId< 216, 64, 64, 0, 0, CRM_0, NMT_X, 0 >::ID, RCM_TETRISFAMILY = MakeId< 61, 512, 0, 0, 0, CRM_8, NMT_V, 0 >::ID, // Rex Soft @@ -492,7 +494,6 @@ namespace Nes SACHEN_SA72008 = MakeId< 133, 64, 32, 0, 0, CRM_0, NMT_X, 0 >::ID, SACHEN_74_374A = MakeId< 243, 64, 128, 0, 0, CRM_0, NMT_V, 0 >::ID, SACHEN_74_374B = MakeId< 150, 64, 128, 0, 0, CRM_0, NMT_X, 0 >::ID, - SACHEN_STREETHEROES = MakeId< NMPR, 512, 512, 0, 0, CRM_8, NMT_2, 0 >::ID, // Someri Team SOMERITEAM_SL12 = MakeId< 116, 256, 512, 0, 0, CRM_0, NMT_X, 0 >::ID, // Subor @@ -526,7 +527,6 @@ namespace Nes TENGEN_800004 = MakeId< 206, 128, 64, 0, 0, CRM_0, NMT_2, 1 >::ID, TENGEN_800008 = MakeId< 3, 64, 64, 0, 0, CRM_0, NMT_X, 0 >::ID, TENGEN_800030 = MakeId< 206, 128, 64, 0, 0, CRM_0, NMT_X, 1 >::ID, - //TENGEN_800032 = MakeId< 64, 128, 128, 0, 0, CRM_0, NMT_V, 0 >::ID, TENGEN_800032 = MakeId< 64, 128, 256, 0, 0, CRM_0, NMT_V, 0 >::ID, TENGEN_800037 = MakeId< 158, 128, 128, 0, 0, CRM_0, NMT_Z, 0 >::ID, TENGEN_800042 = MakeId< 68, 128, 256, 0, 0, CRM_0, NMT_V, 1 >::ID, @@ -539,14 +539,15 @@ namespace Nes TXC_TW = MakeId< 189, 128, 256, 0, 0, CRM_0, NMT_X, 0 >::ID, // Unlicensed UNL_A9746 = MakeId< 219, 128, 256, 0, 0, CRM_0, NMT_X, 0 >::ID, - UNL_CC21 = MakeId< NMPR, 32, 16, 0, 0, CRM_0, NMT_Z, 0 >::ID, - UNL_EDU2000 = MakeId< NMPR, 1024, 0, 32, 0, CRM_8, NMT_Z, 0 >::ID, + UNL_CC21 = MakeId< 27, 32, 8, 0, 0, CRM_0, NMT_Z, 0 >::ID, + UNL_EDU2000 = MakeId< 329, 1024, 0, 0, 32, CRM_8, NMT_Z, 0 >::ID, UNL_KINGOFFIGHTERS96 = MakeId< 187, 512, 512, 0, 0, CRM_0, NMT_X, 0 >::ID, - UNL_KINGOFFIGHTERS97 = MakeId< NMPR, 512, 256, 0, 0, CRM_0, NMT_X, 1 >::ID, + UNL_KINGOFFIGHTERS97 = MakeId< 263, 256, 256, 0, 0, CRM_0, NMT_X, 0 >::ID, UNL_MORTALKOMBAT2 = MakeId< 91, 256, 512, 0, 0, CRM_0, NMT_X, 0 >::ID, UNL_N625092 = MakeId< 221, 1024, 8, 0, 0, CRM_0, NMT_V, 0 >::ID, UNL_SUPERFIGHTER3 = MakeId< 197, 512, 512, 0, 0, CRM_0, NMT_X, 0 >::ID, - UNL_TF1201 = MakeId< NMPR, 256, 256, 0, 0, CRM_0, NMT_V, 0 >::ID, + UNL_SHERO = MakeId< 262, 512, 512, 0, 0, CRM_8, NMT_4, 0 >::ID, + UNL_TF1201 = MakeId< 298, 128, 128, 0, 0, CRM_0, NMT_V, 0 >::ID, UNL_WORLDHERO = MakeId< 27, 128, 512, 0, 0, CRM_0, NMT_X, 0 >::ID, UNL_AXROM = MakeId< 7, 512, 8, 8, 0, CRM_0, NMT_Z, 0 >::ID, UNL_BXROM = MakeId< 34, 4096, 8, 8, 0, CRM_8, NMT_X, 0 >::ID, @@ -653,7 +654,7 @@ namespace Nes Context(Cpu*,Apu*,Ppu*,Ram&,Ram&,const Ram&,Type::Nmt,bool,bool,Chips&); bool DetectBoard(wcstring,dword); - bool DetectBoard(byte,byte,dword,dword,bool); + bool DetectBoard(word,byte,dword,dword,bool); cstring name; Type type; diff --git a/source/core/board/NstBoardCamerica.cpp b/source/core/board/NstBoardCamerica.cpp index 16ae352..12fc511 100644 --- a/source/core/board/NstBoardCamerica.cpp +++ b/source/core/board/NstBoardCamerica.cpp @@ -40,6 +40,7 @@ namespace Nes void Bf9093::SubReset(bool) { Map( 0xC000U, 0xFFFFU, PRG_SWAP_16K_0 ); + Map( 0x8000U, 0xBFFFU, &Bf9093::Poke_C000 ); } void Bf9096::SubReset(bool) @@ -68,6 +69,11 @@ namespace Nes #pragma optimize("", on) #endif + NES_POKE_D(Bf9093,C000) + { + prg.SwapBank( data ); + } + void Bf9096::SwapBasePrg(uint base) { prg.SwapBanks( base | (prg.GetBank() & 0x3), base | 0x3 ); diff --git a/source/core/board/NstBoardCamerica.hpp b/source/core/board/NstBoardCamerica.hpp index c7d0963..5354809 100644 --- a/source/core/board/NstBoardCamerica.hpp +++ b/source/core/board/NstBoardCamerica.hpp @@ -47,6 +47,10 @@ namespace Nes protected: void SubReset(bool); + + private: + + NES_DECL_POKE( C000 ); }; class Bf9096 : public Board diff --git a/source/core/board/NstBoardKaiser.cpp b/source/core/board/NstBoardKaiser.cpp index 90f150b..91e553f 100644 --- a/source/core/board/NstBoardKaiser.cpp +++ b/source/core/board/NstBoardKaiser.cpp @@ -3,6 +3,7 @@ // Nestopia - NES/Famicom emulator written in C++ // // Copyright (C) 2003-2008 Martin Freij +// Copyright (C) 2021 Rupert Carmichael // // This file is part of Nestopia. // @@ -38,27 +39,6 @@ namespace Nes #pragma optimize("s", on) #endif - void Ks7058::SubReset(bool) - { - for (uint i=0x000; i < 0x1000; i += 0x100) - { - Map( 0xF000+i, 0xF07F+i, CHR_SWAP_4K_0 ); - Map( 0xF080+i, 0xF0FF+i, CHR_SWAP_4K_1 ); - } - } - - void Ks7022::SubReset(const bool hard) - { - reg = 0; - - if (hard) - prg.SwapBanks( 0, 0 ); - - Map( 0x8000, &Ks7022::Poke_8000 ); - Map( 0xA000, &Ks7022::Poke_A000 ); - Map( 0xFFFC, &Ks7022::Peek_FFFC ); - } - Ks202::Ks202(const Context& c) : Board(c), irq(*c.cpu) {} @@ -89,6 +69,36 @@ namespace Nes irq.Reset( hard, hard ? false : irq.Connected() ); } + void Ks7013b::SubReset(const bool hard) + { + prg.SwapBank( 0x4000, 0x7 ); + + Map( 0x6000U, 0x7FFFU, &Ks7013b::Poke_6000 ); + Map( 0x8000U, 0xFFFFU, &Ks7013b::Poke_8000 ); + } + + void Ks7016::SubReset(const bool hard) + { + reg = 8; + + prg.SwapBank( 0x0000, 0x3 ); + + Map( 0x6000U, 0x7FFFU, &Ks7016::Peek_6000 ); + Map( 0x8000U, 0xFFFFU, &Ks7016::Poke_8000 ); + } + + void Ks7022::SubReset(const bool hard) + { + reg = 0; + + if (hard) + prg.SwapBanks( 0, 0 ); + + Map( 0x8000, &Ks7022::Poke_8000 ); + Map( 0xA000, &Ks7022::Poke_A000 ); + Map( 0xFFFC, &Ks7022::Peek_FFFC ); + } + void Ks7031::SubReset(const bool hard) { Map( 0x6000U, 0xFFFEU, &Ks7031::Peek_6000 ); @@ -106,6 +116,62 @@ namespace Nes Map( 0x6000U, 0x7FFFU, &Ks7032::Peek_6000 ); } + void Ks7037::SubReset(const bool hard) + { + if (hard) + { + regNum = 0; + + for (uint i = 0; i < 8; ++i) + regs[i] = 0; + } + + Map( 0x6000U, 0x6FFFU, &Ks7037::Peek_6000 ); + Map( 0x6000U, 0x6FFFU, &Ks7037::Poke_6000 ); + + Map( 0x7000U, 0x7FFFU, &Ks7037::Peek_7000 ); + Map( 0x8000U, 0x9FFFU, &Ks7037::Peek_8000 ); + + for (uint i = 0x0000; i < 0x2000; i += 0x2) + { + Map( 0x8000 + i, &Ks7037::Poke_8000 ); + Map( 0x8001 + i, &Ks7037::Poke_8001 ); + } + + Map( 0xA000U, 0xAFFFU, &Ks7037::Peek_A000 ); + + Map( 0xB000U, 0xBFFFU, &Ks7037::Peek_B000 ); + Map( 0xB000U, 0xBFFFU, &Ks7037::Poke_B000 ); + + Map( 0xC000U, 0xDFFFU, &Ks7037::Peek_C000 ); + Map( 0xE000U, 0xEFFFU, &Ks7037::Peek_E000 ); + } + + void Ks7058::SubReset(bool) + { + for (uint i=0x000; i < 0x1000; i += 0x100) + { + Map( 0xF000+i, 0xF07F+i, CHR_SWAP_4K_0 ); + Map( 0xF080+i, 0xF0FF+i, CHR_SWAP_4K_1 ); + } + } + + void Ks7016::SubLoad(State::Loader& state,const dword baseChunk) + { + NST_VERIFY( (baseChunk == AsciiId<'K','7','6'>::V) ); + + if (baseChunk == AsciiId<'K','7','6'>::V) + { + while (const dword chunk = state.Begin()) + { + if (chunk == AsciiId<'R','E','G'>::V) + reg = state.Read8(); + + state.End(); + } + } + } + void Ks7022::SubLoad(State::Loader& state,const dword baseChunk) { NST_VERIFY( (baseChunk == AsciiId<'K','7','2'>::V) ); @@ -178,9 +244,32 @@ namespace Nes } } - void Ks7022::SubSave(State::Saver& state) const + void Ks7037::SubLoad(State::Loader& state,const dword baseChunk) { - state.Begin( AsciiId<'K','7','2'>::V ).Begin( AsciiId<'R','E','G'>::V ).Write8( reg ).End().End(); + NST_VERIFY( (baseChunk == AsciiId<'K','7','7'>::V) ); + + if (baseChunk == AsciiId<'K','7','7'>::V) + { + while (const dword chunk = state.Begin()) + { + if (chunk == AsciiId<'R','E','G'>::V) + { + State::Loader::Data<9> data( state ); + + regs[0] = data[0]; + regs[1] = data[1]; + regs[2] = data[2]; + regs[3] = data[3]; + regs[4] = data[4]; + regs[5] = data[5]; + regs[6] = data[6]; + regs[7] = data[7]; + regNum = data[8]; + } + + state.End(); + } + } } void Ks202::SubSave(State::Saver& state) const @@ -201,6 +290,16 @@ namespace Nes state.End(); } + void Ks7016::SubSave(State::Saver& state) const + { + state.Begin( AsciiId<'K','7','6'>::V ).Begin( AsciiId<'R','E','G'>::V ).Write8( reg ).End().End(); + } + + void Ks7022::SubSave(State::Saver& state) const + { + state.Begin( AsciiId<'K','7','2'>::V ).Begin( AsciiId<'R','E','G'>::V ).Write8( reg ).End().End(); + } + void Ks7031::SubSave(State::Saver& state) const { state.Begin( AsciiId<'K','7','1'>::V ); @@ -209,34 +308,25 @@ namespace Nes state.End(); } + void Ks7037::SubSave(State::Saver& state) const + { + state.Begin( AsciiId<'K','7','7'>::V ); + + const byte data[9] = + { + regs[0], regs[1], regs[2], regs[3], + regs[4], regs[5], regs[6], regs[7], + regNum + }; + + state.Begin( AsciiId<'R','E','G'>::V ).Write( data ).End(); + state.End(); + } + #ifdef NST_MSVC_OPTIMIZE #pragma optimize("", on) #endif - NES_PEEK_A(Ks7032,6000) - { - return wrk[0][address - 0x6000]; - } - - NES_POKE_D(Ks7022,8000) - { - ppu.SetMirroring( (data & 0x4) ? Ppu::NMT_H : Ppu::NMT_V ); - } - - NES_POKE_D(Ks7022,A000) - { - reg = data & 0xF; - } - - NES_PEEK(Ks7022,FFFC) - { - ppu.Update(); - chr.SwapBank( reg ); - prg.SwapBanks( reg, reg ); - - return prg.Peek(0x7FFC); - } - NES_POKE_D(Ks202,8000) { irq.Update(); @@ -326,6 +416,68 @@ namespace Nes } } + bool Ks202::Irq::Clock() + { + return (count++ == 0xFFFF) ? (count=latch, true) : false; + } + + void Ks202::Sync(Event event,Input::Controllers* controllers) + { + if (event == EVENT_END_FRAME) + irq.VSync(); + + Board::Sync( event, controllers ); + } + + NES_POKE_D(Ks7013b,6000) + { + prg.SwapBank( 0x0000, data & 0x7 ); + } + + NES_POKE_D(Ks7013b,8000) + { + ppu.SetMirroring( (data & 0x1) ? Ppu::NMT_H : Ppu::NMT_V ); + } + + NES_PEEK_A(Ks7016,6000) + { + return *(prg.Source().Mem(reg * SIZE_8K) + (address & 0x1FFF)); + } + + NES_POKE_A(Ks7016,8000) + { + bool mode = (address & 0x30) == 0x30; + + switch(address & 0xD943) { + case 0xD943: + reg = mode ? 0xB : (address >> 2) & 0xF; + break; + + case 0xD903: + reg = mode ? 0x8 | ((address >> 2) & 0x3) : reg = 0xB; + break; + } + } + + NES_POKE_D(Ks7022,8000) + { + ppu.SetMirroring( (data & 0x4) ? Ppu::NMT_H : Ppu::NMT_V ); + } + + NES_POKE_D(Ks7022,A000) + { + reg = data & 0xF; + } + + NES_PEEK(Ks7022,FFFC) + { + ppu.Update(); + chr.SwapBank( reg ); + prg.SwapBanks( reg, reg ); + + return prg.Peek(0x7FFC); + } + NES_POKE_AD(Ks7031,8000) { regs[(address >> 11) & 0x03] = data; @@ -345,17 +497,74 @@ namespace Nes return prg[0][new_addr]; } - bool Ks202::Irq::Clock() + NES_PEEK_A(Ks7032,6000) { - return (count++ == 0xFFFF) ? (count=latch, true) : false; + return wrk[0][address - 0x6000]; } - void Ks202::Sync(Event event,Input::Controllers* controllers) + NES_PEEK_A(Ks7037,6000) { - if (event == EVENT_END_FRAME) - irq.VSync(); + NST_VERIFY( wrk.Readable(0) ); + return wrk.Readable(0) ? wrk[0][address - 0x6000] : (address >> 8); + } - Board::Sync( event, controllers ); + NES_POKE_AD(Ks7037,6000) + { + NST_VERIFY( wrk.Writable(0) ); + + if (wrk.Writable(0)) + wrk[0][address- 0x6000] = data; + } + + NES_PEEK_A(Ks7037,7000) + { + return *(prg.Source().Mem(SIZE_4K * 15) + (address & 0xFFF)); + } + + NES_PEEK_A(Ks7037,8000) + { + return *(prg.Source().Mem(regs[6] * SIZE_8K) + (address & 0x1FFF)); + } + + NES_POKE_D(Ks7037,8000) + { + regNum = data & 0x7U; + byte mirror[4] = { regs[2], regs[4], regs[3], regs[5] }; + ppu.SetMirroring(mirror); + } + + NES_POKE_D(Ks7037,8001) + { + regs[regNum] = data; + } + + NES_PEEK_A(Ks7037,A000) + { + return *(prg.Source().Mem(SIZE_4K * 28) + (address & 0xFFF)); + } + + NES_PEEK_A(Ks7037,B000) + { + NST_VERIFY( wrk.Readable(0) ); + return wrk.Readable(0) ? wrk[0][address - 0xA000] : (address >> 8); + } + + NES_POKE_AD(Ks7037,B000) + { + NST_VERIFY( wrk.Writable(0) ); + + if (wrk.Writable(0)) + wrk[0][address- 0xA000] = data; + } + + NES_PEEK_A(Ks7037,C000) + { + return *(prg.Source().Mem(regs[7] * SIZE_8K) + (address & 0x1FFF)); + } + + NES_PEEK_A(Ks7037,E000) + { + return *(prg.Source().Mem(SIZE_8K * 15) + (address & 0x1FFF)); } } } diff --git a/source/core/board/NstBoardKaiser.hpp b/source/core/board/NstBoardKaiser.hpp index 0d6dce9..bf6def2 100644 --- a/source/core/board/NstBoardKaiser.hpp +++ b/source/core/board/NstBoardKaiser.hpp @@ -3,6 +3,7 @@ // Nestopia - NES/Famicom emulator written in C++ // // Copyright (C) 2003-2008 Martin Freij +// Copyright (C) 2021 Rupert Carmichael // // This file is part of Nestopia. // @@ -37,18 +38,6 @@ namespace Nes { namespace Kaiser { - class Ks7058 : public Board - { - public: - - explicit Ks7058(const Context& c) - : Board(c) {} - - private: - - void SubReset(bool); - }; - class Ks202 : public Board { public: @@ -88,6 +77,59 @@ namespace Nes Timer::M2 irq; }; + class Ks7013b : public Board + { + public: + + explicit Ks7013b(const Context& c) + : Board(c) {} + + private: + + void SubReset(bool); + + NES_DECL_POKE( 6000 ); + NES_DECL_POKE( 8000 ); + }; + + class Ks7016 : public Board + { + public: + + explicit Ks7016(const Context& c) + : Board(c) {} + + private: + + void SubReset(bool); + void SubLoad(State::Loader&,dword); + void SubSave(State::Saver&) const; + + NES_DECL_PEEK( 6000 ); + NES_DECL_POKE( 8000 ); + + uint reg; + }; + + class Ks7022 : public Board + { + public: + + explicit Ks7022(const Context& c) + : Board(c) {} + + private: + + void SubReset(bool); + void SubLoad(State::Loader&,dword); + void SubSave(State::Saver&) const; + + NES_DECL_POKE( 8000 ); + NES_DECL_POKE( A000 ); + NES_DECL_PEEK( FFFC ); + + uint reg; + }; class Ks7031 : public Board { @@ -121,11 +163,10 @@ namespace Nes NES_DECL_PEEK( 6000 ); }; - class Ks7022 : public Board + class Ks7037 : public Board { public: - - explicit Ks7022(const Context& c) + explicit Ks7037(const Context& c) : Board(c) {} private: @@ -134,11 +175,32 @@ namespace Nes void SubLoad(State::Loader&,dword); void SubSave(State::Saver&) const; - NES_DECL_POKE( 8000 ); - NES_DECL_POKE( A000 ); - NES_DECL_PEEK( FFFC ); + byte regNum; + byte regs[8]; - uint reg; + NES_DECL_PEEK( 6000 ); + NES_DECL_POKE( 6000 ); + NES_DECL_PEEK( 7000 ); + NES_DECL_PEEK( 8000 ); + NES_DECL_POKE( 8000 ); + NES_DECL_POKE( 8001 ); + NES_DECL_PEEK( A000 ); + NES_DECL_PEEK( B000 ); + NES_DECL_POKE( B000 ); + NES_DECL_PEEK( C000 ); + NES_DECL_PEEK( E000 ); + }; + + class Ks7058 : public Board + { + public: + + explicit Ks7058(const Context& c) + : Board(c) {} + + private: + + void SubReset(bool); }; } } diff --git a/source/core/board/NstBoardKonamiVrc2.cpp b/source/core/board/NstBoardKonamiVrc2.cpp index 5b8f9d2..b61c00f 100644 --- a/source/core/board/NstBoardKonamiVrc2.cpp +++ b/source/core/board/NstBoardKonamiVrc2.cpp @@ -153,7 +153,12 @@ namespace Nes void Vrc2::SwapChr(uint address,uint subBank) const { ppu.Update(); - chr.SwapBank( address, (chr.GetBank(address) & 0xF0U >> OFFSET) | ((subBank >> chrShift & 0xF) << OFFSET) ); + + chr.SwapBank( address, chrShift ? OFFSET ? + (chr.GetBank(address) & 0x07U) | ((subBank & 0xFU) << 3) : + (chr.GetBank(address) & 0xF8U) | ((subBank >> 1) & 0x7U) : + (chr.GetBank(address) & 0xF0U >> OFFSET) | ((subBank & 0xFU) << OFFSET) + ); } NES_POKE_D(Vrc2,B000) { SwapChr<0>( 0x0000, data ); } diff --git a/source/core/board/NstBoardMmc1.cpp b/source/core/board/NstBoardMmc1.cpp index 5438ac5..a4ef082 100644 --- a/source/core/board/NstBoardMmc1.cpp +++ b/source/core/board/NstBoardMmc1.cpp @@ -25,6 +25,7 @@ #include "../NstLog.hpp" #include "NstBoard.hpp" #include "NstBoardMmc1.hpp" +#include "../NstFile.hpp" namespace Nes { @@ -119,6 +120,20 @@ namespace Nes #pragma optimize("", on) #endif + void Mmc1::Save(File& file) const + { + uint offset = (board.GetWram() == SIZE_16K) ? SIZE_8K : 0; // SOROM + if (board.HasBattery() && board.GetSavableWram()) + file.Save( File::BATTERY, wrk.Source().Mem(offset), board.GetSavableWram() ); + } + + void Mmc1::Load(File& file) + { + uint offset = (board.GetWram() == SIZE_16K) ? SIZE_8K : 0; // SOROM + if (board.HasBattery() && board.GetSavableWram()) + file.Load( File::BATTERY, wrk.Source().Mem(offset), board.GetSavableWram() ); + } + void Mmc1::UpdatePrg() { prg.SwapBanks diff --git a/source/core/board/NstBoardMmc1.hpp b/source/core/board/NstBoardMmc1.hpp index 962e966..ffa9e0c 100644 --- a/source/core/board/NstBoardMmc1.hpp +++ b/source/core/board/NstBoardMmc1.hpp @@ -82,6 +82,9 @@ namespace Nes private: + void Save(File&) const; + void Load(File&); + void ResetRegisters(); virtual void NST_FASTCALL UpdateRegisters(uint); diff --git a/source/core/board/NstBoardMmc5.cpp b/source/core/board/NstBoardMmc5.cpp index 714d6af..474468c 100644 --- a/source/core/board/NstBoardMmc5.cpp +++ b/source/core/board/NstBoardMmc5.cpp @@ -655,10 +655,9 @@ namespace Nes NES_HOOK(Mmc5,HActive) { - banks.fetchMode = Banks::FETCH_MODE_BG; - if (ppu.IsEnabled()) { + banks.fetchMode = Banks::FETCH_MODE_BG; spliter.x = 0x1F; if (ppu.GetPixelCycles() != ~0U) diff --git a/source/core/board/NstBoardNamcot.hpp b/source/core/board/NstBoardNamcot.hpp index 89bdd4e..44b6361 100644 --- a/source/core/board/NstBoardNamcot.hpp +++ b/source/core/board/NstBoardNamcot.hpp @@ -31,6 +31,7 @@ #include "NstBoardNamcot163.hpp" #include "NstBoardNamcot175.hpp" +#include "NstBoardNamcot340.hpp" #include "NstBoardNamcot34xx.hpp" namespace Nes diff --git a/source/core/board/NstBoardNamcot175.cpp b/source/core/board/NstBoardNamcot175.cpp index f8f6e40..639b14c 100644 --- a/source/core/board/NstBoardNamcot175.cpp +++ b/source/core/board/NstBoardNamcot175.cpp @@ -3,7 +3,7 @@ // Nestopia - NES/Famicom emulator written in C++ // // Copyright (C) 2003-2008 Martin Freij -// Copyright (C) 2014 R. Danbrook +// Copyright (C) 2021 Rupert Carmichael // // This file is part of Nestopia. // @@ -23,10 +23,7 @@ // //////////////////////////////////////////////////////////////////////////////////////// -#include #include "NstBoard.hpp" -#include "../NstTimer.hpp" -#include "../NstFile.hpp" #include "NstBoardNamcot175.hpp" namespace Nes @@ -43,16 +40,14 @@ namespace Nes N175::N175(const Context& c) : - Board (c), - irq (*c.cpu) + Board (c) { } void N175::SubReset(const bool hard) { - - irq.Reset( hard, hard || irq.Connected() ); - + Map( 0x6000U, 0x7FFFU, &N175::Peek_6000 ); + Map( 0x6000U, 0x7FFFU, &N175::Poke_6000 ); Map( 0x8000U, 0x87FFU, CHR_SWAP_1K_0 ); Map( 0x8800U, 0x8FFFU, CHR_SWAP_1K_1 ); Map( 0x9000U, 0x97FFU, CHR_SWAP_1K_2 ); @@ -61,157 +56,35 @@ namespace Nes Map( 0xA800U, 0xAFFFU, CHR_SWAP_1K_5 ); Map( 0xB000U, 0xB7FFU, CHR_SWAP_1K_6 ); Map( 0xB800U, 0xBFFFU, CHR_SWAP_1K_7 ); + Map( 0xC000U, 0xC7FFU, &N175::Poke_C000 ); Map( 0xE000U, 0xE7FFU, PRG_SWAP_8K_0 ); Map( 0xE800U, 0xEFFFU, PRG_SWAP_8K_1 ); Map( 0xF000U, 0xF7FFU, PRG_SWAP_8K_2 ); } - void N175::Irq::Reset(const bool hard) - { - if (hard) - count = 0; - } - - void N175::Load(File& file) - { - if (board.HasBattery()) - { - const File::LoadBlock block[] = - { - { wrk.Source().Mem(), board.GetWram() } - }; - - file.Load( File::BATTERY, block ); - } - else - { - Board::Load( file ); - } - } - - void N175::Save(File& file) const - { - if (board.HasBattery()) - { - const File::SaveBlock block[] = - { - { wrk.Source().Mem(), board.GetWram() } - }; - - file.Save( File::BATTERY, block ); - } - else - { - Board::Save( file ); - } - } - - void N175::SubLoad(State::Loader& state,const dword baseChunk) - { - NST_VERIFY( baseChunk == (AsciiId<'N','6','3'>::V) ); - - if (baseChunk == AsciiId<'N','6','3'>::V) - { - while (const dword chunk = state.Begin()) - { - switch (chunk) - { - case AsciiId<'I','R','Q'>::V: - { - State::Loader::Data<3> data( state ); - irq.unit.count = data[1] | (data[2] << 8 & 0x7F00) | (data[0] << 15 & 0x8000); - break; - } - } - - state.End(); - } - } - } - - void N175::SubSave(State::Saver& state) const - { - state.Begin( AsciiId<'N','6','3'>::V ); - - const byte data[3] = - { - irq.unit.count >> 15, - irq.unit.count >> 0 & 0xFF, - irq.unit.count >> 8 & 0x7F - }; - - state.Begin( AsciiId<'I','R','Q'>::V ).Write( data ).End(); - - state.End(); - } #ifdef NST_MSVC_OPTIMIZE #pragma optimize("", on) #endif - bool N175::Irq::Clock() + NES_PEEK_A(N175,6000) { - return (count - 0x8000 < 0x7FFF) && (++count == 0xFFFF); + NST_VERIFY( wrk.Readable(0) ); + return wrk.Readable(0) ? wrk[0][address & 0x7FFU] : (address >> 8); } - NES_PEEK(N175,5000) + NES_POKE_AD(N175,6000) { - irq.Update(); - return irq.unit.count & 0xFF; - } + NST_VERIFY( wrk.Writable(0) ); - NES_POKE_D(N175,5000) - { - irq.Update(); - irq.unit.count = (irq.unit.count & 0xFF00) | data; - irq.ClearIRQ(); - } - - NES_PEEK(N175,5800) - { - irq.Update(); - return irq.unit.count >> 8; - } - - NES_POKE_D(N175,5800) - { - irq.Update(); - irq.unit.count = (irq.unit.count & 0x00FF) | (data << 8); - irq.ClearIRQ(); - } - - void N175::SwapNmt(const uint address,const uint data) const - { - ppu.Update(); - nmt.Source( data < 0xE0 ).SwapBank( address, data ); + if (wrk.Writable(0)) + wrk[0][address & 0x7FFU] = data; } NES_POKE_D(N175,C000) { - SwapNmt( 0x0000, data ); - } - - NES_POKE_D(N175,C800) - { - SwapNmt( 0x0400, data ); - } - - NES_POKE_D(N175,D000) - { - SwapNmt( 0x0800, data ); - } - - NES_POKE_D(N175,D800) - { - SwapNmt( 0x0C00, data ); - } - - void N175::Sync(Event event,Input::Controllers* controllers) - { - if (event == EVENT_END_FRAME) - irq.VSync(); - - Board::Sync( event, controllers ); + bool enable = data & 0x1; + wrk.Source().SetSecurity(enable, enable); } } } diff --git a/source/core/board/NstBoardNamcot175.hpp b/source/core/board/NstBoardNamcot175.hpp index 41d9b0c..59052c1 100644 --- a/source/core/board/NstBoardNamcot175.hpp +++ b/source/core/board/NstBoardNamcot175.hpp @@ -3,7 +3,7 @@ // Nestopia - NES/Famicom emulator written in C++ // // Copyright (C) 2003-2008 Martin Freij -// Copyright (C) 2014 R. Danbrook +// Copyright (C) 2021 Rupert Carmichael // // This file is part of Nestopia. // @@ -47,35 +47,10 @@ namespace Nes private: void SubReset(bool); - void SubSave(State::Saver&) const; - void SubLoad(State::Loader&,dword); - void Load(File&); - void Save(File&) const; - void Sync(Event,Input::Controllers*); - void SwapChr(uint,uint,uint) const; - void SwapNmt(uint,uint) const; - struct Irq - { - void Reset(bool); - bool Clock(); - - uint count; - }; - - NES_DECL_PEEK( 4800 ); - NES_DECL_POKE( 4800 ); - NES_DECL_PEEK( 5000 ); - NES_DECL_POKE( 5000 ); - NES_DECL_PEEK( 5800 ); - NES_DECL_POKE( 5800 ); + NES_DECL_PEEK( 6000 ); + NES_DECL_POKE( 6000 ); NES_DECL_POKE( C000 ); - NES_DECL_POKE( C800 ); - NES_DECL_POKE( D000 ); - NES_DECL_POKE( D800 ); - NES_DECL_POKE( F800 ); - - Timer::M2 irq; }; } } diff --git a/source/core/board/NstBoardNamcot340.cpp b/source/core/board/NstBoardNamcot340.cpp new file mode 100644 index 0000000..073266b --- /dev/null +++ b/source/core/board/NstBoardNamcot340.cpp @@ -0,0 +1,89 @@ +//////////////////////////////////////////////////////////////////////////////////////// +// +// Nestopia - NES/Famicom emulator written in C++ +// +// Copyright (C) 2003-2008 Martin Freij +// Copyright (C) 2021 Rupert Carmichael +// +// This file is part of Nestopia. +// +// Nestopia is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// Nestopia is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Nestopia; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//////////////////////////////////////////////////////////////////////////////////////// + +#include "NstBoard.hpp" +#include "NstBoardNamcot340.hpp" + +namespace Nes +{ + namespace Core + { + namespace Boards + { + namespace Namcot + { + #ifdef NST_MSVC_OPTIMIZE + #pragma optimize("s", on) + #endif + + N340::N340(const Context& c) + : + Board (c) + { + } + + void N340::SubReset(const bool hard) + { + Map( 0x8000U, 0x87FFU, CHR_SWAP_1K_0 ); + Map( 0x8800U, 0x8FFFU, CHR_SWAP_1K_1 ); + Map( 0x9000U, 0x97FFU, CHR_SWAP_1K_2 ); + Map( 0x9800U, 0x9FFFU, CHR_SWAP_1K_3 ); + Map( 0xA000U, 0xA7FFU, CHR_SWAP_1K_4 ); + Map( 0xA800U, 0xAFFFU, CHR_SWAP_1K_5 ); + Map( 0xB000U, 0xB7FFU, CHR_SWAP_1K_6 ); + Map( 0xB800U, 0xBFFFU, CHR_SWAP_1K_7 ); + Map( 0xE000U, 0xE7FFU, &N340::Poke_E000 ); + Map( 0xE800U, 0xEFFFU, PRG_SWAP_8K_1 ); + Map( 0xF000U, 0xF7FFU, PRG_SWAP_8K_2 ); + } + + #ifdef NST_MSVC_OPTIMIZE + #pragma optimize("", on) + #endif + + NES_POKE_D(N340,E000) + { + prg.SwapBank( 0, data & 0x3FU ); + + switch ((data >> 6) & 0x3U) + { + case 0x0U: // One-screen A + ppu.SetMirroring( Ppu::NMT_0 ); + break; + case 0x1U: // Vertical + ppu.SetMirroring( Ppu::NMT_V ); + break; + case 0x2U: // One-screen B + ppu.SetMirroring( Ppu::NMT_1 ); + break; + case 0x3U: // Horizontal + ppu.SetMirroring( Ppu::NMT_H ); + break; + } + } + } + } + } +} diff --git a/source/core/board/NstBoardNamcot340.hpp b/source/core/board/NstBoardNamcot340.hpp new file mode 100644 index 0000000..e079a13 --- /dev/null +++ b/source/core/board/NstBoardNamcot340.hpp @@ -0,0 +1,58 @@ +//////////////////////////////////////////////////////////////////////////////////////// +// +// Nestopia - NES/Famicom emulator written in C++ +// +// Copyright (C) 2003-2008 Martin Freij +// Copyright (C) 2021 Rupert Carmichael +// +// This file is part of Nestopia. +// +// Nestopia is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// Nestopia is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Nestopia; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//////////////////////////////////////////////////////////////////////////////////////// + +#ifndef NST_BOARD_NAMCOT_340_H +#define NST_BOARD_NAMCOT_340_H + +#ifdef NST_PRAGMA_ONCE +#pragma once +#endif + +namespace Nes +{ + namespace Core + { + namespace Boards + { + namespace Namcot + { + class N340 : public Board + { + public: + + explicit N340(const Context&); + + private: + + void SubReset(bool); + + NES_DECL_POKE( E000 ); + }; + } + } + } +} + +#endif diff --git a/source/core/board/NstBoardOpenCorp.cpp b/source/core/board/NstBoardOpenCorp.cpp index 1f38c24..2416878 100644 --- a/source/core/board/NstBoardOpenCorp.cpp +++ b/source/core/board/NstBoardOpenCorp.cpp @@ -22,6 +22,8 @@ // //////////////////////////////////////////////////////////////////////////////////////// +// Reference: https://github.com/TASVideos/fceux/blob/master/src/boards/156.cpp + #include "NstBoard.hpp" #include "NstBoardOpenCorp.hpp" @@ -37,17 +39,139 @@ namespace Nes #pragma optimize("s", on) #endif + void Daou306::RemapChr() + { + chr.SwapBank( 0x0000, (chrHigh[0] << 8) | chrLow[0] ); + chr.SwapBank( 0x0400, (chrHigh[1] << 8) | chrLow[1] ); + chr.SwapBank( 0x0800, (chrHigh[2] << 8) | chrLow[2] ); + chr.SwapBank( 0x0C00, (chrHigh[3] << 8) | chrLow[3] ); + chr.SwapBank( 0x1000, (chrHigh[4] << 8) | chrLow[4] ); + chr.SwapBank( 0x1400, (chrHigh[5] << 8) | chrLow[5] ); + chr.SwapBank( 0x1800, (chrHigh[6] << 8) | chrLow[6] ); + chr.SwapBank( 0x1C00, (chrHigh[7] << 8) | chrLow[7] ); + + if (mirrorUsed) { + ppu.SetMirroring( mirror ^ 0x1 ? Ppu::NMT_V : Ppu::NMT_H ); + } + else + { + ppu.SetMirroring( Ppu::NMT_0 ); + } + } + void Daou306::SubReset(bool) { - Map( 0xC000U, CHR_SWAP_1K_0 ); - Map( 0xC001U, CHR_SWAP_1K_1 ); - Map( 0xC002U, CHR_SWAP_1K_2 ); - Map( 0xC003U, CHR_SWAP_1K_3 ); - Map( 0xC008U, CHR_SWAP_1K_4 ); - Map( 0xC009U, CHR_SWAP_1K_5 ); - Map( 0xC00AU, CHR_SWAP_1K_6 ); - Map( 0xC00BU, CHR_SWAP_1K_7 ); + for (uint i = 0; i < 8; i++) + { + chrLow[i] = chrHigh[i] = 0; + } + + Map( 0xC000U, 0xC00FU, &Daou306::Poke_C000 ); Map( 0xC010U, PRG_SWAP_16K_0 ); + Map( 0xC014U, &Daou306::Poke_C014 ); + } + + NES_POKE_AD(Daou306,C000) + { + switch (address) + { + case 0xC000: + case 0xC001: + case 0xC002: + case 0xC003: + chrLow[address & 0x03] = data; + break; + case 0xC004: + case 0xC005: + case 0xC006: + case 0xC007: + chrHigh[address & 0x03] = data; + break; + case 0xC008: + case 0xC009: + case 0xC00A: + case 0xC00B: + chrLow[4 + (address & 0x03)] = data; + break; + case 0xC00C: + case 0xC00D: + case 0xC00E: + case 0xC00F: + chrHigh[4 + (address & 0x03)] = data; + break; + } + RemapChr(); + } + + NES_POKE_D(Daou306,C014) + { + mirror = data; + mirrorUsed = 1; + } + + void Daou306::SubLoad(State::Loader& state,const dword baseChunk) + { + NST_VERIFY( baseChunk == (AsciiId<'O','P','C'>::V) ); + + if (baseChunk == AsciiId<'O','P','C'>::V) + { + state.Begin(); + + State::Loader::Data<18> data( state ); + chrLow[0] = data[0]; + chrLow[1] = data[1]; + chrLow[2] = data[2]; + chrLow[3] = data[3]; + chrLow[4] = data[4]; + chrLow[5] = data[5]; + chrLow[6] = data[6]; + chrLow[7] = data[7]; + chrHigh[0] = data[8]; + chrHigh[1] = data[9]; + chrHigh[2] = data[10]; + chrHigh[3] = data[11]; + chrHigh[4] = data[12]; + chrHigh[5] = data[13]; + chrHigh[6] = data[14]; + chrHigh[7] = data[15]; + mirror = data[16]; + mirrorUsed = data[17]; + + state.End(); + + RemapChr(); + } + } + + void Daou306::SubSave(State::Saver& state) const + { + state.Begin( AsciiId<'O','P','C'>::V ); + + const byte data[18] = + { + chrLow[0], + chrLow[1], + chrLow[2], + chrLow[3], + chrLow[4], + chrLow[5], + chrLow[6], + chrLow[7], + chrHigh[0], + chrHigh[1], + chrHigh[2], + chrHigh[3], + chrHigh[4], + chrHigh[5], + chrHigh[6], + chrHigh[7], + mirror, + mirrorUsed, + }; + + state.Begin( AsciiId<'C','H','R'>::V ).Write( data ).End(); + + state.End(); } #ifdef NST_MSVC_OPTIMIZE diff --git a/source/core/board/NstBoardOpenCorp.hpp b/source/core/board/NstBoardOpenCorp.hpp index 5c276fa..03e128c 100644 --- a/source/core/board/NstBoardOpenCorp.hpp +++ b/source/core/board/NstBoardOpenCorp.hpp @@ -46,7 +46,18 @@ namespace Nes private: + byte chrLow[8]; + byte chrHigh[8]; + byte mirror; + byte mirrorUsed; + + void RemapChr(); void SubReset(bool); + void SubSave(State::Saver&) const; + void SubLoad(State::Loader&,dword); + + NES_DECL_POKE( C000 ); + NES_DECL_POKE( C014 ); }; } } diff --git a/source/core/board/NstBoardSunsoft5b.cpp b/source/core/board/NstBoardSunsoft5b.cpp index a91d840..94fa732 100644 --- a/source/core/board/NstBoardSunsoft5b.cpp +++ b/source/core/board/NstBoardSunsoft5b.cpp @@ -322,7 +322,7 @@ namespace Nes ctrl = data[0] >> 1 & 0x1F; length = data[1] | (data[2] << 8 & 0xF00); volume = levels[(ctrl & 0xF) ? (ctrl & 0xF) * 2 + 1 : 0]; - dc = (status & 0x1) ? ~0UL : 0UL; + dc = (status & 0x1) ? ~dword(0) : dword(0); UpdateSettings( fixed ); } diff --git a/source/core/board/NstBoardTengenRambo1.cpp b/source/core/board/NstBoardTengenRambo1.cpp index 12c8453..7ee4708 100644 --- a/source/core/board/NstBoardTengenRambo1.cpp +++ b/source/core/board/NstBoardTengenRambo1.cpp @@ -54,6 +54,7 @@ namespace Nes if (hard) { count = 0; + cycles = 0; reload = false; latch = 0; enabled = false; @@ -121,14 +122,16 @@ namespace Nes case AsciiId<'I','R','Q'>::V: { - State::Loader::Data<3> data( state ); + State::Loader::Data<4> data( state ); irq.unit.enabled = data[0] & 0x1; + irq.unit.mode = data[0] & 0x2 ? 1 : 0; irq.a12.Connect( data[0] & 0x2 ); irq.m2.Connect( data[0] & 0x2 ); irq.unit.reload = data[0] & 0x4; irq.unit.latch = data[1]; irq.unit.count = data[2]; + irq.unit.cycles = data[3]; break; } @@ -164,13 +167,14 @@ namespace Nes } { - const byte data[3] = + const byte data[4] = { (irq.unit.enabled ? 0x1U : 0x0U) | (irq.m2.Connected() ? 0x2U : 0x0U) | (irq.unit.reload ? 0x4U : 0x0U), irq.unit.latch, - irq.unit.count & 0xFF + irq.unit.count & 0xFF, + irq.unit.cycles, }; state.Begin( AsciiId<'I','R','Q'>::V ).Write( data ).End(); @@ -185,47 +189,39 @@ namespace Nes bool Rambo1::Irq::Unit::Clock() { - /*if (!reload) + cycles++; + + if (latch == 1) { - if (count) - { - return !--count && enabled; - } - else - { - count = latch; - return false; - } + count = 0; + } + else if (reload) + { + reload = false; + count = latch | (latch ? 1 : 0); + + if (mode) + count |= 2; + + if (!latch && cycles > A12_FILTER) + count = 1; + else if (latch && (cycles > (A12_FILTER * 3))) + count++; + + cycles = 0; + } + else if (!count) + { + count = latch; + if (cycles > A12_FILTER) + cycles = 0; } else { - reload = false; - count = latch + 1; - return false; - }*/ - - // From dragon2snow - if (reload) { - if (latch < 1) { - count = latch + 1; - } - else { - count = latch + 2; - } - reload = false; + count--; } - else if (!count) { - count = latch + 1; - } - - count--; - - if (!count && enabled) { - /* wait one M2 cycle, then trigger IRQ */ - return true; - } - - return false; + + return (!count && enabled); } void Rambo1::Irq::Update() @@ -320,6 +316,7 @@ namespace Nes { irq.Update(); irq.unit.latch = data; + irq.unit.mode = irq.m2.Connected(); } NES_POKE_D(Rambo1,C001) diff --git a/source/core/board/NstBoardTengenRambo1.hpp b/source/core/board/NstBoardTengenRambo1.hpp index 1f8593f..9bd64a2 100644 --- a/source/core/board/NstBoardTengenRambo1.hpp +++ b/source/core/board/NstBoardTengenRambo1.hpp @@ -95,9 +95,11 @@ namespace Nes bool Clock(); uint count; + uint cycles; uint latch; ibool reload; ibool enabled; + ibool mode; }; typedef Timer::A12 A12; diff --git a/source/core/board/NstBoardUnlCc21.cpp b/source/core/board/NstBoardUnlCc21.cpp index 0421c7c..98b268e 100644 --- a/source/core/board/NstBoardUnlCc21.cpp +++ b/source/core/board/NstBoardUnlCc21.cpp @@ -49,7 +49,8 @@ namespace Nes NES_POKE_A(Cc21,8000) { ppu.SetMirroring( (address & 0x2) ? Ppu::NMT_1 : Ppu::NMT_0 ); - chr.SwapBank( address ); + chr.SwapBank( address ); + chr.SwapBank( address ); } } } diff --git a/source/core/board/NstBoardUnlKingOfFighters97.cpp b/source/core/board/NstBoardUnlKingOfFighters97.cpp index 9c117b0..b84048c 100644 --- a/source/core/board/NstBoardUnlKingOfFighters97.cpp +++ b/source/core/board/NstBoardUnlKingOfFighters97.cpp @@ -51,7 +51,8 @@ namespace Nes } Map( 0x9000U, &KingOfFighters97::Poke_8001 ); - Map( 0xA000U, &KingOfFighters97::Poke_8000 ); + Map( 0xA000U, &KingOfFighters97::Poke_A000 ); + Map( 0xB000U, &KingOfFighters97::Poke_A001 ); Map( 0xD000U, &KingOfFighters97::Poke_C001 ); for (uint i=0x0000; i < 0x1000; i += 0x2) @@ -89,6 +90,16 @@ namespace Nes Mmc3::NES_DO_POKE(8001,0x8001,Unscramble(data)); } + NES_POKE_D(KingOfFighters97,A000) + { + ppu.SetMirroring( (data & 0x02) ? Ppu::NMT_H : Ppu::NMT_V ); + } + + NES_POKE_D(KingOfFighters97,A001) + { + Mmc3::NES_DO_POKE(A001,0xA001,Unscramble(data)); + } + NES_POKE_D(KingOfFighters97,C000) { Mmc3::NES_DO_POKE(C000,0xC000,Unscramble(data)); diff --git a/source/core/board/NstBoardUnlKingOfFighters97.hpp b/source/core/board/NstBoardUnlKingOfFighters97.hpp index 339d070..78e58f9 100644 --- a/source/core/board/NstBoardUnlKingOfFighters97.hpp +++ b/source/core/board/NstBoardUnlKingOfFighters97.hpp @@ -52,6 +52,8 @@ namespace Nes NES_DECL_POKE( 8000 ); NES_DECL_POKE( 8001 ); + NES_DECL_POKE( A000 ); + NES_DECL_POKE( A001 ); NES_DECL_POKE( C000 ); NES_DECL_POKE( C001 ); NES_DECL_POKE( E000 );