diff --git a/src/boards/222.c b/src/boards/222.c index 3eee006..9ecf914 100644 --- a/src/boards/222.c +++ b/src/boards/222.c @@ -1,7 +1,7 @@ /* FCE Ultra - NES/Famicom Emulator * * Copyright notice for this file: - * Copyright (C) 2005 CaH4e3 + * Copyright (C) 2025 NewRisingSun * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,86 +16,83 @@ * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * (VRC4 mapper) - * */ #include "mapinc.h" +#include "vrc2and4.h" -static uint8 IRQCount; /*, IRQPre; */ -static uint8 IRQa; -static uint8 prg_reg[2]; -static uint8 chr_reg[8]; -static uint8 mirr; +static uint8 clockMode; +static uint8 pending; +static uint8 counter1; +static uint8 counter2; +static uint8 prescaler; -static SFORMAT StateRegs[] = -{ - { &IRQCount, 1, "IRQC" }, - { &IRQa, 1, "IRQA" }, - { prg_reg, 2, "PRG" }, - { chr_reg, 8, "CHR" }, - { &mirr, 1, "MIRR" }, +static SFORMAT Mapper222_stateRegs[] ={ + { &clockMode, 1, "CLKM" }, + { &pending, 1, "PEND" }, + { &counter1, 1, "CNT1" }, + { &counter2, 1, "CNT2" }, + { &prescaler, 1, "PRES" }, { 0 } }; -static void M222IRQ(void) { - if (IRQa) { - IRQCount++; - if (IRQCount >= 238) { - X6502_IRQBegin(FCEU_IQEXT); -/* IRQa=0; */ +static void sync () { + VRC24_syncPRG(0x01F, 0x000); + VRC24_syncCHR(0x1FF, 0x000); + VRC24_syncMirror(); +} + +DECLFW(Mapper222_nibblizeCHR) { + if (~A &1) { + VRC24_writeReg(A, V); + VRC24_writeReg(A |1, V >>4); + } +} + +DECLFW(Mapper222_writeIRQ) { + switch(A &3) { + case 0: clockMode =0; + break; + case 1: pending =false; + if (!clockMode) { + counter1 =V &0xF; + counter2 =V >>4; + } + break; + case 2: clockMode =1; + break; + } +} + +void FP_FASTAPASS(1) Mapper222_cpuCycle(int a) { + while (a--) { + uint8 previousPrescaler =prescaler; + if (pending) + prescaler =0; + else + prescaler++; + if (clockMode && ~previousPrescaler &0x40 && prescaler &0x40) { + if (++counter1 ==0xF && ++counter2 ==0xF) pending =1; + counter1 &=0xF; + counter2 &=0xF; } + if (pending) + X6502_IRQBegin(FCEU_IQEXT); + else + X6502_IRQEnd(FCEU_IQEXT); } } -static void Sync(void) { - int i; - setprg8(0x8000, prg_reg[0]); - setprg8(0xA000, prg_reg[1]); - for (i = 0; i < 8; i++) - setchr1(i << 10, chr_reg[i]); - setmirror(mirr ^ 1); +void Mapper222_power(void) { + clockMode =pending =counter1 =counter2 =prescaler =0; + VRC24_power(); + SetWriteHandler(0xB000, 0xEFFF, Mapper222_nibblizeCHR); + SetWriteHandler(0xF000, 0xFFFF, Mapper222_writeIRQ); } -static DECLFW(M222Write) { - switch (A & 0xF003) { - case 0x8000: prg_reg[0] = V; break; - case 0x9000: mirr = V & 1; break; - case 0xA000: prg_reg[1] = V; break; - case 0xB000: chr_reg[0] = V; break; - case 0xB002: chr_reg[1] = V; break; - case 0xC000: chr_reg[2] = V; break; - case 0xC002: chr_reg[3] = V; break; - case 0xD000: chr_reg[4] = V; break; - case 0xD002: chr_reg[5] = V; break; - case 0xE000: chr_reg[6] = V; break; - case 0xE002: chr_reg[7] = V; break; -#if 0 - case 0xF000: FCEU_printf("%04x:%02x %d\n",A,V,scanline); IRQa=V; if(!V)IRQPre=0; X6502_IRQEnd(FCEU_IQEXT); break; - case 0xF001: FCEU_printf("%04x:%02x %d\n",A,V,scanline); IRQCount=V; break; - case 0xF002: FCEU_printf("%04x:%02x %d\n",A,V,scanline); break; - case 0xD001: IRQa=V; X6502_IRQEnd(FCEU_IQEXT); FCEU_printf("%04x:%02x %d\n",A,V,scanline); break; - case 0xC001: IRQPre=16; FCEU_printf("%04x:%02x %d\n",A,V,scanline); break; -#endif - case 0xF000: IRQa = IRQCount = V; if (scanline < 240) IRQCount -= 8; else IRQCount += 4; X6502_IRQEnd(FCEU_IQEXT); break; - } - Sync(); -} - -static void M222Power(void) { - setprg16(0xC000, ~0); - SetReadHandler(0x8000, 0xFFFF, CartBR); - SetWriteHandler(0x8000, 0xFFFF, M222Write); -} - -static void StateRestore(int version) { - Sync(); -} - -void Mapper222_Init(CartInfo *info) { - info->Power = M222Power; - GameHBIRQHook = M222IRQ; - GameStateRestore = StateRestore; - AddExState(&StateRegs, ~0, 0, 0); +void Mapper222_Init (CartInfo *info) { + VRC24_init(info, sync, 0x01, 0x02, 0, 0, 0); + AddExState(Mapper222_stateRegs, ~0, 0, 0); + info->Power =Mapper222_power; + MapIRQHook =Mapper222_cpuCycle; }