--- BasiliskII/src/rom_patches.cpp 1999/10/31 23:18:33 1.12 +++ BasiliskII/src/rom_patches.cpp 2001/02/10 11:37:42 1.20 @@ -1,7 +1,7 @@ /* * rom_patches.cpp - ROM patches * - * Basilisk II (C) 1997-1999 Christian Bauer + * Basilisk II (C) 1997-2001 Christian Bauer * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -43,14 +43,23 @@ uint32 UniversalInfo; // ROM offset of uint32 PutScrapPatch; // Mac address of PutScrap() patch uint32 ROMBreakpoint = 0; // ROM offset of breakpoint (0 = disabled, 0x2310 = CritError) bool PrintROMInfo = false; // Flag: print ROM information in PatchROM() +bool PatchHWBases = true; // Flag: patch hardware base addresses -static uint32 sony_offset; // ROM offset of .Sony driver -static uint32 serd_offset; // ROM offset of SERD resource (serial drivers) -static uint32 microseconds_offset; // ROM offset of Microseconds() replacement routine +static uint32 sony_offset; // ROM offset of .Sony driver +static uint32 serd_offset; // ROM offset of SERD resource (serial drivers) +static uint32 microseconds_offset; // ROM offset of Microseconds() replacement routine +static uint32 debugutil_offset; // ROM offset of DebugUtil() replacement routine // Prototypes uint16 ROMVersion; +/* + * Macros used to extract one of the 16-bit words from a 32-bit word value + */ + +#define HiWord(X) (((X) >> 16) & 0xffff) +#define LoWord(X) ((X) & 0xffff) + /* * Search ROM for byte string, return ROM offset (or 0) @@ -270,7 +279,7 @@ static void list_universal_infos(void) printf("Universal Table at %08x:\n", q); printf("Offset\t ID\tHWCfg\tROM85\tModel\n"); printf("------------------------------------------------\n"); - while (ofs = ReadMacInt32(ROMBaseMac + q)) { + while ((ofs = ReadMacInt32(ROMBaseMac + q))) { print_universal_info(ROMBaseMac + ofs + q); q += 4; } @@ -693,7 +702,7 @@ static const uint8 adbop_patch[] = { // void InstallDrivers(uint32 pb) { - D(bug("InstallDrivers\n")); + D(bug("InstallDrivers, pb %08x\n", pb)); M68kRegisters r; // Install Microseconds() replacement routine @@ -701,6 +710,11 @@ void InstallDrivers(uint32 pb) r.d[0] = 0xa093; Execute68kTrap(0xa247, &r); // SetOSTrapAddress() + // Install DebugUtil() replacement routine + r.a[0] = ROMBaseMac + debugutil_offset; + r.d[0] = 0xa08d; + Execute68kTrap(0xa247, &r); // SetOSTrapAddress() + // Install disk driver r.a[0] = ROMBaseMac + sony_offset + 0x100; r.d[0] = (uint32)DiskRefNum; @@ -812,8 +826,8 @@ bool CheckROM(void) // Read version ROMVersion = ntohs(*(uint16 *)(ROMBaseHost + 8)); -#if REAL_ADDRESSING - // Real addressing mode requires a 32-bit clean ROM +#if REAL_ADDRESSING || DIRECT_ADDRESSING + // Real and direct addressing modes require a 32-bit clean ROM return ROMVersion == ROM_VERSION_32; #else // Virtual addressing mode works with 32-bit clean Mac II ROMs and Classic ROMs @@ -930,6 +944,11 @@ static bool patch_rom_classic(void) *wp++ = htons(M68K_RTS); microseconds_offset = (uint8 *)wp - ROMBaseHost; *wp++ = htons(M68K_EMUL_OP_MICROSECONDS); + *wp++ = htons(M68K_RTS); + + // Replace DebugUtil + debugutil_offset = (uint8 *)wp - ROMBaseHost; + *wp++ = htons(M68K_EMUL_OP_DEBUGUTIL); *wp = htons(M68K_RTS); // Replace SCSIDispatch() @@ -1010,6 +1029,31 @@ static bool patch_rom_32(void) bp = ROMBaseHost + UniversalInfo + 18; // productKind *bp = PrefsFindInt32("modelid"); +#if !ROM_IS_WRITE_PROTECTED +#if defined(USE_SCRATCHMEM_SUBTERFUGE) + // Set hardware base addresses to scratch memory area + if (PatchHWBases) { + extern uint8 *ScratchMem; + const uint32 ScratchMemBase = Host2MacAddr(ScratchMem); + + D(bug("LMGlob\tOfs/4\tBase\n")); + base = ROMBaseMac + UniversalInfo + ReadMacInt32(ROMBaseMac + UniversalInfo); // decoderInfoPtr + wp = (uint16 *)(ROMBaseHost + 0x94a); + while (*wp != 0xffff) { + int16 ofs = ntohs(*wp++); // offset in decoderInfo (/4) + int16 lmg = ntohs(*wp++); // address of LowMem global + D(bug("0x%04x\t%d\t0x%08x\n", lmg, ofs, ReadMacInt32(base + ofs*4))); + + // Fake address only if this is not the ASC base + if (lmg != 0xcc0) + WriteMacInt32(base + ofs*4, ScratchMemBase); + } + } +#else +#error System specific handling for writable ROM is required here +#endif +#endif + // Make FPU optional if (FPUType == 0) { bp = ROMBaseHost + UniversalInfo + 22; // defaultRSRCs @@ -1192,36 +1236,40 @@ static bool patch_rom_32(void) *wp = htons(M68K_RTS); // Fake CPU speed test (SetupTimeK) + // *** increased jl : MacsBug uses TimeDBRA for kbd repeat timing wp = (uint16 *)(ROMBaseHost + 0x800); *wp++ = htons(0x31fc); // move.w #xxx,TimeDBRA - *wp++ = htons(100); + *wp++ = htons(10000); *wp++ = htons(0x0d00); *wp++ = htons(0x31fc); // move.w #xxx,TimeSCCDBRA - *wp++ = htons(100); + *wp++ = htons(10000); *wp++ = htons(0x0d02); *wp++ = htons(0x31fc); // move.w #xxx,TimeSCSIDBRA - *wp++ = htons(100); + *wp++ = htons(10000); *wp++ = htons(0x0b24); *wp++ = htons(0x31fc); // move.w #xxx,TimeRAMDBRA - *wp++ = htons(100); + *wp++ = htons(10000); *wp++ = htons(0x0cea); *wp = htons(M68K_RTS); #if REAL_ADDRESSING // Move system zone to start of Mac RAM - lp = (uint32 *)(ROMBaseHost + 0x50a); - *lp++ = htonl(RAMBaseMac); - *lp = htonl(RAMBaseMac + 0x1800); + wp = (uint16 *)(ROMBaseHost + 0x50a); + *wp++ = htons(HiWord(RAMBaseMac + 0x2000)); + *wp++ = htons(LoWord(RAMBaseMac + 0x2000)); + *wp++ = htons(HiWord(RAMBaseMac + 0x3800)); + *wp = htons(LoWord(RAMBaseMac + 0x3800)); #endif #if !ROM_IS_WRITE_PROTECTED -#if defined(AMIGA) +#if defined(USE_SCRATCHMEM_SUBTERFUGE) // Set fake handle at 0x0000 to scratch memory area (so broken Mac programs won't write into Mac ROM) - extern uint32 ScratchMem; + extern uint8 *ScratchMem; + const uint32 ScratchMemBase = Host2MacAddr(ScratchMem); wp = (uint16 *)(ROMBaseHost + 0xccaa); *wp++ = htons(0x203c); // move.l #ScratchMem,d0 - *wp++ = htons(ScratchMem >> 16); - *wp = htons(ScratchMem); + *wp++ = htons(ScratchMemBase >> 16); + *wp = htons(ScratchMemBase); #else #error System specific handling for writable ROM is required here #endif @@ -1233,7 +1281,14 @@ static bool patch_rom_32(void) *wp++ = htons(M68K_NOP); *wp = htons(M68K_NOP); #endif - + +#if REAL_ADDRESSING && !defined(AMIGA) + // gb-- Temporary hack to get rid of crashes in Speedometer + wp = (uint16 *)(ROMBaseHost + 0xdba2); + if (ntohs(*wp) == 0x662c) // bne.b #$2c + *wp = htons(0x602c); // bra.b #$2c +#endif + // Don't write to VIA in InitTimeMgr wp = (uint16 *)(ROMBaseHost + 0xb0e2); *wp++ = htons(0x4cdf); // movem.l (sp)+,d0-d5/a0-a4 @@ -1429,12 +1484,14 @@ static bool patch_rom_32(void) if (ROMSize > 0x80000) { // BlockMove() - static const uint8 ptest_dat[] = {0xa0, 0x8d, 0x0c, 0x81, 0x00, 0x00, 0x0c, 0x00, 0x6d, 0x06, 0x4e, 0x71, 0xf4, 0xf8}; - base = find_rom_data(0x87000, 0x87800, ptest_dat, sizeof(ptest_dat)); - D(bug("ptest %08lx\n", base)); + static const uint8 bmove_dat[] = {0x20, 0x5f, 0x22, 0x5f, 0x0c, 0x38, 0x00, 0x04, 0x01, 0x2f}; + base = find_rom_data(0x87000, 0x87800, bmove_dat, sizeof(bmove_dat)); + D(bug("block_move %08lx\n", base)); if (base) { // ROM15/22/23/26/27/32 - wp = (uint16 *)(ROMBaseHost + base + 8); - *wp = htons(M68K_NOP); + wp = (uint16 *)(ROMBaseHost + base + 4); + *wp++ = htons(M68K_EMUL_OP_BLOCK_MOVE); + *wp++ = htons(0x7000); + *wp = htons(M68K_RTS); } // SANE @@ -1461,7 +1518,7 @@ static bool patch_rom_32(void) } // Patch .EDisk driver (don't scan for EDisks in the area ROMBase..0xe00000) - uint32 edisk_offset = find_rom_resource('DRVR', 51); + uint32 edisk_offset = find_rom_resource(FOURCC('D','R','V','R'), 51); if (edisk_offset) { static const uint8 edisk_dat[] = {0xd5, 0xfc, 0x00, 0x01, 0x00, 0x00, 0xb5, 0xfc, 0x00, 0xe0, 0x00, 0x00}; base = find_rom_data(edisk_offset, edisk_offset + 0x10000, edisk_dat, sizeof(edisk_dat)); @@ -1474,7 +1531,7 @@ static bool patch_rom_32(void) } // Replace .Sony driver - sony_offset = find_rom_resource('DRVR', 4); + sony_offset = find_rom_resource(FOURCC('D','R','V','R'), 4); D(bug("sony %08lx\n", sony_offset)); memcpy(ROMBaseHost + sony_offset, sony_driver, sizeof(sony_driver)); @@ -1493,7 +1550,7 @@ static bool patch_rom_32(void) memcpy(ROMBaseHost + sony_offset + 0xa00, CDROMIcon, sizeof(CDROMIcon)); // Install SERD patch and serial drivers - serd_offset = find_rom_resource('SERD', 0); + serd_offset = find_rom_resource(FOURCC('S','E','R','D'), 0); D(bug("serd %08lx\n", serd_offset)); wp = (uint16 *)(ROMBaseHost + serd_offset + 12); *wp++ = htons(M68K_EMUL_OP_SERD); @@ -1526,6 +1583,11 @@ static bool patch_rom_32(void) *wp++ = htons(M68K_RTS); microseconds_offset = (uint8 *)wp - ROMBaseHost; *wp++ = htons(M68K_EMUL_OP_MICROSECONDS); + *wp++ = htons(M68K_RTS); + + // Replace DebugUtil + debugutil_offset = (uint8 *)wp - ROMBaseHost; + *wp++ = htons(M68K_EMUL_OP_DEBUGUTIL); *wp = htons(M68K_RTS); // Replace SCSIDispatch() @@ -1561,17 +1623,9 @@ static bool patch_rom_32(void) *wp++ = htons(base >> 16); *wp = htons(base & 0xffff); -#if EMULATED_68K - // Replace BlockMove() - wp = (uint16 *)(ROMBaseHost + find_rom_trap(0xa02e)); // BlockMove() - *wp++ = htons(M68K_EMUL_OP_BLOCK_MOVE); - *wp++ = htons(0x7000); - *wp = htons(M68K_RTS); -#endif - // Look for double PACK 4 resources - if ((base = find_rom_resource('PACK', 4)) == 0) return false; - if ((base = find_rom_resource('PACK', 4, true)) == 0 && FPUType == 0) + if ((base = find_rom_resource(FOURCC('P','A','C','K'), 4)) == 0) return false; + if ((base = find_rom_resource(FOURCC('P','A','C','K'), 4, true)) == 0 && FPUType == 0) printf("WARNING: This ROM seems to require an FPU\n"); // Patch VIA interrupt handler