diff --git a/src/boards/253.cpp b/src/boards/253.cpp new file mode 100644 index 00000000..0714e412 --- /dev/null +++ b/src/boards/253.cpp @@ -0,0 +1,164 @@ +/* FCE Ultra - NES/Famicom Emulator + * + * Copyright notice for this file: + * Copyright (C) 2009 CaH4e3, qeed + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "mapinc.h" + +static uint8 chrlo[8], chrhi[8], prg[2], mirr; +static int32 IRQa, IRQCount, IRQLatch, IRQClock; +static uint8 *WRAM=NULL; +static uint32 WRAMSIZE; +static uint8 *CHRRAM=NULL; +static uint32 CHRRAMSIZE; + +static SFORMAT StateRegs[]= +{ + {chrlo, 8, "CHRLO"}, + {chrhi, 8, "CHRHI"}, + {prg, 2, "PRGR"}, + {&mirr, 1, "MIRR"}, + {&IRQa, 4, "IRQA"}, + {&IRQCount, 4, "IRQC"}, + {&IRQLatch, 4, "IRQL"}, + {&IRQClock, 4, "IRQCL"}, + {0} +}; + +static void Sync(void) +{ + uint8 i; + setprg8r(0x10,0x6000,0); + setprg8(0x8000,prg[0]); + setprg8(0xa000,prg[1]); + setprg8(0xc000,~1); + setprg8(0xe000,~0); + for(i=0; i<8; i++) + { + uint32 chr = chrlo[i]|(chrhi[i]<<8); + if ((chr==4)||(chr==5)) // [ES-1064] Qi Long Zhu (C) + setchr1r(0x10,i<<10,chr&1); + else + setchr1(i<<10,chr); + } + switch(mirr) + { + case 0: setmirror(MI_V); break; + case 1: setmirror(MI_H); break; + case 2: setmirror(MI_0); break; + case 3: setmirror(MI_1); break; + } +} + +static DECLFW(M253Write) +{ + if((A>=0xB000)&&(A<=0xE00C)) + { + uint8 ind=((((A&8)|(A>>8))>>3)+2)&7; + uint8 sar=A&4; + chrlo[ind]=(chrlo[ind]&(0xF0>>sar))|((V&0x0F)<>4; + Sync(); + } + else + switch(A) + { + case 0x8010: prg[0]=V; Sync(); break; + case 0xA010: prg[1]=V; Sync(); break; + case 0x9400: mirr=V&3; Sync(); break; + case 0xF000: IRQLatch = (IRQLatch & 0xF0) | (V & 0x0F); break; + case 0xF004: IRQLatch = (IRQLatch & 0x0F) | (V << 4); break; + case 0xF008: + IRQa = V&3; + if(IRQa&2) + { + IRQCount = IRQLatch; + IRQClock = 0; + } + X6502_IRQEnd(FCEU_IQEXT); + break; + } +} + +static void M253Power(void) +{ + Sync(); + SetReadHandler(0x6000,0x7FFF,CartBR); + SetWriteHandler(0x6000,0x7FFF,CartBW); + SetReadHandler(0x8000,0xFFFF,CartBR); + SetWriteHandler(0x8000,0xFFFF,M253Write); +} + +static void M253Close(void) +{ + if(WRAM) + FCEU_gfree(WRAM); + if(CHRRAM) + FCEU_gfree(CHRRAM); + WRAM=CHRRAM=NULL; +} + +static void M253IRQ(int cycles) +{ + if(IRQa&2) + { + if((IRQClock+=cycles)>=0x72) + { + IRQClock -= 0x72; + if(IRQCount==0xFF) + { + IRQCount = IRQLatch; + IRQa = (IRQa&2)|((IRQa&0x01)<<1); + X6502_IRQBegin(FCEU_IQEXT); + } + else + IRQCount++; + } + } +} + +static void StateRestore(int version) +{ + Sync(); +} + +void Mapper253_Init(CartInfo *info) +{ + info->Power=M253Power; + info->Close=M253Close; + MapIRQHook=M253IRQ; + GameStateRestore=StateRestore; + + CHRRAMSIZE=4096; + CHRRAM=(uint8*)FCEU_gmalloc(CHRRAMSIZE); + SetupCartPRGMapping(0x10,CHRRAM,CHRRAMSIZE,1); + AddExState(CHRRAM, CHRRAMSIZE, 0, "CRAM"); + + WRAMSIZE=8192; + WRAM=(uint8*)FCEU_gmalloc(WRAMSIZE); + SetupCartPRGMapping(0x10,WRAM,WRAMSIZE,1); + AddExState(WRAM, WRAMSIZE, 0, "WRAM"); + if(info->battery) + { + info->SaveGame[0]=WRAM; + info->SaveGameLen[0]=WRAMSIZE; + } + + AddExState(&StateRegs, ~0, 0, 0); +} diff --git a/src/boards/bandai.cpp b/src/boards/bandai.cpp index 78443417..7e76727d 100644 --- a/src/boards/bandai.cpp +++ b/src/boards/bandai.cpp @@ -48,7 +48,7 @@ static void BandaiIRQHook(int a) { X6502_IRQBegin(FCEU_IQEXT); IRQa = 0; - IRQCount = 0xFFFF; + IRQCount = -1; } } } diff --git a/src/boards/bmc42in1r.cpp b/src/boards/bmc42in1r.cpp index 15afeaf2..bbd77eb9 100644 --- a/src/boards/bmc42in1r.cpp +++ b/src/boards/bmc42in1r.cpp @@ -2,6 +2,7 @@ * * Copyright notice for this file: * Copyright (C) 2005 CaH4e3 + * Copyright (C) 2009 qeed * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -17,77 +18,47 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * BMC 42-in-1 reset switch + * BMC 42-in-1 + * it seems now, mapper not reset-based, + * tested on real hardware and it does menus switch by pressing just Select, not Reset + * new registers behaviour proven this too + * */ #include "mapinc.h" -extern uint32 ROM_size; -static uint8 hrd_sw; static uint8 latche[2]; static SFORMAT StateRegs[]= { - {&hrd_sw, 1, "DIPSW"}, {&latche, sizeof(latche), "LATCHE"}, - {&hrd_sw, 1, "HRDSW"}, {0} }; static void Sync(void) { - int bank = (latche[0] >> 1 & 0x0F) | - (latche[0] >> 3 & 0x10) | - (latche[1] << 5 & 0x20); - -/* if(!(latche&0x02)) - setprg32r(0,0x8000,(latche&0x3F)>>1); - else - { - setprg16r(0,0x8000,latche&0x3f); - setprg16r(0,0xC000,latche&0x3f); - } -*/ - /* the old one, doesnt work with 76 in 1 game - * since it doesn't account for all the PRG-ROM - if(!(latche&0x20)) - setprg32r(hrd_sw,0x8000,(latche>>1)&0x0f); - else - { - setprg16r(hrd_sw,0x8000,latche&0x1f); - setprg16r(hrd_sw,0xC000,latche&0x1f); - } - setmirror((latche>>6)&1);*/ + uint8 bank = (latche[0]&0x1f)|((latche[0]&0x80)>>2)|((latche[1]&1))<<6; if(!(latche[0] & 0x20)) - setprg32r(hrd_sw,0x8000,bank); + setprg32(0x8000,bank >> 1); else { - bank = (bank << 1) | (latche[0] & 1); - setprg16r(hrd_sw,0x8000,bank); - setprg16r(hrd_sw,0xC000,bank); + setprg16(0x8000,bank); + setprg16(0xC000,bank); } - setmirror((latche[0] & 0x40) ? MI_V : MI_H); + setmirror((latche[0]>>6)&1); + setchr8(0); } -static DECLFW(BMC42in1rWrite) +static DECLFW(M226Write) { latche[A & 1] = V; - //latche = V; Sync(); } -static void BMC42in1rReset(void) -{ - hrd_sw^=1; - Sync(); -} - -static void BMC42in1rPower(void) +static void M226Power(void) { latche[0] = latche[1] = 0; - hrd_sw=0; - setchr8(0); Sync(); - SetWriteHandler(0x8000,0xFFFF,BMC42in1rWrite); + SetWriteHandler(0x8000,0xFFFF,M226Write); SetReadHandler(0x8000,0xFFFF,CartBR); } @@ -96,30 +67,9 @@ static void StateRestore(int version) Sync(); } -void BMC42in1r_Init(CartInfo *info) -{ - info->Power=BMC42in1rPower; - info->Reset=BMC42in1rReset; - AddExState(&StateRegs, ~0, 0, 0); - GameStateRestore=StateRestore; -} - -static void M226Power(void) -{ - if(ROM_size==64) - SetupCartPRGMapping(1,PRGptr[0]+512*1024,512,0); - latche[0] = 0; - hrd_sw=0; - setchr8(0); - Sync(); - SetWriteHandler(0x8000,0xFFFF,BMC42in1rWrite); - SetReadHandler(0x8000,0xFFFF,CartBR); -} - void Mapper226_Init(CartInfo *info) { info->Power=M226Power; - info->Reset=BMC42in1rReset; AddExState(&StateRegs, ~0, 0, 0); GameStateRestore=StateRestore; } diff --git a/src/mappers/253.cpp b/src/mappers/253.cpp deleted file mode 100644 index 54ad388c..00000000 --- a/src/mappers/253.cpp +++ /dev/null @@ -1,223 +0,0 @@ -//Thanks to VirtualNES developer for reverse engineering this mapper -//first screen add 32 to chr -//second screen at 0x42000 -#include "mapinc.h" - -static uint8 reg[9], VRAM_switch; -static int32 irq_enable, irq_counter, irq_latch, irq_clock; - -static SFORMAT StateRegs[]= -{ - { reg, sizeof(reg), "MAPPER_REGS" }, - { &VRAM_switch, sizeof(VRAM_switch), "MAPPER_VRAMSWITCH" }, - { &irq_enable, sizeof(irq_enable), "MAPPER_IRQ_ENABLE" }, - { &irq_counter, sizeof(irq_counter), "MAPPER_IRQ_COUNTER" }, - { &irq_latch, sizeof(irq_latch), "MAPPER_IRQ_LATCH" }, - { &irq_clock, sizeof(irq_clock), "MAPPER_IRQ_CLOCK" }, - { 0 } -}; - -static void Mapper253_IRQHook(int cycles) -{ - //basically, this happens at every frame - //0x72 is 114 cycles, so like one scanline - //happens for 0xff scanlines so 256 scanlines (frame) - if( irq_enable & 0x02 ) - { - if( (irq_clock+=cycles) >= 0x72 ) - { - irq_clock -= 0x72; - - if( irq_counter == 0xFF) - { - irq_counter = irq_latch; - irq_enable = (irq_enable & 0x01) * 3; - X6502_IRQBegin(FCEU_IQEXT); - } else - { - irq_counter++; - } - } - } -} - -static void SetBank_PPUSUB(int bank, int page) -{ - if(page == 0x88) - { - VRAM_switch = 0; - return; - } - else if(page == 0xC8) - { - VRAM_switch = 1; - return; - } - if ((page == 4) || (page == 5)) - { - // [ES-1064] Qi Long Zhu (C).NES game uses CHR-RAM for these pages - //and doesn't seem to set VRAM switch so use - //CHR-RAM as default for now - /*if (VRAM_switch == 0) - setchr1(bank << 10, page); //CHR-ROM - else*/ - setvramb1(&CHRRAM[page << 10], page << 10, 0); //CHR-RAM - } - else - setchr1(bank << 10, page); -} - -static DECLFW(Mapper253_Write) -{ - if (A == 0x8010) //8kb select at 0x8000 - { - setprg8(0x8000, V); - return; - } - - if (A == 0xA010) //8kb select at 0xA000 - { - setprg8(0xA000, V); - return; - } - - if (A == 0x9400) //Mirroring - { - V &= 0x03; - switch (V) - { - case 0: - setmirror(MI_V); - break; - case 1: - setmirror(MI_H); - break; - case 2: - setmirror(MI_0); - break; - case 3: - setmirror(MI_1); - break; - } - return; - } - - switch (A & 0xF00C) - { - case 0xB000: - reg[0] = (reg[0] & 0xF0) | (V & 0x0F); - SetBank_PPUSUB( 0, reg[0] ); - break; - case 0xB004: - reg[0] = (reg[0] & 0x0F) | ((V & 0x0F) << 4); - SetBank_PPUSUB( 0, reg[0] + ((V>>4)*0x100) ); - break; - case 0xB008: - reg[1] = (reg[1] & 0xF0) | (V & 0x0F); - SetBank_PPUSUB( 1, reg[1] ); - break; - case 0xB00C: - reg[1] = (reg[1] & 0x0F) | ((V & 0x0F) << 4); - SetBank_PPUSUB( 1, reg[1] + ((V>>4)*0x100) ); - break; - case 0xC000: - reg[2] = (reg[2] & 0xF0) | (V & 0x0F); - SetBank_PPUSUB( 2, reg[2] ); - break; - case 0xC004: - reg[2] = (reg[2] & 0x0F) | ((V & 0x0F) << 4); - SetBank_PPUSUB( 2, reg[2] + ((V>>4)*0x100) ); - break; - case 0xC008: - reg[3] = (reg[3] & 0xF0) | (V & 0x0F); - SetBank_PPUSUB( 3, reg[3] ); - break; - case 0xC00C: - reg[3] = (reg[3] & 0x0F) | ((V & 0x0F) << 4); - SetBank_PPUSUB( 3, reg[3] + ((V>>4)*0x100) ); - break; - case 0xD000: - reg[4] = (reg[4] & 0xF0) | (V & 0x0F); - SetBank_PPUSUB( 4, reg[4] ); - break; - case 0xD004: - reg[4] = (reg[4] & 0x0F) | ((V & 0x0F) << 4); - SetBank_PPUSUB( 4, reg[4] + ((V>>4)*0x100) ); - break; - case 0xD008: - reg[5] = (reg[5] & 0xF0) | (V & 0x0F); - SetBank_PPUSUB( 5, reg[5] ); - break; - case 0xD00C: - reg[5] = (reg[5] & 0x0F) | ((V & 0x0F) << 4); - SetBank_PPUSUB( 5, reg[5] + ((V>>4)*0x100) ); - break; - case 0xE000: - reg[6] = (reg[6] & 0xF0) | (V & 0x0F); - SetBank_PPUSUB( 6, reg[6] ); - break; - case 0xE004: - reg[6] = (reg[6] & 0x0F) | ((V & 0x0F) << 4); - SetBank_PPUSUB( 6, reg[6] + ((V>>4)*0x100) ); - break; - case 0xE008: - reg[7] = (reg[7] & 0xF0) | (V & 0x0F); - SetBank_PPUSUB( 7, reg[7] ); - break; - case 0xE00C: - reg[7] = (reg[7] & 0x0F) | ((V & 0x0F) << 4); - SetBank_PPUSUB( 7, reg[7] + ((V>>4)*0x100) ); - break; - case 0xF000: - irq_latch = (irq_latch & 0xF0) | (V & 0x0F); - break; - case 0xF004: - irq_latch = (irq_latch & 0x0F) | ((V & 0x0F) << 4); - break; - case 0xF008: - irq_enable = V & 0x03; - if (irq_enable & 0x02) - { - irq_counter = irq_latch; - irq_clock = 0; - } - X6502_IRQEnd(FCEU_IQEXT); - break; - } -} - -static void Mapper253_Power(void) -{ - int i; - for (i = 0; i != 8; ++i) - reg[i] = i; - - reg[8] = 0; - irq_enable = 0; - irq_counter = 0; - irq_latch = 0; - irq_clock = 0; - VRAM_switch = 0; - - setprg16(0x8000, 0); //first bank - setprg16(0xC000, head.ROM_size - 1); //last bank - setchr8(0); - - SetWriteHandler(0x8000, 0xFFFF, Mapper253_Write); - SetReadHandler(0x8000, 0xFFFF, CartBR); -} - -static void Mapper253_Close(void) -{ -} - -void Mapper253_Init(CartInfo *info) -{ - info->Power = Mapper253_Power; - MapIRQHook = Mapper253_IRQHook; - info->Close = Mapper253_Close; - SetWriteHandler(0x8000, 0xFFFF, Mapper253_Write); - SetReadHandler(0x8000, 0xFFFF, CartBR); - AddExState(StateRegs, ~0, 0, 0); -} - diff --git a/src/unif.cpp b/src/unif.cpp index 8d0bc63c..9645cf75 100644 --- a/src/unif.cpp +++ b/src/unif.cpp @@ -409,7 +409,6 @@ static BMAPPING bmap[] = { { "Supervision16in1", Supervision16_Init,0}, { "NovelDiamond9999999in1", Novel_Init,0}, { "Super24in1SC03", Super24_Init,0}, - { "42in1ResetSwitch", BMC42in1r_Init, 0}, { "64in1NoRepeat", BMC64in1nr_Init, 0}, { "13in1JY110", BMC13in1JY110_Init, 0}, { "70in1", BMC70in1_Init, 0}, diff --git a/src/unif.h b/src/unif.h index a3ed1a5f..9e5f3091 100644 --- a/src/unif.h +++ b/src/unif.h @@ -83,7 +83,6 @@ void Supervision16_Init(CartInfo *info); void Super24_Init(CartInfo *info); void Novel_Init(CartInfo *info); -void BMC42in1r_Init(CartInfo *info); void BMC64in1nr_Init(CartInfo *info); void BMC70in1_Init(CartInfo *info); void BMC70in1B_Init(CartInfo *info); diff --git a/vc/vc9_fceux.vcproj b/vc/vc9_fceux.vcproj index e24f8b72..ed283b8c 100644 --- a/vc/vc9_fceux.vcproj +++ b/vc/vc9_fceux.vcproj @@ -1,7 +1,7 @@ - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + @@ -731,7 +735,7 @@ /> - - @@ -2316,15 +2316,6 @@ CompileAs="1" /> - - - @@ -2335,6 +2326,15 @@ CompileAs="1" /> + + + @@ -2394,7 +2394,7 @@ />