flycast/core/reios/reios.cpp

776 lines
20 KiB
C++
Raw Normal View History

/*
Extremely primitive bios replacement
2014-12-30 00:57:13 +00:00
Many thanks to Lars Olsson (jlo@ludd.luth.se) for bios decompile work
http://www.ludd.luth.se/~jlo/dc/bootROM.c
http://www.ludd.luth.se/~jlo/dc/bootROM.h
http://www.ludd.luth.se/~jlo/dc/security_stuff.c
2019-07-30 17:04:51 +00:00
Bits and pieces from redream (https://github.com/inolen/redream)
*/
#include "reios.h"
2015-03-22 00:16:28 +00:00
#include "reios_elf.h"
#include "gdrom_hle.h"
#include "descrambl.h"
#include "hw/sh4/sh4_mem.h"
2019-07-30 17:04:51 +00:00
#include "hw/holly/sb_mem.h"
#include "hw/naomi/naomi_cart.h"
2019-07-30 17:04:51 +00:00
#include "iso9660.h"
2019-07-31 11:01:12 +00:00
#include "font.h"
#include <map>
2019-07-01 16:23:10 +00:00
#define debugf(...) DEBUG_LOG(REIOS, __VA_ARGS__)
2014-12-30 00:57:13 +00:00
#define dc_bios_syscall_system 0x8C0000B0
#define dc_bios_syscall_font 0x8C0000B4
#define dc_bios_syscall_flashrom 0x8C0000B8
#define dc_bios_syscall_gd 0x8C0000BC
#define dc_bios_syscall_misc 0x8c0000E0
//At least one game (ooga) uses this directly
#define dc_bios_entrypoint_gd_do_bioscall 0x8c0010F0
#define SYSINFO_ID_ADDR 0x8C001010
2019-07-31 11:01:12 +00:00
#define FONT_TABLE_ADDR 0xa0100020
2019-07-30 17:04:51 +00:00
static u8* biosrom;
static MemChip *flashrom;
static u32 base_fad = 45150;
static bool descrambl = false;
2019-07-30 17:04:51 +00:00
static void reios_pre_init()
{
if (libGDR_GetDiscType() == GdRom) {
base_fad = 45150;
descrambl = false;
} else {
u8 ses[6];
libGDR_GetSessionInfo(ses, 0);
libGDR_GetSessionInfo(ses, ses[2]);
base_fad = (ses[3] << 16) | (ses[4] << 8) | (ses[5] << 0);
descrambl = true;
}
}
2019-07-30 17:04:51 +00:00
static bool reios_locate_bootfile(const char* bootfile="1ST_READ.BIN")
{
reios_pre_init();
// Load IP.BIN bootstrap
libGDR_ReadSector(GetMemPtr(0x8c008000, 0), base_fad, 16, 2048);
u32 data_len = 2048 * 1024;
u8* temp = new u8[data_len];
libGDR_ReadSector(temp, base_fad + 16, 1, 2048);
2019-07-30 17:04:51 +00:00
iso9660_pvd_t *pvd = (iso9660_pvd_t *)temp;
2019-07-30 17:04:51 +00:00
if (pvd->type == 1 && !memcmp(pvd->id, ISO_STANDARD_ID, strlen(ISO_STANDARD_ID)) && pvd->version == 1)
{
INFO_LOG(REIOS, "iso9660 PVD found");
u32 lba = pvd->root_directory_record.extent & 0xffffffff;
u32 len = pvd->root_directory_record.size & 0xffffffff;
2019-07-30 17:04:51 +00:00
data_len = ((len + 2047) / 2048) * 2048;
2019-07-30 17:04:51 +00:00
INFO_LOG(REIOS, "iso9660 root_directory, FAD: %d, len: %d", 150 + lba, data_len);
libGDR_ReadSector(temp, 150 + lba, data_len / 2048, 2048);
}
else {
libGDR_ReadSector(temp, base_fad + 16, data_len / 2048, 2048);
}
2019-07-30 17:04:51 +00:00
int bootfile_len = strlen(bootfile);
while (bootfile_len > 0 && isspace(bootfile[bootfile_len - 1]))
bootfile_len--;
for (int i = 0; i < data_len; )
{
iso9660_dir_t *dir = (iso9660_dir_t *)&temp[i];
if (dir->length == 0)
break;
if ((dir->file_flags & ISO_DIRECTORY) == 0 && memcmp(dir->filename.str + 1, bootfile, bootfile_len) == 0)
{
INFO_LOG(REIOS, "Found %.*s at offset %X", bootfile_len, bootfile, i);
2019-07-30 17:04:51 +00:00
u32 lba = dir->extent & 0xffffffff;
u32 len = dir->size & 0xffffffff;
2019-07-01 16:23:10 +00:00
INFO_LOG(REIOS, "file LBA: %d", lba);
INFO_LOG(REIOS, "file LEN: %d", len);
if (descrambl)
descrambl_file(lba + 150, len, GetMemPtr(0x8c010000, 0));
else
libGDR_ReadSector(GetMemPtr(0x8c010000, 0), lba + 150, (len + 2047) / 2048, 2048);
delete[] temp;
2019-07-30 17:04:51 +00:00
u8 data[24] = {0};
// system id
for (u32 j = 0; j < 8; j++)
data[j] = _vmem_ReadMem8(0x0021a056 + j);
// system properties
for (u32 j = 0; j < 5; j++)
data[8 + j] = _vmem_ReadMem8(0x0021a000 + j);
// system settings
flash_syscfg_block syscfg;
verify(static_cast<DCFlashChip*>(flashrom)->ReadBlock(FLASH_PT_USER, FLASH_USER_SYSCFG, &syscfg));
memcpy(&data[16], &syscfg.time_lo, 8);
memcpy(GetMemPtr(0x8c000068, sizeof(data)), data, sizeof(data));
return true;
}
2019-07-30 17:04:51 +00:00
i += dir->length;
}
delete[] temp;
return false;
}
char reios_hardware_id[17];
char reios_maker_id[17];
char reios_device_info[17];
char reios_area_symbols[9];
char reios_peripherals[9];
char reios_product_number[11];
char reios_product_version[7];
char reios_releasedate[17];
char reios_boot_filename[17];
char reios_software_company[17];
char reios_software_name[129];
char reios_bootfile[32];
bool reios_windows_ce = false;
char* reios_disk_id() {
2019-07-30 17:04:51 +00:00
reios_pre_init();
u8 buf[2048];
libGDR_ReadSector(buf, base_fad, 1, sizeof(buf));
memcpy(&reios_hardware_id[0], &buf[0], 16 * sizeof(char));
memcpy(&reios_maker_id[0], &buf[16], 16 * sizeof(char));
memcpy(&reios_device_info[0], &buf[32], 16 * sizeof(char));
memcpy(&reios_area_symbols[0], &buf[48], 8 * sizeof(char));
memcpy(&reios_peripherals[0], &buf[56], 8 * sizeof(char));
memcpy(&reios_product_number[0], &buf[64], 10 * sizeof(char));
memcpy(&reios_product_version[0], &buf[74], 6 * sizeof(char));
memcpy(&reios_releasedate[0], &buf[80], 16 * sizeof(char));
memcpy(&reios_boot_filename[0], &buf[96], 16 * sizeof(char));
memcpy(&reios_software_company[0], &buf[112], 16 * sizeof(char));
memcpy(&reios_software_name[0], &buf[128], 128 * sizeof(char));
reios_windows_ce = memcmp("0WINCEOS.BIN", &reios_boot_filename[0], 12) == 0;
return reios_product_number;
}
2019-07-30 17:04:51 +00:00
static void reios_sys_system() {
u32 cmd = Sh4cntx.r[7];
switch (cmd) {
case 0: //SYSINFO_INIT
2019-07-30 17:04:51 +00:00
{
debugf("reios_sys_system: SYSINFO_INIT");
// 0x00-0x07: system_id
// 0x08-0x0c: system_props
// 0x0d-0x0f: padding (zeroed out)
// 0x10-0x17: settings (zeroed out)
u8 data[24] = {0};
// read system_id from 0x0001a056
for (int i = 0; i < 8; i++)
data[i] = flashrom->Read8(0x1a056 + i);
// read system_props from 0x0001a000
for (int i = 0; i < 5; i++)
data[8 + i] = flashrom->Read8(0x1a000 + i);
memcpy(GetMemPtr(0x8c000068, sizeof(data)), data, sizeof(data));
Sh4cntx.r[0] = 0;
2019-07-30 17:04:51 +00:00
}
break;
case 2: //SYSINFO_ICON
{
2019-07-30 17:04:51 +00:00
debugf("reios_sys_system: SYSINFO_ICON");
// r4 = icon number (0-9, but only 5-9 seems to really be icons)
// r5 = destination buffer (704 bytes in size)
Sh4cntx.r[0] = 704;
}
break;
case 3: //SYSINFO_ID
{
2019-07-30 17:04:51 +00:00
debugf("reios_sys_system: SYSINFO_ID");
// WriteMem32(SYSINFO_ID_ADDR + 0, 0xe1e2e3e4);
// WriteMem32(SYSINFO_ID_ADDR + 4, 0xe5e6e7e8);
//
// Sh4cntx.r[0] = SYSINFO_ID_ADDR;
// TODO or this?
Sh4cntx.r[0] = 0x8c000068;
}
break;
default:
2019-07-30 17:04:51 +00:00
WARN_LOG(REIOS, "reios_sys_system: unhandled cmd %d", cmd);
break;
}
}
2019-07-30 17:04:51 +00:00
static void reios_sys_font() {
2019-07-31 11:01:12 +00:00
u32 cmd = Sh4cntx.r[1];
switch (cmd)
{
case 0: // FONTROM_ADDRESS
debugf("FONTROM_ADDRESS");
Sh4cntx.r[0] = FONT_TABLE_ADDR; // in ROM
break;
case 1: // FONTROM_LOCK
debugf("FONTROM_LOCK");
Sh4cntx.r[0] = 0;
break;
case 2: // FONTROM_UNLOCK
debugf("FONTROM_UNLOCK");
Sh4cntx.r[0] = 0;
break;
default:
WARN_LOG(REIOS, "reios_sys_font cmd %x", cmd);
break;
}
}
2019-07-30 17:04:51 +00:00
static void reios_sys_flashrom() {
u32 cmd = Sh4cntx.r[7];
2019-07-30 17:04:51 +00:00
switch (cmd)
{
case 0: // FLASHROM_INFO
{
/*
2019-07-30 17:04:51 +00:00
r4 = partition number(0 - 4)
r5 = pointer to two 32 bit integers to receive the result.
The first will be the offset of the partition start, in bytes from the start of the flashrom.
The second will be the size of the partition, in bytes.
#define FLASHROM_PT_SYSTEM 0 /< \brief Factory settings (read-only, 8K)
#define FLASHROM_PT_RESERVED 1 /< \brief reserved (all 0s, 8K)
#define FLASHROM_PT_BLOCK_1 2 /< \brief Block allocated (16K)
#define FLASHROM_PT_SETTINGS 3 /< \brief Game settings (block allocated, 32K)
#define FLASHROM_PT_BLOCK_2 4 /< \brief Block allocated (64K)
*/
u32 part = Sh4cntx.r[4];
u32 dest = Sh4cntx.r[5];
2019-07-30 17:04:51 +00:00
debugf("reios_sys_flashrom: FLASHROM_INFO part %d dest %08x", part, dest);
2019-07-30 17:04:51 +00:00
int* pDst = (int*)GetMemPtr(dest, 8);
if (part <= 4) {
2019-07-30 17:04:51 +00:00
static_cast<DCFlashChip*>(flashrom)->GetPartitionInfo(part, pDst, pDst + 1);
Sh4cntx.r[0] = 0;
}
else {
Sh4cntx.r[0] = -1;
}
}
break;
2019-07-30 17:04:51 +00:00
case 1: //FLASHROM_READ
{
/*
r4 = read start position, in bytes from the start of the flashrom
r5 = pointer to destination buffer
r6 = number of bytes to read
*/
2019-07-30 17:04:51 +00:00
u32 offset = Sh4cntx.r[4];
u32 dest = Sh4cntx.r[5];
u32 size = Sh4cntx.r[6];
2019-07-30 17:04:51 +00:00
debugf("reios_sys_flashrom: FLASHROM_READ offs %x dest %08x size %x", offset, dest, size);
for (int i = 0; i < size; i++)
WriteMem8(dest++, flashrom->Read8(offset + i));
Sh4cntx.r[0] = size;
}
break;
2019-07-30 17:04:51 +00:00
case 2: //FLASHROM_WRITE
{
/*
r4 = write start position, in bytes from the start of the flashrom
r5 = pointer to source buffer
r6 = number of bytes to write
*/
u32 offs = Sh4cntx.r[4];
u32 src = Sh4cntx.r[5];
u32 size = Sh4cntx.r[6];
2019-07-30 17:04:51 +00:00
debugf("reios_sys_flashrom: FLASHROM_WRITE offs %x src %08x size %x", offs, src, size);
u8* pSrc = GetMemPtr(src, size);
for (int i = 0; i < size; i++) {
2019-07-30 17:04:51 +00:00
flashrom->data[offs + i] &= pSrc[i];
}
}
break;
2019-07-30 17:04:51 +00:00
case 3: //FLASHROM_DELETE
{
2019-07-30 17:04:51 +00:00
u32 offset = Sh4cntx.r[4];
debugf("reios_sys_flashrom: FLASHROM_DELETE offs %x", offset);
2019-07-30 17:04:51 +00:00
bool found = false;
2019-07-30 17:04:51 +00:00
for (int part = 0; part < FLASH_PT_NUM; part++)
{
int part_offset;
int size;
static_cast<DCFlashChip*>(flashrom)->GetPartitionInfo(part, &part_offset, &size);
if (offset == part_offset)
{
found = true;
memset(flashrom->data + offset, 0xFF, size);
}
}
2019-07-30 17:04:51 +00:00
Sh4cntx.r[0] = found ? 0 : -1;
}
break;
2019-07-30 17:04:51 +00:00
default:
WARN_LOG(REIOS, "reios_sys_flashrom: not handled, %d", cmd);
break;
}
}
2019-07-30 17:04:51 +00:00
static void reios_sys_gd() {
gdrom_hle_op();
}
2014-12-30 00:57:13 +00:00
/*
- gdGdcReqCmd, 0
- gdGdcGetCmdStat, 1
- gdGdcExecServer, 2
- gdGdcInitSystem, 3
- gdGdcGetDrvStat, 4
*/
2019-07-30 17:04:51 +00:00
static void gd_do_bioscall()
2014-12-30 00:57:13 +00:00
{
//looks like the "real" entrypoint for this on a dreamcast
gdrom_hle_op();
return;
/*
int func1, func2, arg1, arg2;
*/
switch (Sh4cntx.r[7]) {
case 0: //gdGdcReqCmd, wth is r6 ?
GD_HLE_Command(Sh4cntx.r[4], Sh4cntx.r[5]);
Sh4cntx.r[0] = 0xf344312e;
break;
case 1: //gdGdcGetCmdStat, r4 -> id as returned by gdGdcReqCmd, r5 -> buffer to get status in ram, r6 ?
Sh4cntx.r[0] = 0; //All good, no status info
break;
case 2: //gdGdcExecServer
//nop? returns something, though.
//Bios seems to be based on a cooperative threading model
//this is the "context" switch entry point
break;
case 3: //gdGdcInitSystem
//nop? returns something, though.
break;
case 4: //gdGdcGetDrvStat
/*
Looks to same as GDROM_CHECK_DRIVE
*/
WriteMem32(Sh4cntx.r[4] + 0, 0x02); // STANDBY
WriteMem32(Sh4cntx.r[4] + 4, 0x80); // CDROM | 0x80 for GDROM
Sh4cntx.r[0] = 0; // RET SUCCESS
break;
default:
2019-07-01 16:23:10 +00:00
INFO_LOG(REIOS, "gd_do_bioscall: (%d) %d, %d, %d", Sh4cntx.r[4], Sh4cntx.r[5], Sh4cntx.r[6], Sh4cntx.r[7]);
2014-12-30 00:57:13 +00:00
break;
}
//gdGdcInitSystem
}
2019-07-30 17:04:51 +00:00
static void reios_sys_misc()
{
WARN_LOG(REIOS, "reios_sys_misc - r7: 0x%08X, r4 0x%08X, r5 0x%08X, r6 0x%08X", Sh4cntx.r[7], Sh4cntx.r[4], Sh4cntx.r[5], Sh4cntx.r[6]);
Sh4cntx.r[0] = 0;
}
typedef void hook_fp();
2019-07-30 17:04:51 +00:00
static u32 hook_addr(hook_fp* fn);
2019-07-30 17:04:51 +00:00
static void setup_syscall(u32 hook_addr, u32 syscall_addr) {
WriteMem32(syscall_addr, hook_addr);
WriteMem16(hook_addr, REIOS_OPCODE);
2019-07-30 17:04:51 +00:00
debugf("Patching syscall vector %08X, points to %08X", syscall_addr, hook_addr);
debugf(" - address %08X: data %04X [%04X]", hook_addr, ReadMem16(hook_addr), REIOS_OPCODE);
}
2019-07-30 17:04:51 +00:00
static void reios_setup_state(u32 boot_addr) {
2015-03-22 00:16:28 +00:00
/*
Post Boot registers from actual bios boot
r
[0x00000000] 0xac0005d8
[0x00000001] 0x00000009
[0x00000002] 0xac00940c
[0x00000003] 0x00000000
[0x00000004] 0xac008300
[0x00000005] 0xf4000000
[0x00000006] 0xf4002000
[0x00000007] 0x00000070
[0x00000008] 0x00000000
[0x00000009] 0x00000000
[0x0000000a] 0x00000000
[0x0000000b] 0x00000000
[0x0000000c] 0x00000000
[0x0000000d] 0x00000000
[0x0000000e] 0x00000000
[0x0000000f] 0x8d000000
mac
l 0x5bfcb024
h 0x00000000
r_bank
[0x00000000] 0xdfffffff
[0x00000001] 0x500000f1
[0x00000002] 0x00000000
[0x00000003] 0x00000000
[0x00000004] 0x00000000
[0x00000005] 0x00000000
[0x00000006] 0x00000000
[0x00000007] 0x00000000
gbr 0x8c000000
ssr 0x40000001
spc 0x8c000776
sgr 0x8d000000
dbr 0x8c000010
vbr 0x8c000000
pr 0xac00043c
fpul 0x00000000
pc 0xac008300
+ sr {T=1 status = 0x400000f0}
+ fpscr {full=0x00040001}
+ old_sr {T=1 status=0x400000f0}
+ old_fpscr {full=0x00040001}
*/
//Setup registers to immitate a normal boot
sh4rcb.cntx.r[15] = 0x8d000000;
sh4rcb.cntx.gbr = 0x8c000000;
sh4rcb.cntx.ssr = 0x40000001;
sh4rcb.cntx.spc = 0x8c000776;
sh4rcb.cntx.sgr = 0x8d000000;
sh4rcb.cntx.dbr = 0x8c000010;
sh4rcb.cntx.vbr = 0x8c000000;
sh4rcb.cntx.pr = 0xac00043c;
sh4rcb.cntx.fpul = 0x00000000;
sh4rcb.cntx.pc = boot_addr;
sh4rcb.cntx.sr.status = 0x400000f0;
sh4rcb.cntx.sr.T = 1;
sh4rcb.cntx.old_sr.status = 0x400000f0;
sh4rcb.cntx.fpscr.full = 0x00040001;
sh4rcb.cntx.old_fpscr.full = 0x00040001;
}
2019-07-30 17:04:51 +00:00
static void reios_setup_naomi(u32 boot_addr) {
/*
SR 0x60000000 0x00000001
FPSRC 0x00040001
- xffr 0x13e1fe40 float [32]
[0x0] 1.00000000 float
[0x1] 0.000000000 float
[0x2] 0.000000000 float
[0x3] 0.000000000 float
[0x4] 0.000000000 float
[0x5] 1.00000000 float
[0x6] 0.000000000 float
[0x7] 0.000000000 float
[0x8] 0.000000000 float
[0x9] 0.000000000 float
[0xa] 1.00000000 float
[0xb] 0.000000000 float
[0xc] 0.000000000 float
[0xd] 0.000000000 float
[0xe] 0.000000000 float
[0xf] 1.00000000 float
[0x10] 1.00000000 float
[0x11] 2.14748365e+009 float
[0x12] 0.000000000 float
[0x13] 480.000000 float
[0x14] 9.99999975e-006 float
[0x15] 0.000000000 float
[0x16] 0.00208333321 float
[0x17] 0.000000000 float
[0x18] 0.000000000 float
[0x19] 2.14748365e+009 float
[0x1a] 1.00000000 float
[0x1b] -1.00000000 float
[0x1c] 0.000000000 float
[0x1d] 0.000000000 float
[0x1e] 0.000000000 float
[0x1f] 0.000000000 float
- r 0x13e1fec0 unsigned int [16]
[0x0] 0x0c021000 unsigned int
[0x1] 0x0c01f820 unsigned int
[0x2] 0xa0710004 unsigned int
[0x3] 0x0c01f130 unsigned int
[0x4] 0x5bfccd08 unsigned int
[0x5] 0xa05f7000 unsigned int
[0x6] 0xa05f7008 unsigned int
[0x7] 0x00000007 unsigned int
[0x8] 0x00000000 unsigned int
[0x9] 0x00002000 unsigned int
[0xa] 0xffffffff unsigned int
[0xb] 0x0c0e0000 unsigned int
[0xc] 0x00000000 unsigned int
[0xd] 0x00000000 unsigned int
[0xe] 0x00000000 unsigned int
[0xf] 0x0cc00000 unsigned int
- mac {full=0x0000000000002000 l=0x00002000 h=0x00000000 } Sh4Context::<unnamed-tag>::<unnamed-tag>::<unnamed-type-mac>
full 0x0000000000002000 unsigned __int64
l 0x00002000 unsigned int
h 0x00000000 unsigned int
- r_bank 0x13e1ff08 unsigned int [8]
[0x0] 0x00000000 unsigned int
[0x1] 0x00000000 unsigned int
[0x2] 0x00000000 unsigned int
[0x3] 0x00000000 unsigned int
[0x4] 0x00000000 unsigned int
[0x5] 0x00000000 unsigned int
[0x6] 0x00000000 unsigned int
[0x7] 0x00000000 unsigned int
gbr 0x0c2abcc0 unsigned int
ssr 0x60000000 unsigned int
spc 0x0c041738 unsigned int
sgr 0x0cbfffb0 unsigned int
dbr 0x00000fff unsigned int
vbr 0x0c000000 unsigned int
pr 0xac0195ee unsigned int
fpul 0x000001e0 unsigned int
pc 0x0c021000 unsigned int
jdyn 0x0c021000 unsigned int
*/
//Setup registers to immitate a normal boot
sh4rcb.cntx.r[0] = 0x0c021000;
sh4rcb.cntx.r[1] = 0x0c01f820;
sh4rcb.cntx.r[2] = 0xa0710004;
sh4rcb.cntx.r[3] = 0x0c01f130;
sh4rcb.cntx.r[4] = 0x5bfccd08;
sh4rcb.cntx.r[5] = 0xa05f7000;
sh4rcb.cntx.r[6] = 0xa05f7008;
sh4rcb.cntx.r[7] = 0x00000007;
sh4rcb.cntx.r[8] = 0x00000000;
sh4rcb.cntx.r[9] = 0x00002000;
sh4rcb.cntx.r[10] = 0xffffffff;
sh4rcb.cntx.r[11] = 0x0c0e0000;
sh4rcb.cntx.r[12] = 0x00000000;
sh4rcb.cntx.r[13] = 0x00000000;
sh4rcb.cntx.r[14] = 0x00000000;
sh4rcb.cntx.r[15] = 0x0cc00000;
sh4rcb.cntx.gbr = 0x0c2abcc0;
sh4rcb.cntx.ssr = 0x60000000;
sh4rcb.cntx.spc = 0x0c041738;
sh4rcb.cntx.sgr = 0x0cbfffb0;
sh4rcb.cntx.dbr = 0x00000fff;
sh4rcb.cntx.vbr = 0x0c000000;
sh4rcb.cntx.pr = 0xac0195ee;
sh4rcb.cntx.fpul = 0x000001e0;
sh4rcb.cntx.pc = boot_addr;
sh4rcb.cntx.sr.status = 0x60000000;
sh4rcb.cntx.sr.T = 1;
sh4rcb.cntx.old_sr.status = 0x60000000;
sh4rcb.cntx.fpscr.full = 0x00040001;
sh4rcb.cntx.old_fpscr.full = 0x00040001;
}
2019-07-30 17:04:51 +00:00
static void reios_boot()
{
2019-07-01 16:23:10 +00:00
NOTICE_LOG(REIOS, "-----------------");
NOTICE_LOG(REIOS, "REIOS: Booting up");
NOTICE_LOG(REIOS, "-----------------");
//setup syscalls
//find boot file
//boot it
memset(GetMemPtr(0x8C000000, 0), 0xFF, 64 * 1024);
setup_syscall(hook_addr(&reios_sys_system), dc_bios_syscall_system);
setup_syscall(hook_addr(&reios_sys_font), dc_bios_syscall_font);
setup_syscall(hook_addr(&reios_sys_flashrom), dc_bios_syscall_flashrom);
setup_syscall(hook_addr(&reios_sys_gd), dc_bios_syscall_gd);
setup_syscall(hook_addr(&reios_sys_misc), dc_bios_syscall_misc);
2014-12-30 00:57:13 +00:00
WriteMem32(dc_bios_entrypoint_gd_do_bioscall, REIOS_OPCODE);
//Infinitive loop for arm !
WriteMem32(0x80800000, 0xEAFFFFFE);
2015-03-22 00:16:28 +00:00
if (settings.reios.ElfFile.size()) {
if (!reios_loadElf(settings.reios.ElfFile)) {
2019-07-30 17:04:51 +00:00
msgboxf("Failed to open %s", MBX_ICONERROR, settings.reios.ElfFile.c_str());
2015-03-22 00:16:28 +00:00
}
reios_setup_state(0x8C010000);
}
else {
if (settings.platform.system == DC_PLATFORM_DREAMCAST) {
2019-07-30 17:31:35 +00:00
if (reios_boot_filename[0] == '\0' || !reios_locate_bootfile(reios_boot_filename))
2019-07-30 17:04:51 +00:00
msgboxf("Failed to locate bootfile %s", MBX_ICONERROR, reios_boot_filename);
reios_setup_state(0xac008300);
}
else {
verify(settings.platform.system == DC_PLATFORM_NAOMI);
if (CurrentCartridge == NULL)
{
2019-07-01 16:23:10 +00:00
WARN_LOG(REIOS, "No cartridge loaded");
return;
}
u32 data_size = 4;
u32* sz = (u32*)CurrentCartridge->GetPtr(0x368, data_size);
if (!sz || data_size != 4) {
msgboxf("Naomi boot failure", MBX_ICONERROR);
}
int size = *sz;
data_size = 1;
verify(size < RAM_SIZE && CurrentCartridge->GetPtr(size - 1, data_size) && "Invalid cart size");
data_size = size;
WriteMemBlock_nommu_ptr(0x0c020000, (u32*)CurrentCartridge->GetPtr(0, data_size), size);
2019-07-30 17:04:51 +00:00
reios_setup_naomi(0x0c021000);
}
2015-03-22 00:16:28 +00:00
}
}
2019-07-30 17:04:51 +00:00
static std::map<u32, hook_fp*> hooks;
static std::map<hook_fp*, u32> hooks_rev;
#define SYSCALL_ADDR_MAP(addr) ((addr & 0x1FFFFFFF) | 0x80000000)
2019-07-30 17:04:51 +00:00
static void register_hook(u32 pc, hook_fp* fn) {
hooks[SYSCALL_ADDR_MAP(pc)] = fn;
hooks_rev[fn] = pc;
}
void DYNACALL reios_trap(u32 op) {
verify(op == REIOS_OPCODE);
u32 pc = sh4rcb.cntx.pc - 2;
sh4rcb.cntx.pc = sh4rcb.cntx.pr;
u32 mapd = SYSCALL_ADDR_MAP(pc);
2019-07-30 17:04:51 +00:00
//debugf("dispatch %08X -> %08X", pc, mapd);
hooks[mapd]();
}
2019-07-30 17:04:51 +00:00
static u32 hook_addr(hook_fp* fn) {
if (hooks_rev.count(fn))
return hooks_rev[fn];
else {
2019-07-01 16:23:10 +00:00
ERROR_LOG(REIOS, "hook_addr: Failed to reverse lookup %p", fn);
verify(false);
return 0;
}
}
2019-07-30 17:04:51 +00:00
bool reios_init(u8* rom, MemChip* flash) {
2019-07-01 16:23:10 +00:00
INFO_LOG(REIOS, "reios: Init");
biosrom = rom;
flashrom = flash;
memset(rom, 0xEA, 2048 * 1024);
memset(GetMemPtr(0x8C000000, 0), 0, RAM_SIZE);
u16* rom16 = (u16*)rom;
rom16[0] = REIOS_OPCODE;
register_hook(0xA0000000, reios_boot);
register_hook(0x8C001000, reios_sys_system);
register_hook(0x8C001002, reios_sys_font);
register_hook(0x8C001004, reios_sys_flashrom);
register_hook(0x8C001006, reios_sys_gd);
register_hook(0x8C001008, reios_sys_misc);
2014-12-30 00:57:13 +00:00
register_hook(dc_bios_entrypoint_gd_do_bioscall, &gd_do_bioscall);
2019-07-31 11:01:12 +00:00
u8 *pFont = rom + (FONT_TABLE_ADDR % BIOS_SIZE);
// 288 12 × 24 pixels (36 bytes) characters
// 7078 24 × 24 pixels (72 bytes) characters
// 129 32 × 32 pixels (128 bytes) characters
memset(pFont, 0, 536496);
FILE *font = fopen(get_readonly_data_path(DATA_PATH "font.bin").c_str(), "rb");
if (font == NULL)
{
INFO_LOG(REIOS, "font.bin not found. Using built-in font");
memcpy(pFont, builtin_font, sizeof(builtin_font));
}
else
{
fseek(font, 0, SEEK_END);
size_t size = ftell(font);
fseek(font, 0, SEEK_SET);
size_t nread = fread(pFont, 1, size, font);
fclose(font);
if (nread != size)
WARN_LOG(REIOS, "font.bin: read truncated");
else
INFO_LOG(REIOS, "font.bin: loaded %zd bytes", size);
}
return true;
}
void reios_reset() {
}
void reios_term() {
}