--- SheepShaver/src/rom_patches.cpp 2003/12/15 15:27:01 1.23 +++ SheepShaver/src/rom_patches.cpp 2004/07/14 08:24:07 1.35 @@ -1,7 +1,7 @@ /* * rom_patches.cpp - ROM patches * - * SheepShaver (C) 1997-2002 Christian Bauer and Marc Hellwig + * SheepShaver (C) 1997-2004 Christian Bauer and Marc Hellwig * * 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 @@ -847,7 +847,8 @@ static bool patch_nanokernel_boot(void) lp[7] = htonl(0x00040004); // Inst cache assoc/Data cache assoc lp[8] = htonl(0x00400002); // TLB total size/TLB assoc break; - case 8: // 750 + case 8: // 750, 750FX + case 0x7000: lp[0] = htonl(0x1000); // Page size lp[1] = htonl(0x8000); // Data cache size lp[2] = htonl(0x8000); // Inst cache size @@ -871,7 +872,11 @@ static bool patch_nanokernel_boot(void) lp[8] = htonl(0x00800002); // TLB total size/TLB assoc break; // case 11: // X704? - case 12: // ??? + case 12: // 7400, 7410, 7450, 7455, 7457 + case 0x800c: + case 0x8000: + case 0x8001: + case 0x8002: lp[0] = htonl(0x1000); // Page size lp[1] = htonl(0x8000); // Data cache size lp[2] = htonl(0x8000); // Inst cache size @@ -906,6 +911,17 @@ static bool patch_nanokernel_boot(void) lp[7] = htonl(0x00080008); // Inst cache assoc/Data cache assoc lp[8] = htonl(0x00800004); // TLB total size/TLB assoc break; + case 0x39: // 970 + lp[0] = htonl(0x1000); // Page size + lp[1] = htonl(0x8000); // Data cache size + lp[2] = htonl(0x10000); // Inst cache size + lp[3] = htonl(0x00200020); // Coherency block size/Reservation granule size + lp[4] = htonl(0x00010020); // Unified caches/Inst cache line size + lp[5] = htonl(0x00200020); // Data cache line size/Data cache block size touch + lp[6] = htonl(0x00800080); // Inst cache block size/Data cache block size + lp[7] = htonl(0x00020002); // Inst cache assoc/Data cache assoc + lp[8] = htonl(0x02000004); // TLB total size/TLB assoc + break; default: printf("WARNING: Unknown CPU type\n"); break; @@ -1057,7 +1073,7 @@ static bool patch_nanokernel_boot(void) static bool patch_68k_emul(void) { uint32 *lp; - uint32 base; + uint32 base, loc; // Overwrite twi instructions static const uint8 twi_dat[] = {0x0f, 0xff, 0x00, 0x00, 0x0f, 0xff, 0x00, 0x01, 0x0f, 0xff, 0x00, 0x02}; @@ -1121,13 +1137,9 @@ static bool patch_68k_emul(void) // Extra routine for 68k emulator start lp = (uint32 *)(ROM_BASE + 0x36f900); *lp++ = htonl(0x7c2903a6); // mtctr r1 -#if EMULATED_PPC - *lp++ = htonl(NativeOpcode(NATIVE_DISABLE_INTERRUPT)); -#else *lp++ = htonl(0x80200000 + XLM_IRQ_NEST); // lwz r1,XLM_IRQ_NEST *lp++ = htonl(0x38210001); // addi r1,r1,1 *lp++ = htonl(0x90200000 + XLM_IRQ_NEST); // stw r1,XLM_IRQ_NEST -#endif *lp++ = htonl(0x80200000 + XLM_KERNEL_DATA);// lwz r1,XLM_KERNEL_DATA *lp++ = htonl(0x90c10018); // stw r6,0x18(r1) *lp++ = htonl(0x7cc902a6); // mfctr r6 @@ -1155,13 +1167,9 @@ static bool patch_68k_emul(void) // Extra routine for Mixed Mode lp = (uint32 *)(ROM_BASE + 0x36fa00); *lp++ = htonl(0x7c2903a6); // mtctr r1 -#if EMULATED_PPC - *lp++ = htonl(NativeOpcode(NATIVE_DISABLE_INTERRUPT)); -#else *lp++ = htonl(0x80200000 + XLM_IRQ_NEST); // lwz r1,XLM_IRQ_NEST *lp++ = htonl(0x38210001); // addi r1,r1,1 *lp++ = htonl(0x90200000 + XLM_IRQ_NEST); // stw r1,XLM_IRQ_NEST -#endif *lp++ = htonl(0x80200000 + XLM_KERNEL_DATA);// lwz r1,XLM_KERNEL_DATA *lp++ = htonl(0x90c10018); // stw r6,0x18(r1) *lp++ = htonl(0x7cc902a6); // mfctr r6 @@ -1189,13 +1197,9 @@ static bool patch_68k_emul(void) // Extra routine for Reset/FC1E opcode lp = (uint32 *)(ROM_BASE + 0x36fb00); *lp++ = htonl(0x7c2903a6); // mtctr r1 -#if EMULATED_PPC - *lp++ = htonl(NativeOpcode(NATIVE_DISABLE_INTERRUPT)); -#else *lp++ = htonl(0x80200000 + XLM_IRQ_NEST); // lwz r1,XLM_IRQ_NEST *lp++ = htonl(0x38210001); // addi r1,r1,1 *lp++ = htonl(0x90200000 + XLM_IRQ_NEST); // stw r1,XLM_IRQ_NEST -#endif *lp++ = htonl(0x80200000 + XLM_KERNEL_DATA);// lwz r1,XLM_KERNEL_DATA *lp++ = htonl(0x90c10018); // stw r6,0x18(r1) *lp++ = htonl(0x7cc902a6); // mfctr r6 @@ -1223,13 +1227,9 @@ static bool patch_68k_emul(void) // Extra routine for FE0A opcode (QuickDraw 3D needs this) lp = (uint32 *)(ROM_BASE + 0x36fc00); *lp++ = htonl(0x7c2903a6); // mtctr r1 -#if EMULATED_PPC - *lp++ = htonl(NativeOpcode(NATIVE_DISABLE_INTERRUPT)); -#else *lp++ = htonl(0x80200000 + XLM_IRQ_NEST); // lwz r1,XLM_IRQ_NEST *lp++ = htonl(0x38210001); // addi r1,r1,1 *lp++ = htonl(0x90200000 + XLM_IRQ_NEST); // stw r1,XLM_IRQ_NEST -#endif *lp++ = htonl(0x80200000 + XLM_KERNEL_DATA);// lwz r1,XLM_KERNEL_DATA *lp++ = htonl(0x90c10018); // stw r6,0x18(r1) *lp++ = htonl(0x7cc902a6); // mfctr r6 @@ -1265,12 +1265,21 @@ static bool patch_68k_emul(void) return false; dr_found: lp++; - *lp = htonl(0x48000000 + 0xf000 - (((uint32)lp - ROM_BASE) & 0xffff)); // b DR_CACHE_BASE+0x1f000 - lp = (uint32 *)(ROM_BASE + 0x37f000); - *lp++ = htonl(0x3c000000 + ((ROM_BASE + 0x46d0a4) >> 16)); // lis r0,xxx - *lp++ = htonl(0x60000000 + ((ROM_BASE + 0x46d0a4) & 0xffff)); // ori r0,r0,xxx - *lp++ = htonl(0x7c0903a6); // mtctr r0 - *lp = htonl(POWERPC_BCTR); // bctr + loc = (uint32)lp - ROM_BASE; + if ((base = powerpc_branch_target(ROM_BASE + loc)) == 0) base = ROM_BASE + loc; + static const uint8 dr_ret_dat[] = {0x80, 0xbf, 0x08, 0x14, 0x53, 0x19, 0x4d, 0xac, 0x7c, 0xa8, 0x03, 0xa6}; + if ((base = find_rom_data(base - ROM_BASE, 0x380000, dr_ret_dat, sizeof(dr_ret_dat))) == 0) return false; + D(bug("dr_ret %08lx\n", base)); + if (base != loc) { + // OldWorld ROMs contain an absolute branch + D(bug(" patching absolute branch at %08x\n", (uint32)lp - ROM_BASE)); + *lp = htonl(0x48000000 + 0xf000 - (((uint32)lp - ROM_BASE) & 0xffff)); // b DR_CACHE_BASE+0x1f000 + lp = (uint32 *)(ROM_BASE + 0x37f000); + *lp++ = htonl(0x3c000000 + ((ROM_BASE + base) >> 16)); // lis r0,xxx + *lp++ = htonl(0x60000000 + ((ROM_BASE + base) & 0xffff)); // ori r0,r0,xxx + *lp++ = htonl(0x7c0803a6); // mtlr r0 + *lp = htonl(POWERPC_BLR); // blr + } return true; } @@ -1387,15 +1396,10 @@ static bool patch_nanokernel(void) uint32 npc = (uint32)(lp + 1) - ROM_BASE; lp = (uint32 *)(ROM_BASE + 0x318000); -#if EMULATED_PPC - *lp++ = htonl(NativeOpcode(NATIVE_ENABLE_INTERRUPT)); - *lp = htonl(0x48000000 + ((npc - 0x318004) & 0x03fffffc)); // b ROM_BASE+0x312c2c -#else *lp++ = htonl(0x81400000 + XLM_IRQ_NEST); // lwz r10,XLM_IRQ_NEST *lp++ = htonl(0x394affff); // subi r10,r10,1 *lp++ = htonl(0x91400000 + XLM_IRQ_NEST); // stw r10,XLM_IRQ_NEST *lp = htonl(0x48000000 + ((npc - 0x31800c) & 0x03fffffc)); // b ROM_BASE+0x312c2c -#endif /* // Disable FE0A/FE06 opcodes @@ -1747,7 +1751,7 @@ static bool patch_68k(void) *wp++ = htons(M68K_NOP); *wp = htons(M68K_NOP); - // Gestalt PowerPC page size, RAM size (InitGestalt, via 0x25c) + // Gestalt PowerPC page size, CPU type, RAM size (InitGestalt, via 0x25c) static const uint8 page_size2_dat[] = {0x26, 0x79, 0x5f, 0xff, 0xef, 0xd8, 0x25, 0x6b, 0x00, 0x10, 0x00, 0x1e}; if ((base = find_rom_data(0x50000, 0x70000, page_size2_dat, sizeof(page_size2_dat))) == 0) return false; D(bug("page_size2 %08lx\n", base)); @@ -1757,7 +1761,13 @@ static bool patch_68k(void) *wp++ = htons(0x1000); *wp++ = htons(0x001e); *wp++ = htons(0x157c); // move.b #PVR,$1d(a2) - *wp++ = htons(PVR >> 16); + uint32 cput = (PVR >> 16); + if (cput == 0x7000) + cput |= 0x20; + else if (cput >= 0x8000 && cput <= 0x8002) + cput |= 0x10; + cput &= 0xff; + *wp++ = htons(cput); *wp++ = htons(0x001d); *wp++ = htons(0x263c); // move.l #RAMSize,d3 *wp++ = htons(RAMSize >> 16); @@ -1810,8 +1820,12 @@ static bool patch_68k(void) if ((base = find_rom_data(0x13000, 0x20000, gc_mask2_dat, sizeof(gc_mask2_dat))) == 0) return false; D(bug("gc_mask2 %08lx\n", base)); wp = (uint16 *)(ROM_BASE + base); - if (ROMType == ROMTYPE_GOSSAMER) + if (ROMType == ROMTYPE_GOSSAMER) { *wp++ = htons(M68K_NOP); + *wp++ = htons(M68K_NOP); + *wp++ = htons(M68K_NOP); + *wp++ = htons(M68K_NOP); + } for (int i=0; i<5; i++) { *wp++ = htons(M68K_NOP); *wp++ = htons(M68K_NOP); @@ -2227,19 +2241,20 @@ static bool patch_68k(void) lp = (uint32 *)(ROM_BASE + ntohl(*lp)); lp[0xa9fd & 0x3ff] = htonl(GET_SCRAP_PATCH_SPACE); -#if __BEOS__ // Patch SynchIdleTime() if (PrefsFindBool("idlewait")) { wp = (uint16 *)(ROM_BASE + find_rom_trap(0xabf7) + 4); // SynchIdleTime() D(bug("SynchIdleTime at %08lx\n", wp)); - if (ntohs(*wp) == 0x2078) { + if (ntohs(*wp) == 0x2078) { // movea.l ExpandMem,a0 *wp++ = htons(M68K_EMUL_OP_IDLE_TIME); *wp = htons(M68K_NOP); - } else { + } + else if (ntohs(*wp) == 0x70fe) // moveq #-2,d0 + *wp++ = htons(M68K_EMUL_OP_IDLE_TIME_2); + else { D(bug("SynchIdleTime patch not installed\n")); } } -#endif // Construct list of all sifters used by sound components in ROM D(bug("Searching for sound components with type sdev in ROM\n")); @@ -2304,7 +2319,7 @@ void InstallDrivers(void) WriteMacInt16(dce + dCtlFlags, SonyDriverFlags); } -#if DISABLE_SCSI && 0 +#if DISABLE_SCSI && HAVE_SIGSEGV_SKIP_INSTRUCTION // Fake SCSIGlobals WriteMacInt32(0xc0c, SheepMem::ZeroPage()); #endif