diff --git a/src/boards/28.cpp b/src/boards/28.cpp new file mode 100644 index 00000000..67053302 --- /dev/null +++ b/src/boards/28.cpp @@ -0,0 +1,217 @@ +/* + Copyright (C) 2012 FCEUX team + + This file 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 file 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 the this software. If not, see . +*/ + +#include "mapinc.h" + +// http://wiki.nesdev.com/w/index.php/INES_Mapper_028 + +//config +static int prg_mask_16k; + +// state +uint8 reg; +uint8 chr; +uint8 prg; +uint8 mode; +uint8 outer; + +void SyncMirror() +{ + switch (mode & 3) + { + case 0: setmirror(MI_0); break; + case 1: setmirror(MI_1); break; + case 2: setmirror(MI_V); break; + case 3: setmirror(MI_H); break; + } +} + +void Mirror(uint8 value) +{ + if ((mode & 2) == 0) + { + mode &= 0xfe; + mode |= value >> 4 & 1; + } + SyncMirror(); +} + + +static void Sync() +{ + int prglo; + int prghi; + + int outb = outer << 1; + //this can probably be rolled up, but i have no motivation to do so + //until it's been tested + switch (mode & 0x3c) + { + //32K modes + case 0x00: + case 0x04: + prglo = outb; + prghi = outb | 1; + break; + case 0x10: + case 0x14: + prglo = outb & ~2 | prg << 1 & 2; + prghi = outb & ~2 | prg << 1 & 2 | 1; + break; + case 0x20: + case 0x24: + prglo = outb & ~6 | prg << 1 & 6; + prghi = outb & ~6 | prg << 1 & 6 | 1; + break; + case 0x30: + case 0x34: + prglo = outb & ~14 | prg << 1 & 14; + prghi = outb & ~14 | prg << 1 & 14 | 1; + break; + //bottom fixed modes + case 0x08: + prglo = outb; + prghi = outb | prg & 1; + break; + case 0x18: + prglo = outb; + prghi = outb & ~2 | prg & 3; + break; + case 0x28: + prglo = outb; + prghi = outb & ~6 | prg & 7; + break; + case 0x38: + prglo = outb; + prghi = outb & ~14 | prg & 15; + break; + //top fixed modes + case 0x0c: + prglo = outb | prg & 1; + prghi = outb | 1; + break; + case 0x1c: + prglo = outb & ~2 | prg & 3; + prghi = outb | 1; + break; + case 0x2c: + prglo = outb & ~6 | prg & 7; + prghi = outb | 1; + break; + case 0x3c: + prglo = outb & ~14 | prg & 15; + prghi = outb | 1; + break; + } + prglo &= prg_mask_16k; + prghi &= prg_mask_16k; + + setprg16(0x8000, prglo); + setprg16(0xC000, prghi); + setchr8(chr); +} + +static DECLFW(WriteEXP) +{ + uint32 addr = A; + uint8 value = V; + if (addr >= 05000) + reg = value & 0x81; +} + +static DECLFW(WritePRG) +{ + uint32 addr = A; + uint8 value = V; + switch (reg) + { + case 0x00: + chr = value & 3; + Mirror(value); + break; + case 0x01: + prg = value & 15; + Mirror(value); + Sync(); + break; + case 0x80: + mode = value & 63; + SyncMirror(); + Sync(); + break; + case 0x81: + outer = value & 63; + Sync(); + break; + } +} + + + +static void M28Reset(void) +{ + outer = 63; + prg = 15; + Sync(); +} + + +static void M28Power(void) +{ + prg_mask_16k = PRGsize[0] - 1; + + //EXP + SetWriteHandler(0x4020,0x5FFF,WriteEXP); + + //PRG + SetWriteHandler(0x8000,0xFFFF,WritePRG); + SetReadHandler(0x8000,0xFFFF,CartBR); + + //WRAM + SetReadHandler(0x6000,0x7FFF,CartBR); + SetWriteHandler(0x6000,0x7FFF,CartBW); + + M28Reset(); +} + +static void M28Close(void) +{ +} + +static SFORMAT StateRegs[]= +{ + {®, 1, "REG"}, + {&chr, 1, "CHR"}, + {&prg, 1, "PRG"}, + {&mode, 1, "MODE"}, + {&outer, 1, "OUTR"}, + {0} +}; + +static void StateRestore(int version) +{ + Sync(); +} + +void Mapper28_Init(CartInfo* info) +{ + info->Power=M28Power; + info->Reset=M28Reset; + info->Close=M28Close; + GameStateRestore=StateRestore; + AddExState(&StateRegs, ~0, 0, 0); +} diff --git a/src/boards/SConscript b/src/boards/SConscript index 4c3fb14c..0cc186a8 100644 --- a/src/boards/SConscript +++ b/src/boards/SConscript @@ -41,6 +41,7 @@ my_list = Split(""" 246.cpp 252.cpp 253.cpp +28.cpp 32.cpp 33.cpp 34.cpp diff --git a/src/ines.cpp b/src/ines.cpp index e273c381..ca9a42fb 100644 --- a/src/ines.cpp +++ b/src/ines.cpp @@ -551,7 +551,7 @@ static BMAPPINGLocal bmap[] = { {"Konami VRC2/VRC4", 25, Mapper25_Init}, // {"", 26, Mapper26_Init}, // {"", 27, Mapper27_Init}, // Deprecated, dupe for VRC2/VRC4 mapper -// {"", 28, Mapper28_Init}, + {"INL-ROM", 28, Mapper28_Init}, // {"", 29, Mapper29_Init}, // {"", 30, Mapper30_Init}, // {"", 31, Mapper31_Init}, diff --git a/src/ines.h b/src/ines.h index 6c7407cc..d3acc83f 100644 --- a/src/ines.h +++ b/src/ines.h @@ -382,6 +382,7 @@ void Mapper21_Init(CartInfo *); void Mapper22_Init(CartInfo *); void Mapper23_Init(CartInfo *); void Mapper25_Init(CartInfo *); +void Mapper28_Init(CartInfo *); void Mapper32_Init(CartInfo *); void Mapper33_Init(CartInfo *); void Mapper34_Init(CartInfo *); diff --git a/vc/vc10_fceux.vcxproj b/vc/vc10_fceux.vcxproj index 4986faee..6350c546 100644 --- a/vc/vc10_fceux.vcxproj +++ b/vc/vc10_fceux.vcxproj @@ -268,6 +268,7 @@ + diff --git a/vc/vc10_fceux.vcxproj.filters b/vc/vc10_fceux.vcxproj.filters index 28f4a412..1ab310a7 100644 --- a/vc/vc10_fceux.vcxproj.filters +++ b/vc/vc10_fceux.vcxproj.filters @@ -964,6 +964,9 @@ boards + + boards + diff --git a/vc/vc8_fceux.vcproj b/vc/vc8_fceux.vcproj index e0f595dc..96425205 100644 --- a/vc/vc8_fceux.vcproj +++ b/vc/vc8_fceux.vcproj @@ -771,6 +771,10 @@ /> + + diff --git a/vc/vc9_fceux.vcproj b/vc/vc9_fceux.vcproj index 54030c49..8d1b6dc5 100644 --- a/vc/vc9_fceux.vcproj +++ b/vc/vc9_fceux.vcproj @@ -461,10 +461,6 @@ RelativePath="..\src\boards\222.cpp" > - - @@ -473,6 +469,10 @@ RelativePath="..\src\boards\253.cpp" > + + @@ -709,6 +709,10 @@ RelativePath="..\src\boards\tf-1201.cpp" > + +