From b5b5c7affcf7802a80c776d0bafd4e056491a283 Mon Sep 17 00:00:00 2001 From: qeed Date: Sun, 4 Oct 2009 13:56:43 +0000 Subject: [PATCH] preliminary support for mapper 253 --- src/ines.cpp | 1 + src/ines.h | 4 +- src/mappers/253.cpp | 206 +++++++++++++++++++++++++++++++++++++++++ src/mappers/SConscript | 1 + 4 files changed, 211 insertions(+), 1 deletion(-) create mode 100644 src/mappers/253.cpp diff --git a/src/ines.cpp b/src/ines.cpp index 88acd2f2..933cb805 100644 --- a/src/ines.cpp +++ b/src/ines.cpp @@ -1429,6 +1429,7 @@ static BMAPPING bmap[] = { {245, Mapper245_Init}, {249, Mapper249_Init}, {250, Mapper250_Init}, + {253, Mapper253_Init}, {254, Mapper254_Init}, { 0, 0} }; diff --git a/src/ines.h b/src/ines.h index 516428af..9020bb1d 100644 --- a/src/ines.h +++ b/src/ines.h @@ -107,6 +107,7 @@ struct iNES_HEADER { } } }; +extern struct iNES_HEADER head; //for mappers usage void VRAM_BANK1(uint32 A, uint8 V); void VRAM_BANK4(uint32 A,uint32 V); @@ -341,7 +342,7 @@ void Mapper247_init(void); void Mapper249_init(void); void Mapper251_init(void); void Mapper252_init(void); -void Mapper253_init(void); +//void Mapper253_init(void); void Mapper255_init(void); void NSFVRC6_Init(void); @@ -452,6 +453,7 @@ void Mapper240_Init(CartInfo *); void Mapper245_Init(CartInfo *); void Mapper249_Init(CartInfo *); void Mapper250_Init(CartInfo *); +void Mapper253_Init(CartInfo *); void Mapper254_Init(CartInfo *); #endif diff --git a/src/mappers/253.cpp b/src/mappers/253.cpp new file mode 100644 index 00000000..ea878988 --- /dev/null +++ b/src/mappers/253.cpp @@ -0,0 +1,206 @@ +//Thanks to VirtualNES developer for reverse engineering this mapper + +#include "mapinc.h" + +static uint8 reg[9]; +static uint8 irq_enable, irq_counter, irq_latch, irq_clock; +static uint8 VRAM_switch; + +static void Mapper253_IRQHook(int cycles) +{ + 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)) + { + if(VRAM_switch == 0) + setchr1( bank, page ); //CHR-ROM + else + setchr1( bank, page ); //CHR-RAM + } + else + setchr1( bank, page ); +} + +static DECLFW(Mapper253_Write) +{ + printf("Address: 0x%X V: 0x%X\n", A, V); + 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; + } + } + + 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; + default: + printf("Not handled 0x%X 0x%X", A, V); + } +} + +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); //first bank + + 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); +} + diff --git a/src/mappers/SConscript b/src/mappers/SConscript index 6da16380..cd621966 100644 --- a/src/mappers/SConscript +++ b/src/mappers/SConscript @@ -1,4 +1,5 @@ my_list = Split(""" +253.cpp 151.cpp 16.cpp 17.cpp