2013-12-19 17:10:14 +00:00
|
|
|
/*
|
|
|
|
Dreamcast 'area 0' emulation
|
|
|
|
Pretty much all peripheral registers are mapped here
|
2013-12-24 00:56:44 +00:00
|
|
|
|
2013-12-19 17:10:14 +00:00
|
|
|
Routing is mostly handled here, as well as flash/SRAM emulation
|
|
|
|
*/
|
|
|
|
#include "types.h"
|
|
|
|
#include "hw/sh4/sh4_mem.h"
|
|
|
|
|
|
|
|
#include "sb_mem.h"
|
|
|
|
#include "sb.h"
|
|
|
|
#include "hw/pvr/pvr_mem.h"
|
|
|
|
#include "hw/gdrom/gdrom_if.h"
|
|
|
|
#include "hw/aica/aica_if.h"
|
2015-08-09 04:34:02 +00:00
|
|
|
#include "hw/naomi/naomi.h"
|
2018-09-12 11:20:20 +00:00
|
|
|
#include "hw/modem/modem.h"
|
2013-12-19 17:10:14 +00:00
|
|
|
|
|
|
|
#include "hw/flashrom/flashrom.h"
|
2014-12-29 21:05:35 +00:00
|
|
|
#include "reios/reios.h"
|
2013-12-19 17:10:14 +00:00
|
|
|
|
2019-07-09 21:52:19 +00:00
|
|
|
MemChip *sys_rom;
|
|
|
|
MemChip *sys_nvmem;
|
2013-12-19 17:10:14 +00:00
|
|
|
|
2019-07-09 21:52:19 +00:00
|
|
|
extern bool bios_loaded;
|
2013-12-19 17:10:14 +00:00
|
|
|
|
2019-07-09 21:52:19 +00:00
|
|
|
static std::string getRomPrefix()
|
|
|
|
{
|
|
|
|
switch (settings.platform.system)
|
|
|
|
{
|
|
|
|
case DC_PLATFORM_DREAMCAST:
|
|
|
|
return "dc_";
|
|
|
|
case DC_PLATFORM_NAOMI:
|
|
|
|
return "naomi_";
|
|
|
|
case DC_PLATFORM_ATOMISWAVE:
|
|
|
|
return "aw_";
|
|
|
|
default:
|
|
|
|
die("Unsupported platform");
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
}
|
2013-12-19 17:10:14 +00:00
|
|
|
|
2019-08-14 18:05:42 +00:00
|
|
|
static void add_isp_to_nvmem(DCFlashChip *flash)
|
|
|
|
{
|
|
|
|
u8 block[64];
|
|
|
|
if (!flash->ReadBlock(FLASH_PT_USER, FLASH_USER_INET, block))
|
|
|
|
{
|
|
|
|
memset(block, 0, sizeof(block));
|
|
|
|
strcpy((char *)block + 2, "PWBrowser");
|
|
|
|
block[12] = 0x1c;
|
|
|
|
flash->WriteBlock(FLASH_PT_USER, FLASH_USER_INET, block);
|
|
|
|
|
|
|
|
memset(block, 0, sizeof(block));
|
|
|
|
flash->WriteBlock(FLASH_PT_USER, FLASH_USER_INET + 1, block);
|
|
|
|
flash->WriteBlock(FLASH_PT_USER, FLASH_USER_INET + 2, block);
|
|
|
|
flash->WriteBlock(FLASH_PT_USER, FLASH_USER_INET + 3, block);
|
|
|
|
memset(block + 27, 0xFF, sizeof(block) - 27);
|
|
|
|
flash->WriteBlock(FLASH_PT_USER, FLASH_USER_INET + 4, block);
|
|
|
|
memset(block, 0xFF, sizeof(block));
|
|
|
|
for (u32 i = FLASH_USER_INET + 5; i <= 0xbf; i++)
|
|
|
|
flash->WriteBlock(FLASH_PT_USER, i, block);
|
|
|
|
|
|
|
|
flash_isp1_block isp1;
|
|
|
|
memset(&isp1, 0, sizeof(isp1));
|
|
|
|
isp1._unknown[0] = 0xFF;
|
|
|
|
isp1._unknown[1] = 0xFE;
|
|
|
|
isp1._unknown[2] = 0xFF;
|
|
|
|
isp1._unknown[3] = 0xFF;
|
|
|
|
memcpy(isp1.sega, "SEGA", 4);
|
|
|
|
strcpy(isp1.username, "flycast1");
|
|
|
|
strcpy(isp1.password, "password");
|
|
|
|
strcpy(isp1.phone, "1234567");
|
|
|
|
if (flash->WriteBlock(FLASH_PT_USER, FLASH_USER_ISP1, &isp1) != 1)
|
|
|
|
WARN_LOG(FLASHROM, "Failed to save ISP information to flash RAM");
|
|
|
|
|
|
|
|
memset(block, 0xFF, sizeof(block));
|
|
|
|
block[34] = 0;
|
|
|
|
flash->WriteBlock(FLASH_PT_USER, FLASH_USER_ISP1 + 1, block);
|
|
|
|
memset(block, 0xFF, sizeof(block));
|
|
|
|
block[9] = 0;
|
|
|
|
memset(block + 49, 0, 13);
|
|
|
|
flash->WriteBlock(FLASH_PT_USER, FLASH_USER_ISP1 + 2, block);
|
|
|
|
memset(block, 0xFF, sizeof(block));
|
|
|
|
flash->WriteBlock(FLASH_PT_USER, FLASH_USER_ISP1 + 3, block);
|
|
|
|
flash->WriteBlock(FLASH_PT_USER, FLASH_USER_ISP1 + 4, block);
|
|
|
|
flash->WriteBlock(FLASH_PT_USER, FLASH_USER_ISP1 + 5, block);
|
|
|
|
|
|
|
|
flash_isp2_block isp2;
|
|
|
|
memset(&isp2, 0, sizeof(isp2));
|
|
|
|
memcpy(isp2.sega, "SEGA", 4);
|
|
|
|
strcpy(isp2.username, "flycast2");
|
|
|
|
strcpy(isp2.password, "password");
|
|
|
|
strcpy(isp2.phone, "1234567");
|
|
|
|
if (flash->WriteBlock(FLASH_PT_USER, FLASH_USER_ISP2, &isp2) != 1)
|
|
|
|
WARN_LOG(FLASHROM, "Failed to save ISP information to flash RAM");
|
|
|
|
u8 block[64];
|
|
|
|
memset(block, 0xFF, sizeof(block));
|
|
|
|
flash->WriteBlock(FLASH_PT_USER, FLASH_USER_ISP2 + 1, block);
|
|
|
|
block[9] = 0;
|
|
|
|
memset(block + 49, 0, 13);
|
|
|
|
flash->WriteBlock(FLASH_PT_USER, FLASH_USER_ISP2 + 2, block);
|
|
|
|
for (u32 i = FLASH_USER_ISP2 + 3; i <= 0xEA; i++)
|
|
|
|
flash->WriteBlock(FLASH_PT_USER, i, block);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-09-01 14:35:12 +00:00
|
|
|
void FixUpFlash()
|
2019-07-09 21:52:19 +00:00
|
|
|
{
|
2019-07-31 15:59:53 +00:00
|
|
|
if (settings.platform.system == DC_PLATFORM_DREAMCAST)
|
2013-12-19 17:10:14 +00:00
|
|
|
{
|
2019-07-31 15:59:53 +00:00
|
|
|
static_cast<DCFlashChip*>(sys_nvmem)->Validate();
|
2019-09-01 14:35:12 +00:00
|
|
|
|
2019-07-31 15:59:53 +00:00
|
|
|
// overwrite factory flash settings
|
|
|
|
if (settings.dreamcast.region <= 2)
|
2013-12-19 17:10:14 +00:00
|
|
|
{
|
2019-07-31 15:59:53 +00:00
|
|
|
sys_nvmem->data[0x1a002] = '0' + settings.dreamcast.region;
|
|
|
|
sys_nvmem->data[0x1a0a2] = '0' + settings.dreamcast.region;
|
2013-12-19 17:10:14 +00:00
|
|
|
}
|
2019-07-31 15:59:53 +00:00
|
|
|
if (settings.dreamcast.language <= 5)
|
2013-12-19 17:10:14 +00:00
|
|
|
{
|
2019-07-31 15:59:53 +00:00
|
|
|
sys_nvmem->data[0x1a003] = '0' + settings.dreamcast.language;
|
|
|
|
sys_nvmem->data[0x1a0a3] = '0' + settings.dreamcast.language;
|
|
|
|
}
|
|
|
|
if (settings.dreamcast.broadcast <= 3)
|
|
|
|
{
|
|
|
|
sys_nvmem->data[0x1a004] = '0' + settings.dreamcast.broadcast;
|
|
|
|
sys_nvmem->data[0x1a0a4] = '0' + settings.dreamcast.broadcast;
|
2013-12-19 17:10:14 +00:00
|
|
|
}
|
2019-09-01 14:35:12 +00:00
|
|
|
|
2019-07-31 15:59:53 +00:00
|
|
|
// overwrite user settings
|
2019-07-09 21:52:19 +00:00
|
|
|
struct flash_syscfg_block syscfg;
|
|
|
|
int res = static_cast<DCFlashChip*>(sys_nvmem)->ReadBlock(FLASH_PT_USER, FLASH_USER_SYSCFG, &syscfg);
|
2019-09-01 14:35:12 +00:00
|
|
|
|
2019-07-09 21:52:19 +00:00
|
|
|
if (!res)
|
|
|
|
{
|
|
|
|
// write out default settings
|
|
|
|
memset(&syscfg, 0xff, sizeof(syscfg));
|
|
|
|
syscfg.time_lo = 0;
|
|
|
|
syscfg.time_hi = 0;
|
|
|
|
syscfg.lang = 0;
|
|
|
|
syscfg.mono = 0;
|
|
|
|
syscfg.autostart = 1;
|
|
|
|
}
|
|
|
|
u32 time = GetRTC_now();
|
|
|
|
syscfg.time_lo = time & 0xffff;
|
|
|
|
syscfg.time_hi = time >> 16;
|
|
|
|
if (settings.dreamcast.language <= 5)
|
|
|
|
syscfg.lang = settings.dreamcast.language;
|
2019-09-01 14:35:12 +00:00
|
|
|
|
2019-07-09 21:52:19 +00:00
|
|
|
if (static_cast<DCFlashChip*>(sys_nvmem)->WriteBlock(FLASH_PT_USER, FLASH_USER_SYSCFG, &syscfg) != 1)
|
|
|
|
WARN_LOG(FLASHROM, "Failed to save time and language to flash RAM");
|
2019-08-14 18:05:42 +00:00
|
|
|
|
|
|
|
add_isp_to_nvmem(static_cast<DCFlashChip*>(sys_nvmem));
|
2019-07-09 21:52:19 +00:00
|
|
|
}
|
2019-09-01 14:35:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static bool nvmem_load(const string& root)
|
|
|
|
{
|
|
|
|
bool rc;
|
|
|
|
if (settings.platform.system == DC_PLATFORM_DREAMCAST)
|
|
|
|
rc = sys_nvmem->Load(root, getRomPrefix(), "%nvmem.bin;%flash_wb.bin;%flash.bin;%flash.bin.bin", "nvram");
|
|
|
|
else
|
|
|
|
rc = sys_nvmem->Load(get_game_save_prefix() + ".nvmem");
|
|
|
|
if (!rc)
|
|
|
|
INFO_LOG(FLASHROM, "flash/nvmem is missing, will create new file...");
|
2019-08-13 15:12:29 +00:00
|
|
|
|
2019-07-09 21:52:19 +00:00
|
|
|
if (settings.platform.system == DC_PLATFORM_ATOMISWAVE)
|
|
|
|
sys_rom->Load(get_game_save_prefix() + ".nvmem2");
|
2019-08-13 15:12:29 +00:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool LoadRomFiles(const string& root)
|
|
|
|
{
|
|
|
|
if (settings.platform.system != DC_PLATFORM_ATOMISWAVE)
|
|
|
|
{
|
|
|
|
if (!sys_rom->Load(root, getRomPrefix(), "%boot.bin;%boot.bin.bin;%bios.bin;%bios.bin.bin", "bootrom"))
|
|
|
|
{
|
|
|
|
if (settings.platform.system == DC_PLATFORM_DREAMCAST)
|
|
|
|
{
|
|
|
|
// Dreamcast absolutely needs a BIOS
|
|
|
|
msgboxf("Unable to find bios in %s. Exiting...", MBX_ICONERROR, root.c_str());
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
bios_loaded = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
nvmem_load(root);
|
2013-12-24 00:56:44 +00:00
|
|
|
|
2019-08-13 15:12:29 +00:00
|
|
|
return true;
|
2013-12-19 17:10:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void SaveRomFiles(const string& root)
|
|
|
|
{
|
2019-07-09 21:52:19 +00:00
|
|
|
if (settings.platform.system == DC_PLATFORM_DREAMCAST)
|
|
|
|
sys_nvmem->Save(root, getRomPrefix(), "nvmem.bin", "nvmem");
|
|
|
|
else
|
|
|
|
sys_nvmem->Save(get_game_save_prefix() + ".nvmem");
|
|
|
|
if (settings.platform.system == DC_PLATFORM_ATOMISWAVE)
|
|
|
|
sys_rom->Save(get_game_save_prefix() + ".nvmem2");
|
2013-12-19 17:10:14 +00:00
|
|
|
}
|
|
|
|
|
2019-08-13 15:12:29 +00:00
|
|
|
bool LoadHle(const string& root)
|
2019-07-30 17:04:51 +00:00
|
|
|
{
|
2019-08-13 15:12:29 +00:00
|
|
|
if (!nvmem_load(root))
|
|
|
|
WARN_LOG(FLASHROM, "No nvmem loaded\n");
|
|
|
|
|
2019-09-19 09:49:19 +00:00
|
|
|
reios_reset(sys_rom->data, sys_nvmem);
|
|
|
|
|
|
|
|
return true;
|
2014-12-29 21:05:35 +00:00
|
|
|
}
|
|
|
|
|
2019-09-01 14:35:12 +00:00
|
|
|
static u32 ReadFlash(u32 addr,u32 sz) { return sys_nvmem->Read(addr,sz); }
|
|
|
|
static void WriteFlash(u32 addr,u32 data,u32 sz) { sys_nvmem->Write(addr,data,sz); }
|
2013-12-19 17:10:14 +00:00
|
|
|
|
2019-09-01 14:35:12 +00:00
|
|
|
static u32 ReadBios(u32 addr,u32 sz)
|
2019-07-09 21:52:19 +00:00
|
|
|
{
|
|
|
|
return sys_rom->Read(addr, sz);
|
|
|
|
}
|
2013-12-24 00:56:44 +00:00
|
|
|
|
2019-09-01 14:35:12 +00:00
|
|
|
static void WriteBios(u32 addr,u32 data,u32 sz)
|
2019-07-09 21:52:19 +00:00
|
|
|
{
|
|
|
|
if (settings.platform.system == DC_PLATFORM_ATOMISWAVE)
|
2013-12-24 00:56:44 +00:00
|
|
|
{
|
2018-11-07 22:27:32 +00:00
|
|
|
if (sz != 1)
|
2013-12-19 17:10:14 +00:00
|
|
|
{
|
2019-06-30 21:02:26 +00:00
|
|
|
INFO_LOG(MEMORY, "Invalid access size @%08x data %x sz %d", addr, data, sz);
|
2018-11-07 22:27:32 +00:00
|
|
|
return;
|
2013-12-19 17:10:14 +00:00
|
|
|
}
|
2019-07-09 21:52:19 +00:00
|
|
|
sys_rom->Write(addr, data, sz);
|
2013-12-19 17:10:14 +00:00
|
|
|
}
|
2019-07-09 21:52:19 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
INFO_LOG(MEMORY, "Write to [Boot ROM] is not possible, addr=%x, data=%x, size=%d", addr, data, sz);
|
|
|
|
}
|
|
|
|
}
|
2013-12-19 17:10:14 +00:00
|
|
|
|
|
|
|
//Area 0 mem map
|
|
|
|
//0x00000000- 0x001FFFFF :MPX System/Boot ROM
|
|
|
|
//0x00200000- 0x0021FFFF :Flash Memory
|
|
|
|
//0x00400000- 0x005F67FF :Unassigned
|
|
|
|
//0x005F6800- 0x005F69FF :System Control Reg.
|
|
|
|
//0x005F6C00- 0x005F6CFF :Maple i/f Control Reg.
|
|
|
|
//0x005F7000- 0x005F70FF :GD-ROM / NAOMI BD Reg.
|
|
|
|
//0x005F7400- 0x005F74FF :G1 i/f Control Reg.
|
|
|
|
//0x005F7800- 0x005F78FF :G2 i/f Control Reg.
|
|
|
|
//0x005F7C00- 0x005F7CFF :PVR i/f Control Reg.
|
|
|
|
//0x005F8000- 0x005F9FFF :TA / PVR Core Reg.
|
|
|
|
//0x00600000- 0x006007FF :MODEM
|
|
|
|
//0x00600800- 0x006FFFFF :G2 (Reserved)
|
|
|
|
//0x00700000- 0x00707FFF :AICA- Sound Cntr. Reg.
|
|
|
|
//0x00710000- 0x0071000B :AICA- RTC Cntr. Reg.
|
|
|
|
//0x00800000- 0x00FFFFFF :AICA- Wave Memory
|
|
|
|
//0x01000000- 0x01FFFFFF :Ext. Device
|
|
|
|
//0x02000000- 0x03FFFFFF* :Image Area* 2MB
|
|
|
|
|
|
|
|
//use unified size handler for registers
|
2013-12-24 00:56:44 +00:00
|
|
|
//it really makes no sense to use different size handlers on em -> especially when we can use templates :p
|
2013-12-19 17:10:14 +00:00
|
|
|
template<u32 sz, class T>
|
|
|
|
T DYNACALL ReadMem_area0(u32 addr)
|
|
|
|
{
|
|
|
|
addr &= 0x01FFFFFF;//to get rid of non needed bits
|
|
|
|
const u32 base=(addr>>16);
|
|
|
|
//map 0x0000 to 0x01FF to Default handler
|
|
|
|
//mirror 0x0200 to 0x03FF , from 0x0000 to 0x03FFF
|
|
|
|
//map 0x0000 to 0x001F
|
2019-07-09 21:52:19 +00:00
|
|
|
|
|
|
|
// :MPX System/Boot ROM
|
|
|
|
if (base <= (settings.platform.system == DC_PLATFORM_ATOMISWAVE ? 0x0001 : 0x001F)) // Only 128k BIOS on AtomisWave
|
2013-12-19 17:10:14 +00:00
|
|
|
{
|
|
|
|
return ReadBios(addr,sz);
|
|
|
|
}
|
|
|
|
//map 0x0020 to 0x0021
|
2013-12-24 00:56:44 +00:00
|
|
|
else if ((base>= 0x0020) && (base<= 0x0021)) // :Flash Memory
|
2013-12-19 17:10:14 +00:00
|
|
|
{
|
|
|
|
return ReadFlash(addr&0x1FFFF,sz);
|
|
|
|
}
|
|
|
|
//map 0x005F to 0x005F
|
|
|
|
else if (likely(base==0x005F))
|
|
|
|
{
|
2013-12-24 00:56:44 +00:00
|
|
|
if ( /*&& (addr>= 0x00400000)*/ (addr<= 0x005F67FF)) // :Unassigned
|
2013-12-19 17:10:14 +00:00
|
|
|
{
|
2019-06-30 21:02:26 +00:00
|
|
|
INFO_LOG(MEMORY, "Read from area0_32 not implemented [Unassigned], addr=%x", addr);
|
2013-12-19 17:10:14 +00:00
|
|
|
}
|
2013-12-24 00:56:44 +00:00
|
|
|
else if ((addr>= 0x005F7000) && (addr<= 0x005F70FF)) // GD-ROM
|
2013-12-19 17:10:14 +00:00
|
|
|
{
|
2019-07-09 21:52:19 +00:00
|
|
|
if (settings.platform.system != DC_PLATFORM_DREAMCAST)
|
|
|
|
return (T)ReadMem_naomi(addr, sz);
|
|
|
|
else
|
|
|
|
return (T)ReadMem_gdrom(addr, sz);
|
2013-12-19 17:10:14 +00:00
|
|
|
}
|
|
|
|
else if (likely((addr>= 0x005F6800) && (addr<=0x005F7CFF))) // /*:PVR i/f Control Reg.*/ -> ALL SB registers now
|
|
|
|
{
|
|
|
|
return (T)sb_ReadMem(addr,sz);
|
|
|
|
}
|
|
|
|
else if (likely((addr>= 0x005F8000) && (addr<=0x005F9FFF))) // :TA / PVR Core Reg.
|
|
|
|
{
|
2018-10-02 08:07:11 +00:00
|
|
|
if (sz != 4)
|
|
|
|
// House of the Dead 2
|
|
|
|
return 0;
|
2013-12-19 17:10:14 +00:00
|
|
|
return (T)pvr_ReadReg(addr);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
//map 0x0060 to 0x0060
|
|
|
|
else if ((base ==0x0060) /*&& (addr>= 0x00600000)*/ && (addr<= 0x006007FF)) // :MODEM
|
|
|
|
{
|
2019-07-09 21:52:19 +00:00
|
|
|
if (settings.platform.system != DC_PLATFORM_DREAMCAST)
|
|
|
|
return (T)libExtDevice_ReadMem_A0_006(addr, sz);
|
|
|
|
else
|
|
|
|
#if defined(ENABLE_MODEM)
|
|
|
|
return (T)ModemReadMem_A0_006(addr, sz);
|
2019-04-27 10:05:13 +00:00
|
|
|
#else
|
2019-07-09 21:52:19 +00:00
|
|
|
return (T)0;
|
2018-09-12 11:20:20 +00:00
|
|
|
#endif
|
2013-12-19 17:10:14 +00:00
|
|
|
}
|
|
|
|
//map 0x0060 to 0x006F
|
|
|
|
else if ((base >=0x0060) && (base <=0x006F) && (addr>= 0x00600800) && (addr<= 0x006FFFFF)) // :G2 (Reserved)
|
|
|
|
{
|
|
|
|
EMUERROR2("Read from area0_32 not implemented [G2 (Reserved)], addr=%x",addr);
|
|
|
|
}
|
|
|
|
//map 0x0070 to 0x0070
|
|
|
|
else if ((base ==0x0070) /*&& (addr>= 0x00700000)*/ && (addr<=0x00707FFF)) // :AICA- Sound Cntr. Reg.
|
|
|
|
{
|
|
|
|
return (T) ReadMem_aica_reg(addr,sz);//libAICA_ReadReg(addr,sz);
|
|
|
|
}
|
|
|
|
//map 0x0071 to 0x0071
|
|
|
|
else if ((base ==0x0071) /*&& (addr>= 0x00710000)*/ && (addr<= 0x0071000B)) // :AICA- RTC Cntr. Reg.
|
|
|
|
{
|
|
|
|
return (T)ReadMem_aica_rtc(addr,sz);
|
|
|
|
}
|
|
|
|
//map 0x0080 to 0x00FF
|
|
|
|
else if ((base >=0x0080) && (base <=0x00FF) /*&& (addr>= 0x00800000) && (addr<=0x00FFFFFF)*/) // :AICA- Wave Memory
|
|
|
|
{
|
|
|
|
ReadMemArrRet(aica_ram.data,addr&ARAM_MASK,sz);
|
|
|
|
}
|
|
|
|
//map 0x0100 to 0x01FF
|
|
|
|
else if ((base >=0x0100) && (base <=0x01FF) /*&& (addr>= 0x01000000) && (addr<= 0x01FFFFFF)*/) // :Ext. Device
|
|
|
|
{
|
|
|
|
return (T)libExtDevice_ReadMem_A0_010(addr,sz);
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
template<u32 sz, class T>
|
|
|
|
void DYNACALL WriteMem_area0(u32 addr,T data)
|
|
|
|
{
|
|
|
|
addr &= 0x01FFFFFF;//to get rid of non needed bits
|
|
|
|
|
|
|
|
const u32 base=(addr>>16);
|
|
|
|
|
|
|
|
//map 0x0000 to 0x001F
|
2019-07-09 21:52:19 +00:00
|
|
|
// :MPX System/Boot ROM
|
|
|
|
if (base <= (settings.platform.system == DC_PLATFORM_ATOMISWAVE ? 0x0001 : 0x001F)) // Only 128k BIOS on AtomisWave
|
2013-12-19 17:10:14 +00:00
|
|
|
{
|
2013-12-24 00:56:44 +00:00
|
|
|
WriteBios(addr,data,sz);
|
2013-12-19 17:10:14 +00:00
|
|
|
}
|
|
|
|
//map 0x0020 to 0x0021
|
2013-12-24 00:56:44 +00:00
|
|
|
else if ((base >=0x0020) && (base <=0x0021) /*&& (addr>= 0x00200000) && (addr<= 0x0021FFFF)*/) // Flash Memory
|
2013-12-19 17:10:14 +00:00
|
|
|
{
|
|
|
|
WriteFlash(addr,data,sz);
|
|
|
|
}
|
2013-12-24 00:56:44 +00:00
|
|
|
//map 0x0040 to 0x005F -> actually, I'll only map 0x005F to 0x005F, b/c the rest of it is unspammed (left to default handler)
|
2013-12-19 17:10:14 +00:00
|
|
|
//map 0x005F to 0x005F
|
|
|
|
else if ( likely(base==0x005F) )
|
|
|
|
{
|
2013-12-24 00:56:44 +00:00
|
|
|
if (/*&& (addr>= 0x00400000) */ (addr<= 0x005F67FF)) // Unassigned
|
2013-12-19 17:10:14 +00:00
|
|
|
{
|
|
|
|
EMUERROR4("Write to area0_32 not implemented [Unassigned], addr=%x,data=%x,size=%d",addr,data,sz);
|
|
|
|
}
|
2013-12-24 00:56:44 +00:00
|
|
|
else if ((addr>= 0x005F7000) && (addr<= 0x005F70FF)) // GD-ROM
|
2013-12-19 17:10:14 +00:00
|
|
|
{
|
2019-07-09 21:52:19 +00:00
|
|
|
if (settings.platform.system != DC_PLATFORM_DREAMCAST)
|
|
|
|
WriteMem_naomi(addr,data,sz);
|
|
|
|
else
|
|
|
|
WriteMem_gdrom(addr,data,sz);
|
2013-12-19 17:10:14 +00:00
|
|
|
}
|
2013-12-24 00:56:44 +00:00
|
|
|
else if ( likely((addr>= 0x005F6800) && (addr<=0x005F7CFF)) ) // /*:PVR i/f Control Reg.*/ -> ALL SB registers
|
2013-12-19 17:10:14 +00:00
|
|
|
{
|
|
|
|
sb_WriteMem(addr,data,sz);
|
|
|
|
}
|
2013-12-24 00:56:44 +00:00
|
|
|
else if ( likely((addr>= 0x005F8000) && (addr<=0x005F9FFF)) ) // TA / PVR Core Reg.
|
2013-12-19 17:10:14 +00:00
|
|
|
{
|
|
|
|
verify(sz==4);
|
|
|
|
pvr_WriteReg(addr,data);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
//map 0x0060 to 0x0060
|
2013-12-24 00:56:44 +00:00
|
|
|
else if ((base ==0x0060) /*&& (addr>= 0x00600000)*/ && (addr<= 0x006007FF)) // MODEM
|
2013-12-19 17:10:14 +00:00
|
|
|
{
|
2019-07-09 21:52:19 +00:00
|
|
|
if (settings.platform.system != DC_PLATFORM_DREAMCAST)
|
|
|
|
libExtDevice_WriteMem_A0_006(addr, data, sz);
|
|
|
|
#if defined(ENABLE_MODEM)
|
|
|
|
else
|
|
|
|
ModemWriteMem_A0_006(addr, data, sz);
|
2018-09-12 11:20:20 +00:00
|
|
|
#endif
|
2013-12-19 17:10:14 +00:00
|
|
|
}
|
|
|
|
//map 0x0060 to 0x006F
|
2013-12-24 00:56:44 +00:00
|
|
|
else if ((base >=0x0060) && (base <=0x006F) && (addr>= 0x00600800) && (addr<= 0x006FFFFF)) // G2 (Reserved)
|
2013-12-19 17:10:14 +00:00
|
|
|
{
|
|
|
|
EMUERROR4("Write to area0_32 not implemented [G2 (Reserved)], addr=%x,data=%x,size=%d",addr,data,sz);
|
|
|
|
}
|
|
|
|
//map 0x0070 to 0x0070
|
2013-12-24 00:56:44 +00:00
|
|
|
else if ((base >=0x0070) && (base <=0x0070) /*&& (addr>= 0x00700000)*/ && (addr<=0x00707FFF)) // AICA- Sound Cntr. Reg.
|
2013-12-19 17:10:14 +00:00
|
|
|
{
|
|
|
|
WriteMem_aica_reg(addr,data,sz);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
//map 0x0071 to 0x0071
|
2013-12-24 00:56:44 +00:00
|
|
|
else if ((base >=0x0071) && (base <=0x0071) /*&& (addr>= 0x00710000)*/ && (addr<= 0x0071000B)) // AICA- RTC Cntr. Reg.
|
2013-12-19 17:10:14 +00:00
|
|
|
{
|
|
|
|
WriteMem_aica_rtc(addr,data,sz);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
//map 0x0080 to 0x00FF
|
2013-12-24 00:56:44 +00:00
|
|
|
else if ((base >=0x0080) && (base <=0x00FF) /*&& (addr>= 0x00800000) && (addr<=0x00FFFFFF)*/) // AICA- Wave Memory
|
2013-12-19 17:10:14 +00:00
|
|
|
{
|
2019-08-31 15:36:34 +00:00
|
|
|
WriteMemArr(aica_ram.data, addr & ARAM_MASK, data, sz);
|
2013-12-19 17:10:14 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
//map 0x0100 to 0x01FF
|
2013-12-24 00:56:44 +00:00
|
|
|
else if ((base >=0x0100) && (base <=0x01FF) /*&& (addr>= 0x01000000) && (addr<= 0x01FFFFFF)*/) // Ext. Device
|
2013-12-19 17:10:14 +00:00
|
|
|
{
|
|
|
|
libExtDevice_WriteMem_A0_010(addr,data,sz);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//Init/Res/Term
|
|
|
|
void sh4_area0_Init()
|
|
|
|
{
|
|
|
|
sb_Init();
|
|
|
|
}
|
|
|
|
|
2019-07-10 15:25:11 +00:00
|
|
|
void sh4_area0_Reset(bool hard)
|
2013-12-19 17:10:14 +00:00
|
|
|
{
|
2019-07-10 15:25:11 +00:00
|
|
|
if (hard)
|
2019-07-09 21:52:19 +00:00
|
|
|
{
|
|
|
|
if (sys_rom != NULL)
|
|
|
|
{
|
|
|
|
delete sys_rom;
|
|
|
|
sys_rom = NULL;
|
|
|
|
}
|
|
|
|
if (sys_nvmem != NULL)
|
|
|
|
{
|
|
|
|
delete sys_nvmem;
|
|
|
|
sys_nvmem = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (settings.platform.system)
|
|
|
|
{
|
|
|
|
case DC_PLATFORM_DREAMCAST:
|
|
|
|
sys_rom = new RomChip(settings.platform.bios_size);
|
|
|
|
sys_nvmem = new DCFlashChip(settings.platform.flash_size);
|
|
|
|
break;
|
|
|
|
case DC_PLATFORM_NAOMI:
|
|
|
|
sys_rom = new RomChip(settings.platform.bios_size);
|
|
|
|
sys_nvmem = new SRamChip(settings.platform.bbsram_size);
|
|
|
|
break;
|
|
|
|
case DC_PLATFORM_ATOMISWAVE:
|
|
|
|
sys_rom = new DCFlashChip(settings.platform.bios_size, settings.platform.bios_size / 2);
|
|
|
|
sys_nvmem = new SRamChip(settings.platform.bbsram_size);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
sys_rom->Reset();
|
|
|
|
sys_nvmem->Reset();
|
|
|
|
}
|
2019-07-10 15:25:11 +00:00
|
|
|
sb_Reset(hard);
|
2013-12-19 17:10:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void sh4_area0_Term()
|
|
|
|
{
|
2019-07-09 21:52:19 +00:00
|
|
|
if (sys_rom != NULL)
|
|
|
|
{
|
|
|
|
delete sys_rom;
|
|
|
|
sys_rom = NULL;
|
|
|
|
}
|
|
|
|
if (sys_nvmem != NULL)
|
|
|
|
{
|
|
|
|
delete sys_nvmem;
|
|
|
|
sys_nvmem = NULL;
|
|
|
|
}
|
2013-12-19 17:10:14 +00:00
|
|
|
sb_Term();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//AREA 0
|
2019-09-01 14:35:12 +00:00
|
|
|
static _vmem_handler area0_handler;
|
2013-12-19 17:10:14 +00:00
|
|
|
|
|
|
|
|
|
|
|
void map_area0_init()
|
|
|
|
{
|
|
|
|
|
|
|
|
area0_handler = _vmem_register_handler_Template(ReadMem_area0,WriteMem_area0);
|
|
|
|
}
|
|
|
|
void map_area0(u32 base)
|
|
|
|
{
|
|
|
|
verify(base<0xE0);
|
|
|
|
|
|
|
|
_vmem_map_handler(area0_handler,0x00|base,0x01|base);
|
|
|
|
|
|
|
|
//0x0240 to 0x03FF mirrors 0x0040 to 0x01FF (no flashrom or bios)
|
|
|
|
//0x0200 to 0x023F are unused
|
|
|
|
_vmem_mirror_mapping(0x02|base,0x00|base,0x02);
|
|
|
|
}
|