📄 h_mmc5.c
字号:
#include "h_MMC5.h"
#include "Sound\s_MMC5.h"
TMMC5 MMC5;
void MMC5_Init (void)
{
u8 x;
MP->SetReadHandler(0x5,MMC5_Read);
MP->SetWriteHandler(0x5,MMC5_Write);
MMC5.PRG_Write_6789ABCDEF = MP->GetWriteHandler(0x8);
for (x = 6; x <= 0xF; x++)
MP->SetWriteHandler(x,MMC5_WritePRG);
MP->Mirror_4();
MMC5.NameTable0 = MP->GetCHR_Ptr1(0x8);
MMC5.NameTable1 = MP->GetCHR_Ptr1(0x9);
MMC5.ExRAM = MP->GetCHR_Ptr1(0xA);
MMC5.ExNameTable = MP->GetCHR_Ptr1(0xB);
MMC5.PRGsize = 3;
MMC5.CHRsize = 0;
MMC5.IRQenabled = MMC5.IRQreads = MMC5.IRQline = 0;
MMC5.Mul1 = MMC5.Mul2 = MMC5.GfxMode = 0;
MMC5.SplitMode = MMC5.SplitBank = MMC5.SplitScroll = 0;
for (x = 0; x < 8; x++) MMC5.CHR_A[x] = x;
for (x = 0; x < 4; x++) MMC5.CHR_B[x] = x;
for (x = 0; x < 2; x++) MMC5.WRAMprot[x] = 0;
for (x = 0; x < 4; x++)
{
u8 y = x | 4;
MMC5.WRAMtable[MMC5WRAM_0KB_0KB][x] =
MMC5.WRAMtable[MMC5WRAM_0KB_8KB][x] =
MMC5.WRAMtable[MMC5WRAM_0KB_32KB][x] = -1;
MMC5.WRAMtable[MMC5WRAM_0KB_0KB][y] =
MMC5.WRAMtable[MMC5WRAM_8KB_0KB][y] =
MMC5.WRAMtable[MMC5WRAM_32KB_0KB][y] = -1;
MMC5.WRAMtable[MMC5WRAM_8KB_0KB][x] =
MMC5.WRAMtable[MMC5WRAM_8KB_8KB][x] =
MMC5.WRAMtable[MMC5WRAM_8KB_32KB][x] = 0;
MMC5.WRAMtable[MMC5WRAM_0KB_8KB][y] =
MMC5.WRAMtable[MMC5WRAM_8KB_8KB][y] =
MMC5.WRAMtable[MMC5WRAM_32KB_8KB][y] = 1;
MMC5.WRAMtable[MMC5WRAM_32KB_0KB][x] =
MMC5.WRAMtable[MMC5WRAM_32KB_8KB][x] =
MMC5.WRAMtable[MMC5WRAM_32KB_32KB][x] = x;
MMC5.WRAMtable[MMC5WRAM_0KB_32KB][y] =
MMC5.WRAMtable[MMC5WRAM_8KB_32KB][y] =
MMC5.WRAMtable[MMC5WRAM_32KB_32KB][y] = y;
}
for (x = 0; x < 5; x++) MMC5.PRG[x] = 0xFF;
MMC5.UpdateCache = 0;
MMC5.DrawStatus = 2;
MMC5.TileCache = 0x40;
MMC5sound_Init();
MMC5_SyncPRG();
}
void MMC5_Destroy (void)
{
MMC5sound_Destroy();
}
int MMC5_SaveMI (Ar128 MI, int x)
{
u8 i;
MI[x++] = MMC5.PRGsize;
MI[x++] = MMC5.CHRsize;
MI[x++] = MMC5.IRQenabled;
MI[x++] = MMC5.IRQreads;
MI[x++] = MMC5.IRQline;
MI[x++] = MMC5.Mul1;
MI[x++] = MMC5.Mul2;
MI[x++] = MMC5.GfxMode;
for (i = 0; i < 8; i++) MI[x++] = MMC5.CHR_A[i];
for (i = 0; i < 4; i++) MI[x++] = MMC5.CHR_B[i];
for (i = 0; i < 5; i++) MI[x++] = MMC5.PRG[i];
for (i = 0; i < 2; i++) MI[x++] = MMC5.WRAMprot[i];
MI[x++] = MMC5.SplitMode;
MI[x++] = MMC5.SplitBank;
MI[x++] = MMC5.SplitScroll;
x = MMC5sound_SaveMI(MI,x);
return x;
}
int MMC5_LoadMI (const Ar128 MI, int x)
{
u8 i;
MMC5.PRGsize = MI[x++];
MMC5.CHRsize = MI[x++];
MMC5.IRQenabled = MI[x++];
MMC5.IRQreads = MI[x++];
MMC5.IRQline = MI[x++];
MMC5.Mul1 = MI[x++];
MMC5.Mul2 = MI[x++];
MMC5.GfxMode = MI[x++];
for (i = 0; i < 8; i++) MMC5.CHR_A[i] = MI[x++];
for (i = 0; i < 4; i++) MMC5.CHR_B[i] = MI[x++];
for (i = 0; i < 5; i++) MMC5.PRG[i] = MI[x++];
for (i = 0; i < 2; i++) MMC5.WRAMprot[i] = MI[x++];
MMC5.SplitMode = MI[x++];
MMC5.SplitBank = MI[x++];
MMC5.SplitScroll = MI[x++];
x = MMC5sound_LoadMI(MI,x);
MMC5_SyncPRG();
return x;
}
void MMC5_SetPRG (int Size, int Loc, int Bank)
{
u8 x;
if (Bank & 0x80)
{
if (Size == 8) MP->SetPRG_ROM8(Loc,Bank);
else if (Size == 16) MP->SetPRG_ROM16(Loc,Bank >> 1);
else if (Size == 32) MP->SetPRG_ROM32(Loc,Bank >> 2);
}
else
{
if (Size == 8)
{
if (MMC5.WRAMtable[MMC5.WRAMsize][Bank & 0x7] == -1)
for (x = Loc; x < Loc + 2; x++)
MP->SetPRG_OB4(x);
else MP->SetPRG_RAM8(Loc,MMC5.WRAMtable[MMC5.WRAMsize][Bank & 0x7]);
}
else if (Size == 16)
{
if (MMC5.WRAMtable[MMC5.WRAMsize][Bank & 0x6] == -1)
for (x = Loc; x < Loc + 4; x++)
MP->SetPRG_OB4(x);
else
{
MP->SetPRG_RAM8(Loc+0,MMC5.WRAMtable[MMC5.WRAMsize][(Bank & 0x6) | 0]);
MP->SetPRG_RAM8(Loc+2,MMC5.WRAMtable[MMC5.WRAMsize][(Bank & 0x6) | 1]);
}
}
}
}
void MMC5_SyncPRG (void)
{
MMC5_SetPRG( 8,0x6,MMC5.PRG[0] & 0x7F);
switch (MMC5.PRGsize)
{
case 0: MMC5_SetPRG(32,0x8,MMC5.PRG[4] | 0x80); break;
case 1: MMC5_SetPRG(16,0x8,MMC5.PRG[2] );
MMC5_SetPRG(16,0xC,MMC5.PRG[4] | 0x80); break;
case 2: MMC5_SetPRG(16,0x8,MMC5.PRG[2] );
MMC5_SetPRG( 8,0xC,MMC5.PRG[3] );
MMC5_SetPRG( 8,0xE,MMC5.PRG[4] | 0x80); break;
case 3: MMC5_SetPRG( 8,0x8,MMC5.PRG[1] );
MMC5_SetPRG( 8,0xA,MMC5.PRG[2] );
MMC5_SetPRG( 8,0xC,MMC5.PRG[3] );
MMC5_SetPRG( 8,0xE,MMC5.PRG[4] | 0x80); break;
}
}
void MMC5_SyncCHRA (int Bank)
{
switch (MMC5.CHRsize)
{
case 0: MP->SetCHR_ROM8(0 ,MMC5.CHR_A[7 ]); break;
case 1: MP->SetCHR_ROM4(0 | Bank,MMC5.CHR_A[3 | Bank]); break;
case 2: MP->SetCHR_ROM2(0 | Bank,MMC5.CHR_A[1 | Bank]);
MP->SetCHR_ROM2(2 | Bank,MMC5.CHR_A[3 | Bank]); break;
case 3: MP->SetCHR_ROM1(0 | Bank,MMC5.CHR_A[0 | Bank]);
MP->SetCHR_ROM1(1 | Bank,MMC5.CHR_A[1 | Bank]);
MP->SetCHR_ROM1(2 | Bank,MMC5.CHR_A[2 | Bank]);
MP->SetCHR_ROM1(3 | Bank,MMC5.CHR_A[3 | Bank]); break;
}
}
void MMC5_SyncCHRB (int Bank)
{
switch (MMC5.CHRsize)
{
case 0: MP->SetCHR_ROM8(0 ,MMC5.CHR_B[3]);break;
case 1: MP->SetCHR_ROM4(0 | Bank,MMC5.CHR_B[3]);break;
case 2: MP->SetCHR_ROM2(0 | Bank,MMC5.CHR_B[1]);
MP->SetCHR_ROM2(2 | Bank,MMC5.CHR_B[3]);break;
case 3: MP->SetCHR_ROM1(0 | Bank,MMC5.CHR_B[0]);
MP->SetCHR_ROM1(1 | Bank,MMC5.CHR_B[1]);
MP->SetCHR_ROM1(2 | Bank,MMC5.CHR_B[2]);
MP->SetCHR_ROM1(3 | Bank,MMC5.CHR_B[3]);break;
}
}
void MMC5_SyncMirror (void)
{
MP->Mirror_Custom(
(MMC5.Mirror >> 0) & 3,
(MMC5.Mirror >> 2) & 3,
(MMC5.Mirror >> 4) & 3,
(MMC5.Mirror >> 6) & 3);
}
int __cdecl MMC5_Read (int Bank, int Where)
{
u8 read = 0xFF;
switch (Where & 0xF00)
{
case 0x200:
switch (Where)
{
case 0x204: read = MMC5.IRQreads;
MMC5.IRQreads &= 0x40;
if (!MMC5.IRQenabled)
MMC5.IRQreads = 0; break;
case 0x205: read = ((MMC5.Mul1 * MMC5.Mul2) & 0x00FF) >> 0; break;
case 0x206: read = ((MMC5.Mul1 * MMC5.Mul2) & 0xFF00) >> 8; break;
} break;
case 0xC00:
case 0xD00:
case 0xE00:
case 0xF00: if (MMC5.GfxMode != 1)
read = MMC5.ExRAM[Where & 0x3FF]; break;
}
return read;
}
void __cdecl MMC5_Write (int Bank, int Where, int What)
{
switch (Where & 0xF00)
{
case 0x000: MMC5sound_Write((Bank << 12) | Where,What); break;
case 0x100:
switch (Where)
{
case 0x100: MMC5.PRGsize = What & 3;
MMC5_SyncPRG(); break;
case 0x101: MMC5.CHRsize = What & 3;
/*MMC5_SyncCHRA(0); MMC5_SyncCHRA(4);*/
break;
case 0x102: MMC5.WRAMprot[0] = What & 3;
break;
case 0x103: MMC5.WRAMprot[1] = What & 3;
break;
case 0x104: MMC5.GfxMode = What & 3;
MMC5.UpdateCache = 1; break;
case 0x105: MMC5.Mirror = What;
MMC5_SyncMirror(); break;
case 0x106: memset(MMC5.ExNameTable,What,0x3C0);
break;
case 0x107: memset(MMC5.ExNameTable+0x3C0,((What & 3) |
((What & 3) << 2) | ((What & 3) << 4) |
((What & 3) << 6)),0x3C);
break;
case 0x113:
case 0x114:
case 0x115:
case 0x116:
case 0x117: MMC5.PRG[Where - 0x113] = What;
MMC5_SyncPRG(); break;
case 0x120:
case 0x121:
case 0x122:
case 0x123:
case 0x124:
case 0x125:
case 0x126:
case 0x127: MMC5.CHR_A[Where & 0x7] = What;
MMC5_SyncCHRA(0);
MMC5_SyncCHRA(4); break;
case 0x128:
case 0x129:
case 0x12A:
case 0x12B: MMC5.CHR_B[Where & 0x3] = What;
MMC5_SyncCHRB(0);
MMC5_SyncCHRB(4); break;
case 0x130: /* nobody knows... */ break;
} break;
case 0x200:
switch (Where)
{
case 0x200: MMC5.SplitMode = What; break;
case 0x201: MMC5.SplitScroll = What;break;
case 0x202: MMC5.SplitBank = What; break;
case 0x203: MMC5.IRQline = What; break;
case 0x204: MMC5.IRQenabled = What; break;
case 0x205: MMC5.Mul1 = What; break;
case 0x206: MMC5.Mul2 = What; break;
} break;
case 0xC00:
case 0xD00:
case 0xE00:
case 0xF00: if (MMC5.GfxMode != 3)
MMC5.ExRAM[Where & 0x3FF] = What;
if (MMC5.GfxMode == 1)
MMC5.UpdateCache = 1; break;
}
}
void __cdecl MMC5_WritePRG (int Bank, int Where, int What)
{
if ((MMC5.WRAMprot[0] == 2) && (MMC5.WRAMprot[1] == 1))
MMC5.PRG_Write_6789ABCDEF(Bank,Where,What);
}
static u8 VScroll;
int __cdecl MMC5_TileHandler (int Bank, int TileNum, int Index)
{
unsigned char Palette;
if (Index == -1)
{
if ((MMC5.DrawStatus == 1) && (MMC5.DrawBank == Bank))
return 0;
MMC5.DrawStatus = 1;
MMC5.DrawBank = Bank;
MMC5_SyncCHRA(Bank);
return 1;
}
else
{
MMC5.CurTile++;
if ((MMC5.GfxMode < 2) && (MMC5.SplitMode & 0x80) && (MMC5.CurTile < 0x20))
{
if (((~MMC5.SplitMode & 0x40) && (MMC5.CurTile == 0)) || ((MMC5.SplitMode & 0x40) && (MMC5.CurTile == (MMC5.SplitMode & 0x1F))))
{
MP->Mirror_Custom(2,2,2,2);
MP->SetCHR_ROM4(Bank,MMC5.SplitBank & 0x3F);
return 1;
}
else if ((~MMC5.SplitMode & 0x40) && (MMC5.CurTile == 1 + (MMC5.SplitMode & 0x1F)))
{
MMC5_SyncMirror();
MMC5_SyncCHRB(Bank);
}
}
if (MMC5.CurTile == 0x20)
{
MMC5_SyncMirror();
MMC5_SyncCHRB(Bank);
}
if (MMC5.GfxMode == 1)
{
int ExRAM = MMC5.ExRAM[Index];
if (MMC5.TileCache != (ExRAM & 0x3F))
MP->SetCHR_ROM4(Bank,MMC5.TileCache = ExRAM & 0x3F);
Palette = ((ExRAM & 0xC0) >> 6) * 0x55;
MMC5.NameTable0[0x3C0 | ((Index & 0x1C) >> 2) | ((Index & 0x380) >> 4)] = Palette;
MMC5.NameTable1[0x3C0 | ((Index & 0x1C) >> 2) | ((Index & 0x380) >> 4)] = Palette;
return 1;
}
else
{
if ((MMC5.DrawStatus == 0) && (MMC5.DrawBank == Bank))
return 0;
MMC5.DrawStatus = 0;
MMC5.DrawBank = Bank;
MMC5_SyncCHRB(Bank);
return 1;
}
}
return 0;
}
void __cdecl MMC5_HBlank (int Scanline, int Byte2001)
{
MMC5.TileCache = 0x40;
MMC5.DrawStatus = 2;
MMC5.CurTile = -1;
if (Scanline == -1)
{
if ((MMC5.UpdateCache) && (MMC5.GfxMode == 1))
{
MP->MMC5_UpdateAttributeCache();
MMC5.UpdateCache = 0;
}
}
if (Scanline == -1)
VScroll = MMC5.SplitScroll;
else if (Scanline < 240)
VScroll++;
if (VScroll >= 240)
VScroll -= 240;
if (Scanline <= 240)
{
if ((Scanline == MMC5.IRQline) && (Byte2001 & 0x18))
MMC5.IRQreads |= 0x80;
if ((MMC5.IRQreads & 0x80) && (MMC5.IRQenabled & 0x80))
MP->IRQ();
}
else MMC5.IRQreads |= 0x40;
if (Scanline == 241)
{
MMC5_SyncCHRA(0);
MMC5_SyncCHRA(4);
}
}
void __cdecl MMC5_MapperSnd (s16 *Buffer, int Len)
{
MMC5sound_Get(Buffer,Len);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -