Merge pull request #505 from NRS-NewRisingSun/mappers

Updates to mappers 256, 289, 344, 432.
This commit is contained in:
Autechre
2022-03-01 19:20:50 +01:00
committed by GitHub
5 changed files with 152 additions and 96 deletions

View File

@@ -32,18 +32,19 @@ static void M432CW(uint32 A, uint8 V) {
static void M432PW(uint32 A, uint8 V) {
int prgAND = (EXPREGS[1] & 0x02) ? 0x0F : 0x1F;
int prgOR = ((EXPREGS[1] << 4) & 0x10) | (EXPREGS[1] << 1) & 0x20;
if ((A < 0xC000) || (~EXPREGS[1] & 0x40)) setprg8(A, (V & prgAND) | (prgOR & ~prgAND));
if ((A < 0xC000) && (EXPREGS[1] & 0x40)) setprg8(A | 0x4000, (V & prgAND) | (prgOR & ~prgAND));
if ((A < 0xC000) || (~EXPREGS[1] & 0x40)) setprg8(A, (V & prgAND) | (prgOR & ~prgAND) & (EXPREGS[1] & 0x80?~2:~0));
if ((A < 0xC000) && (EXPREGS[1] & 0x40)) setprg8(A | 0x4000, (V & prgAND) | (prgOR & ~prgAND) | (EXPREGS[1] & 0x80? 2: 0));
}
static DECLFR(M432Read) {
if (EXPREGS[0] & 1)
if (EXPREGS[0] & 1 || EXPREGS[1] & 0x20)
return EXPREGS[2];
return CartBR(A);
}
static DECLFW(M432Write) {
EXPREGS[A & 1] = V;
if (~A &1 && ~V &1) EXPREGS[1] =0; /* Writing 0 to register 0 clears register 1 */
FixMMC3PRG(MMC3_cmd);
FixMMC3CHR(MMC3_cmd);
}
@@ -51,7 +52,7 @@ static DECLFW(M432Write) {
static void M432Reset(void) {
EXPREGS[0] = 0;
EXPREGS[1] = 0;
EXPREGS[2] = (EXPREGS[2] +1) & 3;
EXPREGS[2]++;
MMC3RegReset();
}

View File

@@ -24,79 +24,51 @@
#include "mapinc.h"
static uint8 inner_bank, outer_bank, mode;
static uint8 latch, reg[2];
static SFORMAT StateRegs[] =
{
{ &inner_bank, 1, "INB0" },
{ &outer_bank, 1, "OUTB" },
{ &mode, 1, "MODE" },
{ &latch, 1, "LATC" },
{ reg, 2, "REGS" },
{ 0 }
};
static void Sync(void) {
uint8 bbank = (mode & 4) ? 0 : (inner_bank & 7);
uint8 bank = outer_bank | bbank;
uint8 preg[2];
/* 0: NROM-128: Same inner/outer 16 KiB bank at CPU $8000-$BFFF
* and $C000-$FFFF
* 1: NROM-256: 32 kiB bank at CPU $8000-$FFFF (Selected inner/outer bank SHR 1)
* 2: UNROM: Inner/outer bank at CPU $8000-BFFF,
* fixed inner bank 7 within outer bank at $C000-$FFFF
* 3: Unknown
*
* The combined inner/outer bank is simply the inner bank, selected by the
* latch at $8000-$FFFF (or 0 if the latch is disabled) ORed with the
* outer bank selected by $6001, without any bit shifting.
*/
preg[0] = bank;
preg[1] = 0;
switch (mode & 3) {
case 0x00:
case 0x01:
preg[1] = bank | ((mode & 1) ? 1 : 0);
break;
case 0x02:
preg[1] = outer_bank | 7;
case 0x03:
break;
if (reg[0] &2) { /* UNROM */
setprg16(0x8000, latch &7 | reg[1] &~7);
setprg16(0xC000, 7 | reg[1] &~7);
} else
if (reg[0] &1) /* NROM-256 */
setprg32(0x8000, reg[1] >>1);
else { /* NROM-128 */
setprg16(0x8000, reg[1]);
setprg16(0xC000, reg[1]);
}
SetupCartCHRMapping(0, CHRptr[0], 0x2000, !(reg[0] &4)); /* CHR-RAM write-protect */
setchr8(0);
setprg16(0x8000, preg[0]);
setprg16(0xC000, preg[1]);
setmirror(((mode & 8) >> 3) ^ 1);
setmirror(!(reg[0] &8));
}
static DECLFW(Write0) {
mode = V;
static DECLFW(WriteReg) {
reg[A &1] =V;
Sync();
}
static DECLFW(Write1) {
outer_bank = V;
Sync();
}
static DECLFW(Write8) {
inner_bank = V;
static DECLFW(WriteLatch) {
latch = V;
Sync();
}
static void BMC60311CPower(void) {
inner_bank = outer_bank = mode = 0;
latch =reg[0] =reg[1] =0;
Sync();
SetReadHandler(0x8000, 0xFFFF, CartBR);
SetWriteHandler(0x6000, 0x6000, Write0);
SetWriteHandler(0x6001, 0x6001, Write1);
SetWriteHandler(0x8000, 0xFFFF, Write8);
SetWriteHandler(0x6000, 0x6001, WriteReg);
SetWriteHandler(0x8000, 0xFFFF, WriteLatch);
}
static void BMC60311CReset(void) {
inner_bank = outer_bank = mode = 0;
latch =reg[0] =reg[1] =0;
Sync();
}

View File

@@ -27,26 +27,25 @@
#include "mmc3.h"
static void BMCGN26CW(uint32 A, uint8 V) {
uint32 base = (EXPREGS[0] & 0x03) << 7;
setchr1(A, base | (V & 0xFF));
int chrAND = EXPREGS[0]&0x04? 0xFF: 0x7F;
int chrOR = EXPREGS[0] <<7;
setchr1(A, V &chrAND | chrOR &~chrAND);
}
static void BMCGN26PW(uint32 A, uint8 V) {
/* Re-ordered -> 0:SF4 1:Contra Force 2:Revolution Hero */
uint32 table[] = { 0, 0, 1, 2 };
uint32 base = table[(EXPREGS[0] & 0x03)];
if (EXPREGS[0] & 4) {
if (A == 0x8000)
setprg32(0x8000, (base << 2) | (V >> 2));
setprg32(0x8000, (EXPREGS[0] << 2) | (V >> 2));
} else
setprg8(A, (base << 4) | (V & 0x0F));
setprg8(A, (EXPREGS[0] << 4) | (V & 0x0F));
}
static DECLFW(BMCGN26Write) {
EXPREGS[0] = A & 0x0F;
FixMMC3PRG(MMC3_cmd);
FixMMC3CHR(MMC3_cmd);
if (A001B &0x80 && ~A001B &0x40) {
EXPREGS[0] = A;
FixMMC3PRG(MMC3_cmd);
FixMMC3CHR(MMC3_cmd);
}
}
static void BMCGN26Reset(void) {
@@ -56,7 +55,7 @@ static void BMCGN26Reset(void) {
static void BMCGN26Power(void) {
GenMMC3Power();
SetWriteHandler(0x6800, 0x68FF, BMCGN26Write);
SetWriteHandler(0x6000, 0x7FFF, BMCGN26Write);
}
void BMCGN26_Init(CartInfo *info) {

View File

@@ -474,27 +474,33 @@ void Mapper44_Init(CartInfo *info) {
/* ---------------------------- Mapper 45 ------------------------------- */
static void M45CW(uint32 A, uint8 V) {
if (!UNIFchrrama) {
uint32 NV = V;
if (EXPREGS[2] & 8)
NV &= (1 << ((EXPREGS[2] & 7) + 1)) - 1;
else
if (EXPREGS[2])
NV &= 0; /* hack ;( don't know exactly how it should be */
NV |= EXPREGS[0] | ((EXPREGS[2] & 0xF0) << 4);
setchr1(A, NV);
} else
/* setchr8(0); */ /* i don't know what cart need this, but a new one need other lol */
if (CHRsize[0] ==8192)
setchr1(A, V);
else {
int chrAND =0xFF >>(~EXPREGS[2] &0xF);
int chrOR =EXPREGS[0] | EXPREGS[2] <<4 &0xF00;
setchr1(A, V &chrAND | chrOR &~chrAND);
}
}
static DECLFR(M45ReadOB) {
return X.DB;
}
static void M45PW(uint32 A, uint8 V) {
uint32 MV = V & ((EXPREGS[3] & 0x3F) ^ 0x3F);
MV |= EXPREGS[1];
if(UNIFchrrama)
MV |= ((EXPREGS[2] & 0x40) << 2);
setprg8(A, MV);
/* FCEU_printf("1:%02x 2:%02x 3:%02x A=%04x V=%03x\n",EXPREGS[1],EXPREGS[2],EXPREGS[3],A,MV); */
int prgAND =~EXPREGS[3] &0x3F;
int prgOR =EXPREGS[1] | EXPREGS[2] <<2 &0x300;
setprg8(A, V &prgAND | prgOR &~prgAND);
/* Some multicarts select between five different menus by connecting one of the higher address lines to PRG /CE.
The menu code selects between menus by checking which of the higher address lines disables PRG-ROM when set. */
if (PRGsize[0] <0x200000 && EXPREGS[5] ==1 && EXPREGS[1] &0x80 ||
PRGsize[0] <0x200000 && EXPREGS[5] ==2 && EXPREGS[2] &0x40 ||
PRGsize[0] <0x100000 && EXPREGS[5] ==3 && EXPREGS[1] &0x40 ||
PRGsize[0] <0x100000 && EXPREGS[5] ==4 && EXPREGS[2] &0x20)
SetReadHandler(0x8000, 0xFFFF, M45ReadOB);
else
SetReadHandler(0x8000, 0xFFFF, CartBR);
}
static DECLFW(M45Write) {

View File

@@ -27,6 +27,8 @@
#include "mapinc.h"
static uint8 submapper;
/* General Purpose Registers */
static uint8 cpu410x[16], ppu201x[16], apu40xx[64];
@@ -35,9 +37,6 @@ static uint8 IRQCount, IRQa, IRQReload;
#define IRQLatch cpu410x[0x1] /* accc cccc, a = 0, AD12 switching, a = 1, HSYNC switching */
/* MMC3 Registers */
static uint8 inv_hack = 0; /* some OneBus Systems have swapped PRG reg commans in MMC3 inplementation,
* trying to autodetect unusual behavior, due not to add a new mapper.
*/
#define mmc3cmd cpu410x[0x5] /* pcv- ----, p - program swap, c - video swap, v - internal VRAM enable */
#define mirror cpu410x[0x6] /* ---- ---m, m = 0 - H, m = 1 - V */
@@ -65,6 +64,8 @@ static SFORMAT StateRegs[] =
{ 0 }
};
static uint8 *WRAM;
static void PSync(void) {
uint8 bankmode = cpu410x[0xb] & 7;
uint8 mask = (bankmode == 0x7) ? (0xff) : (0x3f >> bankmode);
@@ -77,8 +78,8 @@ static void PSync(void) {
uint8 bank2 = (cpu410x[0xb] & 0x40)?(cpu410x[0x9]):(~1);
uint8 bank3 = ~0;
#endif
uint8 bank0 = cpu410x[0x7 ^ inv_hack];
uint8 bank1 = cpu410x[0x8 ^ inv_hack];
uint8 bank0 = cpu410x[0x7];
uint8 bank1 = cpu410x[0x8];
uint8 bank2 = (cpu410x[0xb] & 0x40) ? (cpu410x[0x9]) : (~1);
uint8 bank3 = ~0;
@@ -124,29 +125,91 @@ static void Sync(void) {
CSync();
}
static const uint8 cpuMangle[16][4] = {
{ 0, 1, 2, 3 }, /* Submapper 0: Normal */
{ 0, 1, 2, 3 }, /* Submapper 1: Waixing VT03 */
{ 1, 0, 2, 3 }, /* Submapper 2: Trump Grand */
{ 0, 1, 2, 3 }, /* Submapper 3: Zechess */
{ 0, 1, 2, 3 }, /* Submapper 4: Qishenglong */
{ 0, 1, 2, 3 }, /* Submapper 5: Waixing VT02 */
{ 0, 1, 2, 3 }, /* Submapper 6: unused so far */
{ 0, 1, 2, 3 }, /* Submapper 7: unused so far */
{ 0, 1, 2, 3 }, /* Submapper 8: unused so far */
{ 0, 1, 2, 3 }, /* Submapper 9: unused so far */
{ 0, 1, 2, 3 }, /* Submapper A: unused so far */
{ 0, 1, 2, 3 }, /* Submapper B: unused so far */
{ 0, 1, 2, 3 }, /* Submapper C: unused so far */
{ 0, 1, 2, 3 }, /* Submapper D: Cube Tech (CPU opcode encryption only) */
{ 0, 1, 2, 3 }, /* Submapper E: Karaoto (CPU opcode encryption only) */
{ 0, 1, 2, 3 } /* Submapper F: Jungletac (CPU opcode encryption only) */
};
static DECLFW(UNLOneBusWriteCPU410X) {
/* FCEU_printf("CPU %04x:%04x\n",A,V); */
switch (A & 0xf) {
A &=0xF;
switch (A) {
case 0x1: IRQLatch = V & 0xfe; break; /* íå ïî äàòàøèòó */
case 0x2: IRQReload = 1; break;
case 0x3: X6502_IRQEnd(FCEU_IQEXT); IRQa = 0; break;
case 0x4: IRQa = 1; break;
default:
cpu410x[A & 0xf] = V;
if (A >=0x7 && A <=0xA) A =0x7 +cpuMangle[submapper][A -0x7];
cpu410x[A] = V;
Sync();
}
}
static const uint8 ppuMangle[16][6] = {
{ 0, 1, 2, 3, 4, 5 }, /* Submapper 0: Normal */
{ 1, 0, 5, 4, 3, 2 }, /* Submapper 1: Waixing VT03 */
{ 0, 1, 2, 3, 4, 5 }, /* Submapper 2: Trump Grand */
{ 5, 4, 3, 2, 0, 1 }, /* Submapper 3: Zechess */
{ 2, 5, 0, 4, 3, 1 }, /* Submapper 4: Qishenglong */
{ 1, 0, 5, 4, 3, 2 }, /* Submapper 5: Waixing VT02 */
{ 0, 1, 2, 3, 4, 5 }, /* Submapper 6: unused so far */
{ 0, 1, 2, 3, 4, 5 }, /* Submapper 7: unused so far */
{ 0, 1, 2, 3, 4, 5 }, /* Submapper 8: unused so far */
{ 0, 1, 2, 3, 4, 5 }, /* Submapper 9: unused so far */
{ 0, 1, 2, 3, 4, 5 }, /* Submapper A: unused so far */
{ 0, 1, 2, 3, 4, 5 }, /* Submapper B: unused so far */
{ 0, 1, 2, 3, 4, 5 }, /* Submapper C: unused so far */
{ 0, 1, 2, 3, 4, 5 }, /* Submapper D: Cube Tech (CPU opcode encryption only) */
{ 0, 1, 2, 3, 4, 5 }, /* Submapper E: Karaoto (CPU opcode encryption only) */
{ 0, 1, 2, 3, 4, 5 } /* Submapper F: Jungletac (CPU opcode encryption only) */
};
static DECLFW(UNLOneBusWritePPU201X) {
/* FCEU_printf("PPU %04x:%04x\n",A,V); */
ppu201x[A & 0x0f] = V;
A &=0x0F;
if (A >=2 && A <=7) A =2 +ppuMangle[submapper][A -2];
ppu201x[A] = V;
Sync();
}
static const uint8 mmc3Mangle[16][8] = {
{ 0, 1, 2, 3, 4, 5, 6, 7 }, /* Submapper 0: Normal */
{ 5, 4, 3, 2, 1, 0, 6, 7 }, /* Submapper 1: Waixing VT03 */
{ 0, 1, 2, 3, 4, 5, 7, 6 }, /* Submapper 2: Trump Grand */
{ 0, 1, 2, 3, 4, 5, 6, 7 }, /* Submapper 3: Zechess */
{ 0, 1, 2, 3, 4, 5, 6, 7 }, /* Submapper 4: Qishenglong */
{ 0, 1, 2, 3, 4, 5, 6, 7 }, /* Submapper 5: Waixing VT02 */
{ 0, 1, 2, 3, 4, 5, 6, 7 }, /* Submapper 6: unused so far */
{ 0, 1, 2, 3, 4, 5, 6, 7 }, /* Submapper 7: unused so far */
{ 0, 1, 2, 3, 4, 5, 6, 7 }, /* Submapper 8: unused so far */
{ 0, 1, 2, 3, 4, 5, 6, 7 }, /* Submapper 9: unused so far */
{ 0, 1, 2, 3, 4, 5, 6, 7 }, /* Submapper A: unused so far */
{ 0, 1, 2, 3, 4, 5, 6, 7 }, /* Submapper B: unused so far */
{ 0, 1, 2, 3, 4, 5, 6, 7 }, /* Submapper C: unused so far */
{ 0, 1, 2, 3, 4, 5, 6, 7 }, /* Submapper D: Cube Tech (CPU opcode encryption only) */
{ 0, 1, 2, 3, 4, 5, 6, 7 }, /* Submapper E: Karaoto (CPU opcode encryption only) */
{ 0, 1, 2, 3, 4, 5, 6, 7 } /* Submapper F: Jungletac (CPU opcode encryption only) */
};
static DECLFW(UNLOneBusWriteMMC3) {
/* FCEU_printf("MMC %04x:%04x\n",A,V); */
switch (A & 0xe001) {
case 0x8000: mmc3cmd = (mmc3cmd & 0x38) | (V & 0xc7); Sync(); break;
case 0x8000:
V =V &0xF8 | mmc3Mangle[submapper][V &0x07];
mmc3cmd = (mmc3cmd & 0x38) | (V & 0xc7);
Sync();
break;
case 0x8001:
{
switch (mmc3cmd & 7) {
@@ -263,11 +326,14 @@ static void UNLOneBusPower(void) {
SetReadHandler(0x4000, 0x403f, UNLOneBusReadAPU40XX);
SetWriteHandler(0x4000, 0x403f, UNLOneBusWriteAPU40XX);
SetReadHandler(0x8000, 0xFFFF, CartBR);
SetReadHandler(0x6000, 0xFFFF, CartBR);
SetWriteHandler(0x6000, 0x7FFF, CartBW);
SetWriteHandler(0x2010, 0x201f, UNLOneBusWritePPU201X);
SetWriteHandler(0x4100, 0x410f, UNLOneBusWriteCPU410X);
SetWriteHandler(0x8000, 0xffff, UNLOneBusWriteMMC3);
FCEU_CheatAddRAM(8, 0x6000, WRAM);
setprg8r(0x10, 0x6000, 0);
Sync();
}
@@ -285,16 +351,28 @@ static void StateRestore(int version) {
Sync();
}
void UNLOneBus_Close(void) {
if (WRAM)
FCEU_gfree(WRAM);
WRAM = NULL;
}
void UNLOneBus_Init(CartInfo *info) {
info->Power = UNLOneBusPower;
info->Reset = UNLOneBusReset;
info->Close = UNLOneBus_Close;
if (((*(uint32*)&(info->MD5)) == 0x305fcdc3) || /* PowerJoy Supermax Carts */
((*(uint32*)&(info->MD5)) == 0x6abfce8e))
inv_hack = 0xf;
if (info->iNES2)
submapper =info->submapper;
else
submapper =(((*(uint32*)&(info->MD5)) == 0x305fcdc3) || ((*(uint32*)&(info->MD5)) == 0x6abfce8e))? 2: 0; /* PowerJoy Supermax Carts */
GameHBIRQHook = UNLOneBusIRQHook;
MapIRQHook = UNLOneBusCpuHook;
GameStateRestore = StateRestore;
AddExState(&StateRegs, ~0, 0, 0);
WRAM = (uint8*)FCEU_gmalloc(8192);
SetupCartPRGMapping(0x10, WRAM, 8192, 1);
}