1 |
|
/* |
2 |
|
* rom_patches.cpp - ROM patches |
3 |
|
* |
4 |
< |
* Basilisk II (C) 1997-1999 Christian Bauer |
4 |
> |
* Basilisk II (C) 1997-2001 Christian Bauer |
5 |
|
* |
6 |
|
* This program is free software; you can redistribute it and/or modify |
7 |
|
* it under the terms of the GNU General Public License as published by |
38 |
|
#include "debug.h" |
39 |
|
|
40 |
|
|
41 |
– |
// Breakpoint |
42 |
– |
//#define M68K_BREAKPOINT 0x2310 // CritError |
43 |
– |
//#define M68K_BREAKPOINT 0x1d10 // BootMe |
44 |
– |
|
41 |
|
// Global variables |
42 |
< |
uint32 UniversalInfo; // ROM offset of UniversalInfo |
43 |
< |
uint32 PutScrapPatch; // Mac address of PutScrap() patch |
44 |
< |
|
45 |
< |
static uint32 sony_offset; // ROM offset of .Sony driver |
46 |
< |
static uint32 serd_offset; // ROM offset of SERD resource (serial drivers) |
47 |
< |
static uint32 microseconds_offset; // ROM offset of Microseconds() replacement routine |
48 |
< |
static uint32 memory_dispatch_offset; // ROM offset of MemoryDispatch() replacement routine |
42 |
> |
uint32 UniversalInfo; // ROM offset of UniversalInfo |
43 |
> |
uint32 PutScrapPatch; // Mac address of PutScrap() patch |
44 |
> |
uint32 ROMBreakpoint = 0; // ROM offset of breakpoint (0 = disabled, 0x2310 = CritError) |
45 |
> |
bool PrintROMInfo = false; // Flag: print ROM information in PatchROM() |
46 |
> |
bool PatchHWBases = true; // Flag: patch hardware base addresses |
47 |
> |
|
48 |
> |
static uint32 sony_offset; // ROM offset of .Sony driver |
49 |
> |
static uint32 serd_offset; // ROM offset of SERD resource (serial drivers) |
50 |
> |
static uint32 microseconds_offset; // ROM offset of Microseconds() replacement routine |
51 |
> |
static uint32 debugutil_offset; // ROM offset of DebugUtil() replacement routine |
52 |
|
|
53 |
|
// Prototypes |
54 |
|
uint16 ROMVersion; |
55 |
|
|
56 |
+ |
/* |
57 |
+ |
* Macros used to extract one of the 16-bit words from a 32-bit word value |
58 |
+ |
*/ |
59 |
+ |
|
60 |
+ |
#define HiWord(X) (((X) >> 16) & 0xffff) |
61 |
+ |
#define LoWord(X) ((X) & 0xffff) |
62 |
+ |
|
63 |
|
|
64 |
|
/* |
65 |
|
* Search ROM for byte string, return ROM offset (or 0) |
90 |
|
|
91 |
|
if (!cont) |
92 |
|
rsrc_ptr = x; |
93 |
+ |
else |
94 |
+ |
rsrc_ptr = ReadMacInt32(ROMBaseMac + rsrc_ptr + 8); |
95 |
|
|
96 |
|
for (;;) { |
97 |
|
lp = ROMBaseMac + rsrc_ptr; |
150 |
|
|
151 |
|
|
152 |
|
/* |
153 |
+ |
* Print ROM information to stream, |
154 |
+ |
*/ |
155 |
+ |
|
156 |
+ |
static void list_rom_resources(void) |
157 |
+ |
{ |
158 |
+ |
printf("ROM Resources:\n"); |
159 |
+ |
printf("Offset\t Type\tID\tSize\tName\n"); |
160 |
+ |
printf("------------------------------------------------\n"); |
161 |
+ |
|
162 |
+ |
uint32 lp = ROMBaseMac + ReadMacInt32(ROMBaseMac + 0x1a); |
163 |
+ |
uint32 rsrc_ptr = ReadMacInt32(lp); |
164 |
+ |
|
165 |
+ |
for (;;) { |
166 |
+ |
lp = ROMBaseMac + rsrc_ptr; |
167 |
+ |
uint32 data = ReadMacInt32(lp + 12); |
168 |
+ |
|
169 |
+ |
char name[32]; |
170 |
+ |
int name_len = ReadMacInt8(lp + 23), i; |
171 |
+ |
for (i=0; i<name_len; i++) |
172 |
+ |
name[i] = ReadMacInt8(lp + 24 + i); |
173 |
+ |
name[i] = 0; |
174 |
+ |
|
175 |
+ |
printf("%08x %c%c%c%c\t%d\t%d\t%s\n", data, ReadMacInt8(lp + 16), ReadMacInt8(lp + 17), ReadMacInt8(lp + 18), ReadMacInt8(lp + 19), ReadMacInt16(lp + 20), ReadMacInt32(ROMBaseMac + data - 8), name); |
176 |
+ |
|
177 |
+ |
rsrc_ptr = ReadMacInt32(lp + 8); |
178 |
+ |
if (!rsrc_ptr) |
179 |
+ |
break; |
180 |
+ |
} |
181 |
+ |
printf("\n"); |
182 |
+ |
} |
183 |
+ |
|
184 |
+ |
// Mapping of Model IDs to Model names |
185 |
+ |
struct mac_desc { |
186 |
+ |
char *name; |
187 |
+ |
int32 id; |
188 |
+ |
}; |
189 |
+ |
|
190 |
+ |
static mac_desc MacDesc[] = { |
191 |
+ |
{"Classic" , 1}, |
192 |
+ |
{"Mac XL" , 2}, |
193 |
+ |
{"Mac 512KE" , 3}, |
194 |
+ |
{"Mac Plus" , 4}, |
195 |
+ |
{"Mac SE" , 5}, |
196 |
+ |
{"Mac II" , 6}, |
197 |
+ |
{"Mac IIx" , 7}, |
198 |
+ |
{"Mac IIcx" , 8}, |
199 |
+ |
{"Mac SE/030" , 9}, |
200 |
+ |
{"Mac Portable" , 10}, |
201 |
+ |
{"Mac IIci" , 11}, |
202 |
+ |
{"Mac IIfx" , 13}, |
203 |
+ |
{"Mac Classic" , 17}, |
204 |
+ |
{"Mac IIsi" , 18}, |
205 |
+ |
{"Mac LC" , 19}, |
206 |
+ |
{"Quadra 900" , 20}, |
207 |
+ |
{"PowerBook 170" , 21}, |
208 |
+ |
{"Quadra 700" , 22}, |
209 |
+ |
{"Classic II" , 23}, |
210 |
+ |
{"PowerBook 100" , 24}, |
211 |
+ |
{"PowerBook 140" , 25}, |
212 |
+ |
{"Quadra 950" , 26}, |
213 |
+ |
{"Mac LCIII/Performa 450", 27}, |
214 |
+ |
{"PowerBook Duo 210" , 29}, |
215 |
+ |
{"Centris 650" , 30}, |
216 |
+ |
{"PowerBook Duo 230" , 32}, |
217 |
+ |
{"PowerBook 180" , 33}, |
218 |
+ |
{"PowerBook 160" , 34}, |
219 |
+ |
{"Quadra 800" , 35}, |
220 |
+ |
{"Quadra 650" , 36}, |
221 |
+ |
{"Mac LCII" , 37}, |
222 |
+ |
{"PowerBook Duo 250" , 38}, |
223 |
+ |
{"Mac IIvi" , 44}, |
224 |
+ |
{"Mac IIvm/Performa 600", 45}, |
225 |
+ |
{"Mac IIvx" , 48}, |
226 |
+ |
{"Color Classic/Performa 250", 49}, |
227 |
+ |
{"PowerBook 165c" , 50}, |
228 |
+ |
{"Centris 610" , 52}, |
229 |
+ |
{"Quadra 610" , 53}, |
230 |
+ |
{"PowerBook 145" , 54}, |
231 |
+ |
{"Mac LC520" , 56}, |
232 |
+ |
{"Quadra/Centris 660AV" , 60}, |
233 |
+ |
{"Performa 46x" , 62}, |
234 |
+ |
{"PowerBook 180c" , 71}, |
235 |
+ |
{"PowerBook 520/520c/540/540c", 72}, |
236 |
+ |
{"PowerBook Duo 270c" , 77}, |
237 |
+ |
{"Quadra 840AV" , 78}, |
238 |
+ |
{"Performa 550" , 80}, |
239 |
+ |
{"PowerBook 165" , 84}, |
240 |
+ |
{"PowerBook 190" , 85}, |
241 |
+ |
{"Mac TV" , 88}, |
242 |
+ |
{"Mac LC475/Performa 47x", 89}, |
243 |
+ |
{"Mac LC575" , 92}, |
244 |
+ |
{"Quadra 605" , 94}, |
245 |
+ |
{"Quadra 630" , 98}, |
246 |
+ |
{"Mac LC580" , 99}, |
247 |
+ |
{"PowerBook Duo 280" , 102}, |
248 |
+ |
{"PowerBook Duo 280c" , 103}, |
249 |
+ |
{"PowerBook 150" , 115}, |
250 |
+ |
{"unknown", -1} |
251 |
+ |
}; |
252 |
+ |
|
253 |
+ |
static void print_universal_info(uint32 info) |
254 |
+ |
{ |
255 |
+ |
uint8 id = ReadMacInt8(info + 18); |
256 |
+ |
uint16 hwcfg = ReadMacInt16(info + 16); |
257 |
+ |
uint16 rom85 = ReadMacInt16(info + 20); |
258 |
+ |
|
259 |
+ |
// Find model name |
260 |
+ |
char *name = "unknown"; |
261 |
+ |
for (int i=0; MacDesc[i].id >= 0; i++) |
262 |
+ |
if (MacDesc[i].id == id + 6) { |
263 |
+ |
name = MacDesc[i].name; |
264 |
+ |
break; |
265 |
+ |
} |
266 |
+ |
|
267 |
+ |
printf("%08x %02x\t%04x\t%04x\t%s\n", info - ROMBaseMac, id, hwcfg, rom85, name); |
268 |
+ |
} |
269 |
+ |
|
270 |
+ |
static void list_universal_infos(void) |
271 |
+ |
{ |
272 |
+ |
uint32 ofs = 0x3000; |
273 |
+ |
for (int i=0; i<0x2000; i+=2, ofs+=2) |
274 |
+ |
if (ReadMacInt32(ROMBaseMac + ofs) == 0xdc000505) { |
275 |
+ |
ofs -= 16; |
276 |
+ |
uint32 q; |
277 |
+ |
for (q=ofs; q > 0 && ReadMacInt32(ROMBaseMac + q) != ofs - q; q-=4) ; |
278 |
+ |
if (q > 0) { |
279 |
+ |
printf("Universal Table at %08x:\n", q); |
280 |
+ |
printf("Offset\t ID\tHWCfg\tROM85\tModel\n"); |
281 |
+ |
printf("------------------------------------------------\n"); |
282 |
+ |
while ((ofs = ReadMacInt32(ROMBaseMac + q))) { |
283 |
+ |
print_universal_info(ROMBaseMac + ofs + q); |
284 |
+ |
q += 4; |
285 |
+ |
} |
286 |
+ |
} |
287 |
+ |
break; |
288 |
+ |
} |
289 |
+ |
printf("\n"); |
290 |
+ |
} |
291 |
+ |
|
292 |
+ |
static void print_rom_info(void) |
293 |
+ |
{ |
294 |
+ |
printf("\nROM Info:\n"); |
295 |
+ |
printf("Checksum : %08x\n", ReadMacInt32(ROMBaseMac)); |
296 |
+ |
printf("Version : %04x\n", ROMVersion); |
297 |
+ |
printf("Sub Version : %04x\n", ReadMacInt16(ROMBaseMac + 18)); |
298 |
+ |
printf("Resource Map: %08x\n", ReadMacInt32(ROMBaseMac + 26)); |
299 |
+ |
printf("Trap Tables : %08x\n\n", ReadMacInt32(ROMBaseMac + 34)); |
300 |
+ |
if (ROMVersion == ROM_VERSION_32) { |
301 |
+ |
list_rom_resources(); |
302 |
+ |
list_universal_infos(); |
303 |
+ |
} |
304 |
+ |
} |
305 |
+ |
|
306 |
+ |
|
307 |
+ |
/* |
308 |
|
* Driver stubs |
309 |
|
*/ |
310 |
|
|
702 |
|
|
703 |
|
void InstallDrivers(uint32 pb) |
704 |
|
{ |
705 |
< |
D(bug("InstallDrivers\n")); |
705 |
> |
D(bug("InstallDrivers, pb %08x\n", pb)); |
706 |
|
M68kRegisters r; |
707 |
|
|
708 |
|
// Install Microseconds() replacement routine |
710 |
|
r.d[0] = 0xa093; |
711 |
|
Execute68kTrap(0xa247, &r); // SetOSTrapAddress() |
712 |
|
|
713 |
+ |
// Install DebugUtil() replacement routine |
714 |
+ |
r.a[0] = ROMBaseMac + debugutil_offset; |
715 |
+ |
r.d[0] = 0xa08d; |
716 |
+ |
Execute68kTrap(0xa247, &r); // SetOSTrapAddress() |
717 |
+ |
|
718 |
|
// Install disk driver |
719 |
|
r.a[0] = ROMBaseMac + sony_offset + 0x100; |
720 |
|
r.d[0] = (uint32)DiskRefNum; |
810 |
|
|
811 |
|
void PatchAfterStartup(void) |
812 |
|
{ |
813 |
< |
// Install MemoryDispatch() replacement routine |
646 |
< |
M68kRegisters r; |
647 |
< |
r.a[0] = ROMBaseMac + memory_dispatch_offset; |
648 |
< |
r.d[0] = 0xa05c; |
649 |
< |
Execute68kTrap(0xa247, &r); // SetOSTrapAddress() |
650 |
< |
|
813 |
> |
#if SUPPORTS_EXTFS |
814 |
|
// Install external file system |
815 |
|
InstallExtFS(); |
816 |
+ |
#endif |
817 |
|
} |
818 |
|
|
819 |
|
|
826 |
|
// Read version |
827 |
|
ROMVersion = ntohs(*(uint16 *)(ROMBaseHost + 8)); |
828 |
|
|
829 |
< |
#if REAL_ADDRESSING |
830 |
< |
// Real addressing mode requires a 32-bit clean ROM |
829 |
> |
#if REAL_ADDRESSING || DIRECT_ADDRESSING |
830 |
> |
// Real and direct addressing modes require a 32-bit clean ROM |
831 |
|
return ROMVersion == ROM_VERSION_32; |
832 |
|
#else |
833 |
< |
// Virtual addressing mode works with 32-bit clean Mac II ROMs and Classic ROMs (experimental) |
833 |
> |
// Virtual addressing mode works with 32-bit clean Mac II ROMs and Classic ROMs |
834 |
|
return (ROMVersion == ROM_VERSION_CLASSIC) || (ROMVersion == ROM_VERSION_32); |
835 |
|
#endif |
836 |
|
} |
944 |
|
*wp++ = htons(M68K_RTS); |
945 |
|
microseconds_offset = (uint8 *)wp - ROMBaseHost; |
946 |
|
*wp++ = htons(M68K_EMUL_OP_MICROSECONDS); |
947 |
+ |
*wp++ = htons(M68K_RTS); |
948 |
+ |
|
949 |
+ |
// Replace DebugUtil |
950 |
+ |
debugutil_offset = (uint8 *)wp - ROMBaseHost; |
951 |
+ |
*wp++ = htons(M68K_EMUL_OP_DEBUGUTIL); |
952 |
|
*wp = htons(M68K_RTS); |
953 |
|
|
954 |
|
// Replace SCSIDispatch() |
1029 |
|
bp = ROMBaseHost + UniversalInfo + 18; // productKind |
1030 |
|
*bp = PrefsFindInt32("modelid"); |
1031 |
|
|
1032 |
+ |
#if !ROM_IS_WRITE_PROTECTED |
1033 |
+ |
#if defined(USE_SCRATCHMEM_SUBTERFUGE) |
1034 |
+ |
// Set hardware base addresses to scratch memory area |
1035 |
+ |
if (PatchHWBases) { |
1036 |
+ |
extern uint8 *ScratchMem; |
1037 |
+ |
const uint32 ScratchMemBase = Host2MacAddr(ScratchMem); |
1038 |
+ |
|
1039 |
+ |
D(bug("LMGlob\tOfs/4\tBase\n")); |
1040 |
+ |
base = ROMBaseMac + UniversalInfo + ReadMacInt32(ROMBaseMac + UniversalInfo); // decoderInfoPtr |
1041 |
+ |
wp = (uint16 *)(ROMBaseHost + 0x94a); |
1042 |
+ |
while (*wp != 0xffff) { |
1043 |
+ |
int16 ofs = ntohs(*wp++); // offset in decoderInfo (/4) |
1044 |
+ |
int16 lmg = ntohs(*wp++); // address of LowMem global |
1045 |
+ |
D(bug("0x%04x\t%d\t0x%08x\n", lmg, ofs, ReadMacInt32(base + ofs*4))); |
1046 |
+ |
|
1047 |
+ |
// Fake address only if this is not the ASC base |
1048 |
+ |
if (lmg != 0xcc0) |
1049 |
+ |
WriteMacInt32(base + ofs*4, ScratchMemBase); |
1050 |
+ |
} |
1051 |
+ |
} |
1052 |
+ |
#else |
1053 |
+ |
#error System specific handling for writable ROM is required here |
1054 |
+ |
#endif |
1055 |
+ |
#endif |
1056 |
+ |
|
1057 |
|
// Make FPU optional |
1058 |
|
if (FPUType == 0) { |
1059 |
|
bp = ROMBaseHost + UniversalInfo + 22; // defaultRSRCs |
1236 |
|
*wp = htons(M68K_RTS); |
1237 |
|
|
1238 |
|
// Fake CPU speed test (SetupTimeK) |
1239 |
+ |
// *** increased jl : MacsBug uses TimeDBRA for kbd repeat timing |
1240 |
|
wp = (uint16 *)(ROMBaseHost + 0x800); |
1241 |
|
*wp++ = htons(0x31fc); // move.w #xxx,TimeDBRA |
1242 |
< |
*wp++ = htons(100); |
1242 |
> |
*wp++ = htons(10000); |
1243 |
|
*wp++ = htons(0x0d00); |
1244 |
|
*wp++ = htons(0x31fc); // move.w #xxx,TimeSCCDBRA |
1245 |
< |
*wp++ = htons(100); |
1245 |
> |
*wp++ = htons(10000); |
1246 |
|
*wp++ = htons(0x0d02); |
1247 |
|
*wp++ = htons(0x31fc); // move.w #xxx,TimeSCSIDBRA |
1248 |
< |
*wp++ = htons(100); |
1248 |
> |
*wp++ = htons(10000); |
1249 |
|
*wp++ = htons(0x0b24); |
1250 |
|
*wp++ = htons(0x31fc); // move.w #xxx,TimeRAMDBRA |
1251 |
< |
*wp++ = htons(100); |
1251 |
> |
*wp++ = htons(10000); |
1252 |
|
*wp++ = htons(0x0cea); |
1253 |
|
*wp = htons(M68K_RTS); |
1254 |
|
|
1255 |
|
#if REAL_ADDRESSING |
1256 |
|
// Move system zone to start of Mac RAM |
1257 |
< |
lp = (uint32 *)(ROMBaseHost + 0x50a); |
1258 |
< |
*lp++ = htonl(RAMBaseMac); |
1259 |
< |
*lp = htonl(RAMBaseMac + 0x1800); |
1257 |
> |
wp = (uint16 *)(ROMBaseHost + 0x50a); |
1258 |
> |
*wp++ = htons(HiWord(RAMBaseMac + 0x2000)); |
1259 |
> |
*wp++ = htons(LoWord(RAMBaseMac + 0x2000)); |
1260 |
> |
*wp++ = htons(HiWord(RAMBaseMac + 0x3800)); |
1261 |
> |
*wp = htons(LoWord(RAMBaseMac + 0x3800)); |
1262 |
|
#endif |
1263 |
|
|
1264 |
|
#if !ROM_IS_WRITE_PROTECTED |
1265 |
< |
#if defined(AMIGA) |
1265 |
> |
#if defined(USE_SCRATCHMEM_SUBTERFUGE) |
1266 |
|
// Set fake handle at 0x0000 to scratch memory area (so broken Mac programs won't write into Mac ROM) |
1267 |
< |
extern uint32 ScratchMem; |
1267 |
> |
extern uint8 *ScratchMem; |
1268 |
> |
const uint32 ScratchMemBase = Host2MacAddr(ScratchMem); |
1269 |
|
wp = (uint16 *)(ROMBaseHost + 0xccaa); |
1270 |
|
*wp++ = htons(0x203c); // move.l #ScratchMem,d0 |
1271 |
< |
*wp++ = htons(ScratchMem >> 16); |
1272 |
< |
*wp = htons(ScratchMem); |
1271 |
> |
*wp++ = htons(ScratchMemBase >> 16); |
1272 |
> |
*wp = htons(ScratchMemBase); |
1273 |
|
#else |
1274 |
|
#error System specific handling for writable ROM is required here |
1275 |
|
#endif |
1281 |
|
*wp++ = htons(M68K_NOP); |
1282 |
|
*wp = htons(M68K_NOP); |
1283 |
|
#endif |
1284 |
< |
|
1284 |
> |
|
1285 |
> |
#if REAL_ADDRESSING && !defined(AMIGA) |
1286 |
> |
// gb-- Temporary hack to get rid of crashes in Speedometer |
1287 |
> |
wp = (uint16 *)(ROMBaseHost + 0xdba2); |
1288 |
> |
if (ntohs(*wp) == 0x662c) // bne.b #$2c |
1289 |
> |
*wp = htons(0x602c); // bra.b #$2c |
1290 |
> |
#endif |
1291 |
> |
|
1292 |
|
// Don't write to VIA in InitTimeMgr |
1293 |
|
wp = (uint16 *)(ROMBaseHost + 0xb0e2); |
1294 |
|
*wp++ = htons(0x4cdf); // movem.l (sp)+,d0-d5/a0-a4 |
1360 |
|
*wp++ = htons(M68K_NOP); |
1361 |
|
*wp = htons(M68K_NOP); |
1362 |
|
|
1363 |
< |
// Fix logical/physical RAM size (CompBootStack) (must be done after InitMemMgr!) |
1364 |
< |
static const uint8 fix_memsize_dat[] = {0x4e, 0x75}; |
1365 |
< |
if ((base = find_rom_data(0x490, 0x4b0, fix_memsize_dat, sizeof(fix_memsize_dat))) == 0) return false; |
1366 |
< |
D(bug("fix_memsize %08lx\n", base)); |
1367 |
< |
wp = (uint16 *)(ROMBaseHost + base); |
1363 |
> |
// Compute boot stack pointer and fix logical/physical RAM size (CompBootStack) (must be done after InitMemMgr!) |
1364 |
> |
wp = (uint16 *)(ROMBaseHost + 0x490); |
1365 |
> |
*wp++ = htons(0x2038); // move.l $10c,d0 |
1366 |
> |
*wp++ = htons(0x010c); |
1367 |
> |
*wp++ = htons(0xd0b8); // add.l $2a6,d0 |
1368 |
> |
*wp++ = htons(0x02a6); |
1369 |
> |
*wp++ = htons(0xe288); // lsr.l #1,d0 |
1370 |
> |
*wp++ = htons(0x0880); // bclr #0,d0 |
1371 |
> |
*wp++ = htons(0x0000); |
1372 |
> |
*wp++ = htons(0x0440); // subi.w #$400,d0 |
1373 |
> |
*wp++ = htons(0x0400); |
1374 |
> |
*wp++ = htons(0x2040); // move.l d0,a0 |
1375 |
|
*wp++ = htons(M68K_EMUL_OP_FIX_MEMSIZE); |
1376 |
< |
*wp = htons(M68K_RTS); |
1376 |
> |
*wp++ = htons(M68K_RTS); |
1377 |
|
|
1378 |
|
static const uint8 fix_memsize2_dat[] = {0x22, 0x30, 0x81, 0xe2, 0x0d, 0xdc, 0xff, 0xba, 0xd2, 0xb0, 0x81, 0xe2, 0x0d, 0xdc, 0xff, 0xec, 0x21, 0xc1, 0x1e, 0xf8}; |
1379 |
|
base = find_rom_data(0x4c000, 0x4c080, fix_memsize2_dat, sizeof(fix_memsize2_dat)); |
1484 |
|
if (ROMSize > 0x80000) { |
1485 |
|
|
1486 |
|
// BlockMove() |
1487 |
< |
static const uint8 ptest_dat[] = {0xa0, 0x8d, 0x0c, 0x81, 0x00, 0x00, 0x0c, 0x00, 0x6d, 0x06, 0x4e, 0x71, 0xf4, 0xf8}; |
1488 |
< |
base = find_rom_data(0x87000, 0x87800, ptest_dat, sizeof(ptest_dat)); |
1489 |
< |
D(bug("ptest %08lx\n", base)); |
1487 |
> |
static const uint8 bmove_dat[] = {0x20, 0x5f, 0x22, 0x5f, 0x0c, 0x38, 0x00, 0x04, 0x01, 0x2f}; |
1488 |
> |
base = find_rom_data(0x87000, 0x87800, bmove_dat, sizeof(bmove_dat)); |
1489 |
> |
D(bug("block_move %08lx\n", base)); |
1490 |
|
if (base) { // ROM15/22/23/26/27/32 |
1491 |
< |
wp = (uint16 *)(ROMBaseHost + base + 8); |
1492 |
< |
*wp = htons(M68K_NOP); |
1491 |
> |
wp = (uint16 *)(ROMBaseHost + base + 4); |
1492 |
> |
*wp++ = htons(M68K_EMUL_OP_BLOCK_MOVE); |
1493 |
> |
*wp++ = htons(0x7000); |
1494 |
> |
*wp = htons(M68K_RTS); |
1495 |
|
} |
1496 |
|
|
1497 |
|
// SANE |
1508 |
|
} |
1509 |
|
} |
1510 |
|
|
1511 |
+ |
// Don't set MemoryDispatch() to unimplemented trap |
1512 |
+ |
static const uint8 memdisp_dat[] = {0x30, 0x3c, 0xa8, 0x9f, 0xa7, 0x46, 0x30, 0x3c, 0xa0, 0x5c, 0xa2, 0x47}; |
1513 |
+ |
base = find_rom_data(0x4f100, 0x4f180, memdisp_dat, sizeof(memdisp_dat)); |
1514 |
+ |
D(bug("memdisp %08lx\n", base)); |
1515 |
+ |
if (base) { // ROM15/22/23/26/27/32 |
1516 |
+ |
wp = (uint16 *)(ROMBaseHost + base + 10); |
1517 |
+ |
*wp = htons(M68K_NOP); |
1518 |
+ |
} |
1519 |
+ |
|
1520 |
|
// Patch .EDisk driver (don't scan for EDisks in the area ROMBase..0xe00000) |
1521 |
< |
uint32 edisk_offset = find_rom_resource('DRVR', 51); |
1521 |
> |
uint32 edisk_offset = find_rom_resource(FOURCC('D','R','V','R'), 51); |
1522 |
|
if (edisk_offset) { |
1523 |
|
static const uint8 edisk_dat[] = {0xd5, 0xfc, 0x00, 0x01, 0x00, 0x00, 0xb5, 0xfc, 0x00, 0xe0, 0x00, 0x00}; |
1524 |
|
base = find_rom_data(edisk_offset, edisk_offset + 0x10000, edisk_dat, sizeof(edisk_dat)); |
1531 |
|
} |
1532 |
|
|
1533 |
|
// Replace .Sony driver |
1534 |
< |
sony_offset = find_rom_resource('DRVR', 4); |
1534 |
> |
sony_offset = find_rom_resource(FOURCC('D','R','V','R'), 4); |
1535 |
|
D(bug("sony %08lx\n", sony_offset)); |
1536 |
|
memcpy(ROMBaseHost + sony_offset, sony_driver, sizeof(sony_driver)); |
1537 |
|
|
1550 |
|
memcpy(ROMBaseHost + sony_offset + 0xa00, CDROMIcon, sizeof(CDROMIcon)); |
1551 |
|
|
1552 |
|
// Install SERD patch and serial drivers |
1553 |
< |
serd_offset = find_rom_resource('SERD', 0); |
1553 |
> |
serd_offset = find_rom_resource(FOURCC('S','E','R','D'), 0); |
1554 |
|
D(bug("serd %08lx\n", serd_offset)); |
1555 |
|
wp = (uint16 *)(ROMBaseHost + serd_offset + 12); |
1556 |
|
*wp++ = htons(M68K_EMUL_OP_SERD); |
1583 |
|
*wp++ = htons(M68K_RTS); |
1584 |
|
microseconds_offset = (uint8 *)wp - ROMBaseHost; |
1585 |
|
*wp++ = htons(M68K_EMUL_OP_MICROSECONDS); |
1586 |
+ |
*wp++ = htons(M68K_RTS); |
1587 |
+ |
|
1588 |
+ |
// Replace DebugUtil |
1589 |
+ |
debugutil_offset = (uint8 *)wp - ROMBaseHost; |
1590 |
+ |
*wp++ = htons(M68K_EMUL_OP_DEBUGUTIL); |
1591 |
|
*wp = htons(M68K_RTS); |
1592 |
|
|
1593 |
|
// Replace SCSIDispatch() |
1623 |
|
*wp++ = htons(base >> 16); |
1624 |
|
*wp = htons(base & 0xffff); |
1625 |
|
|
1626 |
< |
// Install MemoryDispatch() replacement routine (activated in PatchAfterStartup()) |
1627 |
< |
memory_dispatch_offset = sony_offset + 0xc20; |
1628 |
< |
wp = (uint16 *)(ROMBaseHost + memory_dispatch_offset); |
1629 |
< |
*wp++ = htons(M68K_EMUL_OP_MEMORY_DISPATCH); |
1402 |
< |
*wp = htons(M68K_RTS); |
1626 |
> |
// Look for double PACK 4 resources |
1627 |
> |
if ((base = find_rom_resource(FOURCC('P','A','C','K'), 4)) == 0) return false; |
1628 |
> |
if ((base = find_rom_resource(FOURCC('P','A','C','K'), 4, true)) == 0 && FPUType == 0) |
1629 |
> |
printf("WARNING: This ROM seems to require an FPU\n"); |
1630 |
|
|
1631 |
|
// Patch VIA interrupt handler |
1632 |
|
wp = (uint16 *)(ROMBaseHost + 0x9bc4); // Level 1 handler |
1645 |
|
|
1646 |
|
bool PatchROM(void) |
1647 |
|
{ |
1648 |
< |
// Print ROM info |
1649 |
< |
D(bug("ROM Info:\n")); |
1650 |
< |
D(bug("Checksum: %08lx\n", ReadMacInt32(ROMBaseMac))); |
1424 |
< |
D(bug("Version: %04x\n", ROMVersion)); |
1425 |
< |
D(bug("Sub Version: %04x\n", ReadMacInt16(ROMBaseMac + 18))); |
1648 |
> |
// Print some information about the ROM |
1649 |
> |
if (PrintROMInfo) |
1650 |
> |
print_rom_info(); |
1651 |
|
|
1652 |
|
// Patch ROM depending on version |
1653 |
|
switch (ROMVersion) { |
1663 |
|
return false; |
1664 |
|
} |
1665 |
|
|
1441 |
– |
#ifdef M68K_BREAKPOINT |
1666 |
|
// Install breakpoint |
1667 |
< |
uint16 *wp = (uint16 *)(ROMBaseHost + M68K_BREAKPOINT); |
1668 |
< |
*wp = htons(M68K_EMUL_BREAK); |
1669 |
< |
#endif |
1667 |
> |
if (ROMBreakpoint) { |
1668 |
> |
uint16 *wp = (uint16 *)(ROMBaseHost + ROMBreakpoint); |
1669 |
> |
*wp = htons(M68K_EMUL_BREAK); |
1670 |
> |
} |
1671 |
|
|
1672 |
|
// Clear caches as we loaded and patched code |
1673 |
|
FlushCodeCache(ROMBaseHost, ROMSize); |