AxibugEmuOnline/References/VirtuaNESex_src_191105/NES/Mapper/Mapper049.cpp
2024-08-05 17:58:53 +08:00

171 lines
3.9 KiB
C++

//////////////////////////////////////////////////////////////////////////
// Mapper120 Tobidase Daisakusen //
//////////////////////////////////////////////////////////////////////////
#include "BoardMMC3.h"
void Mapper049::Reset()
{
// nes->ppu->SetVromWrite(1);
MMC3_RegReset();
temp = 0;
// nes->ppu->SetExtLatchMode( TRUE );
}
void Mapper049::WriteLow( WORD addr, BYTE data )
{
DEBUGOUT( "MPRWR A=%04X D=%02X L=%3d CYC=%d\n", addr&0xFFFF, data&0xFF, nes->GetScanline(), nes->cpu->GetTotalCycles() );
if ((addr&0x4100)==0x4100) {
temp=data;
// temp &= 0x03;
// if ( temp == 0 ) SetVRAM_Mirror( VRAM_VMIRROR );
// else if ( temp == 1 ) SetVRAM_Mirror( VRAM_HMIRROR );
// else if ( temp == 2 ) SetVRAM_Mirror( VRAM_MIRROR4L );
// else SetVRAM_Mirror( VRAM_MIRROR4H );
FixCHR(MMC3_cmd);
}
}
void Mapper049::Write( WORD addr, BYTE data )
{
// DEBUGOUT( "MPRWR A=%04X D=%02X L=%3d CYC=%d\n", addr&0xFFFF, data&0xFF, nes->GetScanline(), nes->cpu->GetTotalCycles() );
MMC3CMDWrite(addr, data);
MMC3_IRQWrite(addr, data);
if((addr&0xE001)==0xE000) nes->cpu->ClrIRQ(IRQ_MAPPER);
}
void Mapper049::MMC3CMDWrite(WORD A, BYTE V)
{
switch (A & 0xE001) {
case 0x8000:
if ((V & 0x40) != (MMC3_cmd & 0x40))
FixMMC3PRG(V);
if ((V & 0x80) != (MMC3_cmd & 0x80))
FixCHR(V);
MMC3_cmd = V;
break;
case 0x8001:
{
int cbase = (MMC3_cmd & 0x80) << 5;
MMC3_DRegBuf[MMC3_cmd & 0x7] = V;
switch (MMC3_cmd & 0x07) {
case 0:
wrapc((cbase ^ 0x000), V & (~1));
wrapc((cbase ^ 0x400), V | 1);
break;
case 1:
wrapc((cbase ^ 0x800), V & (~1));
wrapc((cbase ^ 0xC00), V | 1);
break;
case 2:
wrapc(cbase ^ 0x1000, V);
break;
case 3:
wrapc(cbase ^ 0x1400, V);
break;
case 4:
wrapc(cbase ^ 0x1800, V);
break;
case 5:
wrapc(cbase ^ 0x1C00, V);
break;
case 6:
if (MMC3_cmd&0x40) pwrap(0xC000, V);
else pwrap(0x8000, V);
break;
case 7:
pwrap(0xA000, V);
break;
}
break;
}
case 0xA000:
MMC3_A000B = V;
mwrap(MMC3_A000B);
break;
case 0xA001:
MMC3_A001B = V;
break;
}
}
void Mapper049::wrapc(WORD A, BYTE V)
{
if(temp&2)
SetCRAM_8K_Bank(0);
else
SetVROM_1K_Bank(A>>10,V);
}
void Mapper049::FixCHR(BYTE V)
{
int cbase = (V & 0x80) << 5;
wrapc((cbase ^ 0x000), MMC3_DRegBuf[0] & (~1));
wrapc((cbase ^ 0x400), MMC3_DRegBuf[0] | 1);
wrapc((cbase ^ 0x800), MMC3_DRegBuf[1] & (~1));
wrapc((cbase ^ 0xC00), MMC3_DRegBuf[1] | 1);
wrapc(cbase ^ 0x1000, MMC3_DRegBuf[2]);
wrapc(cbase ^ 0x1400, MMC3_DRegBuf[3]);
wrapc(cbase ^ 0x1800, MMC3_DRegBuf[4]);
wrapc(cbase ^ 0x1c00, MMC3_DRegBuf[5]);
mwrap(MMC3_A000B);
}
void Mapper049::HSync( INT scanline )
{
if ((scanline >= 0 && scanline <= 239)) {
if (nes->ppu->IsDispON())
{
if (MMC3_IRQa && !MMC3_IRQReload) {
if (scanline == 0) {
if (MMC3_IRQCount) {
MMC3_IRQCount -= 1;
}
}
if (!(MMC3_IRQCount)){
MMC3_IRQReload = 0xFF;
MMC3_IRQCount = MMC3_IRQLatch;
nes->cpu->SetIRQ(IRQ_MAPPER);
}
MMC3_IRQCount--;
}
}
}
}
void Mapper049::PPU_ExtLatch( WORD ntbladr, BYTE& chr_l, BYTE& chr_h, BYTE& attr )
{
INT loopy_v = nes->ppu->GetPPUADDR();
INT loopy_y = nes->ppu->GetTILEY();
INT tileofs = (PPUREG[0]&PPU_BGTBL_BIT)<<8;
INT attradr = 0x23C0+(loopy_v&0x0C00)+((loopy_v&0x0380)>>4);
INT attrsft = (ntbladr&0x0040)>>4;
LPBYTE pNTBL = PPU_MEM_BANK[ntbladr>>10];
INT ntbl_x = ntbladr&0x001F;
INT tileadr, ntb;
ntb = (ntbladr>>10)&3;
if(ntb==2)
tileofs |= 0x1000;
else if(ntb && temp)
tileofs |= 0x1000;
else
tileofs |= 0x0000;
attradr &= 0x3FF;
attr = ((pNTBL[attradr+(ntbl_x>>2)]>>((ntbl_x&2)+attrsft))&3)<<2;
tileadr = tileofs+pNTBL[ntbladr&0x03FF]*0x10+loopy_y;
chr_l = PPU_MEM_BANK[tileadr>>10][ tileadr&0x03FF ];
chr_h = PPU_MEM_BANK[tileadr>>10][(tileadr&0x03FF)+8];
}
void Mapper049::PPU_Latch( WORD addr )
{
if(DirectInput.m_Sw[DIK_PAUSE]){
nes->Dump_CRAM();
}
}