bandai eeprom emulation, enjoy
This commit is contained in:
parent
abcb50e2e3
commit
95b120fcf4
|
@ -22,14 +22,9 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//Famicom Jump 2 should get transformed to m153
|
|
||||||
//All other games are not supporting EEPROM saving right now.
|
|
||||||
//We may need to distinguish between 16 and 159 in order to know the EEPROM configuration.
|
|
||||||
//Until then, we just return 0x00 from the EEPROM read
|
|
||||||
|
|
||||||
#include "mapinc.h"
|
#include "mapinc.h"
|
||||||
|
|
||||||
static uint8 reg[16], is153;
|
static uint8 reg[16], is153, x24c02;
|
||||||
static uint8 IRQa;
|
static uint8 IRQa;
|
||||||
static int16 IRQCount, IRQLatch;
|
static int16 IRQCount, IRQLatch;
|
||||||
|
|
||||||
|
@ -45,18 +40,130 @@ static SFORMAT StateRegs[] =
|
||||||
{ 0 }
|
{ 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
static void BandaiIRQHook(int a) {
|
// x24C0x interface
|
||||||
if (IRQa) {
|
|
||||||
IRQCount -= a;
|
#define X24C0X_STANDBY 0
|
||||||
if (IRQCount < 0) {
|
#define X24C0X_ADDRESS 1
|
||||||
X6502_IRQBegin(FCEU_IQEXT);
|
#define X24C0X_WORD 2
|
||||||
IRQa = 0;
|
#define X24C0X_READ 3
|
||||||
IRQCount = -1;
|
#define X24C0X_WRITE 4
|
||||||
|
|
||||||
|
static uint8 x24c0x_data[256], x24c0x_state;
|
||||||
|
static uint8 x24c0x_addr, x24c0x_word, x24c0x_latch, x24c0x_bitcount;
|
||||||
|
static uint8 x24c0x_sda, x24c0x_scl, x24c0x_out, x24c0x_oe;
|
||||||
|
|
||||||
|
static SFORMAT x24c01StateRegs[] =
|
||||||
|
{
|
||||||
|
{ x24c0x_data, 128, "DATA" },
|
||||||
|
{ &x24c0x_addr, 1, "ADDR" },
|
||||||
|
{ &x24c0x_word, 1, "WORD" },
|
||||||
|
{ &x24c0x_latch, 1, "LATC" },
|
||||||
|
{ &x24c0x_bitcount, 1, "BITC" },
|
||||||
|
{ &x24c0x_sda, 1, "SDA" },
|
||||||
|
{ &x24c0x_scl, 1, "SCL" },
|
||||||
|
{ &x24c0x_out, 1, "OUT" },
|
||||||
|
{ &x24c0x_oe, 1, "OE" },
|
||||||
|
{ &x24c0x_state, 1, "STAT" },
|
||||||
|
{ 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
static void x24c0x_init() {
|
||||||
|
x24c0x_addr = x24c0x_word = x24c0x_latch = x24c0x_bitcount = x24c0x_sda = x24c0x_scl = x24c0x_oe = 0;
|
||||||
|
x24c0x_state = X24C0X_STANDBY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void x24c0x_write(uint8 data) {
|
||||||
|
uint8 sda = (data >> 6) & 1;
|
||||||
|
uint8 scl = (data >> 5) & 1;
|
||||||
|
x24c0x_oe = (data >> 7);
|
||||||
|
|
||||||
|
if(x24c0x_scl && scl) {
|
||||||
|
if(x24c0x_sda && !sda) { // START
|
||||||
|
x24c0x_state = X24C0X_ADDRESS;
|
||||||
|
x24c0x_bitcount = 0;
|
||||||
|
x24c0x_addr = 0;
|
||||||
|
} else if(!x24c0x_sda && sda) { //STOP
|
||||||
|
x24c0x_state = X24C0X_STANDBY;
|
||||||
|
}
|
||||||
|
} else if(!x24c0x_scl && scl) { // RISING EDGE
|
||||||
|
switch(x24c0x_state) {
|
||||||
|
case X24C0X_ADDRESS:
|
||||||
|
if(x24c0x_bitcount < 7) {
|
||||||
|
x24c0x_addr <<= 1;
|
||||||
|
x24c0x_addr |= sda;
|
||||||
|
} else {
|
||||||
|
if(!x24c02) // X24C01 mode
|
||||||
|
x24c0x_word = x24c0x_addr;
|
||||||
|
if(sda) { // READ COMMAND
|
||||||
|
x24c0x_state = X24C0X_READ;
|
||||||
|
} else { // WRITE COMMAND
|
||||||
|
if(x24c02) // X24C02 mode
|
||||||
|
x24c0x_state = X24C0X_WORD;
|
||||||
|
else
|
||||||
|
x24c0x_state = X24C0X_WRITE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
x24c0x_bitcount++;
|
||||||
|
break;
|
||||||
|
case X24C0X_WORD:
|
||||||
|
if(x24c0x_bitcount == 8) { // ACK
|
||||||
|
x24c0x_word = 0;
|
||||||
|
x24c0x_out = 0;
|
||||||
|
} else { // WORD ADDRESS INPUT
|
||||||
|
x24c0x_word <<= 1;
|
||||||
|
x24c0x_word |= sda;
|
||||||
|
if(x24c0x_bitcount == 16) { // END OF ADDRESS INPUT
|
||||||
|
x24c0x_bitcount = 7;
|
||||||
|
x24c0x_state = X24C0X_WRITE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
x24c0x_bitcount++;
|
||||||
|
break;
|
||||||
|
case X24C0X_READ:
|
||||||
|
if (x24c0x_bitcount == 8) { // ACK
|
||||||
|
x24c0x_out = 0;
|
||||||
|
x24c0x_latch = x24c0x_data[x24c0x_word];
|
||||||
|
x24c0x_bitcount = 0;
|
||||||
|
} else { // REAL OUTPUT
|
||||||
|
x24c0x_out = x24c0x_latch >> 7;
|
||||||
|
x24c0x_latch <<= 1;
|
||||||
|
x24c0x_bitcount++;
|
||||||
|
if(x24c0x_bitcount == 8) {
|
||||||
|
x24c0x_word++;
|
||||||
|
x24c0x_word &= 0xff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case X24C0X_WRITE:
|
||||||
|
if (x24c0x_bitcount == 8) { // ACK
|
||||||
|
x24c0x_out = 0;
|
||||||
|
x24c0x_latch = 0;
|
||||||
|
x24c0x_bitcount = 0;
|
||||||
|
} else { // REAL INPUT
|
||||||
|
x24c0x_latch <<= 1;
|
||||||
|
x24c0x_latch |= sda;
|
||||||
|
x24c0x_bitcount++;
|
||||||
|
if(x24c0x_bitcount == 8) {
|
||||||
|
x24c0x_data[x24c0x_word] = x24c0x_latch;
|
||||||
|
x24c0x_word++;
|
||||||
|
x24c0x_word &= 0xff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void BandaiSync(void) {
|
x24c0x_sda = sda;
|
||||||
|
x24c0x_scl = scl;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint8 x24c0x_read() {
|
||||||
|
return x24c0x_out << 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
static void Sync(void) {
|
||||||
if (is153) {
|
if (is153) {
|
||||||
int base = (reg[0] & 1) << 4;
|
int base = (reg[0] & 1) << 4;
|
||||||
setchr8(0);
|
setchr8(0);
|
||||||
|
@ -80,36 +187,71 @@ static DECLFW(BandaiWrite) {
|
||||||
A &= 0x0F;
|
A &= 0x0F;
|
||||||
if (A < 0x0A) {
|
if (A < 0x0A) {
|
||||||
reg[A & 0x0F] = V;
|
reg[A & 0x0F] = V;
|
||||||
BandaiSync();
|
Sync();
|
||||||
} else
|
} else
|
||||||
switch (A) {
|
switch (A) {
|
||||||
case 0x0A: X6502_IRQEnd(FCEU_IQEXT); IRQa = V & 1; IRQCount = IRQLatch; break;
|
case 0x0A: X6502_IRQEnd(FCEU_IQEXT); IRQa = V & 1; IRQCount = IRQLatch; break;
|
||||||
case 0x0B: IRQLatch &= 0xFF00; IRQLatch |= V; break;
|
case 0x0B: IRQLatch &= 0xFF00; IRQLatch |= V; break;
|
||||||
case 0x0C: IRQLatch &= 0xFF; IRQLatch |= V << 8; break;
|
case 0x0C: IRQLatch &= 0xFF; IRQLatch |= V << 8; break;
|
||||||
case 0x0D: break; // Serial EEPROM control port
|
case 0x0D: x24c0x_write(V); break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static DECLFR(BandaiRead) {
|
static DECLFR(BandaiRead) {
|
||||||
return 0xef; // TODO: EEPROM
|
return (X.DB & 0xEF) | x24c0x_read();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void BandaiIRQHook(int a) {
|
||||||
|
if (IRQa) {
|
||||||
|
IRQCount -= a;
|
||||||
|
if (IRQCount < 0) {
|
||||||
|
X6502_IRQBegin(FCEU_IQEXT);
|
||||||
|
IRQa = 0;
|
||||||
|
IRQCount = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void BandaiPower(void) {
|
static void BandaiPower(void) {
|
||||||
BandaiSync();
|
IRQa = 0;
|
||||||
|
x24c0x_init();
|
||||||
|
Sync();
|
||||||
SetReadHandler(0x6000, 0x7FFF, BandaiRead);
|
SetReadHandler(0x6000, 0x7FFF, BandaiRead);
|
||||||
SetReadHandler(0x8000, 0xFFFF, CartBR);
|
SetReadHandler(0x8000, 0xFFFF, CartBR);
|
||||||
SetWriteHandler(0x6000, 0xFFFF, BandaiWrite);
|
SetWriteHandler(0x6000, 0xFFFF, BandaiWrite);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void StateRestore(int version) {
|
static void StateRestore(int version) {
|
||||||
BandaiSync();
|
Sync();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mapper16_Init(CartInfo *info) {
|
void Mapper16_Init(CartInfo *info) {
|
||||||
|
x24c02 = 1;
|
||||||
is153 = 0;
|
is153 = 0;
|
||||||
info->Power = BandaiPower;
|
info->Power = BandaiPower;
|
||||||
MapIRQHook = BandaiIRQHook;
|
MapIRQHook = BandaiIRQHook;
|
||||||
|
|
||||||
|
info->battery = 1;
|
||||||
|
info->SaveGame[0] = x24c0x_data;
|
||||||
|
info->SaveGameLen[0] = 256;
|
||||||
|
|
||||||
GameStateRestore = StateRestore;
|
GameStateRestore = StateRestore;
|
||||||
|
AddExState(&x24c01StateRegs, ~0, 0, 0);
|
||||||
|
AddExState(&StateRegs, ~0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mapper159_Init(CartInfo *info) {
|
||||||
|
x24c02 = 0;
|
||||||
|
is153 = 0;
|
||||||
|
info->Power = BandaiPower;
|
||||||
|
MapIRQHook = BandaiIRQHook;
|
||||||
|
|
||||||
|
info->battery = 1;
|
||||||
|
info->SaveGame[0] = x24c0x_data;
|
||||||
|
info->SaveGameLen[0] = 128;
|
||||||
|
|
||||||
|
GameStateRestore = StateRestore;
|
||||||
|
AddExState(&x24c01StateRegs, ~0, 0, 0);
|
||||||
AddExState(&StateRegs, ~0, 0, 0);
|
AddExState(&StateRegs, ~0, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,7 +263,7 @@ void Mapper16_Init(CartInfo *info) {
|
||||||
// last CHR address read).
|
// last CHR address read).
|
||||||
|
|
||||||
static void M153Power(void) {
|
static void M153Power(void) {
|
||||||
BandaiSync();
|
Sync();
|
||||||
setprg8r(0x10, 0x6000, 0);
|
setprg8r(0x10, 0x6000, 0);
|
||||||
SetReadHandler(0x6000, 0x7FFF, CartBR);
|
SetReadHandler(0x6000, 0x7FFF, CartBR);
|
||||||
SetWriteHandler(0x6000, 0x7FFF, CartBW);
|
SetWriteHandler(0x6000, 0x7FFF, CartBW);
|
||||||
|
@ -296,12 +438,13 @@ static DECLFR(BarcodeRead) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void M157Power(void) {
|
static void M157Power(void) {
|
||||||
|
IRQa = 0;
|
||||||
BarcodeData[0] = 0xFF;
|
BarcodeData[0] = 0xFF;
|
||||||
BarcodeReadPos = 0;
|
BarcodeReadPos = 0;
|
||||||
BarcodeOut = 0;
|
BarcodeOut = 0;
|
||||||
BarcodeCycleCount = 0;
|
BarcodeCycleCount = 0;
|
||||||
|
|
||||||
BandaiSync();
|
Sync();
|
||||||
|
|
||||||
SetWriteHandler(0x6000, 0xFFFF, BandaiWrite);
|
SetWriteHandler(0x6000, 0xFFFF, BandaiWrite);
|
||||||
SetReadHandler(0x6000, 0x7FFF, BarcodeRead);
|
SetReadHandler(0x6000, 0x7FFF, BarcodeRead);
|
||||||
|
|
|
@ -81,8 +81,8 @@
|
||||||
{0xcd373baa, 14, -1}, /* Samurai Spirits (Rex Soft) */
|
{0xcd373baa, 14, -1}, /* Samurai Spirits (Rex Soft) */
|
||||||
{0xbfc7a2e9, 16, 8},
|
{0xbfc7a2e9, 16, 8},
|
||||||
{0x6e68e31a, 16, 8}, /* Dragon Ball 3*/
|
{0x6e68e31a, 16, 8}, /* Dragon Ball 3*/
|
||||||
{0x183859d2, 16, -1},
|
|
||||||
{0x33b899c9, 16, -1}, /* Dragon Ball - Dai Maou Fukkatsu (J) [!] */
|
{0x33b899c9, 16, -1}, /* Dragon Ball - Dai Maou Fukkatsu (J) [!] */
|
||||||
|
{0xa262a81f, 16, -1}, /* Rokudenashi Blues (J) */
|
||||||
{0x286fcd20, 23, -1}, /* Ganbare Goemon Gaiden 2 - Tenka no Zaihou (J) [!] */
|
{0x286fcd20, 23, -1}, /* Ganbare Goemon Gaiden 2 - Tenka no Zaihou (J) [!] */
|
||||||
{0xe4a291ce, 23, -1}, /* World Hero (Unl) [!] */
|
{0xe4a291ce, 23, -1}, /* World Hero (Unl) [!] */
|
||||||
{0x51e9cd33, 23, -1}, /* World Hero (Unl) [b1] */
|
{0x51e9cd33, 23, -1}, /* World Hero (Unl) [b1] */
|
||||||
|
@ -180,12 +180,12 @@
|
||||||
{0x0be0a328, 157, 8}, /* Datach SD Gundam Wars */
|
{0x0be0a328, 157, 8}, /* Datach SD Gundam Wars */
|
||||||
{0x5b457641, 157, 8}, /* Datach Ultraman Club */
|
{0x5b457641, 157, 8}, /* Datach Ultraman Club */
|
||||||
{0xf51a7f46, 157, 8}, /* Datach Yuu Yuu Hakusho */
|
{0xf51a7f46, 157, 8}, /* Datach Yuu Yuu Hakusho */
|
||||||
{0xb7f28915, 159, -1}, /* Magical Taruruuto-kun 2 - Mahou Daibouken (J) */
|
|
||||||
{0xa262a81f, 159, -1}, /* Rokudenashi Blues (J) */
|
|
||||||
{0xe170404c, 159, -1}, /* SD Gundam Gaiden - Knight Gundam Monogatari (J) (V1.0) [!] */
|
{0xe170404c, 159, -1}, /* SD Gundam Gaiden - Knight Gundam Monogatari (J) (V1.0) [!] */
|
||||||
{0x276ac722, 159, -1}, /* SD Gundam Gaiden - Knight Gundam Monogatari (J) (V1.1) [!] */
|
{0x276ac722, 159, -1}, /* SD Gundam Gaiden - Knight Gundam Monogatari (J) (V1.1) [!] */
|
||||||
{0xb049a8c4, 159, -1}, /* SD Gundam Gaiden - Knight Gundam Monogatari 2 - Hikari no Kishi (J) [!] */
|
{0x0cf42e69, 159, -1}, /* Magical Taruruuto-kun - Fantastic World!! (J) (V1.0) [!] */
|
||||||
{0xc2840372, 159, -1}, /* SD Gundam Gaiden - Knight Gundam Monogatari 3 - Densetsu no Kishi Dan (J) [!] */
|
{0xdcb972ce, 159, -1}, /* Magical Taruruuto-kun - Fantastic World!! (J) (V1.1) [!] */
|
||||||
|
{0xb7f28915, 159, -1}, /* Magical Taruruuto-kun 2 - Mahou Daibouken (J) */
|
||||||
|
{0x183859d2, 159, -1}, /* Dragon Ball Z - Kyoushuu! Saiya Jin (J) [!] */
|
||||||
{0x58152b42, 160, 1}, /* Pipe 5 (Sachen) */
|
{0x58152b42, 160, 1}, /* Pipe 5 (Sachen) */
|
||||||
{0x1c098942, 162, -1}, /* Xi You Ji Hou Zhuan (Ch) */
|
{0x1c098942, 162, -1}, /* Xi You Ji Hou Zhuan (Ch) */
|
||||||
{0x081caaff, 163, -1}, /* Commandos (Ch) */
|
{0x081caaff, 163, -1}, /* Commandos (Ch) */
|
||||||
|
|
|
@ -597,13 +597,13 @@ static BMAPPINGLocal bmap[] = {
|
||||||
{"S74LS374N", 150, S74LS374N_Init},
|
{"S74LS374N", 150, S74LS374N_Init},
|
||||||
{"", 151, Mapper151_Init},
|
{"", 151, Mapper151_Init},
|
||||||
{"", 152, Mapper152_Init},
|
{"", 152, Mapper152_Init},
|
||||||
{"", 153, Mapper153_Init},
|
{"BANDAI SRAM", 153, Mapper153_Init}, // Bandai board 16 with SRAM instead of EEPROM
|
||||||
{"", 154, Mapper154_Init},
|
{"", 154, Mapper154_Init},
|
||||||
{"", 155, Mapper155_Init},
|
{"", 155, Mapper155_Init},
|
||||||
{"", 156, Mapper156_Init},
|
{"", 156, Mapper156_Init},
|
||||||
{"", 157, Mapper157_Init},
|
{"BANDAI BARCODE", 157, Mapper157_Init},
|
||||||
// {"", 158, Mapper158_Init},
|
// {"", 158, Mapper158_Init},
|
||||||
{"BANDAI 24C01", 159, Mapper16_Init}, // Different type of EEPROM on bandai board
|
{"BANDAI 24C01", 159, Mapper159_Init}, // Different type of EEPROM on the bandai board
|
||||||
{"SA009", 160, SA009_Init},
|
{"SA009", 160, SA009_Init},
|
||||||
// {"", 161, Mapper161_Init},
|
// {"", 161, Mapper161_Init},
|
||||||
{"", 162, UNLFS304_Init},
|
{"", 162, UNLFS304_Init},
|
||||||
|
|
|
@ -188,6 +188,7 @@ void Mapper154_Init(CartInfo *);
|
||||||
void Mapper155_Init(CartInfo *);
|
void Mapper155_Init(CartInfo *);
|
||||||
void Mapper156_Init(CartInfo *);
|
void Mapper156_Init(CartInfo *);
|
||||||
void Mapper157_Init(CartInfo *);
|
void Mapper157_Init(CartInfo *);
|
||||||
|
void Mapper159_Init(CartInfo *);
|
||||||
void Mapper163_Init(CartInfo *);
|
void Mapper163_Init(CartInfo *);
|
||||||
void Mapper164_Init(CartInfo *);
|
void Mapper164_Init(CartInfo *);
|
||||||
void Mapper165_Init(CartInfo *);
|
void Mapper165_Init(CartInfo *);
|
||||||
|
|
Loading…
Reference in New Issue