736 |
|
* file_read_error: Cannot read ROM file |
737 |
|
*/ |
738 |
|
|
739 |
– |
// Decode LZSS data |
740 |
– |
static void decode_lzss(const uint8 *src, uint8 *dest, int size) |
741 |
– |
{ |
742 |
– |
char dict[0x1000]; |
743 |
– |
int run_mask = 0, dict_idx = 0xfee; |
744 |
– |
for (;;) { |
745 |
– |
if (run_mask < 0x100) { |
746 |
– |
// Start new run |
747 |
– |
if (--size < 0) |
748 |
– |
break; |
749 |
– |
run_mask = *src++ | 0xff00; |
750 |
– |
} |
751 |
– |
bool bit = run_mask & 1; |
752 |
– |
run_mask >>= 1; |
753 |
– |
if (bit) { |
754 |
– |
// Verbatim copy |
755 |
– |
if (--size < 0) |
756 |
– |
break; |
757 |
– |
int c = *src++; |
758 |
– |
dict[dict_idx++] = c; |
759 |
– |
*dest++ = c; |
760 |
– |
dict_idx &= 0xfff; |
761 |
– |
} else { |
762 |
– |
// Copy from dictionary |
763 |
– |
if (--size < 0) |
764 |
– |
break; |
765 |
– |
int idx = *src++; |
766 |
– |
if (--size < 0) |
767 |
– |
break; |
768 |
– |
int cnt = *src++; |
769 |
– |
idx |= (cnt << 4) & 0xf00; |
770 |
– |
cnt = (cnt & 0x0f) + 3; |
771 |
– |
while (cnt--) { |
772 |
– |
char c = dict[idx++]; |
773 |
– |
dict[dict_idx++] = c; |
774 |
– |
*dest++ = c; |
775 |
– |
idx &= 0xfff; |
776 |
– |
dict_idx &= 0xfff; |
777 |
– |
} |
778 |
– |
} |
779 |
– |
} |
780 |
– |
} |
781 |
– |
|
739 |
|
void SheepShaver::load_rom(void) |
740 |
|
{ |
741 |
|
// Get rom file path from preferences |
764 |
|
|
765 |
|
uint8 *rom = new uint8[ROM_SIZE]; // Reading directly into the area doesn't work |
766 |
|
ssize_t actual = file.Read((void *)rom, ROM_SIZE); |
767 |
< |
if (actual == ROM_SIZE) { |
768 |
< |
// Plain ROM image |
769 |
< |
memcpy((void *)ROM_BASE, rom, ROM_SIZE); |
770 |
< |
delete[] rom; |
814 |
< |
} else { |
815 |
< |
if (strncmp((char *)rom, "<CHRP-BOOT>", 11) == 0) { |
816 |
< |
// CHRP compressed ROM image |
817 |
< |
D(bug("CHRP ROM image\n")); |
818 |
< |
uint32 lzss_offset, lzss_size; |
819 |
< |
|
820 |
< |
char *s = strstr((char *)rom, "constant lzss-offset"); |
821 |
< |
if (s == NULL) |
822 |
< |
throw rom_size_error(); |
823 |
< |
s -= 7; |
824 |
< |
if (sscanf(s, "%06lx", &lzss_offset) != 1) |
825 |
< |
throw rom_size_error(); |
826 |
< |
s = strstr((char *)rom, "constant lzss-size"); |
827 |
< |
if (s == NULL) |
828 |
< |
throw rom_size_error(); |
829 |
< |
s -= 7; |
830 |
< |
if (sscanf(s, "%06lx", &lzss_size) != 1) |
831 |
< |
throw rom_size_error(); |
832 |
< |
D(bug("Offset of compressed data: %08lx\n", lzss_offset)); |
833 |
< |
D(bug("Size of compressed data: %08lx\n", lzss_size)); |
834 |
< |
|
835 |
< |
D(bug("Uncompressing ROM...\n")); |
836 |
< |
decode_lzss(rom + lzss_offset, (uint8 *)ROM_BASE, lzss_size); |
837 |
< |
delete[] rom; |
838 |
< |
} else if (rom_size != 4*1024*1024) |
767 |
> |
|
768 |
> |
// Decode Mac ROM |
769 |
> |
if (!DecodeROM(rom, actual)) { |
770 |
> |
if (rom_size != 4*1024*1024) |
771 |
|
throw rom_size_error(); |
772 |
|
else |
773 |
|
throw file_read_error(); |
774 |
|
} |
775 |
+ |
delete[] rom; |
776 |
|
} |
777 |
|
|
778 |
|
|