From 60b314feb3939e31cf2a5f36ad938866eec90fb7 Mon Sep 17 00:00:00 2001 From: g0me3 Date: Sat, 27 Apr 2019 21:35:59 +0300 Subject: [PATCH] vrc5 mapper update, prepare to add extra ppu render for it cheats.cpp int converions warnings fix change default tool index for vc project. if you have problem with it, feel free to revert. but i can't compile with just "8.1" in there sadly... --- src/boards/vrc5.cpp | 297 ++++++++++++++++++++++++++---------------- src/cheat.cpp | 10 +- src/fceu.cpp | 1 + src/fceu.h | 2 +- src/ines.cpp | 2 +- src/ines.h | 1 + src/ppu.cpp | 2 +- src/unif.cpp | 2 +- src/unif.h | 2 +- vc/vc14_fceux.vcxproj | 2 +- 10 files changed, 201 insertions(+), 120 deletions(-) diff --git a/src/boards/vrc5.cpp b/src/boards/vrc5.cpp index 6d17bd5a..8973919c 100644 --- a/src/boards/vrc5.cpp +++ b/src/boards/vrc5.cpp @@ -1,7 +1,7 @@ /* FCE Ultra - NES/Famicom Emulator * * Copyright notice for this file: - * Copyright (C) 2005 CaH4e3 + * Copyright (C) 2005-2019 CaH4e3 * * 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 @@ -23,19 +23,89 @@ #include "mapinc.h" -static uint8 QTAINTRAM[2048]; +#define CAI_DEBUG + +static writefunc old2006wrap; static writefunc old2007wrap; +static uint8 QTAINTRAM[2048]; +static uint16 qtaintramofs; static uint16 CHRSIZE = 8192; -static uint16 WRAMSIZE = 8192 + 4096; +static uint16 WRAMSIZE = 8192 + 8192; static uint8 *CHRRAM = NULL; static uint8 *WRAM = NULL; static uint8 IRQa, K4IRQ; static uint32 IRQLatch, IRQCount; +static uint8 conv_tbl[128][4] = { + { 0x40, 0x40, 0x40, 0x40 }, + { 0x41, 0x41, 0x41, 0x41 }, + { 0x42, 0x42, 0x42, 0x42 }, + { 0x43, 0x43, 0x43, 0x43 }, + { 0x44, 0x44, 0x44, 0x44 }, + { 0x45, 0x45, 0x45, 0x45 }, + { 0x46, 0x46, 0x46, 0x46 }, + { 0x47, 0x47, 0x47, 0x47 }, + { 0x40, 0x40, 0x40, 0x40 }, + { 0x41, 0x41, 0x41, 0x41 }, + { 0x42, 0x42, 0x42, 0x42 }, + { 0x43, 0x43, 0x43, 0x43 }, + { 0x44, 0x44, 0x44, 0x44 }, + { 0x45, 0x45, 0x45, 0x45 }, + { 0x46, 0x46, 0x46, 0x46 }, + { 0x47, 0x47, 0x47, 0x47 }, + { 0x40, 0x40, 0x48, 0x44 }, + { 0x41, 0x41, 0x49, 0x45 }, + { 0x42, 0x42, 0x4A, 0x46 }, + { 0x43, 0x43, 0x4B, 0x47 }, + { 0x44, 0x40, 0x48, 0x44 }, + { 0x45, 0x41, 0x49, 0x45 }, + { 0x46, 0x42, 0x4A, 0x46 }, + { 0x47, 0x43, 0x4B, 0x47 }, + { 0x40, 0x50, 0x58, 0x60 }, + { 0x41, 0x51, 0x59, 0x61 }, + { 0x42, 0x52, 0x5A, 0x62 }, + { 0x43, 0x53, 0x5B, 0x63 }, + { 0x44, 0x54, 0x5C, 0x64 }, + { 0x45, 0x55, 0x5D, 0x65 }, + { 0x46, 0x56, 0x5E, 0x66 }, + { 0x47, 0x57, 0x5F, 0x67 }, + { 0x40, 0x68, 0x70, 0x78 }, + { 0x41, 0x69, 0x71, 0x79 }, + { 0x42, 0x6A, 0x72, 0x7A }, + { 0x43, 0x6B, 0x73, 0x7B }, + { 0x44, 0x6C, 0x74, 0x7C }, + { 0x45, 0x6D, 0x75, 0x7D }, + { 0x46, 0x6E, 0x76, 0x7E }, + { 0x47, 0x6F, 0x77, 0x7F }, + { 0x40, 0x40, 0x48, 0x50 }, + { 0x41, 0x41, 0x49, 0x51 }, + { 0x42, 0x42, 0x4A, 0x52 }, + { 0x43, 0x43, 0x4B, 0x53 }, + { 0x44, 0x44, 0x4C, 0x54 }, + { 0x45, 0x45, 0x4D, 0x55 }, + { 0x46, 0x46, 0x4E, 0x56 }, + { 0x47, 0x47, 0x4F, 0x57 }, + { 0x40, 0x58, 0x60, 0x68 }, + { 0x41, 0x59, 0x61, 0x69 }, + { 0x42, 0x5A, 0x62, 0x6A }, + { 0x43, 0x5B, 0x63, 0x6B }, + { 0x44, 0x5C, 0x64, 0x6C }, + { 0x45, 0x5D, 0x65, 0x6D }, + { 0x46, 0x5E, 0x66, 0x6E }, + { 0x47, 0x5F, 0x67, 0x6F }, + { 0x40, 0x70, 0x78, 0x74 }, + { 0x41, 0x71, 0x79, 0x75 }, + { 0x42, 0x72, 0x7A, 0x76 }, + { 0x43, 0x73, 0x7B, 0x77 }, + { 0x44, 0x74, 0x7C, 0x74 }, + { 0x45, 0x75, 0x7D, 0x75 }, + { 0x46, 0x76, 0x7E, 0x76 }, + { 0x47, 0x77, 0x7F, 0x77 }, +}; + static uint8 regs[16]; -//static uint8 test[8]; static SFORMAT StateRegs[] = { { &IRQCount, 1, "IRQC" }, @@ -48,93 +118,81 @@ static SFORMAT StateRegs[] = static void chrSync(void) { setchr4r(0x10, 0x0000, regs[5] & 1); - setchr4r(0x10, 0x1000, 0); +// one more hack to make visible some screens in common. will be replaced with proper code later + setchr4r(0x10, 0x1000, QTAINTRAM[0] & 1); +// setchr4r(0x10, 0x1000, 1); } static void Sync(void) { chrSync(); -// if(regs[0xA]&0x10) -// { -/* setchr1r(0x10,0x0000,(((regs[5]&1))<<2)+0); - setchr1r(0x10,0x0400,(((regs[5]&1))<<2)+1); - setchr1r(0x10,0x0800,(((regs[5]&1))<<2)+2); - setchr1r(0x10,0x0c00,(((regs[5]&1))<<2)+3); - setchr1r(0x10,0x1000,0); - setchr1r(0x10,0x1400,1); - setchr1r(0x10,0x1800,2); - setchr1r(0x10,0x1c00,3);*/ -/* setchr1r(0x10,0x0000,(((regs[5]&1))<<2)+0); - setchr1r(0x10,0x0400,(((regs[5]&1))<<2)+1); - setchr1r(0x10,0x0800,(((regs[5]&1))<<2)+2); - setchr1r(0x10,0x0c00,(((regs[5]&1))<<2)+3); - setchr1r(0x10,0x1000,(((regs[5]&1)^1)<<2)+4); - setchr1r(0x10,0x1400,(((regs[5]&1)^1)<<2)+5); - setchr1r(0x10,0x1800,(((regs[5]&1)^1)<<2)+6); - setchr1r(0x10,0x1c00,(((regs[5]&1)^1)<<2)+7); -*/ -// } -// else -// { -/* - setchr1r(0x10,0x0000,(((regs[5]&1)^1)<<2)+0); - setchr1r(0x10,0x0400,(((regs[5]&1)^1)<<2)+1); - setchr1r(0x10,0x0800,(((regs[5]&1)^1)<<2)+2); - setchr1r(0x10,0x0c00,(((regs[5]&1)^1)<<2)+3); - setchr1r(0x10,0x1000,(((regs[5]&1))<<2)+4); - setchr1r(0x10,0x1400,(((regs[5]&1))<<2)+5); - setchr1r(0x10,0x1800,(((regs[5]&1))<<2)+6); - setchr1r(0x10,0x1c00,(((regs[5]&1))<<2)+7); -// } -//*/ -/* setchr1r(1,0x0000,test[0]); - setchr1r(1,0x0400,test[1]); - setchr1r(1,0x0800,test[2]); - setchr1r(1,0x0c00,test[3]); - setchr1r(1,0x1000,test[4]); - setchr1r(1,0x1400,test[5]); - setchr1r(1,0x1800,test[6]); - setchr1r(1,0x1c00,test[7]); -*/ - setprg4r(0x10, 0x6000, regs[0] & 1); - if (regs[2] >= 0x40) - setprg8r(1, 0x8000, (regs[2] - 0x40)); - else - setprg8r(0, 0x8000, (regs[2] & 0x3F)); - if (regs[3] >= 0x40) - setprg8r(1, 0xA000, (regs[3] - 0x40)); - else - setprg8r(0, 0xA000, (regs[3] & 0x3F)); - if (regs[4] >= 0x40) - setprg8r(1, 0xC000, (regs[4] - 0x40)); - else - setprg8r(0, 0xC000, (regs[4] & 0x3F)); - + setprg4r(0x10, 0x6000, (regs[0] & 1) | (regs[0] >> 2)); + setprg4r(0x10, 0x7000, (regs[1] & 1) | (regs[1] >> 2)); +#ifdef CAI_DEBUG + setprg8(0x8000, regs[2]); + setprg8(0xA000, regs[3]); + setprg8(0xC000, regs[4]); + setprg8(0xE000, ~0); +#else + setprg8r((regs[2] >> 6) & 1, 0x8000, (regs[2] & 0x3F)); + setprg8r((regs[3] >> 6) & 1, 0xA000, (regs[3] & 0x3F)); + setprg8r((regs[4] >> 6) & 1, 0xC000, (regs[4] & 0x3F)); setprg8r(1, 0xE000, ~0); - setmirror(MI_V); +#endif + setmirror(((regs[0xA]&2)>>1)^1); } -/*static DECLFW(TestWrite) -{ - test[A&7] = V; - Sync(); -}*/ - -static DECLFW(M190Write) { -// FCEU_printf("write %04x:%04x %d, %d\n",A,V,scanline,timestamp); +static DECLFW(QTAiWrite) { regs[(A & 0x0F00) >> 8] = V; switch (A) { - case 0xd600: IRQLatch &= 0xFF00; IRQLatch |= V; break; - case 0xd700: IRQLatch &= 0x00FF; IRQLatch |= V << 8; break; - case 0xd900: IRQCount = IRQLatch; IRQa = V & 2; K4IRQ = V & 1; X6502_IRQEnd(FCEU_IQEXT); break; - case 0xd800: IRQa = K4IRQ; X6502_IRQEnd(FCEU_IQEXT); break; + case 0xd600: { + IRQLatch &= 0xFF00; + IRQLatch |= V; + FCEU_printf("irq latch lo=%02x\n", V); + break; + } + case 0xd700: { + IRQLatch &= 0x00FF; + IRQLatch |= V << 8; + FCEU_printf("irq latch hi=%02x\n", V); + break; + } + case 0xd900: { + IRQCount = IRQLatch; + IRQa = V & 2; + K4IRQ = V & 1; + X6502_IRQEnd(FCEU_IQEXT); + FCEU_printf("irq reload\n", V); + break; + } + case 0xd800: { + IRQa = K4IRQ; + X6502_IRQEnd(FCEU_IQEXT); + FCEU_printf("irq stop\n", V); + break; + } + default: + FCEU_printf("write %04x:%04x %d, %d\n", A, V, scanline, timestamp); } Sync(); } -static DECLFR(M190Read) { -// FCEU_printf("read %04x:%04x %d, %d\n",A,regs[(A&0x0F00)>>8],scanline,timestamp); - return regs[(A & 0x0F00) >> 8] + regs[0x0B]; +#ifdef CAI_DEBUG +static DECLFR(DebugExtNT) { + return QTAINTRAM[A & 0x07FF]; } +#endif + +static DECLFR(QTAiRead) { + // OH = conv_tbl[DD00 >> 1][DC00 >> 6] + // OL = ((DC00 & 0x3F) << 2) + DB00 + if (A == 0xDD00) + return conv_tbl[regs[0xD] >> 1][regs[0xC] >> 6]; + else if (A == 0xDC00) + return ((regs[0xC] & 0x3F) << 2) + regs[0xB]; + else + return 0; +} + static void VRC5IRQ(int a) { if (IRQa) { IRQCount += a; @@ -145,50 +203,48 @@ static void VRC5IRQ(int a) { } } -//static void Mapper190_PPU(uint32 A) -//{ -// if(A<0x2000) -// setchr4r(0x10,0x1000,QTAINTRAM[A&0x1FFF]&1); -// else -// chrSync(); -//} - -static DECLFW(M1902007Wrap) { - if (A >= 0x2000) { - if (regs[0xA] & 1) - QTAINTRAM[A & 0x1FFF] = V; - else - old2007wrap(A, V); - } +// debug hack. mapper does not track ppu address himseld, instead the regular ppu offset is used +// these handlers must be moved in ppu code in order to be emulated properly. +// +static DECLFW(QTAi2006Wrap) { + if (regs[0xA] & 1) + qtaintramofs = (qtaintramofs << 8) | V; + else + old2006wrap(0x2006, V); } +static DECLFW(QTAi2007Wrap) { + if (regs[0xA] & 1) { + QTAINTRAM[qtaintramofs & 0x07FF] = V; + qtaintramofs++; + } else + old2007wrap(0x2007, V); +} -static void M190Power(void) { -/* test[0]=0; - test[1]=1; - test[2]=2; - test[3]=3; - test[4]=4; - test[5]=5; - test[6]=6; - test[7]=7; -*/ - setprg4r(0x10, 0x7000, 2); +static void QTAiPower(void) { + QTAIHack = 1; + qtaintramofs = 0; + + old2006wrap = GetWriteHandler(0x2006); old2007wrap = GetWriteHandler(0x2007); - SetWriteHandler(0x2007, 0x2007, M1902007Wrap); + SetWriteHandler(0x2006, 0x2006, QTAi2006Wrap); + SetWriteHandler(0x2007, 0x2007, QTAi2007Wrap); + +#ifdef CAI_DEBUG + SetReadHandler(0x5000, 0x5FFF, DebugExtNT); +#endif SetReadHandler(0x6000, 0xFFFF, CartBR); -// SetWriteHandler(0x5000,0x5007,TestWrite); SetWriteHandler(0x6000, 0x7FFF, CartBW); - SetWriteHandler(0x8000, 0xFFFF, M190Write); - SetReadHandler(0xDC00, 0xDC00, M190Read); - SetReadHandler(0xDD00, 0xDD00, M190Read); + SetWriteHandler(0x8000, 0xFFFF, QTAiWrite); + SetReadHandler(0xDC00, 0xDC00, QTAiRead); + SetReadHandler(0xDD00, 0xDD00, QTAiRead); FCEU_CheatAddRAM(WRAMSIZE >> 10, 0x6000, WRAM); Sync(); } -static void M190Close(void) { +static void QTAiClose(void) { if (CHRRAM) FCEU_gfree(CHRRAM); CHRRAM = NULL; @@ -200,3 +256,26 @@ static void M190Close(void) { static void StateRestore(int version) { Sync(); } + +void QTAi_Init(CartInfo *info) { + info->Power = QTAiPower; + info->Close = QTAiClose; + GameStateRestore = StateRestore; + + MapIRQHook = VRC5IRQ; + + CHRRAM = (uint8*)FCEU_gmalloc(CHRSIZE); + SetupCartCHRMapping(0x10, CHRRAM, CHRSIZE, 1); + AddExState(CHRRAM, CHRSIZE, 0, "CRAM"); + + WRAM = (uint8*)FCEU_gmalloc(WRAMSIZE); + SetupCartPRGMapping(0x10, WRAM, WRAMSIZE, 1); + AddExState(WRAM, WRAMSIZE, 0, "WRAM"); + + if (info->battery) { + info->SaveGame[0] = WRAM; + info->SaveGameLen[0] = WRAMSIZE - 4096; + } + + AddExState(&StateRegs, ~0, 0, 0); +} diff --git a/src/cheat.cpp b/src/cheat.cpp index e6ebbedd..0b8f4166 100644 --- a/src/cheat.cpp +++ b/src/cheat.cpp @@ -61,7 +61,7 @@ void FCEU_CheatAddRAM(int s, uint32 A, uint8 *p) CHEATF_SUBFAST SubCheats[256]; -int numsubcheats=0; +uint32 numsubcheats=0; struct CHEATF *cheats=0,*cheatsl=0; @@ -98,7 +98,7 @@ static DECLFR(SubCheatsRead) void RebuildSubCheats(void) { - int x; + uint32 x; struct CHEATF *c=cheats; for(x=0;x= address && SubCheats[i].addr < address + size) ++count; return count; @@ -945,7 +945,7 @@ void UpdateFrozenList(void) //and make these accessible to other dialogs that deal with memory addresses such as //memwatch, hex editor, ramfilter, etc. - int x; + uint32 x; FrozenAddresses.clear(); //Clear vector and repopulate for(x=0;x{6893EF44-FEA3-46DF-B236-C4C200F54294} fceux Win32Proj - 8.1 + 10.0.15063.0