Skip to content

Commit

Permalink
-slightly reduced default volume to reduce potential clipping
Browse files Browse the repository at this point in the history
-implemented mapper 30, should work in both flashable and non-flashable configurations
  • Loading branch information
FIX94 committed Jan 16, 2019
1 parent 0e99975 commit 8656faa
Show file tree
Hide file tree
Showing 6 changed files with 351 additions and 13 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ To start a file, simply drag and drop it into the fixNES Application or call it
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,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.
0,1,2,3,4,5,7,9,10,11,12,13,15,19,21,22,23,24,25,26,28,30,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
6 changes: 3 additions & 3 deletions apu.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2017 - 2018 FIX94
* Copyright (C) 2017 - 2019 FIX94
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
Expand Down Expand Up @@ -110,9 +110,9 @@ static struct {
} apu;

#if AUDIO_FLOAT
static float APU_ampVol[7] = { 3.0f, 2.0f, 1.5f, 1.2f, 1.0f, 0.85f, 0.75f };
static float APU_ampVol[7] = { 2.0f, 1.75f, 1.5f, 1.2f, 1.0f, 0.85f, 0.75f };
#else
static int32_t APU_ampVol[7] = { 192, 128, 96, 77, 64, 55, 48 };
static int32_t APU_ampVol[7] = { 128, 112, 96, 77, 64, 55, 48 };
#endif

//used externally
Expand Down
33 changes: 26 additions & 7 deletions main.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2017 - 2018 FIX94
* Copyright (C) 2017 - 2019 FIX94
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
Expand Down Expand Up @@ -38,7 +38,7 @@
#define DEBUG_KEY 0
#define DEBUG_LOAD_INFO 1

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

Expand Down Expand Up @@ -143,6 +143,9 @@ uint32_t cpuCycleTimer;
uint32_t vrc7CycleTimer;
//from input.c
extern uint8_t inValReads[8];
//from m30.c
extern bool m30_flashable;
extern bool m30_singlescreen;
//from m32.c
extern bool m32_singlescreen;
//from p16c8.c
Expand Down Expand Up @@ -223,16 +226,27 @@ int main(int argc, char** argv)
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;
if(mapper == 30 && emuSaveEnabled) //rewritable prg
{
emuPrgRAMsize = prgROMsize;
m30_flashable = true;
}
else
{
emuPrgRAMsize = emuNesROM[8] * 0x2000;
if(emuPrgRAMsize == 0) emuPrgRAMsize = 0x2000;
m30_flashable = false;
if(mapper == 5) //just to be on the safe side
emuPrgRAMsize = 0x10000;
else
{
emuPrgRAMsize = emuNesROM[8] * 0x2000;
if(emuPrgRAMsize == 0) emuPrgRAMsize = 0x2000;
}
}
emuPrgRAM = malloc(emuPrgRAMsize);
uint8_t *prgROM = emuNesROM+16;
if(trainer)
if(m30_flashable) //initial prg fill
memcpy(emuPrgRAM, prgROM, prgROMsize);
else if(trainer)
{
memcpy(emuPrgRAM+0x1000,prgROM,0x200);
prgROM += 512;
Expand Down Expand Up @@ -270,6 +284,11 @@ int main(int argc, char** argv)
#endif
if(mapper == 5)
ppuMapper5 = true;
else if(mapper == 30)
{
//TODO: add single screen ones here
m30_singlescreen = false;
}
else if(mapper == 32)
{
if(strstr(emuFileName,"Major League") != NULL)
Expand Down
300 changes: 300 additions & 0 deletions mapper/m30.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,300 @@
/*
* Copyright (C) 2019 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 <stdbool.h>
#include <inttypes.h>
#include <string.h>
#include "../ppu.h"
#include "../mapper.h"
#include "../mem.h"
#include "../mapper_h/common.h"

//sector erase and byte write
enum {
//get erase/write cmd
M30_STATE_C0_INIT = 0,
M30_STATE_80_INIT,
M30_STATE_C1_INIT,
M30_STATE_81_INIT,
M30_STATE_C2_INIT,
M30_STATE_82_INIT,
//erase cmd check
M30_STATE_C3_DEL,
M30_STATE_83_DEL,
M30_STATE_C4_DEL,
M30_STATE_84_DEL,
//erase cmd execute
M30_STATE_C5_DEL,
M30_STATE_85_DEL,
//write cmd execute
M30_STATE_C3_WRI,
M30_STATE_83_WRI,
};

static struct {
uint8_t chrRAM[0x8000];
uint8_t *chrRAMBankPtr;
uint8_t *prgRAMptr;
uint8_t *prgRAMBankPtr;
uint32_t prgRAMsize;
uint32_t prgRAMand;
uint8_t step, manID, devID;
bool software_id;
} m30;
//used externally
bool m30_flashable;
bool m30_singlescreen;

void m30init(uint8_t *prgROMin, uint32_t prgROMsizeIn,
uint8_t *prgRAMin, uint32_t prgRAMsizeIn,
uint8_t *chrROMin, uint32_t chrROMsizeIn)
{
if(m30_flashable)
{
m30.prgRAMptr = prgRAMin;
m30.prgRAMBankPtr = m30.prgRAMptr;
m30.prgRAMsize = prgRAMsizeIn;
m30.prgRAMand = mapperGetAndValue(prgRAMsizeIn);
prg16init(prgRAMin, prgRAMsizeIn);
prg16setBank1(prgRAMsizeIn - 0x4000);
m30.step = M30_STATE_C0_INIT; //sequence progress
m30.software_id = false; //replaces 8000/8001
m30.manID = 0xBF; //SST, Device ID Below
m30.devID = (prgRAMsizeIn == 0x20000 ? 0xB5 : (prgRAMsizeIn == 0x40000 ? 0xB6 : (prgRAMsizeIn == 0x80000 ? 0xB7 : 0)));
printf("Mapper 30 flashable, Man ID %02x Dev ID %02x\n", m30.manID, m30.devID);
}
else
{
m30.prgRAMptr = NULL, m30.prgRAMBankPtr = NULL;
m30.prgRAMsize = 0;
prg16init(prgROMin, prgROMsizeIn);
prg16setBank1(prgROMsizeIn - 0x4000);
printf("Mapper 30 not flashable\n");
}
(void)chrROMin; (void)chrROMsizeIn;
m30.chrRAMBankPtr = m30.chrRAM;
if(m30_singlescreen)
ppuSetNameTblSingleLower();
printf("Mapper 30 inited\n");
}

static void m30setParamsNoFlash(uint16_t addr, uint8_t val)
{
(void)addr;
prg16setBank0((val&0x1F)<<14);
m30.chrRAMBankPtr = m30.chrRAM+((val&0x60)<<8);
if(m30_singlescreen)
{
if(val & 0x80)
ppuSetNameTblSingleUpper();
else
ppuSetNameTblSingleLower();
}
}

static uint8_t m30GetId0(uint16_t addr) { (void)addr; return m30.manID; }
static uint8_t m30GetId1(uint16_t addr) { (void)addr; return m30.devID; }

static void m30sidEntry()
{
//printf("M30 Software ID CMD Entry\n");
m30.software_id = true;
memInitMapperGetPointer(0x8000, m30GetId0);
memInitMapperGetPointer(0x8001, m30GetId1);
}

static void m30sidExit()
{
//printf("M30 Software ID CMD Exit\n");
m30.software_id = false;
prg16initGet8(0x8000);
prg16initGet8(0x8001);
}

static void m30setParams8000(uint16_t addr, uint8_t val)
{
//printf("%04x %02x\n", addr, val);
if(val == 0xF0 && m30.software_id)
m30sidExit();
switch(m30.step)
{
//initial cmd check
case M30_STATE_80_INIT:
if(addr == 0x9555 && val == 0xAA)
m30.step = M30_STATE_C1_INIT;
else goto _8000_step_reset;
break;
case M30_STATE_81_INIT:
if(addr == 0xAAAA && val == 0x55)
m30.step = M30_STATE_C2_INIT;
else goto _8000_step_reset;
break;
case M30_STATE_82_INIT:
if(addr == 0x9555 && val == 0x80)
{
//printf("M30 Erase CMD\n");
m30.step = M30_STATE_C3_DEL;
}
else if(addr == 0x9555 && val == 0xA0)
{
//printf("M30 Write CMD\n");
m30.step = M30_STATE_C3_WRI;
}
else
{
if(addr == 0x9555 && val == 0x90 && !m30.software_id)
m30sidEntry();
//redundant since any address exits software id?
//else if(addr == 0x9555 && val == 0xF0 && m30.software_id)
// m30sidExit();
goto _8000_step_reset;
}
break;
//delete cmd check
case M30_STATE_83_DEL:
if(addr == 0x9555 && val == 0xAA)
m30.step = M30_STATE_C4_DEL;
else goto _8000_step_reset;
break;
case M30_STATE_84_DEL:
if(addr == 0xAAAA && val == 0x55)
m30.step = M30_STATE_C5_DEL;
else goto _8000_step_reset;
break;
//executes delete
case M30_STATE_85_DEL:
if(addr == 0x9555 && val == 0x10) //full erase
{
//printf("M30 Full Erase\n");
if(m30.prgRAMptr && m30.prgRAMsize)
memset(m30.prgRAMptr, 0xFF, m30.prgRAMsize);
}
else if(val == 30) //sector erase
{
//printf("M30 Sector Erase %04x\n", (addr&0x7000));
if(m30.prgRAMBankPtr)
memset(m30.prgRAMBankPtr+(addr&0x7000), 0xFF, 0x1000);
}
goto _8000_step_reset;
//executes write
case M30_STATE_83_WRI:
if(m30.prgRAMBankPtr) //byte write
{
//printf("M30 Byte Write %04x %02x\n", addr&0x7FFF, val);
m30.prgRAMBankPtr[addr&0x7FFF] = val;
}
goto _8000_step_reset;
//any other state or state verify fail
//will result in a command reset
default:
_8000_step_reset:
m30.step = M30_STATE_C0_INIT;
break;
}
}

static void m30setParamsC000(uint16_t addr, uint8_t val)
{
//printf("%04x %02x\n", addr, val);
m30setParamsNoFlash(addr, val);
if(val == 0xF0 && m30.software_id)
m30sidExit();
switch(m30.step)
{
//initial cmd check
case M30_STATE_C0_INIT:
if(addr == 0xC000 && val == 1)
m30.step = M30_STATE_80_INIT;
break;
case M30_STATE_C1_INIT:
if(addr == 0xC000 && val == 0)
m30.step = M30_STATE_81_INIT;
else goto c000_step_reset;
break;
case M30_STATE_C2_INIT:
if(addr == 0xC000 && val == 1)
m30.step = M30_STATE_82_INIT;
else goto c000_step_reset;
break;
//delete cmd check
case M30_STATE_C3_DEL:
if(addr == 0xC000 && val == 1)
m30.step = M30_STATE_83_DEL;
else goto c000_step_reset;
break;
case M30_STATE_C4_DEL:
if(addr == 0xC000 && val == 0)
m30.step = M30_STATE_84_DEL;
else goto c000_step_reset;
break;
//executes delete
case M30_STATE_C5_DEL:
if(addr == 0xC000 && val < 0x20)
{
m30.step = M30_STATE_85_DEL;
if(m30.prgRAMptr) //for memset
{
//printf("M30 Delete Bank %04x\n", val);
m30.prgRAMBankPtr = m30.prgRAMptr+((val<<14)&m30.prgRAMand);
}
}
else goto c000_step_reset;
break;
//executes write
case M30_STATE_C3_WRI:
if(addr == 0xC000 && val < 0x20)
{
m30.step = M30_STATE_83_WRI;
if(m30.prgRAMptr) //for byte write
{
//printf("M30 Write Bank %04x\n", val);
m30.prgRAMBankPtr = m30.prgRAMptr+((val<<14)&m30.prgRAMand);
}
}
else goto c000_step_reset;
break;
//any other state or state verify fail
//will result in a command reset
default:
c000_step_reset:
//immediately do M30_STATE_C0_INIT check
if(addr == 0xC000 && val == 1)
m30.step = M30_STATE_80_INIT;
else //different values, full reset
m30.step = M30_STATE_C0_INIT;
break;
}
}

void m30initSet8(uint16_t addr)
{
if(addr < 0x8000) return;
if(m30_flashable)
{
if(addr < 0xC000)
memInitMapperSetPointer(addr, m30setParams8000);
else
memInitMapperSetPointer(addr, m30setParamsC000);
}
else
memInitMapperSetPointer(addr, m30setParamsNoFlash);
}

static uint8_t m30ChrGetRAM(uint16_t addr) { return m30.chrRAMBankPtr[addr]; }
void m30initPPUGet8(uint16_t addr)
{
if(addr < 0x2000)
memInitMapperPPUGetPointer(addr, m30ChrGetRAM);
}

static void m30ChrSetRAM(uint16_t addr, uint8_t val) { m30.chrRAMBankPtr[addr] = val; }
void m30initPPUSet8(uint16_t addr)
{
if(addr < 0x2000)
memInitMapperPPUSetPointer(addr, m30ChrSetRAM);
}
Loading

0 comments on commit 8656faa

Please sign in to comment.