📄 mappers.h
字号:
}/** Mapper #15 ***********************************************//** This is a switch from the 100in1 cartridge. **//*************************************************************/int SelectROM15(int A,int V){ register int J; if ( A == 0x8000 ) { SetMirror(~V&0x40); NES_Page[4]=PAGE(V)+(V&0x80? 0x2000:0); NES_Page[5]=PAGE(V)+(V&0x80? 0:0x2000); V++; NES_Page[6]=PAGE(V)+(V&0x80? 0x2000:0); NES_Page[7]=PAGE(V)+(V&0x80? 0:0x2000); return(1); } else if ( A == 0x8001 ){ NES_Page[6]=PAGE(V)+(V&0x80? 0x2000:0); NES_Page[7]=PAGE(V)+(V&0x80? 0:0x2000); return(1); } else if ( A == 0x8002 ) { NES_Page[4]=PAGE(V)+(V&0x80? 0x2000:0); NES_Page[5]=NES_Page[6]=NES_Page[7]=NES_Page[4]; return(1); } else if ( A == 0x8003 ) { SetMirror(~V&0x40); NES_Page[6]=PAGE(V)+(V&0x80? 0x2000:0); NES_Page[7]=PAGE(V)+(V&0x80? 0:0x2000); return(1); } /* Unknown address */ return(0);}/** Mapper #16 ***********************************************//** This is a Bandai mapper used in DragonBallZ series. It **//** switches 16kB NES_ROM at $8000 and 8 256-byte VROM pages at **//** $0000. It also includes an IRQ source. **//*************************************************************/int SelectROM16(int A,int V){ register int N, J; /* We are only interested in certain writes */ if(A<0x8000) return(0); J = A&0x000F; if ( J == 8 ) { /* 16kB NES_ROM page at $8000 */ NES_Page[4]=PAGE(V); NES_Page[5]=NES_Page[4]+0x2000; return(1); } else if ( J == 9 ) { /* Mirroring */ if(!(V&0x02)) SetMirror(~V&0x01); else { ines->VPage[8]=ines->VPage[9]=ines->VPage[10]=ines->VPage[11]=NES_VRAM+(V&0x01? 0x2400:0x2000); SetTables(); } return(1); } else if ( J == 10 ) { /* IRQ enable/disable */ if(V&(V^MM.M16.R800A)&0x01) { /* Clear pending IRQ */ NES_CPU.IRequest=NES_INT_NONE; /* Set counter to the new value */ MM.M16.Count=MM.M16.Period; /* If in VBlank, correct counter value */ if(!NCURLINE) MM.M16.Count-=NES_CPU.ICount; /* Counter is now on */ MM.M16.IRQ=1; } MM.M16.R800A=V; return(1); } else if ( A == 11 ) { /* Lower byte of IRQ counter */ MM.M16.Period=(MM.M16.Period&0xFF00)+V; return(1); } else if ( A == 12 ) { /* Upper byte of IRQ counter */ MM.M16.Period=(MM.M16.Period&0x00FF)+((int)V<<8); return(1); } else if ( J == 13 ) { return(1); } else if ( J >= 0 && J <= 7 ) { /* 256-byte VROM pages */ N=A&0x07; V&=(ines->VROMMask<<3)|0x07; if((V!=ines->VPageN[N])&&VPAGE(V>>3)) { ines->VPageN[N]=V; memcpy(ines->VPage[N],VPAGE(V>>3)+(V&0x07)*0x0400,0x0400); } return(1); } /* Unknown address */ return(0);}/** Mapper #17 ***********************************************//** This is a mapper used by the FrontFarEast copier when **//** running trained games from the F8xxx group, such as **//** FinalFantasy3J or DragonQuest4J. **//*************************************************************/int SelectROM17(int A,int V){ register int J; /* We are only interested in certain writes */ if((A&0xFFE8)!=0x4500) return(0); if ( A == 0x4501 || A == 0x4502 ) { return(1); } else if ( A == 0x4503 ) { MM.Count=V;MM.IRQ=1; return(1); } else if ( A >= 0x4510 && A <= 0x4517 ) { A-=0x4510; if((V!=ines->VPageN[A])&&VPAGE(V>>3)) { ines->VPageN[A]=V; memcpy(ines->VPage[A],VPAGE(V>>3)+(V&0x07)*0x0400,0x0400); } return(1); } else if ( A >= 0x4504 && A <= 0x4507 ) { A-=0x4500; NES_Page[A]=PAGE(V>>1)+(V&0x01? 0x2000:0); return(1); } /* Unknown address */ return(0);}/** Mapper #18 ***********************************************//** This is a Jaleco SS8806 chip used in their Baseball3. **//*************************************************************/int SelectROM18(int A,int V){ register int J; /* We are only interested in certain writes */ if((A&0x8FFC)!=0x8000) return(0); /* Special cases: mirroring, interrupts, etc. */ if ( A == 0xF002 ) { SetMirror(V&0x01); return(1); } else if ( A == 0xF000 ) { MM.IRQ=V&0x01; NES_CPU.IRequest=NES_INT_NONE; return(1); } else if ( A == 0xF001 ) { NES_CPU.IRequest=NES_INT_NONE; return(1); } else if ( A == 0x9002 || A == 0x9003 ) { return(1); } else if ( A == 0xE000 || A == 0xE002 ) { MM.M18.BufIRQ1[(A>>1)&1]=V; MM.Count=(((MM.M18.BufIRQ1[1])<<8)+MM.M18.BufIRQ1[0])/ines->HPeriod+1; return(1); } else if ( A == 0xE001 || A == 0xE003 ) { MM.M18.BufIRQ2[(A>>1)&1]=V; MM.Count=(((MM.M18.BufIRQ2[1])<<8)+MM.M18.BufIRQ2[0])/ines->HPeriod+1; return(1); } /* NES_ROM switch */ if(A<0xA000) { A=(A&0x03)+((A>>10)&0x04); MM.M18.BufROM[A]=V; V=(MM.M18.BufROM[A&0x06]&0x0F)+(MM.M18.BufROM[A|0x01]<<4); A=(A>>1)+4; NES_Page[A]=PAGE(V>>1)+(V&0x01? 0x2000:0); return(1); } /* VROM switch */ if(A<0xE000) { A=(A&0x03)+((A>>10)&0x04)+((A>>11)&0x08); MM.M18.BufVROM[A]=V; V=(MM.M18.BufVROM[A&0x0E]&0x0F)+(MM.M18.BufVROM[A|0x01]<<4); A>>=1; if((V!=ines->VPageN[A])&&VPAGE(V>>3)) { ines->VPageN[A]=V; memcpy(ines->VPage[A],VPAGE(V>>3)+(V&0x07)*0x0400,0x0400); } return(1); } /* Unknown address */ return(0);}/** Mapper #19 ***********************************************//** This is a Namcot 106 chip. **//*************************************************************/int SelectROM19(int A,int V){ register int J; /* We are only interested in certain writes */ if((A&0x87FF)!=0x8000) return(0); if ( A == 0x5000 || A == 0x5800 ) { /* Interrupt counter */ return(1); } else if ( A==0xC000 || A==0xC800 || A==0xD000 || A==0xD800 ){ /* Switch screen buffers */ A=((A>>11)&0x03)+8; if(V>=0xE0) ines->VPage[A]=NES_VRAM+0x2000+0x400*(V&0x01); else ines->VPage[A]=VPAGE(V>>3)+0x400*(V&0x07); return(1); } else if(A==0x8000||A==0x8800||A==0x9000||A==0x9800||A==0xA000 || A == 0xA800 || A == 0xB000 || A == 0xB800){ /* Switch VROM */ A=(A>>11)&0x07; if((V!=ines->VPageN[A])&&VPAGE(V>>3)) { ines->VPageN[A]=V; memcpy(ines->VPage[A],VPAGE(V>>3)+(V&0x07)*0x0400,0x0400); } return(1); } else if (A==0xE000||A==0xE800||A==0xF000) { /* When >=0xC0, NES_VRAM selected at $0000-$1FFF */ if(V>=0xC0) SetVPages(0,7,NES_VRAM); /* Now, switch NES_ROM */ A=((A>>11)&0x03)+4; NES_Page[A]=PAGE(V>>1)+(V&0x01? 0x2000:0); return(1); } /* Unknown address */ return(0);}/** Mapper #21 ***********************************************//** This is a Konami mapper VRC4. **//*************************************************************/int SelectROM21(int A,int V){ /* We are only interested in certain writes */ if((A&0x8F39)!=0x8000) return(0); /* Shifting address bits to accomodate unknown Fanwen's cart */ A=(A&0xFF3F)|((A>>5)&0x06); switch(A) { case 0x9002: MM.M21.SPg=V&0x02? 6:4; return(1); case 0xF000: MM.M21.IRQLatch=(MM.M21.IRQLatch&0xF0)+(V&0x0F); MM.Count=MM.M21.IRQLatch<240? 240-MM.M21.IRQLatch:1; NES_CPU.IRequest=NES_INT_NONE; return(1); case 0xF002: MM.M21.IRQLatch=(MM.M21.IRQLatch&0x0F)+(V<<4); MM.Count=MM.M21.IRQLatch<240? 240-MM.M21.IRQLatch:1; NES_CPU.IRequest=NES_INT_NONE; return(1); case 0xF004: MM.IRQ=V&0x02; NES_CPU.IRequest=NES_INT_NONE; return(1); case 0xF006: MM.Count=MM.M21.IRQLatch<240? 240-MM.M21.IRQLatch:1; NES_CPU.IRequest=NES_INT_NONE; return(1); case 0x9000: if(V&0x02) { /* Single page case */ ines->VPage[8]=ines->VPage[9]=ines->VPage[10]=ines->VPage[11]=NES_VRAM+(V&0x01? 0x2400:0x2000); SetTables(); } else SetMirror(~V&0x01); return(1); case 0x8000: NES_Page[MM.M21.SPg]=PAGE(V>>1)+(V&0x01? 0x2000:0); return(1); case 0xA000: NES_Page[5]=PAGE(V>>1)+(V&0x01? 0x2000:0); return(1); case 0xB000: case 0xB002: case 0xB004: case 0xB006: case 0xC000: case 0xC002: case 0xC004: case 0xC006: case 0xD000: case 0xD002: case 0xD004: case 0xD006: case 0xE000: case 0xE002: case 0xE004: case 0xE006: A=((A-0xB000)>>10)+((A>>1)&0x03); MM.M21.Latch[A]=V; A&=0x0E; V=(MM.M21.Latch[A]&0x0F)+(MM.M21.Latch[A+1]<<4); A>>=1; if((V!=ines->VPageN[A])&&VPAGE(V>>3)) { memcpy(ines->VPage[A],VPAGE(V>>3)+(V&0x07)*0x0400,0x0400); ines->VPageN[A]=V; } return(1); } /* Unknown address */ return(0);}/** Mapper #22/#23 *******************************************//** This is a Konami mapper VRC2 used in TwinBee3. A second **//** modification of VRC2 is known as mapper #23 and also **//** handled by this function. **//*************************************************************/int SelectROM22(int A,int V){ /* We are only interested in certain writes */ if(A<0x8000) return(0); switch(A&0xF003) { case 0x9000: SetMirror(~V&0x01); return(1); case 0x8000: case 0xA000: A=((A>>13)&0x01)+4; NES_Page[A]=PAGE(V>>1)+(V&0x01? 0x2000:0); return(1); case 0xB000: case 0xB001: case 0xB002: case 0xB003: case 0xC000: case 0xC001: case 0xC002: case 0xC003: case 0xD000: case 0xD001: case 0xD002: case 0xD003: case 0xE000: case 0xE001: case 0xE002: case 0xE003: A = (((A-0x3000)>>10)&0x0C) + (ines->ROMType==23? A&0x03:((A&0x01)<<1)+((A&0x02)>>1)); MM.M22.Latch[A]=V; A&=0x0E; V=(MM.M22.Latch[A]&0x0F)+(MM.M22.Latch[A+1]<<4); if(ines->ROMType==22) V>>=1; A>>=1; if((V!=ines->VPageN[A])&&VPAGE(V>>3)) { memcpy(ines->VPage[A],VPAGE(V>>3)+(V&0x07)*0x0400,0x0400); ines->VPageN[A]=V; } return(1); } /* Unknown address */ return(0);}/** Mapper #32 ***********************************************//** This is an IREM G-101 chip. **//*************************************************************/int SelectROM32(int A,int V){ register int J, I; /* We are only interested in certain writes */ if((A&0xC000)!=0x8000) return(0); I = A&0xF000; if ( A == 0x9000 ) { MM.M32.SPg=V&0x02? 6:4; SetMirror(~V&0x01); return(1); } else if ( A == 0x8000 ) { NES_Page[MM.M32.SPg]=PAGE(V>>1)+(V&0x01? 0x2000:0); return(1); } else if ( A == 0xA000 ) { NES_Page[5]=PAGE(V>>1)+(V&0x01? 0x2000:0); return(1); } else if ( A == 0xB000 ) { A&=0x07; if((V!=ines->VPageN[A])&&VPAGE(V>>3)) { ines->VPageN[A]=V; memcpy(ines->VPage[A],VPAGE(V>>3)+(V&0x07)*0x0400,0x0400); } return(1); } /* Unknown address */ return(0);}/** Mapper #33 ***********************************************//** This is Taito TC0190/TC0350 chips. **//*************************************************************/int SelectROM33(int A,int V){ register int J; /* We are only interested in certain writes */ if((A&0xCFFC)!=0x8000) return(0); if ( A == 0x8002 || A == 0x8003 ) { A=(A&0x01)<<1;V<<=1; if((V!=ines->VPageN[A])&&VPAGE(V>>3)) { ines->VPageN[A]=V; memcpy(ines->VPage[A],VPAGE(V>>3)+(V&0x07)*0x0400,0x0800); } return(1); } else if ( A >= 0xA000 && A <= 0xA003 ) { A=(A&0x03)+4; if((V!=ines->VPageN[A])&&VPAGE(V>>3)) { ines->VPageN[A]=V; memcpy(ines->VPage[A],VPAGE(V>>3)+(V&0x07)*0x0400,0x0400); } return(1); } else if ( A == 0x8000 ) { SetMirror(~V&0x40); NES_Page[4]=PAGE(V>>1)+(V&0x01? 0x2000:0); return(1); } else if ( A == 0x8001 ) { NES_Page[5]=PAGE(V>>1)+(V&0x01? 0x2000:0); return(1); } /* Unknown address */ return(0);}/** Mapper #34 ***********************************************//** This mapper will satisfy ImpossibleMission2 and **//** DeadlyTowers games. It switches 32kB NES_ROM at $8000 and **//** 2 8kB VROM pages at $0000 and $1000. **//*************************************************************/int SelectROM34(int A,int V){ register int J; /*** Mission Impossible 2 ***/ if ( A == 0x7FFD ) { /* Proceed to the NES_ROM switch */ } else if ( A == 0x7FFE ) { /*** 8kB VROM at $0000 ***/ SetVPages(0,3,VROM? VPAGE(V>>1)+(V&0x01? 0x1000:0x0000):NES_VRAM); return(1); } else if ( A == 0x7FFF ) { /*** 8kB VROM at $1000 ***/ SetVPages(4,7,VROM? VPAGE(V>>1)+(V&0x01? 0x1000:0x0000):NES_VRAM+0x1000); return(1); } else { /* Address should be in $8000..$FFFF range */ if(A<0x8000) return(0); } /* Switch 32kB NES_ROM at $8000 */ V<<=1; NES_Page[4]=PAGE(V); NES_Page[5]=NES_Page[4]+0x2000; V++; NES_Page[6]=PAGE(V); NES_Page[7]=NES_Page[6]+0x2000; return(1);}#endif#endif /*INES*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -