Skip to content

Commit

Permalink
added support for mappers 28,31,107,132,136,137,138,139,141,172,173,1…
Browse files Browse the repository at this point in the history
…93,221,229,230,235 and 237 and improved implementations of mappers 36,45,58,62,112 and 225
  • Loading branch information
FIX94 committed Jul 23, 2018
1 parent 6ae44f3 commit 0e99975
Show file tree
Hide file tree
Showing 24 changed files with 1,297 additions and 111 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ If you want to check it out for some reason I do include a windows binary in the

Loading Files:
NTSC and PAL .nes ROMs are supported, it also creates .sav files if the chosen game supports saving.
If you are starting a PAL NES title then make sure it has (E),(Europe),(Australia),(France),(Germany),(Italy),(Spain) or (Sweden) in the filename to be started in PAL mode.
If you are starting a PAL NES title then make sure it has (E),(Europe),(PAL),(Australia),(France),(Germany),(Italy),(Spain) or (Sweden) in the filename to be started in PAL mode.
You can also play FDS titles if you have the FDS BIOS named disksys.rom in the same folder as your .fds/.qd files.
You can also listen to .nsf music files, changing tracks works by pressing left/right.
To start a file, simply drag and drop it into the fixNES Application or call it via command line with the file as argument.
You can also load from a .zip file, the first found supported file from that .zip will be used.

Supported .nes Mappers:
0,1,2,3,4,5,7,9,10,11,12,13,15,19,21,22,23,24,25,26,32,33,34,36,37,38,41,44,45,46,47,48,49,52,57,58,60,61,62,65,66,67,68,69,70,71,73,75,76,78,79,85,87,88,89,93,94,95,97,101,112,113,118,119,133,140,144,145,146,147,148,149,152,154,155,156,174,180,184,185,200,201,202,203,205,206,210,212,225,226,228,232,232,240 and 242.
0,1,2,3,4,5,7,9,10,11,12,13,15,19,21,22,23,24,25,26,28,31,32,33,34,36,37,38,41,44,45,46,47,48,49,52,57,58,60,61,62,65,66,67,68,69,70,71,73,75,76,78,79,85,87,88,89,93,94,95,97,101,107,112,113,118,119,132,133,136,137,138,139,140,141,144,145,146,147,148,149,152,154,155,156,172,173,174,180,184,185,193,200,201,202,203,205,206,210,212,221,225,226,228,229,230,231,232,235,237,240 and 242.
Supported Audio Expansions (for both ROMs and NSF Files):
VRC6, VRC7, FDS, MMC5, N163, Sunsoft 5B

Expand Down
5 changes: 5 additions & 0 deletions libretro/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -352,10 +352,15 @@ OBJS += ../mapper/common.o
OBJS += ../mapper/fds.o
OBJS += ../mapper/m13.o
OBJS += ../mapper/m15.o
OBJS += ../mapper/m137.o
OBJS += ../mapper/m156.o
OBJS += ../mapper/m193.o
OBJS += ../mapper/m28.o
OBJS += ../mapper/m206.o
OBJS += ../mapper/m225.o
OBJS += ../mapper/m228.o
OBJS += ../mapper/m237.o
OBJS += ../mapper/m31.o
OBJS += ../mapper/m32.o
OBJS += ../mapper/m33.o
OBJS += ../mapper/m34.o
Expand Down
22 changes: 19 additions & 3 deletions main.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
#define DEBUG_KEY 0
#define DEBUG_LOAD_INFO 1

const char *VERSION_STRING = "fixNES Alpha v1.2.2";
const char *VERSION_STRING = "fixNES Alpha v1.2.3";
static char window_title[256];
static char window_title_pause[256];

Expand Down Expand Up @@ -195,18 +195,34 @@ int main(int argc, char** argv)
nesEmuFileClose();
nesPAL = (strstr(emuFileName,"(E)") != NULL) || (strstr(emuFileName,"(Europe)") != NULL) || (strstr(emuFileName,"(Australia)") != NULL)
|| (strstr(emuFileName,"(France)") != NULL) || (strstr(emuFileName,"(Germany)") != NULL) || (strstr(emuFileName,"(Italy)") != NULL)
|| (strstr(emuFileName,"(Spain)") != NULL) || (strstr(emuFileName,"(Sweden)") != NULL);
|| (strstr(emuFileName,"(Spain)") != NULL) || (strstr(emuFileName,"(Sweden)") != NULL) || (strstr(emuFileName,"(PAL)") != NULL);
uint8_t mapper = ((emuNesROM[6] & 0xF0) >> 4) | ((emuNesROM[7] & 0xF0));
emuSaveEnabled = (emuNesROM[6] & (1<<1)) != 0;
bool trainer = (emuNesROM[6] & (1<<2)) != 0;
uint32_t ROMsize = emuNesROMsize-16;
uint32_t prgROMsize = emuNesROM[4] * 0x4000;
if(prgROMsize > ROMsize) //ensure we read in bounds
{
printf("Suggested PRG ROM of 0x%04x is too big, using 0x%04x instead\n", prgROMsize, ROMsize);
prgROMsize = ROMsize;
}
ROMsize -= prgROMsize;
uint32_t chrROMsize = emuNesROM[5] * 0x2000;
if(chrROMsize > ROMsize) //ensure we read in bounds
if(prgROMsize == 0) //can happen on some roms...
{
printf("PRG ROM size was 0, forcing the whole file to be PRG ROM\n");
prgROMsize = ROMsize;
if(chrROMsize) //force use CHR RAM in this case for now...
{
printf("CHR ROM was set to 0x%04x, instead of the suggested CHR ROM it will now use CHR RAM\n", chrROMsize);
chrROMsize = 0;
}
}
else if(chrROMsize > ROMsize) //ensure we read in bounds
{
printf("Suggested CHR ROM of 0x%04x is too big, using 0x%04x instead\n", chrROMsize, ROMsize);
chrROMsize = ROMsize;
}
if(mapper == 5) //just to be on the safe side
emuPrgRAMsize = 0x10000;
else
Expand Down
52 changes: 52 additions & 0 deletions mapper/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,58 @@
#include "../mem.h"


static struct {
uint8_t *prgROM;
uint32_t prgROMand;
uint8_t *prgROMBank0Ptr, *prgROMBank1Ptr,
*prgROMBank2Ptr, *prgROMBank3Ptr,
*prgROMBank4Ptr, *prgROMBank5Ptr,
*prgROMBank6Ptr, *prgROMBank7Ptr;
} prg4;

void prg4init(uint8_t *prgROM, uint32_t prgROMsize)
{
prg4.prgROM = prgROM;
prg4.prgROMand = mapperGetAndValue(prgROMsize);
prg4setBank0(0); prg4setBank1(0); prg4setBank2(0); prg4setBank3(0);
prg4setBank4(0); prg4setBank5(0); prg4setBank6(0); prg4setBank7(0);
printf("Using Common PRG ROM (%iKB Total) 4KB Banks\n", (prgROMsize>>10));
}

static uint8_t prg4GetROM0(uint16_t addr) { return prg4.prgROMBank0Ptr[addr&0xFFF]; }
static uint8_t prg4GetROM1(uint16_t addr) { return prg4.prgROMBank1Ptr[addr&0xFFF]; }
static uint8_t prg4GetROM2(uint16_t addr) { return prg4.prgROMBank2Ptr[addr&0xFFF]; }
static uint8_t prg4GetROM3(uint16_t addr) { return prg4.prgROMBank3Ptr[addr&0xFFF]; }
static uint8_t prg4GetROM4(uint16_t addr) { return prg4.prgROMBank4Ptr[addr&0xFFF]; }
static uint8_t prg4GetROM5(uint16_t addr) { return prg4.prgROMBank5Ptr[addr&0xFFF]; }
static uint8_t prg4GetROM6(uint16_t addr) { return prg4.prgROMBank6Ptr[addr&0xFFF]; }
static uint8_t prg4GetROM7(uint16_t addr) { return prg4.prgROMBank7Ptr[addr&0xFFF]; }

void prg4initGet8(uint16_t addr)
{
if(addr < 0x8000) return;
else if(addr < 0x9000) memInitMapperGetPointer(addr, prg4GetROM0);
else if(addr < 0xA000) memInitMapperGetPointer(addr, prg4GetROM1);
else if(addr < 0xB000) memInitMapperGetPointer(addr, prg4GetROM2);
else if(addr < 0xC000) memInitMapperGetPointer(addr, prg4GetROM3);
else if(addr < 0xD000) memInitMapperGetPointer(addr, prg4GetROM4);
else if(addr < 0xE000) memInitMapperGetPointer(addr, prg4GetROM5);
else if(addr < 0xF000) memInitMapperGetPointer(addr, prg4GetROM6);
else memInitMapperGetPointer(addr, prg4GetROM7);
}

void prg4setBank0(uint32_t val) { prg4.prgROMBank0Ptr = prg4.prgROM+(val&prg4.prgROMand); }
void prg4setBank1(uint32_t val) { prg4.prgROMBank1Ptr = prg4.prgROM+(val&prg4.prgROMand); }
void prg4setBank2(uint32_t val) { prg4.prgROMBank2Ptr = prg4.prgROM+(val&prg4.prgROMand); }
void prg4setBank3(uint32_t val) { prg4.prgROMBank3Ptr = prg4.prgROM+(val&prg4.prgROMand); }
void prg4setBank4(uint32_t val) { prg4.prgROMBank4Ptr = prg4.prgROM+(val&prg4.prgROMand); }
void prg4setBank5(uint32_t val) { prg4.prgROMBank5Ptr = prg4.prgROM+(val&prg4.prgROMand); }
void prg4setBank6(uint32_t val) { prg4.prgROMBank6Ptr = prg4.prgROM+(val&prg4.prgROMand); }
void prg4setBank7(uint32_t val) { prg4.prgROMBank7Ptr = prg4.prgROM+(val&prg4.prgROMand); }




static struct {
uint8_t *prgROM;
uint32_t prgROMand;
Expand Down
235 changes: 235 additions & 0 deletions mapper/m137.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,235 @@
/*
* Copyright (C) 2018 FIX94
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/

#include <stdio.h>
#include <inttypes.h>
#include <stdbool.h>
#include <string.h>
#include "../ppu.h"
#include "../mapper.h"
#include "../mem.h"
#include "../mapper_h/common.h"

static struct {
uint8_t reg, regB, regC,
regc, regd, rege, regf;
uint8_t mode, mirror;
bool revhv;
} m137;

static void m137setChrBankPtr()
{
uint8_t chrBank0 = m137.regc&7;
if(m137.mode == 0)
{
uint8_t chrBank1 = (m137.regd&7)|((m137.regB&1)?0x10:0);
uint8_t chrBank2 = (m137.rege&7)|((m137.regB&2)?0x10:0);
uint8_t chrBank3 = (m137.regf&7)|((m137.regB&4)?0x10:0)|((m137.regC&1)?8:0);
chr1setBank0(chrBank0<<10); chr1setBank1(chrBank1<<10);
chr1setBank2(chrBank2<<10); chr1setBank3(chrBank3<<10);
}
else
{
chr1setBank0(chrBank0<<10); chr1setBank1(chrBank0<<10);
chr1setBank2(chrBank0<<10); chr1setBank3(chrBank0<<10);
}
}

static void m138setChrBankPtr()
{
uint8_t chrBank0 = (m137.regc&7)|((m137.regB<<3)&0x38);
if(m137.mode == 0)
{
uint8_t chrBank1 = (m137.regd&7)|((m137.regB<<3)&0x38);
uint8_t chrBank2 = (m137.rege&7)|((m137.regB<<3)&0x38);
uint8_t chrBank3 = (m137.regf&7)|((m137.regB<<3)&0x38);
chr2setBank0(chrBank0<<11); chr2setBank1(chrBank1<<11);
chr2setBank2(chrBank2<<11); chr2setBank3(chrBank3<<11);
}
else
{
chr2setBank0(chrBank0<<11); chr2setBank1(chrBank0<<11);
chr2setBank2(chrBank0<<11); chr2setBank3(chrBank0<<11);
}
}

static void m139setChrBankPtr()
{
uint8_t chrBank0 = ((m137.regc<<2)&0x1C)|((m137.regB<<5)&0xE0);
if(m137.mode == 0)
{
uint8_t chrBank1 = ((m137.regd<<2)&0x1C)|((m137.regB<<5)&0xE0);
uint8_t chrBank2 = ((m137.rege<<2)&0x1C)|((m137.regB<<5)&0xE0);
uint8_t chrBank3 = ((m137.regf<<2)&0x1C)|((m137.regB<<5)&0xE0);
chr2setBank0((chrBank0|0)<<11); chr2setBank1((chrBank1|1)<<11);
chr2setBank2((chrBank2|2)<<11); chr2setBank3((chrBank3|3)<<11);
}
else
{
chr2setBank0((chrBank0|0)<<11); chr2setBank1((chrBank0|1)<<11);
chr2setBank2((chrBank0|2)<<11); chr2setBank3((chrBank0|3)<<11);
}
}

static void m141setChrBankPtr()
{
uint8_t chrBank0 = ((m137.regc<<1)&0xE)|((m137.regB<<4)&0x70);
if(m137.mode == 0)
{
uint8_t chrBank1 = ((m137.regd<<1)&0xE)|((m137.regB<<4)&0x70);
uint8_t chrBank2 = ((m137.rege<<1)&0xE)|((m137.regB<<4)&0x70);
uint8_t chrBank3 = ((m137.regf<<1)&0xE)|((m137.regB<<4)&0x70);
chr2setBank0((chrBank0|0)<<11); chr2setBank1((chrBank1|1)<<11);
chr2setBank2((chrBank2|0)<<11); chr2setBank3((chrBank3|1)<<11);
}
else
{
chr2setBank0((chrBank0|0)<<11); chr2setBank1((chrBank0|1)<<11);
chr2setBank2((chrBank0|0)<<11); chr2setBank3((chrBank0|1)<<11);
}
}

static void m137_commonInit()
{
m137.reg = 0, m137.regB = 0, m137.regC = 0,
m137.regc = 0, m137.regd = 0, m137.rege = 0, m137.regf = 0;
m137.mode = 0, m137.mirror = 0;
}

void m137init(uint8_t *prgROMin, uint32_t prgROMsizeIn,
uint8_t *prgRAMin, uint32_t prgRAMsizeIn,
uint8_t *chrROMin, uint32_t chrROMsizeIn)
{
m137_commonInit();
m137.revhv = true;
prg32init(prgROMin, prgROMsizeIn);
(void)prgRAMin;
(void)prgRAMsizeIn;
chr1init(chrROMin, chrROMsizeIn);
m137setChrBankPtr();
chr1setBank4(chrROMsizeIn - 0x1000);
chr1setBank5(chrROMsizeIn - 0x0C00);
chr1setBank6(chrROMsizeIn - 0x0800);
chr1setBank7(chrROMsizeIn - 0x0400);
printf("Mapper 137 inited\n");
}

void m138init(uint8_t *prgROMin, uint32_t prgROMsizeIn,
uint8_t *prgRAMin, uint32_t prgRAMsizeIn,
uint8_t *chrROMin, uint32_t chrROMsizeIn)
{
m137_commonInit();
m137.revhv = false;
prg32init(prgROMin, prgROMsizeIn);
(void)prgRAMin;
(void)prgRAMsizeIn;
chr2init(chrROMin, chrROMsizeIn);
m138setChrBankPtr();
printf("Mapper 138 inited\n");
}

void m139init(uint8_t *prgROMin, uint32_t prgROMsizeIn,
uint8_t *prgRAMin, uint32_t prgRAMsizeIn,
uint8_t *chrROMin, uint32_t chrROMsizeIn)
{
m137_commonInit();
m137.revhv = false;
prg32init(prgROMin, prgROMsizeIn);
(void)prgRAMin;
(void)prgRAMsizeIn;
chr2init(chrROMin, chrROMsizeIn);
m139setChrBankPtr();
printf("Mapper 139 inited\n");
}

void m141init(uint8_t *prgROMin, uint32_t prgROMsizeIn,
uint8_t *prgRAMin, uint32_t prgRAMsizeIn,
uint8_t *chrROMin, uint32_t chrROMsizeIn)
{
m137_commonInit();
m137.revhv = false;
prg32init(prgROMin, prgROMsizeIn);
(void)prgRAMin;
(void)prgRAMsizeIn;
chr2init(chrROMin, chrROMsizeIn);
m141setChrBankPtr();
printf("Mapper 141 inited\n");
}

static void m137common_setParams4100(uint16_t addr, uint8_t val) { (void)addr; m137.reg = val&7; }
static void m137common_setParams4101(uint16_t addr, uint8_t val)
{
(void)addr;
switch(m137.reg&7)
{
case 0:
m137.regc = val&7;
break;
case 1:
m137.regd = val&7;
break;
case 2:
m137.rege = val&7;
break;
case 3:
m137.regf = val&7;
break;
case 4:
m137.regB = val&7;
break;
case 5:
prg32setBank0((val&7)<<15);
break;
case 6:
m137.regC = val&1;
break;
case 7:
m137.mode = val&1;
m137.mirror = (val>>1)&3;
//update ppu mirroring
if(m137.mirror == 0 || m137.mode)
m137.revhv ? ppuSetNameTblHorizontal() : ppuSetNameTblVertical();
else if(m137.mirror == 1)
m137.revhv ? ppuSetNameTblVertical() : ppuSetNameTblHorizontal();
else if(m137.mirror == 2)
ppuSetNameTblCustom(0,0x400,0x400,0x400);
else if(m137.mirror == 3)
ppuSetNameTblSingleLower();
break;
}
}
static void m137setParams4101(uint16_t addr, uint8_t val) { m137common_setParams4101(addr,val); m137setChrBankPtr(); }
void m137initSet8(uint16_t ori_addr)
{
uint16_t proc_addr = ori_addr&0xC101;
if(proc_addr == 0x4100) memInitMapperSetPointer(ori_addr, m137common_setParams4100);
else if(proc_addr == 0x4101) memInitMapperSetPointer(ori_addr, m137setParams4101);
}

static void m138setParams4101(uint16_t addr, uint8_t val) { m137common_setParams4101(addr,val); m138setChrBankPtr(); }
void m138initSet8(uint16_t ori_addr)
{
uint16_t proc_addr = ori_addr&0xC101;
if(proc_addr == 0x4100) memInitMapperSetPointer(ori_addr, m137common_setParams4100);
else if(proc_addr == 0x4101) memInitMapperSetPointer(ori_addr, m138setParams4101);
}

static void m139setParams4101(uint16_t addr, uint8_t val) { m137common_setParams4101(addr,val); m139setChrBankPtr(); }
void m139initSet8(uint16_t ori_addr)
{
uint16_t proc_addr = ori_addr&0xC101;
if(proc_addr == 0x4100) memInitMapperSetPointer(ori_addr, m137common_setParams4100);
else if(proc_addr == 0x4101) memInitMapperSetPointer(ori_addr, m139setParams4101);
}

static void m141setParams4101(uint16_t addr, uint8_t val) { m137common_setParams4101(addr,val); m141setChrBankPtr(); }
void m141initSet8(uint16_t ori_addr)
{
uint16_t proc_addr = ori_addr&0xC101;
if(proc_addr == 0x4100) memInitMapperSetPointer(ori_addr, m137common_setParams4100);
else if(proc_addr == 0x4101) memInitMapperSetPointer(ori_addr, m141setParams4101);
}
Loading

0 comments on commit 0e99975

Please sign in to comment.