AxibugEmuOnline/virtuanessrc097-master/NES/MMU.cpp

284 lines
13 KiB
C++
Raw Normal View History

<EFBFBD><EFBFBD>//////////////////////////////////////////////////////////////////////////
// //
// NES Memory Management Unit //
// Norix //
// written 2001/02/21 //
// last modify ----/--/-- //
//////////////////////////////////////////////////////////////////////////
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include "typedef.h"
#include "macro.h"
#include "DebugOut.h"
#include "mmu.h"
// CPU <EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0
LPBYTE CPU_MEM_BANK[8]; // 8KXSMO
BYTE CPU_MEM_TYPE[8];
INT CPU_MEM_PAGE[8]; // <EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0(u
// PPU <EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0
LPBYTE PPU_MEM_BANK[12]; // 1KXSMO
BYTE PPU_MEM_TYPE[12];
INT PPU_MEM_PAGE[12]; // <EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0(u
BYTE CRAM_USED[16]; // <EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0(u
// NES<EFBFBD>0<EFBFBD>0<EFBFBD>0
BYTE RAM [ 8*1024]; // NES<EFBFBD>QӁRAM
BYTE WRAM[128*1024]; // <EFBFBD>0<EFBFBD>0<EFBFBD>0/<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0RAM
BYTE DRAM[ 40*1024]; // <EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0RAM
BYTE XRAM[ 8*1024]; // <EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0
BYTE ERAM[ 32*1024]; // <EFBFBD>b5__jhV(uRAM
BYTE CRAM[ 32*1024]; // <EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0RAM
BYTE VRAM[ 4*1024]; // <EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0/<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0RAM
BYTE SPRAM[0x100]; // <EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0RAM
BYTE BGPAL[0x10]; // BG<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0
BYTE SPPAL[0x10]; // SP<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0
// <EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0
BYTE CPUREG[0x18]; // Nes $4000-$4017
BYTE PPUREG[0x04]; // Nes $2000-$2003
// Frame-IRQ<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0($4017)
BYTE FrameIRQ;
// PPU<EFBFBD>Q<EFBFBD><EFBFBD><EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0
BYTE PPU56Toggle; // $2005-$2006 Toggle
BYTE PPU7_Temp; // $2007 read buffer
WORD loopy_t; // same as $2005/$2006
WORD loopy_v; // same as $2005/$2006
WORD loopy_x; // tile x offset
// ROM<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0
LPBYTE PROM; // PROM ptr
LPBYTE VROM; // VROM ptr
// For dis...
LPBYTE PROM_ACCESS = NULL;
// ROM <EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0
INT PROM_8K_SIZE, PROM_16K_SIZE, PROM_32K_SIZE;
INT VROM_1K_SIZE, VROM_2K_SIZE, VROM_4K_SIZE, VROM_8K_SIZE;
//
// hQ<EFBFBD>0<EFBFBD>0<EFBFBD>0/<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0I{n0RgS
//
void NesSub_MemoryInitial()
{
INT i;
// <EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0
ZEROMEMORY( RAM, sizeof(RAM) );
ZEROMEMORY( WRAM, sizeof(WRAM) );
ZEROMEMORY( DRAM, sizeof(DRAM) );
ZEROMEMORY( ERAM, sizeof(ERAM) );
ZEROMEMORY( XRAM, sizeof(XRAM) );
ZEROMEMORY( CRAM, sizeof(CRAM) );
ZEROMEMORY( VRAM, sizeof(VRAM) );
ZEROMEMORY( SPRAM, sizeof(SPRAM) );
ZEROMEMORY( BGPAL, sizeof(BGPAL) );
ZEROMEMORY( SPPAL, sizeof(SPPAL) );
ZEROMEMORY( CPUREG, sizeof(CPUREG) );
ZEROMEMORY( PPUREG, sizeof(PPUREG) );
FrameIRQ = 0xC0;
PROM = VROM = NULL;
// 0 d<EFBFBD><EFBFBD>{2<EFBFBD>bk<EFBFBD>[V{
PROM_8K_SIZE = PROM_16K_SIZE = PROM_32K_SIZE = 1;
VROM_1K_SIZE = VROM_2K_SIZE = VROM_4K_SIZE = VROM_8K_SIZE = 1;
// <EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0<EFBFBD>0-<EFBFBD><EFBFBD>[
for( i = 0; i < 8; i++ ) {
CPU_MEM_BANK[i] = NULL;
CPU_MEM_TYPE[i] = BANKTYPE_ROM;
CPU_MEM_PAGE[i] = 0;
}
// <EFBFBD>QӁRAM/WRAM
SetPROM_Bank( 0, RAM, BANKTYPE_RAM );
SetPROM_Bank( 3, WRAM, BANKTYPE_RAM );
// <EFBFBD>0<EFBFBD>0<EFBFBD>0
SetPROM_Bank( 1, XRAM, BANKTYPE_ROM );
SetPROM_Bank( 2, XRAM, BANKTYPE_ROM );
for( i = 0; i < 8; i++ ) {
CRAM_USED[i] = 0;
}
// PPU VROM<EFBFBD>0<EFBFBD>0<EFBFBD>0-<EFBFBD><EFBFBD>[
// SetVRAM_Mirror( VRAM_MIRROR4 );
}
// CPU ROM bank
void SetPROM_Bank( BYTE page, LPBYTE ptr, BYTE type )
{
CPU_MEM_BANK[page] = ptr;
CPU_MEM_TYPE[page] = type;
CPU_MEM_PAGE[page] = 0;
}
void SetPROM_8K_Bank( BYTE page, INT bank )
{
bank %= PROM_8K_SIZE;
CPU_MEM_BANK[page] = PROM+0x2000*bank;
CPU_MEM_TYPE[page] = BANKTYPE_ROM;
CPU_MEM_PAGE[page] = bank;
}
void SetPROM_16K_Bank( BYTE page, INT bank )
{
SetPROM_8K_Bank( page+0, bank*2+0 );
SetPROM_8K_Bank( page+1, bank*2+1 );
}
void SetPROM_32K_Bank( INT bank )
{
SetPROM_8K_Bank( 4, bank*4+0 );
SetPROM_8K_Bank( 5, bank*4+1 );
SetPROM_8K_Bank( 6, bank*4+2 );
SetPROM_8K_Bank( 7, bank*4+3 );
}
void SetPROM_32K_Bank( INT bank0, INT bank1, INT bank2, INT bank3 )
{
SetPROM_8K_Bank( 4, bank0 );
SetPROM_8K_Bank( 5, bank1 );
SetPROM_8K_Bank( 6, bank2 );
SetPROM_8K_Bank( 7, bank3 );
}
// PPU VROM bank
void SetVROM_Bank( BYTE page, LPBYTE ptr, BYTE type )
{
PPU_MEM_BANK[page] = ptr;
PPU_MEM_TYPE[page] = type;
PPU_MEM_PAGE[page] = 0;
}
void SetVROM_1K_Bank( BYTE page, INT bank )
{
bank %= VROM_1K_SIZE;
PPU_MEM_BANK[page] = VROM+0x0400*bank;
PPU_MEM_TYPE[page] = BANKTYPE_VROM;
PPU_MEM_PAGE[page] = bank;
}
void SetVROM_2K_Bank( BYTE page, INT bank )
{
SetVROM_1K_Bank( page+0, bank*2+0 );
SetVROM_1K_Bank( page+1, bank*2+1 );
}
void SetVROM_4K_Bank( BYTE page, INT bank )
{
SetVROM_1K_Bank( page+0, bank*4+0 );
SetVROM_1K_Bank( page+1, bank*4+1 );
SetVROM_1K_Bank( page+2, bank*4+2 );
SetVROM_1K_Bank( page+3, bank*4+3 );
}
void SetVROM_8K_Bank( INT bank )
{
for( INT i = 0; i < 8; i++ ) {
SetVROM_1K_Bank( i, bank*8+i );
}
}
void SetVROM_8K_Bank( INT bank0, INT bank1, INT bank2, INT bank3,
INT bank4, INT bank5, INT bank6, INT bank7 )
{
SetVROM_1K_Bank( 0, bank0 );
SetVROM_1K_Bank( 1, bank1 );
SetVROM_1K_Bank( 2, bank2 );
SetVROM_1K_Bank( 3, bank3 );
SetVROM_1K_Bank( 4, bank4 );
SetVROM_1K_Bank( 5, bank5 );
SetVROM_1K_Bank( 6, bank6 );
SetVROM_1K_Bank( 7, bank7 );
}
void SetCRAM_1K_Bank( BYTE page, INT bank )
{
bank &= 0x1F;
PPU_MEM_BANK[page] = CRAM+0x0400*bank;
PPU_MEM_TYPE[page] = BANKTYPE_CRAM;
PPU_MEM_PAGE[page] = bank;
CRAM_USED[bank>>2] = 0xFF; // CRAMO(u<EFBFBD>0<EFBFBD>0<EFBFBD>0
}
void SetCRAM_2K_Bank( BYTE page, INT bank )
{
SetCRAM_1K_Bank( page+0, bank*2+0 );
SetCRAM_1K_Bank( page+1, bank*2+1 );
}
void SetCRAM_4K_Bank( BYTE page, INT bank )
{
SetCRAM_1K_Bank( page+0, bank*4+0 );
SetCRAM_1K_Bank( page+1, bank*4+1 );
SetCRAM_1K_Bank( page+2, bank*4+2 );
SetCRAM_1K_Bank( page+3, bank*4+3 );
}
void SetCRAM_8K_Bank( INT bank )
{
for( INT i = 0; i < 8; i++ ) {
SetCRAM_1K_Bank( i, bank*8+i ); // fix
}
}
void SetVRAM_1K_Bank( BYTE page, INT bank )
{
bank &= 3;
PPU_MEM_BANK[page] = VRAM+0x0400*bank;
PPU_MEM_TYPE[page] = BANKTYPE_VRAM;
PPU_MEM_PAGE[page] = bank;
}
void SetVRAM_Bank( INT bank0, INT bank1, INT bank2, INT bank3 )
{
SetVRAM_1K_Bank( 8, bank0 );
SetVRAM_1K_Bank( 9, bank1 );
SetVRAM_1K_Bank( 10, bank2 );
SetVRAM_1K_Bank( 11, bank3 );
}
void SetVRAM_Mirror( INT type )
{
switch( type ) {
case VRAM_HMIRROR:
SetVRAM_Bank( 0, 0, 1, 1 );
break;
case VRAM_VMIRROR:
SetVRAM_Bank( 0, 1, 0, 1 );
break;
case VRAM_MIRROR4L:
SetVRAM_Bank( 0, 0, 0, 0 );
break;
case VRAM_MIRROR4H:
SetVRAM_Bank( 1, 1, 1, 1 );
break;
case VRAM_MIRROR4:
SetVRAM_Bank( 0, 1, 2, 3 );
break;
}
}
void SetVRAM_Mirror( INT bank0, INT bank1, INT bank2, INT bank3 )
{
SetVRAM_1K_Bank( 8, bank0 );
SetVRAM_1K_Bank( 9, bank1 );
SetVRAM_1K_Bank( 10, bank2 );
SetVRAM_1K_Bank( 11, bank3 );
}