📄 mappers.h
字号:
/* Copyright 2001, ESS Technology, Inc./* SCCSID @(#)mappers.h 1.7 02/28/02 *//* * $Log$ *//** iNES: portable NES emulator ******************************//** **//** Mappers.h **//** **//** This file contains memory mapper handlers used to **//** switch NES_ROM, VROM, and handle custom cartridge hardware. **//** This file is included from NES.c. **//** **//** Copyright (C) Marat Fayzullin 1996-2000 **//** The contents of this file are property of Marat **//** Fayzullin and should only be used as agreed with **//** him. The file is confidential. Absolutely no **//** distribution allowed. **//*************************************************************/#ifdef INEStypedef struct { int R[4],S[4],C[4]; } MMC1;typedef struct { byte R8000,RC000,R[8],IRQ,Count,Carry; } MMC3;typedef struct { byte R[8],IRQ,Count; } MMC5;typedef struct { byte Latch[16]; } VRC2;typedef struct { byte SPg; } G101;typedef struct{ byte BufROM[8],BufVROM[16]; byte BufIRQ1[2],BufIRQ2[2];} SS8806;typedef struct{ byte Latch[16]; byte IRQLatch; byte SPg;} VRC4;typedef struct{ int Period; /* Counter period (in NES_CPU cycles) */ int Count; /* Counter value (in NES_CPU cycles) */ byte IRQ; /* Counter enabled/disabled */ byte R800A; /* Trigger bit which starts counter */} Bandai;typedef struct{ byte Control; /* Contents of $4025 register */ byte Data; /* Contents of $4024 register */ byte Status; byte SoundON; /* 1: DiskSystem sound is on */ byte Volume; /* Contents of $4080 register */ word Freq; /* Contents of $4082/$4083 registers */ int Period; int Count; byte Latch; byte IRQ;} FDS;union{ MMC1 M1; MMC3 M4; MMC5 M5; Bandai M16; SS8806 M18; FDS M20; VRC4 M21; VRC2 M22; G101 M32; byte Latch; /* Generic byte latch */ byte Count; /* Generic interval counter */ byte IRQ; /* Generic IRQ switch */} MM;/** InitROM#() ***********************************************//** These are the initialization handlers for different **//** mappers. **//*************************************************************/static void InitROM1(void);static void InitROM4(void);#ifdef MULTI_MAPPERSstatic void InitVROM00(void);static void InitVROM07(void);static void InitROMLL(void);static void InitROMFF(void);static void InitROM5(void);static void InitROM16(void);static void InitROM21(void);static void InitROM32(void);#endif/** SelectROM#() *********************************************//** These are the access handlers for different mappers. **//*************************************************************/static int SelectROM1(register int A,register int V);static int SelectROM2(register int A,register int V);static int SelectROM3(register int A,register int V);static int SelectROM4(register int A,register int V);#ifdef MULTI_MAPPERSstatic int SelectROM5(register int A,register int V);static int SelectROM6(register int A,register int V);static int SelectROM7(register int A,register int V);static int SelectROM8(register int A,register int V);static int SelectROM10(register int A,register int V);static int SelectROM11(register int A,register int V);static int SelectROM15(register int A,register int V);static int SelectROM16(register int A,register int V);static int SelectROM17(register int A,register int V);static int SelectROM18(register int A,register int V);static int SelectROM19(register int A,register int V);static int SelectROM21(register int A,register int V);static int SelectROM22(register int A,register int V);static int SelectROM32(register int A,register int V);static int SelectROM33(register int A,register int V);static int SelectROM34(register int A,register int V);#endif/** LoopROM#() ***********************************************//** These are loop handlers for different mappers. **//*************************************************************/static void LoopROM4(void);#ifdef MULTI_MAPPERSstatic void LoopROM5(void);static void LoopROM16(void);static void LoopROMX(void);#endif/** InitMapper() *********************************************//** Initialize NES_ROM and VROM pages and the mapper. **//*************************************************************/void InitMapper(byte ROMType){ int J; /* Initialize generic mapper structures */ MM.Latch=0x00; MM.Count=0; MM.IRQ=0; /* Compute masks for the NES_ROM and VROM page numbers */ for(J=1;J<ines->ROMPages;J<<=1);ines->ROMMask=J-1; for(J=1;J<ines->VROMPages;J<<=1);ines->VROMMask=J-1; /* Choose correct LoopROM#() and SelectROM#() routines */ SelectROM = 0; if(ROMType == 1) SelectROM = SelectROM1; else if (ROMType == 2) SelectROM = SelectROM2; else if (ROMType == 3) SelectROM = SelectROM3; else if (ROMType == 4) SelectROM = SelectROM4;#ifdef MULTI_MAPPERS else if (ROMType == 5) SelectROM = SelectROM5; else if (ROMType == 6) SelectROM = SelectROM6; else if (ROMType == 7) SelectROM = SelectROM7; else if (ROMType == 8) SelectROM = SelectROM8; else if (ROMType == 10) SelectROM = SelectROM10; else if (ROMType == 11) SelectROM = SelectROM11; else if (ROMType == 15) SelectROM = SelectROM15; else if (ROMType == 16) SelectROM = SelectROM16; else if (ROMType == 17) SelectROM = SelectROM17; else if (ROMType == 18) SelectROM = SelectROM18; else if (ROMType == 19) SelectROM = SelectROM19; else if (ROMType == 21) SelectROM = SelectROM21; else if (ROMType == 22) SelectROM = SelectROM22; else if (ROMType == 23) SelectROM = SelectROM22; else if (ROMType == 25) SelectROM = SelectROM21; else if (ROMType == 26) SelectROM = SelectROM22; else if (ROMType == 32) SelectROM = SelectROM32; else if (ROMType == 33) SelectROM = SelectROM33; else if (ROMType == 34) SelectROM = SelectROM34;#endif LoopROM = 0; if ( ROMType == 4) LoopROM = LoopROM4;#ifdef MULTI_MAPPERS else if (ROMType == 5) LoopROM = LoopROM5; else if (ROMType == 16) LoopROM = LoopROM16; else if (ROMType == 17) LoopROM = LoopROMX; else if (ROMType == 18) LoopROM = LoopROMX; else if (ROMType == 21) LoopROM = LoopROMX; else if (ROMType == 25) LoopROM = LoopROMX;#endif /* By default, set VROM to the first 8kB page */ if(VROM) SetVPages(0,7,VPAGE(0)); /* By default, set NES_ROM to the first and last 16kB pages */ if(NES_ROM){ NES_Page[4]=PAGE(0); NES_Page[5]=NES_Page[4]+0x2000; NES_Page[6]=PAGE(ines->ROMPages-1); NES_Page[7]=NES_Page[6]+0x2000; if(ROMType == 0 || ROMType == 3){ memcpy(NES_RAM+0x8000, PAGE(0), 0x4000); memcpy(NES_RAM+0xC000, PAGE(ines->ROMPages-1), 0x4000); FYH_RAM = NES_RAM+0x8000; } } if(ROMType==2&&ines->ROMPages<=8&&ines->VROMPages<=8){ FYH_RAM=NES_ROM+0x30000; for(J=0;J<8;J++)FYH_PAGE[J]=FYH_RAM+0x8000*J; for(J=0;J<(ines->ROMPages-1);J++){ memcpy(FYH_PAGE[J], PAGE(J), 0x4000); memcpy(FYH_PAGE[J]+0x4000, PAGE(ines->ROMPages-1), 0x4000); } } /* Call mapper initialization handler, if present */ if (ROMType == 1) InitROM1(); else if ( ROMType == 4) InitROM4();#ifdef MULTI_MAPPERS else if ( ROMType == 5) InitROM5(); else if ( ROMType == 8) InitROMFF(); else if ( ROMType == 10) InitROMLL(); else if ( ROMType == 11) InitROMFF(); else if ( ROMType == 15) InitROMFF(); else if ( ROMType == 16) InitROM16(); else if ( ROMType == 17) InitVROM00(); else if ( ROMType == 18) InitVROM00(); else if ( ROMType == 21) InitROM21(); else if ( ROMType == 22) InitVROM00(); else if ( ROMType == 23) InitVROM00(); else if ( ROMType == 32) InitROM32(); else if ( ROMType == 33) InitVROM07();#endif /* Finish initialization */ SetTables();}#ifdef MULTI_MAPPERS/** InitVROM00() *********************************************//** Initialization for mappers with 1kB VROM pages which **//** initialize to 0.0.0.0.0.0.0.0. **//*************************************************************/void InitVROM00(void){ int J; SetVPages(0,7,NES_VRAM); for(J=0;J<8;J++) { if(VROM) memcpy(ines->VPage[J],VPAGE(0),0x0400); ines->VPageN[J]=0; }}/** InitVROM07() *********************************************//** Initialization for mappers with 1kB VROM pages which **//** initialize to 0.1.2.3.4.5.6.7. **//*************************************************************/void InitVROM07(void){ int J; SetVPages(0,7,NES_VRAM); if(VROM) { memcpy(NES_VRAM,VPAGE(0),0x2000); for(J=0;J<8;J++) ines->VPageN[J]=J; }}/** InitROMFF() **********************************************//** Initialization for mappers which start with first 32kB **//** of NES_ROM switched in. **//*************************************************************/void InitROMFF(void){ if(NES_ROM) { NES_Page[4]=PAGE(0); NES_Page[5]=NES_Page[4]+0x2000; NES_Page[6]=PAGE(1); NES_Page[7]=NES_Page[6]+0x2000; }}/** InitROMLL() **********************************************//** Initialization for mappers which start with last 32kB **//** of NES_ROM switched in. **//*************************************************************/void InitROMLL(void){ if(NES_ROM) { NES_Page[4]=PAGE(ines->ROMPages>1? ines->ROMPages-2:0); NES_Page[5]=NES_Page[4]+0x2000; NES_Page[6]=PAGE(ines->ROMPages-1); NES_Page[7]=NES_Page[6]+0x2000; }}#endif/** InitROM1() ***********************************************//** Initialization for MMC1 hardware. **//*************************************************************/void InitROM1(void){ /* Set registers */ MM.M1.C[0]=MM.M1.C[1]=MM.M1.C[2]=MM.M1.C[3]=0x01; MM.M1.S[0]=MM.M1.S[1]=MM.M1.S[2]=MM.M1.S[3]=0x00; MM.M1.R[0]=0x0C; MM.M1.R[1]=0x00; MM.M1.R[2]=0x00; MM.M1.R[3]=0x00; /* Set screen buffers */ ines->VPage[8]=ines->VPage[9]=ines->VPage[10]=ines->VPage[11]=NES_VRAM+0x2000; /* Set VROM pages */ if(VROM) SetVPages(0,7,VPAGE(0)); /* Set NES_ROM pages */ if(NES_ROM) { NES_Page[4]=PAGE(0); NES_Page[5]=NES_Page[4]+0x2000; NES_Page[6]=PAGE(0x0F); NES_Page[7]=NES_Page[6]+0x2000; }}/** InitROM4() ***********************************************//** Initialization for MMC3 hardware. **//*************************************************************/void InitROM4(void){ /* Set registers */ MM.M4.R[0]=MM.M4.R[1]=0x00; MM.M4.R[2]=MM.M4.R[3]=MM.M4.R[4]=MM.M4.R[5]=0x00; MM.M4.R[6]=MM.M4.R[7]=0x00; MM.M4.R8000=0x00; MM.M4.RC000=0x00; MM.M4.Count=0; MM.M4.Carry=0; MM.M4.IRQ=0; /* Set NES_VRAM for VROM pages */ SetVPages(0,7,NES_VRAM); /* Set VROM pages */ if(VROM) { memcpy(NES_VRAM,VPAGE(0),0x800); memcpy(NES_VRAM+0x800,VPAGE(0),0x800); memcpy(NES_VRAM+0x1000,VPAGE(0),0x400); memcpy(NES_VRAM+0x1400,VPAGE(0),0x400); memcpy(NES_VRAM+0x1800,VPAGE(0),0x400); memcpy(NES_VRAM+0x1C00,VPAGE(0),0x400); } /* Set NES_ROM pages */ if(NES_ROM) { NES_Page[4]=PAGE(0); NES_Page[5]=PAGE(0); NES_Page[6]=PAGE(ines->ROMPages-1); NES_Page[7]=NES_Page[6]+0x2000; }}#ifdef MULTI_MAPPERS/** InitROM5() ***********************************************//** Initialization for MMC5 hardware. **//*************************************************************/void InitROM5(void){ /* Set registers */ MM.M5.R[0]=MM.M5.R[1]=MM.M5.R[2]=MM.M5.R[3]=0x00; MM.M5.R[4]=MM.M5.R[5]=MM.M5.R[6]=MM.M5.R[7]=0x00; MM.M5.Count=0; MM.M5.IRQ=0; /* Set NES_VRAM for VROM pages */ SetVPages(0,7,NES_VRAM); /* Set VROM pages */ if(VROM) { memcpy(NES_VRAM,VPAGE(0),0x800); memcpy(NES_VRAM+0x800,VPAGE(0),0x800); memcpy(NES_VRAM+0x1000,VPAGE(0),0x400); memcpy(NES_VRAM+0x1400,VPAGE(0),0x400); memcpy(NES_VRAM+0x1800,VPAGE(0),0x400); memcpy(NES_VRAM+0x1C00,VPAGE(0),0x400); } /* Set NES_ROM pages */ if(NES_ROM) NES_Page[4]=NES_Page[5]=NES_Page[6]=NES_Page[7]=PAGE(ines->ROMPages-1)+0x2000;}/** InitROM16() **********************************************//** Initialization for Bandai hardware. **//*************************************************************/void InitROM16(void){ int J; /* Set registers */ MM.M16.R800A = 0x00; MM.M16.Count = 0; MM.M16.Period = 0; MM.M16.IRQ = 0; /* Set VROM pages */ InitVROM00(); /* Set NES_ROM pages */ if(NES_ROM) { NES_Page[4]=PAGE(0); NES_Page[5]=NES_Page[4]+0x2000; NES_Page[6]=PAGE(ines->ROMPages-1); NES_Page[7]=NES_Page[6]+0x2000; }}/** InitROM21() **********************************************//** Initialization for the Konami VRC4 hardware. **//*************************************************************/void InitROM21(void){ MM.M21.IRQLatch=0x00; MM.M21.SPg=4; InitVROM00();}/** InitROM32() **********************************************//** Initialization for the Irem G-101 hardware. **//*************************************************************/void InitROM32(void){ MM.M32.SPg=4; InitVROM07();}#endif/** LoopROM4() ***********************************************//** Loop handler for MMC3 hardware. **//*************************************************************/void LoopROM4(void){ if(MM.M4.Carry) { MM.M4.Count=MM.M4.RC000; MM.M4.Carry=0; } else { MM.M4.Count--; if(!MM.M4.Count) { if(MM.M4.IRQ) NES_CPU.IRequest=NES_INT_IRQ; MM.M4.Carry=1; } }}#ifdef MULTI_MAPPERS/** LoopROM5() ***********************************************//** Loop handler for MMC5 hardware. **//*************************************************************/void LoopROM5(void){ if(MM.M5.Count==NCURLINE) if(MM.M5.IRQ) NES_CPU.IRequest=NES_INT_IRQ;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -