847 |
|
lp[7] = htonl(0x00040004); // Inst cache assoc/Data cache assoc |
848 |
|
lp[8] = htonl(0x00400002); // TLB total size/TLB assoc |
849 |
|
break; |
850 |
< |
case 8: // 750 |
850 |
> |
case 8: // 750, 750FX |
851 |
> |
case 0x7000: |
852 |
|
lp[0] = htonl(0x1000); // Page size |
853 |
|
lp[1] = htonl(0x8000); // Data cache size |
854 |
|
lp[2] = htonl(0x8000); // Inst cache size |
872 |
|
lp[8] = htonl(0x00800002); // TLB total size/TLB assoc |
873 |
|
break; |
874 |
|
// case 11: // X704? |
875 |
< |
case 12: // 7400, 7410 |
875 |
> |
case 12: // 7400, 7410, 7450, 7455, 7457 |
876 |
|
case 0x800c: |
877 |
+ |
case 0x8000: |
878 |
+ |
case 0x8001: |
879 |
+ |
case 0x8002: |
880 |
|
lp[0] = htonl(0x1000); // Page size |
881 |
|
lp[1] = htonl(0x8000); // Data cache size |
882 |
|
lp[2] = htonl(0x8000); // Inst cache size |
911 |
|
lp[7] = htonl(0x00080008); // Inst cache assoc/Data cache assoc |
912 |
|
lp[8] = htonl(0x00800004); // TLB total size/TLB assoc |
913 |
|
break; |
914 |
+ |
case 0x39: // 970 |
915 |
+ |
lp[0] = htonl(0x1000); // Page size |
916 |
+ |
lp[1] = htonl(0x8000); // Data cache size |
917 |
+ |
lp[2] = htonl(0x10000); // Inst cache size |
918 |
+ |
lp[3] = htonl(0x00200020); // Coherency block size/Reservation granule size |
919 |
+ |
lp[4] = htonl(0x00010020); // Unified caches/Inst cache line size |
920 |
+ |
lp[5] = htonl(0x00200020); // Data cache line size/Data cache block size touch |
921 |
+ |
lp[6] = htonl(0x00800080); // Inst cache block size/Data cache block size |
922 |
+ |
lp[7] = htonl(0x00020002); // Inst cache assoc/Data cache assoc |
923 |
+ |
lp[8] = htonl(0x02000004); // TLB total size/TLB assoc |
924 |
+ |
break; |
925 |
|
default: |
926 |
|
printf("WARNING: Unknown CPU type\n"); |
927 |
|
break; |
1073 |
|
static bool patch_68k_emul(void) |
1074 |
|
{ |
1075 |
|
uint32 *lp; |
1076 |
< |
uint32 base; |
1076 |
> |
uint32 base, loc; |
1077 |
|
|
1078 |
|
// Overwrite twi instructions |
1079 |
|
static const uint8 twi_dat[] = {0x0f, 0xff, 0x00, 0x00, 0x0f, 0xff, 0x00, 0x01, 0x0f, 0xff, 0x00, 0x02}; |
1137 |
|
// Extra routine for 68k emulator start |
1138 |
|
lp = (uint32 *)(ROM_BASE + 0x36f900); |
1139 |
|
*lp++ = htonl(0x7c2903a6); // mtctr r1 |
1125 |
– |
#if EMULATED_PPC |
1126 |
– |
*lp++ = htonl(NativeOpcode(NATIVE_DISABLE_INTERRUPT)); |
1127 |
– |
#else |
1140 |
|
*lp++ = htonl(0x80200000 + XLM_IRQ_NEST); // lwz r1,XLM_IRQ_NEST |
1141 |
|
*lp++ = htonl(0x38210001); // addi r1,r1,1 |
1142 |
|
*lp++ = htonl(0x90200000 + XLM_IRQ_NEST); // stw r1,XLM_IRQ_NEST |
1131 |
– |
#endif |
1143 |
|
*lp++ = htonl(0x80200000 + XLM_KERNEL_DATA);// lwz r1,XLM_KERNEL_DATA |
1144 |
|
*lp++ = htonl(0x90c10018); // stw r6,0x18(r1) |
1145 |
|
*lp++ = htonl(0x7cc902a6); // mfctr r6 |
1167 |
|
// Extra routine for Mixed Mode |
1168 |
|
lp = (uint32 *)(ROM_BASE + 0x36fa00); |
1169 |
|
*lp++ = htonl(0x7c2903a6); // mtctr r1 |
1159 |
– |
#if EMULATED_PPC |
1160 |
– |
*lp++ = htonl(NativeOpcode(NATIVE_DISABLE_INTERRUPT)); |
1161 |
– |
#else |
1170 |
|
*lp++ = htonl(0x80200000 + XLM_IRQ_NEST); // lwz r1,XLM_IRQ_NEST |
1171 |
|
*lp++ = htonl(0x38210001); // addi r1,r1,1 |
1172 |
|
*lp++ = htonl(0x90200000 + XLM_IRQ_NEST); // stw r1,XLM_IRQ_NEST |
1165 |
– |
#endif |
1173 |
|
*lp++ = htonl(0x80200000 + XLM_KERNEL_DATA);// lwz r1,XLM_KERNEL_DATA |
1174 |
|
*lp++ = htonl(0x90c10018); // stw r6,0x18(r1) |
1175 |
|
*lp++ = htonl(0x7cc902a6); // mfctr r6 |
1197 |
|
// Extra routine for Reset/FC1E opcode |
1198 |
|
lp = (uint32 *)(ROM_BASE + 0x36fb00); |
1199 |
|
*lp++ = htonl(0x7c2903a6); // mtctr r1 |
1193 |
– |
#if EMULATED_PPC |
1194 |
– |
*lp++ = htonl(NativeOpcode(NATIVE_DISABLE_INTERRUPT)); |
1195 |
– |
#else |
1200 |
|
*lp++ = htonl(0x80200000 + XLM_IRQ_NEST); // lwz r1,XLM_IRQ_NEST |
1201 |
|
*lp++ = htonl(0x38210001); // addi r1,r1,1 |
1202 |
|
*lp++ = htonl(0x90200000 + XLM_IRQ_NEST); // stw r1,XLM_IRQ_NEST |
1199 |
– |
#endif |
1203 |
|
*lp++ = htonl(0x80200000 + XLM_KERNEL_DATA);// lwz r1,XLM_KERNEL_DATA |
1204 |
|
*lp++ = htonl(0x90c10018); // stw r6,0x18(r1) |
1205 |
|
*lp++ = htonl(0x7cc902a6); // mfctr r6 |
1227 |
|
// Extra routine for FE0A opcode (QuickDraw 3D needs this) |
1228 |
|
lp = (uint32 *)(ROM_BASE + 0x36fc00); |
1229 |
|
*lp++ = htonl(0x7c2903a6); // mtctr r1 |
1227 |
– |
#if EMULATED_PPC |
1228 |
– |
*lp++ = htonl(NativeOpcode(NATIVE_DISABLE_INTERRUPT)); |
1229 |
– |
#else |
1230 |
|
*lp++ = htonl(0x80200000 + XLM_IRQ_NEST); // lwz r1,XLM_IRQ_NEST |
1231 |
|
*lp++ = htonl(0x38210001); // addi r1,r1,1 |
1232 |
|
*lp++ = htonl(0x90200000 + XLM_IRQ_NEST); // stw r1,XLM_IRQ_NEST |
1233 |
– |
#endif |
1233 |
|
*lp++ = htonl(0x80200000 + XLM_KERNEL_DATA);// lwz r1,XLM_KERNEL_DATA |
1234 |
|
*lp++ = htonl(0x90c10018); // stw r6,0x18(r1) |
1235 |
|
*lp++ = htonl(0x7cc902a6); // mfctr r6 |
1265 |
|
return false; |
1266 |
|
dr_found: |
1267 |
|
lp++; |
1268 |
< |
*lp = htonl(0x48000000 + 0xf000 - (((uint32)lp - ROM_BASE) & 0xffff)); // b DR_CACHE_BASE+0x1f000 |
1269 |
< |
lp = (uint32 *)(ROM_BASE + 0x37f000); |
1270 |
< |
*lp++ = htonl(0x3c000000 + ((ROM_BASE + 0x46d0a4) >> 16)); // lis r0,xxx |
1271 |
< |
*lp++ = htonl(0x60000000 + ((ROM_BASE + 0x46d0a4) & 0xffff)); // ori r0,r0,xxx |
1272 |
< |
*lp++ = htonl(0x7c0903a6); // mtctr r0 |
1273 |
< |
*lp = htonl(POWERPC_BCTR); // bctr |
1268 |
> |
loc = (uint32)lp - ROM_BASE; |
1269 |
> |
if ((base = powerpc_branch_target(ROM_BASE + loc)) == 0) base = ROM_BASE + loc; |
1270 |
> |
static const uint8 dr_ret_dat[] = {0x80, 0xbf, 0x08, 0x14, 0x53, 0x19, 0x4d, 0xac, 0x7c, 0xa8, 0x03, 0xa6}; |
1271 |
> |
if ((base = find_rom_data(base - ROM_BASE, 0x380000, dr_ret_dat, sizeof(dr_ret_dat))) == 0) return false; |
1272 |
> |
D(bug("dr_ret %08lx\n", base)); |
1273 |
> |
if (base != loc) { |
1274 |
> |
// OldWorld ROMs contain an absolute branch |
1275 |
> |
D(bug(" patching absolute branch at %08x\n", (uint32)lp - ROM_BASE)); |
1276 |
> |
*lp = htonl(0x48000000 + 0xf000 - (((uint32)lp - ROM_BASE) & 0xffff)); // b DR_CACHE_BASE+0x1f000 |
1277 |
> |
lp = (uint32 *)(ROM_BASE + 0x37f000); |
1278 |
> |
*lp++ = htonl(0x3c000000 + ((ROM_BASE + base) >> 16)); // lis r0,xxx |
1279 |
> |
*lp++ = htonl(0x60000000 + ((ROM_BASE + base) & 0xffff)); // ori r0,r0,xxx |
1280 |
> |
*lp++ = htonl(0x7c0803a6); // mtlr r0 |
1281 |
> |
*lp = htonl(POWERPC_BLR); // blr |
1282 |
> |
} |
1283 |
|
return true; |
1284 |
|
} |
1285 |
|
|
1396 |
|
uint32 npc = (uint32)(lp + 1) - ROM_BASE; |
1397 |
|
|
1398 |
|
lp = (uint32 *)(ROM_BASE + 0x318000); |
1391 |
– |
#if EMULATED_PPC |
1392 |
– |
*lp++ = htonl(NativeOpcode(NATIVE_ENABLE_INTERRUPT)); |
1393 |
– |
*lp = htonl(0x48000000 + ((npc - 0x318004) & 0x03fffffc)); // b ROM_BASE+0x312c2c |
1394 |
– |
#else |
1399 |
|
*lp++ = htonl(0x81400000 + XLM_IRQ_NEST); // lwz r10,XLM_IRQ_NEST |
1400 |
|
*lp++ = htonl(0x394affff); // subi r10,r10,1 |
1401 |
|
*lp++ = htonl(0x91400000 + XLM_IRQ_NEST); // stw r10,XLM_IRQ_NEST |
1402 |
|
*lp = htonl(0x48000000 + ((npc - 0x31800c) & 0x03fffffc)); // b ROM_BASE+0x312c2c |
1399 |
– |
#endif |
1403 |
|
|
1404 |
|
/* |
1405 |
|
// Disable FE0A/FE06 opcodes |
1751 |
|
*wp++ = htons(M68K_NOP); |
1752 |
|
*wp = htons(M68K_NOP); |
1753 |
|
|
1754 |
< |
// Gestalt PowerPC page size, RAM size (InitGestalt, via 0x25c) |
1754 |
> |
// Gestalt PowerPC page size, CPU type, RAM size (InitGestalt, via 0x25c) |
1755 |
|
static const uint8 page_size2_dat[] = {0x26, 0x79, 0x5f, 0xff, 0xef, 0xd8, 0x25, 0x6b, 0x00, 0x10, 0x00, 0x1e}; |
1756 |
|
if ((base = find_rom_data(0x50000, 0x70000, page_size2_dat, sizeof(page_size2_dat))) == 0) return false; |
1757 |
|
D(bug("page_size2 %08lx\n", base)); |
1761 |
|
*wp++ = htons(0x1000); |
1762 |
|
*wp++ = htons(0x001e); |
1763 |
|
*wp++ = htons(0x157c); // move.b #PVR,$1d(a2) |
1764 |
< |
*wp++ = htons(PVR >> 16); |
1764 |
> |
uint32 cput = (PVR >> 16); |
1765 |
> |
if (cput == 0x7000) |
1766 |
> |
cput |= 0x20; |
1767 |
> |
else if (cput >= 0x8000 && cput <= 0x8002) |
1768 |
> |
cput |= 0x10; |
1769 |
> |
cput &= 0xff; |
1770 |
> |
*wp++ = htons(cput); |
1771 |
|
*wp++ = htons(0x001d); |
1772 |
|
*wp++ = htons(0x263c); // move.l #RAMSize,d3 |
1773 |
|
*wp++ = htons(RAMSize >> 16); |
1820 |
|
if ((base = find_rom_data(0x13000, 0x20000, gc_mask2_dat, sizeof(gc_mask2_dat))) == 0) return false; |
1821 |
|
D(bug("gc_mask2 %08lx\n", base)); |
1822 |
|
wp = (uint16 *)(ROM_BASE + base); |
1823 |
< |
if (ROMType == ROMTYPE_GOSSAMER) |
1823 |
> |
if (ROMType == ROMTYPE_GOSSAMER) { |
1824 |
> |
*wp++ = htons(M68K_NOP); |
1825 |
|
*wp++ = htons(M68K_NOP); |
1826 |
+ |
*wp++ = htons(M68K_NOP); |
1827 |
+ |
*wp++ = htons(M68K_NOP); |
1828 |
+ |
} |
1829 |
|
for (int i=0; i<5; i++) { |
1830 |
|
*wp++ = htons(M68K_NOP); |
1831 |
|
*wp++ = htons(M68K_NOP); |
2241 |
|
lp = (uint32 *)(ROM_BASE + ntohl(*lp)); |
2242 |
|
lp[0xa9fd & 0x3ff] = htonl(GET_SCRAP_PATCH_SPACE); |
2243 |
|
|
2231 |
– |
#if __BEOS__ |
2244 |
|
// Patch SynchIdleTime() |
2245 |
|
if (PrefsFindBool("idlewait")) { |
2246 |
|
wp = (uint16 *)(ROM_BASE + find_rom_trap(0xabf7) + 4); // SynchIdleTime() |
2247 |
|
D(bug("SynchIdleTime at %08lx\n", wp)); |
2248 |
< |
if (ntohs(*wp) == 0x2078) { |
2248 |
> |
if (ntohs(*wp) == 0x2078) { // movea.l ExpandMem,a0 |
2249 |
|
*wp++ = htons(M68K_EMUL_OP_IDLE_TIME); |
2250 |
|
*wp = htons(M68K_NOP); |
2251 |
< |
} else { |
2251 |
> |
} |
2252 |
> |
else if (ntohs(*wp) == 0x70fe) // moveq #-2,d0 |
2253 |
> |
*wp++ = htons(M68K_EMUL_OP_IDLE_TIME_2); |
2254 |
> |
else { |
2255 |
|
D(bug("SynchIdleTime patch not installed\n")); |
2256 |
|
} |
2257 |
|
} |
2243 |
– |
#endif |
2258 |
|
|
2259 |
|
// Construct list of all sifters used by sound components in ROM |
2260 |
|
D(bug("Searching for sound components with type sdev in ROM\n")); |
2319 |
|
WriteMacInt16(dce + dCtlFlags, SonyDriverFlags); |
2320 |
|
} |
2321 |
|
|
2322 |
< |
#if DISABLE_SCSI && 0 |
2322 |
> |
#if DISABLE_SCSI && HAVE_SIGSEGV_SKIP_INSTRUCTION |
2323 |
|
// Fake SCSIGlobals |
2324 |
|
WriteMacInt32(0xc0c, SheepMem::ZeroPage()); |
2325 |
|
#endif |