From f4a5c2a420ef60eaf5662f7b50599dba4c1c6c53 Mon Sep 17 00:00:00 2001 From: NewRisingSun <8vytz1+dhp372pv94ebg@sharklasers.com> Date: Wed, 7 Apr 2021 18:45:37 +0200 Subject: [PATCH] Mapper 332: Add CNROM mode, support larger multicarts --- src/boards/super40in1.c | 49 ++++++++++++++++++++++++++++++++--------- 1 file changed, 39 insertions(+), 10 deletions(-) diff --git a/src/boards/super40in1.c b/src/boards/super40in1.c index ef5a5e1..3de6804 100644 --- a/src/boards/super40in1.c +++ b/src/boards/super40in1.c @@ -23,43 +23,72 @@ #include "mapinc.h" -static uint8 preg, creg; +static uint8 preg, creg, latch, dipSwitch; static SFORMAT StateRegs[] = { { &preg, 1, "PREG" }, { &creg, 1, "CREG" }, + { &latch, 1, "LATC" }, + { &dipSwitch, 1, "DPSW" }, { 0 } }; static void Sync(void) { + int prg = (preg & 7) | ((preg >> 3) & 0x08); // There is a high bit 3 of the PRG register that applies both to PRG and CHR if (preg & 8) { - setprg16(0x8000, preg & 7); - setprg16(0xc000, preg & 7); + setprg16(0x8000, prg); + setprg16(0xc000, prg); } else - setprg32(0x8000, (preg & 6) >> 1); - setchr8(creg); + setprg32(0x8000, prg >> 1); + + int chr = (creg & 7) | ((preg >> 3) & 0x08); // There is a high bit 3 of the PRG register that applies both to PRG and CHR + int mask = (creg & 0x10)? 0: (creg & 0x20)? 1: 3; // There is an CNROM mode that takes either two or four inner CHR banks from a CNROM-like latch register at $8000-$FFFF. + setchr8((chr &~mask) | (latch &mask)); // This "inner CHR bank" substitutes the respective bit(s) of the creg register. + setmirror(((preg >> 4) & 1) ^ 1); } +static DECLFR(BMCWSRead) { + if ((creg >> 6) & (dipSwitch &3)) + return X.DB; + else + return CartBR(A); +} + static DECLFW(BMCWSWrite) { if (preg & 0x20) return; switch (A & 1) { - case 0: preg = V; Sync(); break; - case 1: creg = V; Sync(); break; + case 0: preg = V; Sync(); break; + case 1: creg = V; Sync(); break; } } -static void MBMCWSPower(void) { +static DECLFW(LatchWrite) { + latch =V; Sync(); - SetReadHandler(0x8000, 0xFFFF, CartBR); - SetWriteHandler(0x6000, 0x6001, BMCWSWrite); +} + +static void MBMCWSPower(void) { + dipSwitch =0; + Sync(); + SetReadHandler(0x8000, 0xFFFF, BMCWSRead); + SetWriteHandler(0x6000, 0x7FFF, BMCWSWrite); + SetWriteHandler(0x8000, 0xFFFF, LatchWrite); } static void BMCWSReset(void) { + dipSwitch++; // Soft-resetting cycles through solder pad or DIP switch settings + if (dipSwitch == 3) dipSwitch = 0; // Only 00b, 01b and 10b settings are valid + + // Always reset to menu + preg =0; + creg =0; + latch =0; + Sync(); } static void StateRestore(int version) {