172 lines
4.2 KiB
C++
172 lines
4.2 KiB
C++
/******************************************************************************/
|
|
/* Mednafen Sega Saturn Emulation Module */
|
|
/******************************************************************************/
|
|
/* cart.cpp - Expansion cart emulation
|
|
** Copyright (C) 2016-2017 Mednafen Team
|
|
**
|
|
** 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 "ss.h"
|
|
|
|
#include "cart.h"
|
|
#include "cart/backup.h"
|
|
#include "cart/cs1ram.h"
|
|
#include "cart/debug.h"
|
|
#include "cart/extram.h"
|
|
//#include "cart/nlmodem.h"
|
|
#include "cart/rom.h"
|
|
|
|
namespace MDFN_IEN_SS
|
|
{
|
|
|
|
CartInfo Cart;
|
|
|
|
template<typename T>
|
|
static MDFN_HOT void DummyRead(uint32 A, uint16* DB)
|
|
{
|
|
// Don't set *DB here.
|
|
SS_DBG(SS_DBG_WARNING, "[CART] Unknown %zu-byte read from 0x%08x\n", sizeof(T), A);
|
|
}
|
|
|
|
template<typename T>
|
|
static MDFN_HOT void DummyWrite(uint32 A, uint16* DB)
|
|
{
|
|
SS_DBG(SS_DBG_WARNING, "[CART] Unknown %zu-byte write to 0x%08x(DB=0x%04x)\n", sizeof(T), A, *DB);
|
|
}
|
|
|
|
static sscpu_timestamp_t DummyUpdate(sscpu_timestamp_t timestamp)
|
|
{
|
|
return SS_EVENT_DISABLED_TS;
|
|
}
|
|
|
|
static void DummyAdjustTS(const int32 delta)
|
|
{
|
|
|
|
}
|
|
|
|
static void DummySetCPUClock(const int32 master_clock, const int32 divider)
|
|
{
|
|
|
|
}
|
|
|
|
static MDFN_COLD void DummyReset(bool powering_up)
|
|
{
|
|
|
|
}
|
|
|
|
static MDFN_COLD bool DummyGetClearNVDirty(void)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
static MDFN_COLD void DummyGetNVInfo(const char** ext, void** nv_ptr, uint64* nv_size)
|
|
{
|
|
*ext = nullptr;
|
|
*nv_ptr = nullptr;
|
|
*nv_size = 0;
|
|
}
|
|
|
|
void CartInfo::CS01_SetRW8W16(uint32 Astart, uint32 Aend, void (*r16)(uint32 A, uint16* DB), void (*w8)(uint32 A, uint16* DB), void (*w16)(uint32 A, uint16* DB))
|
|
{
|
|
assert(Astart >= 0x02000000 && Aend <= 0x04FFFFFF);
|
|
|
|
assert(!(Astart & ((1U << 20) - 1)));
|
|
assert(!((Aend + 1) & ((1U << 20) - 1)));
|
|
|
|
for(unsigned i = (Astart - 0x02000000) >> 20; i <= (Aend - 0x02000000) >> 20; i++)
|
|
{
|
|
auto& rw = Cart.CS01_RW[i];
|
|
|
|
if(r16) rw.Read16 = r16;
|
|
if(w8) rw.Write8 = w8;
|
|
if(w16) rw.Write16 = w16;
|
|
}
|
|
}
|
|
|
|
void CartInfo::CS2M_SetRW8W16(uint8 Ostart, uint8 Oend, void (*r16)(uint32 A, uint16* DB), void (*w8)(uint32 A, uint16* DB), void (*w16)(uint32 A, uint16* DB))
|
|
{
|
|
assert(!(Ostart & 0x1));
|
|
assert(Oend & 0x1);
|
|
assert(Ostart < 0x40);
|
|
assert(Oend < 0x40);
|
|
|
|
for(int i = Ostart >> 1; i <= Oend >> 1; i++)
|
|
{
|
|
auto& rw = Cart.CS2M_RW[i];
|
|
|
|
if(r16) rw.Read16 = r16;
|
|
if(w8) rw.Write8 = w8;
|
|
if(w16) rw.Write16 = w16;
|
|
}
|
|
}
|
|
|
|
|
|
void CART_Init(const int cart_type)
|
|
{
|
|
Cart.CS01_SetRW8W16(0x02000000, 0x04FFFFFF, DummyRead<uint16>, DummyWrite<uint8>, DummyWrite<uint16>);
|
|
Cart.CS2M_SetRW8W16(0x00, 0x3F, DummyRead<uint16>, DummyWrite<uint8>, DummyWrite<uint16>);
|
|
|
|
Cart.Reset = DummyReset;
|
|
Cart.GetNVInfo = DummyGetNVInfo;
|
|
Cart.GetClearNVDirty = DummyGetClearNVDirty;
|
|
Cart.EventHandler = DummyUpdate;
|
|
Cart.AdjustTS = DummyAdjustTS;
|
|
Cart.SetCPUClock = DummySetCPUClock;
|
|
|
|
switch(cart_type)
|
|
{
|
|
default:
|
|
case CART_NONE:
|
|
break;
|
|
|
|
case CART_BACKUP_MEM:
|
|
CART_Backup_Init(&Cart);
|
|
break;
|
|
|
|
case CART_EXTRAM_1M:
|
|
case CART_EXTRAM_4M:
|
|
CART_ExtRAM_Init(&Cart, cart_type == CART_EXTRAM_4M);
|
|
break;
|
|
|
|
case CART_KOF95:
|
|
case CART_ULTRAMAN:
|
|
{
|
|
CART_ROM_Init(&Cart, cart_type == CART_KOF95 ? "ss.cart.kof95_path" : "ss.cart.ultraman_path");
|
|
}
|
|
break;
|
|
|
|
case CART_CS1RAM_16M:
|
|
CART_CS1RAM_Init(&Cart);
|
|
break;
|
|
|
|
case CART_MDFN_DEBUG:
|
|
CART_Debug_Init(&Cart);
|
|
break;
|
|
|
|
// case CART_NLMODEM:
|
|
// CART_NLModem_Init(&Cart);
|
|
// break;
|
|
}
|
|
|
|
for(auto& m : Cart.CS01_RW)
|
|
assert(m.Read16 != nullptr && m.Write8 != nullptr && m.Write16 != nullptr);
|
|
|
|
for(auto& m : Cart.CS2M_RW)
|
|
assert(m.Read16 != nullptr && m.Write8 != nullptr && m.Write16 != nullptr);
|
|
}
|
|
|
|
}
|