From 952b1ae6e93e36847bf82a4ad80111217e272041 Mon Sep 17 00:00:00 2001 From: Stefanos Kornilios Mitsis Poiitidis Date: Wed, 25 Feb 2015 15:21:22 +0100 Subject: [PATCH] reios/hleboot: support cdroms, descramble, slightly smarter bootfile search --- core/reios/descrambl.cpp | 103 ++++++++++++++++++++++++++++++++++ core/reios/descrambl.h | 3 + core/reios/reios.cpp | 44 +++++++++++++-- shell/reicast.vcxproj | 2 + shell/reicast.vcxproj.filters | 6 ++ 5 files changed, 152 insertions(+), 6 deletions(-) create mode 100644 core/reios/descrambl.cpp create mode 100644 core/reios/descrambl.h diff --git a/core/reios/descrambl.cpp b/core/reios/descrambl.cpp new file mode 100644 index 000000000..1272297fc --- /dev/null +++ b/core/reios/descrambl.cpp @@ -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 + +#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; +} \ No newline at end of file diff --git a/core/reios/descrambl.h b/core/reios/descrambl.h new file mode 100644 index 000000000..d244bf293 --- /dev/null +++ b/core/reios/descrambl.h @@ -0,0 +1,3 @@ +#include "types.h" + +void descrambl_file(u32 FAD, u32 file_size, u8* dst); \ No newline at end of file diff --git a/core/reios/reios.cpp b/core/reios/reios.cpp index c79e99162..4ace49bed 100644 --- a/core/reios/reios.cpp +++ b/core/reios/reios.cpp @@ -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); } diff --git a/shell/reicast.vcxproj b/shell/reicast.vcxproj index 7f2afb2ad..72556aa05 100644 --- a/shell/reicast.vcxproj +++ b/shell/reicast.vcxproj @@ -157,6 +157,7 @@ true true + @@ -288,6 +289,7 @@ + diff --git a/shell/reicast.vcxproj.filters b/shell/reicast.vcxproj.filters index d73d9a06c..ee2612452 100644 --- a/shell/reicast.vcxproj.filters +++ b/shell/reicast.vcxproj.filters @@ -405,6 +405,9 @@ reios + + reios + @@ -883,6 +886,9 @@ reios + + reios +