reios/hleboot: support cdroms, descramble, slightly smarter bootfile search

This commit is contained in:
Stefanos Kornilios Mitsis Poiitidis 2015-02-25 15:21:22 +01:00
parent 0bf6272b9c
commit 952b1ae6e9
5 changed files with 152 additions and 6 deletions

103
core/reios/descrambl.cpp Normal file
View File

@ -0,0 +1,103 @@
/*
Based on work of Marcus Comstedt
http://mc.pp.se, http://mc.pp.se/dc/sw.html, http://mc.pp.se/dc/files/scramble.c
License: Gotta verify
Adapted by Stefanos Kornilios Mitsis Poiitidis (skmp) for reicast
*/
#include "descrambl.h"
#include <algorithm>
#define MAXCHUNK (2048*1024)
static unsigned int seed;
void my_srand(unsigned int n)
{
seed = n & 0xffff;
}
unsigned int my_rand()
{
seed = (seed * 2109 + 9273) & 0x7fff;
return (seed + 0xc000) & 0xffff;
}
/*
void load(FILE *fh, unsigned char *ptr, unsigned long sz)
{
if (fread(ptr, 1, sz, fh) != sz)
{
fprintf(stderr, "Read error!\n");
exit(1);
}
}
*/
void load_chunk(u8* &src, unsigned char *ptr, unsigned long sz)
{
verify(sz < MAXCHUNK);
static int idx[MAXCHUNK / 32];
int i;
/* Convert chunk size to number of slices */
sz /= 32;
/* Initialize index table with unity,
so that each slice gets loaded exactly once */
for (i = 0; i < sz; i++)
idx[i] = i;
for (i = sz - 1; i >= 0; --i)
{
/* Select a replacement index */
int x = (my_rand() * i) >> 16;
/* Swap */
swap(idx[i], idx[x]);
/*
int tmp = idx[i];
idx[i] = idx[x];
idx[x] = tmp;
*/
/* Load resulting slice */
//load(fh, ptr + 32 * idx[i], 32);
memcpy(ptr + 32 * idx[i], src, 32);
src += 32;
}
}
void descrambl_buffer(u8* src, unsigned char *dst, unsigned long filesz)
{
unsigned long chunksz;
my_srand(filesz);
/* Descramble 2 meg blocks for as long as possible, then
gradually reduce the window down to 32 bytes (1 slice) */
for (chunksz = MAXCHUNK; chunksz >= 32; chunksz >>= 1)
while (filesz >= chunksz)
{
load_chunk(src, dst, chunksz);
filesz -= chunksz;
dst += chunksz;
}
/* Load final incomplete slice */
if (filesz)
memcpy(dst, src, filesz);
}
void descrambl_file(u32 FAD, u32 file_size, u8* dst) {
u8* temp_file = new u8[file_size + 2048];
libGDR_ReadSector(temp_file, FAD, file_size / 2048, 2048);
descrambl_buffer(temp_file, dst, file_size);
delete[] temp_file;
}

3
core/reios/descrambl.h Normal file
View File

@ -0,0 +1,3 @@
#include "types.h"
void descrambl_file(u32 FAD, u32 file_size, u8* dst);

View File

@ -10,6 +10,7 @@
#include "reios.h"
#include "gdrom_hle.h"
#include "descrambl.h"
#include "hw/sh4/sh4_mem.h"
@ -28,13 +29,28 @@
u8* biosrom;
u8* flashrom;
u32 base_fad = 45150;
bool descrambl = false;
bool reios_locate_bootfile(const char* bootfile="1ST_READ.BIN") {
u8* temp = new u8[2048 * 1024];
u32 data_len = 2048 * 1024;
u8* temp = new u8[data_len];
libGDR_ReadSector(temp, 45150 + 16, 1024, 2048);
libGDR_ReadSector(temp, base_fad + 16, 1, 2048);
for (int i = 0; i < 2048 * 1023; i++) {
if (memcmp(temp, "\001CD001\001", 7) == 0) {
u32 lba = (u32&)temp[156 + 2]; //Root directory lba, should use the big endian one
u32 len = (u32&)temp[156 + 10]; //should use the big endian one
data_len = ((len + 2047) / 2048) *2048;
libGDR_ReadSector(temp, 150 + lba, data_len/2048, 2048);
}
else {
libGDR_ReadSector(temp, base_fad + 16, data_len / 2048, 2048);
}
for (int i = 0; i < (data_len-20); i++) {
if (memcmp(temp+i, bootfile, strlen(bootfile)) == 0){
printf("Found %s at %06X\n", bootfile, i);
@ -45,7 +61,10 @@ bool reios_locate_bootfile(const char* bootfile="1ST_READ.BIN") {
u32 lba = (u32&)temp[i - 33 + 2]; //should use the big endian one, but i'm lazy
u32 len = (u32&)temp[i - 33 + 10]; //should use the big endian one, but i'm lazy
libGDR_ReadSector(GetMemPtr(0x8c010000, 0), lba + 150, (len + 2047) / 2048, 2048);
if (descrambl)
descrambl_file(lba + 150, len, GetMemPtr(0x8c010000, 0));
else
libGDR_ReadSector(GetMemPtr(0x8c010000, 0), lba + 150, (len + 2047) / 2048, 2048);
delete[] temp;
return true;
@ -58,7 +77,20 @@ bool reios_locate_bootfile(const char* bootfile="1ST_READ.BIN") {
char reios_bootfile[32];
const char* reios_locate_ip() {
libGDR_ReadSector(GetMemPtr(0x8c008000, 0), 45150, 16, 2048);
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;
}
libGDR_ReadSector(GetMemPtr(0x8c008000, 0), base_fad, 16, 2048);
memset(reios_bootfile, 0, sizeof(reios_bootfile));
memcpy(reios_bootfile, GetMemPtr(0x8c008060, 0), 16);
@ -316,7 +348,7 @@ void reios_boot() {
WriteMem32(0x80800000, 0xEAFFFFFE);
const char* bootfile = reios_locate_ip();
if (!reios_locate_bootfile(bootfile))
if (!bootfile || !reios_locate_bootfile(bootfile))
msgboxf("Failed to locate bootfile", MBX_ICONERROR);
}

View File

@ -157,6 +157,7 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Fast|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Fast|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\core\reios\descrambl.cpp" />
<ClCompile Include="..\core\reios\gdrom_hle.cpp" />
<ClCompile Include="..\core\reios\reios.cpp" />
<ClCompile Include="..\core\rend\d3d11\d3d11.cpp" />
@ -288,6 +289,7 @@
<ClInclude Include="..\core\oslib\audiostream_rif.h" />
<ClInclude Include="..\core\oslib\oslib.h" />
<ClInclude Include="..\core\profiler\profiler.h" />
<ClInclude Include="..\core\reios\descrambl.h" />
<ClInclude Include="..\core\reios\gdrom_hle.h" />
<ClInclude Include="..\core\reios\reios.h" />
<ClInclude Include="..\core\rend\gles\gles.h" />

View File

@ -405,6 +405,9 @@
<ClCompile Include="..\core\reios\gdrom_hle.cpp">
<Filter>reios</Filter>
</ClCompile>
<ClCompile Include="..\core\reios\descrambl.cpp">
<Filter>reios</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<Filter Include="hw">
@ -883,6 +886,9 @@
<ClInclude Include="..\core\reios\gdrom_hle.h">
<Filter>reios</Filter>
</ClInclude>
<ClInclude Include="..\core\reios\descrambl.h">
<Filter>reios</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="..\core\deps\zlib\Makefile">