Add mapper 594 with expansion sound.
This commit is contained in:
133
src/boards/594.c
Normal file
133
src/boards/594.c
Normal file
@@ -0,0 +1,133 @@
|
||||
/* FCEUmm - NES/Famicom Emulator
|
||||
*
|
||||
* Copyright notice for this file:
|
||||
* Copyright (C) 2020
|
||||
*
|
||||
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#include "mapinc.h"
|
||||
#include "asic_mmc3.h"
|
||||
#include "fifo.h"
|
||||
#include "msm6585.h"
|
||||
#include <stdio.h>
|
||||
|
||||
static uint8 reg[4];
|
||||
static FIFO fifo;
|
||||
static MSM6585 adpcm;
|
||||
static int32 soundOffset = 0;
|
||||
|
||||
static void sync () {
|
||||
int prgAND = 0x3F;
|
||||
int chrAND = reg[2] &0xC0? 0x0FF: 0x1FF;
|
||||
int prgOR = (reg[2] &0x40? 0x0C0: 0x000) | (reg[2] &0x80? 0x100: 0x000);
|
||||
int chrOR = (reg[2] &0x40? 0x200: 0x000) | (reg[2] &0x80? 0x300: 0x000);
|
||||
setprg8(0x6000, reg[0] | prgOR);
|
||||
MMC3_syncPRG(prgAND, prgOR &~prgAND);
|
||||
MMC3_syncCHR(chrAND, chrOR &~chrAND);
|
||||
MMC3_syncMirror();
|
||||
}
|
||||
|
||||
static int getCHRBank (uint8 bank) {
|
||||
return MMC3_getCHRBank(bank) | bank <<6 &0x100;
|
||||
}
|
||||
|
||||
static DECLFR (readADPCM) {
|
||||
return FIFO_halfFull(&fifo)? 0x00: 0x40;
|
||||
}
|
||||
|
||||
static DECLFW (writeADPCM) {
|
||||
if (A &1) {
|
||||
MSM6585_setRate(&adpcm, V >>6);
|
||||
FIFO_reset(&fifo);
|
||||
} else
|
||||
FIFO_add(&fifo, V);
|
||||
}
|
||||
|
||||
static int serveADPCM (void) {
|
||||
return FIFO_retrieve(&fifo);
|
||||
}
|
||||
|
||||
static DECLFW (writeReg) {
|
||||
reg[A >>12 &2 | A &1] = V;
|
||||
sync();
|
||||
}
|
||||
|
||||
static void reset () {
|
||||
reg[0] = reg[1] = reg[2] = reg[3] = 0;
|
||||
MMC3_clear();
|
||||
FIFO_reset(&fifo);
|
||||
MSM6585_reset(&adpcm);
|
||||
}
|
||||
|
||||
static void power () {
|
||||
reg[0] = reg[1] = reg[2] = reg[3] = 0;
|
||||
MMC3_power();
|
||||
FIFO_reset(&fifo);
|
||||
MSM6585_reset(&adpcm);
|
||||
SetReadHandler(0x5000, 0x5FFF, readADPCM);
|
||||
SetWriteHandler(0x5000, 0x5FFF, writeADPCM);
|
||||
SetWriteHandler(0x9000, 0x9FFF, writeReg);
|
||||
SetWriteHandler(0xB000, 0xBFFF, writeReg);
|
||||
}
|
||||
|
||||
static void mapperSound_fillBufferLow (int count) {
|
||||
int i;
|
||||
int end = (SOUNDTS <<16) /soundtsinc;
|
||||
for (i = soundOffset; i < end; i++) {
|
||||
MSM6585_run(&adpcm);
|
||||
Wave[i >>4] += MSM6585_getOutput(&adpcm) >>1;
|
||||
}
|
||||
soundOffset = count;
|
||||
}
|
||||
|
||||
static void mapperSound_fillBufferHigh () {
|
||||
int i;
|
||||
for (i = soundOffset; i < SOUNDTS; i++) {
|
||||
MSM6585_run(&adpcm);
|
||||
WaveHi[i] += MSM6585_getOutput(&adpcm)*8 +16384;
|
||||
}
|
||||
soundOffset = SOUNDTS;
|
||||
}
|
||||
|
||||
static void mapperSound_setSoundOffset(int32 newSoundOffset) {
|
||||
soundOffset = newSoundOffset;
|
||||
}
|
||||
|
||||
static void mapperSound_init (void) {
|
||||
if (FSettings.SndRate) {
|
||||
GameExpSound.Fill = mapperSound_fillBufferLow;
|
||||
GameExpSound.HiFill = mapperSound_fillBufferHigh;
|
||||
GameExpSound.HiSync = mapperSound_setSoundOffset;
|
||||
GameExpSound.RChange = mapperSound_init;
|
||||
}
|
||||
MSM6585_init(&adpcm, FSettings.soundq >=1? 1789773: FSettings.SndRate*16, serveADPCM);
|
||||
}
|
||||
|
||||
static void close() {
|
||||
FIFO_close(&fifo);
|
||||
}
|
||||
|
||||
void Mapper594_Init (CartInfo *info) {
|
||||
MMC3_init(info, sync, MMC3_TYPE_AX5202P, NULL, getCHRBank, NULL, NULL);
|
||||
FIFO_init(&fifo, 1024);
|
||||
info->Power = power;
|
||||
info->Reset = reset;
|
||||
info->Close = close;
|
||||
mapperSound_init();
|
||||
AddExState(reg, 4, 0, "EXPR");
|
||||
}
|
||||
43
src/boards/fifo.c
Normal file
43
src/boards/fifo.c
Normal file
@@ -0,0 +1,43 @@
|
||||
#include "mapinc.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "fifo.h"
|
||||
|
||||
size_t FIFO_size (FIFO *fifo) {
|
||||
fifo->front %= fifo->capacity;
|
||||
fifo->back %= fifo->capacity;
|
||||
return (fifo->back -fifo->front +fifo->capacity) %fifo->capacity;
|
||||
}
|
||||
|
||||
uint8 FIFO_halfFull (FIFO *fifo) {
|
||||
return FIFO_size(fifo) >= fifo->capacity /2;
|
||||
}
|
||||
|
||||
int FIFO_retrieve (FIFO *fifo) {
|
||||
fifo->front %= fifo->capacity;
|
||||
return FIFO_size(fifo)? fifo->data[fifo->front++]: 0;
|
||||
}
|
||||
|
||||
void FIFO_add (FIFO *fifo, uint8 value) {
|
||||
fifo->back %= fifo->capacity;
|
||||
if (FIFO_size(fifo) <fifo->capacity) fifo->data[fifo->back++] = value;
|
||||
}
|
||||
|
||||
void FIFO_reset (FIFO *fifo) {
|
||||
fifo->front = fifo->back = 0;
|
||||
}
|
||||
|
||||
void FIFO_init (FIFO *fifo, size_t newCapacity) {
|
||||
fifo->capacity = newCapacity;
|
||||
fifo->data = (uint8*)FCEU_gmalloc(newCapacity);
|
||||
AddExState(fifo->data, fifo->capacity, 0, "FIFD");
|
||||
AddExState(&fifo->front, 2, 0, "FIFF");
|
||||
AddExState(&fifo->back, 2, 0, "FIFB");
|
||||
}
|
||||
|
||||
void FIFO_close (FIFO *fifo) {
|
||||
if (fifo->data) {
|
||||
free(fifo->data);
|
||||
fifo->data = NULL;
|
||||
}
|
||||
}
|
||||
19
src/boards/fifo.h
Normal file
19
src/boards/fifo.h
Normal file
@@ -0,0 +1,19 @@
|
||||
#ifndef _FIFO_H
|
||||
#define _FIFO_H
|
||||
|
||||
typedef struct {
|
||||
size_t capacity;
|
||||
uint8 *data;
|
||||
int16 front;
|
||||
int16 back;
|
||||
} FIFO;
|
||||
|
||||
size_t FIFO_size (FIFO *);
|
||||
uint8 FIFO_halfFull (FIFO *);
|
||||
int FIFO_retrieve (FIFO *);
|
||||
void FIFO_add (FIFO *, uint8);
|
||||
void FIFO_reset (FIFO *);
|
||||
void FIFO_init (FIFO *, size_t);
|
||||
void FIFO_close (FIFO *);
|
||||
|
||||
#endif
|
||||
101
src/boards/msm6585.c
Normal file
101
src/boards/msm6585.c
Normal file
@@ -0,0 +1,101 @@
|
||||
#include "mapinc.h"
|
||||
#include "msm6585.h"
|
||||
|
||||
static const int16_t diff_lookup[49*16] = {
|
||||
2, 6, 10, 14, 18, 22, 26, 30, -2, -6, -10, -14, -18, -22, -26, -30,
|
||||
2, 6, 10, 14, 19, 23, 27, 31, -2, -6, -10, -14, -19, -23, -27, -31,
|
||||
2, 6, 11, 15, 21, 25, 30, 34, -2, -6, -11, -15, -21, -25, -30, -34,
|
||||
2, 7, 12, 17, 23, 28, 33, 38, -2, -7, -12, -17, -23, -28, -33, -38,
|
||||
2, 7, 13, 18, 25, 30, 36, 41, -2, -7, -13, -18, -25, -30, -36, -41,
|
||||
3, 9, 15, 21, 28, 34, 40, 46, -3, -9, -15, -21, -28, -34, -40, -46,
|
||||
3, 10, 17, 24, 31, 38, 45, 52, -3, -10, -17, -24, -31, -38, -45, -52,
|
||||
3, 10, 18, 25, 34, 41, 49, 56, -3, -10, -18, -25, -34, -41, -49, -56,
|
||||
4, 12, 21, 29, 38, 46, 55, 63, -4, -12, -21, -29, -38, -46, -55, -63,
|
||||
4, 13, 22, 31, 41, 50, 59, 68, -4, -13, -22, -31, -41, -50, -59, -68,
|
||||
5, 15, 25, 35, 46, 56, 66, 76, -5, -15, -25, -35, -46, -56, -66, -76,
|
||||
5, 16, 27, 38, 50, 61, 72, 83, -5, -16, -27, -38, -50, -61, -72, -83,
|
||||
6, 18, 31, 43, 56, 68, 81, 93, -6, -18, -31, -43, -56, -68, -81, -93,
|
||||
6, 19, 33, 46, 61, 74, 88, 101, -6, -19, -33, -46, -61, -74, -88, -101,
|
||||
7, 22, 37, 52, 67, 82, 97, 112, -7, -22, -37, -52, -67, -82, -97, -112,
|
||||
8, 24, 41, 57, 74, 90, 107, 123, -8, -24, -41, -57, -74, -90, -107, -123,
|
||||
9, 27, 45, 63, 82, 100, 118, 136, -9, -27, -45, -63, -82, -100, -118, -136,
|
||||
10, 30, 50, 70, 90, 110, 130, 150, -10, -30, -50, -70, -90, -110, -130, -150,
|
||||
11, 33, 55, 77, 99, 121, 143, 165, -11, -33, -55, -77, -99, -121, -143, -165,
|
||||
12, 36, 60, 84, 109, 133, 157, 181, -12, -36, -60, -84, -109, -133, -157, -181,
|
||||
13, 39, 66, 92, 120, 146, 173, 199, -13, -39, -66, -92, -120, -146, -173, -199,
|
||||
14, 43, 73, 102, 132, 161, 191, 220, -14, -43, -73, -102, -132, -161, -191, -220,
|
||||
16, 48, 81, 113, 146, 178, 211, 243, -16, -48, -81, -113, -146, -178, -211, -243,
|
||||
17, 52, 88, 123, 160, 195, 231, 266, -17, -52, -88, -123, -160, -195, -231, -266,
|
||||
19, 58, 97, 136, 176, 215, 254, 293, -19, -58, -97, -136, -176, -215, -254, -293,
|
||||
21, 64, 107, 150, 194, 237, 280, 323, -21, -64, -107, -150, -194, -237, -280, -323,
|
||||
23, 70, 118, 165, 213, 260, 308, 355, -23, -70, -118, -165, -213, -260, -308, -355,
|
||||
26, 78, 130, 182, 235, 287, 339, 391, -26, -78, -130, -182, -235, -287, -339, -391,
|
||||
28, 85, 143, 200, 258, 315, 373, 430, -28, -85, -143, -200, -258, -315, -373, -430,
|
||||
31, 94, 157, 220, 284, 347, 410, 473, -31, -94, -157, -220, -284, -347, -410, -473,
|
||||
34, 103, 173, 242, 313, 382, 452, 521, -34, -103, -173, -242, -313, -382, -452, -521,
|
||||
38, 114, 191, 267, 345, 421, 498, 574, -38, -114, -191, -267, -345, -421, -498, -574,
|
||||
42, 126, 210, 294, 379, 463, 547, 631, -42, -126, -210, -294, -379, -463, -547, -631,
|
||||
46, 138, 231, 323, 417, 509, 602, 694, -46, -138, -231, -323, -417, -509, -602, -694,
|
||||
51, 153, 255, 357, 459, 561, 663, 765, -51, -153, -255, -357, -459, -561, -663, -765,
|
||||
56, 168, 280, 392, 505, 617, 729, 841, -56, -168, -280, -392, -505, -617, -729, -841,
|
||||
61, 184, 308, 431, 555, 678, 802, 925, -61, -184, -308, -431, -555, -678, -802, -925,
|
||||
68, 204, 340, 476, 612, 748, 884, 1020, -68, -204, -340, -476, -612, -748, -884, -1020,
|
||||
74, 223, 373, 522, 672, 821, 971, 1120, -74, -223, -373, -522, -672, -821, -971, -1120,
|
||||
82, 246, 411, 575, 740, 904, 1069, 1233, -82, -246, -411, -575, -740, -904, -1069, -1233,
|
||||
90, 271, 452, 633, 814, 995, 1176, 1357, -90, -271, -452, -633, -814, -995, -1176, -1357,
|
||||
99, 298, 497, 696, 895, 1094, 1293, 1492, -99, -298, -497, -696, -895, -1094, -1293, -1492,
|
||||
109, 328, 547, 766, 985, 1204, 1423, 1642, -109, -328, -547, -766, -985, -1204, -1423, -1642,
|
||||
120, 360, 601, 841, 1083, 1323, 1564, 1804, -120, -360, -601, -841, -1083, -1323, -1564, -1804,
|
||||
132, 397, 662, 927, 1192, 1457, 1722, 1987, -132, -397, -662, -927, -1192, -1457, -1722, -1987,
|
||||
145, 436, 728, 1019, 1311, 1602, 1894, 2185, -145, -436, -728, -1019, -1311, -1602, -1894, -2185,
|
||||
160, 480, 801, 1121, 1442, 1762, 2083, 2403, -160, -480, -801, -1121, -1442, -1762, -2083, -2403,
|
||||
176, 528, 881, 1233, 1587, 1939, 2292, 2644, -176, -528, -881, -1233, -1587, -1939, -2292, -2644,
|
||||
194, 582, 970, 1358, 1746, 2134, 2522, 2910, -194, -582, -970, -1358, -1746, -2134, -2522, -2910
|
||||
};
|
||||
static const int16_t index_shift[8] = { -1, -1, -1, -1, 2, 4, 6, 8 };
|
||||
|
||||
void MSM6585_init (MSM6585* chip, int32 newHostClock, int (*newGetInput)(void)) {
|
||||
chip->hostClock = newHostClock;
|
||||
chip->getInput = newGetInput;
|
||||
AddExState(&chip->whichNibble, 1, 0, "MSMW");
|
||||
AddExState(&chip->input, 1, 0, "MSMI");
|
||||
AddExState(&chip->signal, 2, 0, "MSMO");
|
||||
AddExState(&chip->count, 4, 0, "MSMC");
|
||||
AddExState(&chip->rate, 4, 0, "MSMR");
|
||||
AddExState(&chip->step, 2, 0, "MSMS");
|
||||
}
|
||||
|
||||
void MSM6585_reset (MSM6585* chip) {
|
||||
chip->count = 0;
|
||||
chip->step = 0;
|
||||
chip->signal = -2;
|
||||
}
|
||||
|
||||
void MSM6585_setRate (MSM6585* chip, uint8 rateByte) {
|
||||
chip->rate = 4000 <<(rateByte &3);
|
||||
}
|
||||
|
||||
void MSM6585_run (MSM6585* chip) {
|
||||
chip->count += chip->rate;
|
||||
while (chip->count >= chip->hostClock) {
|
||||
chip->count -= chip->hostClock;
|
||||
uint8_t nibble;
|
||||
if (chip->whichNibble)
|
||||
nibble = chip->input &0x0F;
|
||||
else {
|
||||
chip->input = chip->getInput();
|
||||
nibble = chip->input >>4;
|
||||
}
|
||||
chip->whichNibble = !chip->whichNibble;
|
||||
chip->signal += diff_lookup[chip->step *16 +nibble];
|
||||
if (chip->signal > 2047) chip->signal = 2047;
|
||||
if (chip->signal <-2048) chip->signal =-2048;
|
||||
chip->step += index_shift[nibble &7];
|
||||
if (chip->step > 48) chip->step = 48;
|
||||
if (chip->step < 0) chip->step = 0;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t MSM6585_getOutput (MSM6585* chip) {
|
||||
return chip->signal;
|
||||
}
|
||||
19
src/boards/msm6585.h
Normal file
19
src/boards/msm6585.h
Normal file
@@ -0,0 +1,19 @@
|
||||
#ifndef _MSM6585_H
|
||||
#define _MSM6585_H
|
||||
typedef struct {
|
||||
uint8 whichNibble;
|
||||
uint8 input;
|
||||
int16 signal;
|
||||
int32 count;
|
||||
int32 hostClock;
|
||||
int32 rate;
|
||||
int16 step;
|
||||
int (*getInput)(void);
|
||||
} MSM6585;
|
||||
|
||||
void MSM6585_init (MSM6585*, int32, int (*)(void));
|
||||
void MSM6585_reset (MSM6585*);
|
||||
void MSM6585_setRate (MSM6585*, uint8);
|
||||
void MSM6585_run (MSM6585*);
|
||||
int32_t MSM6585_getOutput (MSM6585*);
|
||||
#endif
|
||||
@@ -1015,6 +1015,7 @@ INES_BOARD_BEGIN()
|
||||
INES_BOARD( "810430", 590, Mapper590_Init )
|
||||
INES_BOARD( "07027/810543", 591, Mapper591_Init )
|
||||
INES_BOARD( "8-in-1 1991", 592, Mapper592_Init )
|
||||
INES_BOARD( "Rinco FSG2", 594, Mapper594_Init )
|
||||
INES_BOARD_END()
|
||||
|
||||
static uint32 iNES_get_mapper_id(void)
|
||||
|
||||
@@ -482,6 +482,7 @@ void Mapper589_Init(CartInfo *);
|
||||
void Mapper590_Init(CartInfo *);
|
||||
void Mapper591_Init(CartInfo *);
|
||||
void Mapper592_Init(CartInfo *);
|
||||
void Mapper594_Init(CartInfo *);
|
||||
|
||||
void FFE_Init(CartInfo *);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user