ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/rsrc_patches.cpp
Revision: 1.1
Committed: 1999-10-03T14:16:25Z (25 years, 1 month ago) by cebix
Branch: MAIN
Branch point for: cebix
Log Message:
Initial revision

File Contents

# User Rev Content
1 cebix 1.1 /*
2     * rsrc_patches.cpp - Resource patches
3     *
4     * Basilisk II (C) 1997-1999 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
8     * the Free Software Foundation; either version 2 of the License, or
9     * (at your option) any later version.
10     *
11     * This program is distributed in the hope that it will be useful,
12     * but WITHOUT ANY WARRANTY; without even the implied warranty of
13     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14     * GNU General Public License for more details.
15     *
16     * You should have received a copy of the GNU General Public License
17     * along with this program; if not, write to the Free Software
18     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19     */
20    
21     #include <string.h>
22    
23     #include "sysdeps.h"
24     #include "cpu_emulation.h"
25     #include "main.h"
26     #include "emul_op.h"
27     #include "audio.h"
28     #include "audio_defs.h"
29     #include "rsrc_patches.h"
30    
31     #define DEBUG 0
32     #include "debug.h"
33    
34    
35     #if !EMULATED_68K
36     // Assembly functions
37     extern "C" void Scod060Patch1(void);
38     extern "C" void Scod060Patch2(void);
39     extern "C" void ThInitFPUPatch(void);
40     #endif
41    
42    
43     /*
44     * Search resource for byte string, return offset (or 0)
45     */
46    
47     static uint32 find_rsrc_data(const uint8 *rsrc, uint32 max, const uint8 *search, uint32 search_len, uint32 ofs = 0)
48     {
49     while (ofs < max - search_len) {
50     if (!memcmp(rsrc + ofs, search, search_len))
51     return ofs;
52     ofs++;
53     }
54     return 0;
55     }
56    
57    
58     /*
59     * Resource patches via vCheckLoad
60     */
61    
62     void CheckLoad(uint32 type, int16 id, uint8 *p, uint32 size)
63     {
64     uint16 *p16;
65     uint32 base;
66     D(bug("vCheckLoad %c%c%c%c (%08lx) ID %d, data %08lx, size %ld\n", (char)(type >> 24), (char)((type >> 16) & 0xff), (char )((type >> 8) & 0xff), (char )(type & 0xff), type, id, p, size));
67    
68     if (type == 'boot' && id == 3) {
69     D(bug(" boot 3 found\n"));
70    
71     // Set boot stack pointer (7.5, 7.6, 7.6.1, 8.0)
72     static const uint8 dat[] = {0x22, 0x00, 0xe4, 0x89, 0x90, 0x81, 0x22, 0x40};
73     base = find_rsrc_data(p, size, dat, sizeof(dat));
74     if (base) {
75     p16 = (uint16 *)(p + base + 6);
76     *p16 = htons(M68K_EMUL_OP_FIX_BOOTSTACK);
77     FlushCodeCache(p + base + 6, 2);
78     D(bug(" patch 1 applied\n"));
79     }
80    
81     #if !ROM_IS_WRITE_PROTECTED
82     // Set fake handle at 0x0000 to some safe place (so broken Mac programs won't write into Mac ROM) (7.5, 8.0)
83     static const uint8 dat2[] = {0x20, 0x78, 0x02, 0xae, 0xd1, 0xfc, 0x00, 0x01, 0x00, 0x00, 0x21, 0xc8, 0x00, 0x00};
84     base = find_rsrc_data(p, size, dat2, sizeof(dat2));
85     if (base) {
86     p16 = (uint16 *)(p + base);
87    
88     #if defined(AMIGA)
89     // Set 0x0000 to scratch memory area
90     extern uint32 ScratchMem;
91     *p16++ = htons(0x207c); // move.l #ScratchMem,a0
92     *p16++ = htons(ScratchMem >> 16);
93     *p16++ = htons(ScratchMem);
94     *p16++ = htons(M68K_NOP);
95     *p16 = htons(M68K_NOP);
96     #else
97     #error System specific handling for writable ROM is required here
98     #endif
99     FlushCodeCache(p + base, 14);
100     D(bug(" patch 2 applied\n"));
101     }
102    
103     } else if (type == 'boot' && id == 2) {
104     D(bug(" boot 2 found\n"));
105    
106     // Set fake handle at 0x0000 to some safe place (so broken Mac programs won't write into Mac ROM) (7.5, 8.0)
107     static const uint8 dat[] = {0x20, 0x78, 0x02, 0xae, 0xd1, 0xfc, 0x00, 0x01, 0x00, 0x00, 0x21, 0xc8, 0x00, 0x00};
108     base = find_rsrc_data(p, size, dat, sizeof(dat));
109     if (base) {
110     p16 = (uint16 *)(p + base);
111    
112     #if defined(AMIGA)
113     // Set 0x0000 to scratch memory area
114     extern uint32 ScratchMem;
115     *p16++ = htons(0x207c); // move.l #ScratchMem,a0
116     *p16++ = htons(ScratchMem >> 16);
117     *p16++ = htons(ScratchMem);
118     *p16++ = htons(M68K_NOP);
119     *p16 = htons(M68K_NOP);
120     #else
121     #error System specific handling for writable ROM is required here
122     #endif
123     FlushCodeCache(p + base, 14);
124     D(bug(" patch 1 applied\n"));
125     }
126     #endif
127    
128     } else if (type == 'PTCH' && id == 630) {
129     D(bug("PTCH 630 found\n"));
130    
131     // Don't replace Time Manager (Classic ROM, 6.0.3)
132     static const uint8 dat[] = {0x30, 0x3c, 0x00, 0x58, 0xa2, 0x47};
133     base = find_rsrc_data(p, size, dat, sizeof(dat));
134     if (base) {
135     p16 = (uint16 *)(p + base);
136     p16[2] = htons(M68K_NOP);
137     p16[7] = htons(M68K_NOP);
138     p16[12] = htons(M68K_NOP);
139     FlushCodeCache(p + base, 26);
140     D(bug(" patch 1 applied\n"));
141     }
142    
143     // Don't replace Time Manager (Classic ROM, 6.0.8)
144     static const uint8 dat2[] = {0x70, 0x58, 0xa2, 0x47};
145     base = find_rsrc_data(p, size, dat2, sizeof(dat2));
146     if (base) {
147     p16 = (uint16 *)(p + base);
148     p16[1] = htons(M68K_NOP);
149     p16[5] = htons(M68K_NOP);
150     p16[9] = htons(M68K_NOP);
151     FlushCodeCache(p + base, 20);
152     D(bug(" patch 1 applied\n"));
153     }
154    
155     } else if (type == 'ptch' && id == 26) {
156     D(bug(" ptch 26 found\n"));
157    
158     // Trap ABC4 is initialized with absolute ROM address (7.5, 7.6, 7.6.1, 8.0)
159     static const uint8 dat[] = {0x40, 0x83, 0x36, 0x10};
160     base = find_rsrc_data(p, size, dat, sizeof(dat));
161     if (base) {
162     p16 = (uint16 *)(p + base);
163     *p16++ = htons((ROMBaseMac + 0x33610) >> 16);
164     *p16 = htons((ROMBaseMac + 0x33610) & 0xffff);
165     FlushCodeCache(p + base, 4);
166     D(bug(" patch 1 applied\n"));
167     }
168    
169     } else if (type == 'ptch' && id == 34) {
170     D(bug(" ptch 34 found\n"));
171    
172     // Don't wait for VIA (Classic ROM, 6.0.8)
173     static const uint8 dat[] = {0x22, 0x78, 0x01, 0xd4, 0x10, 0x11, 0x02, 0x00, 0x00, 0x30};
174     base = find_rsrc_data(p, size, dat, sizeof(dat));
175     if (base) {
176     p16 = (uint16 *)(p + base + 14);
177     *p16 = htons(M68K_NOP);
178     FlushCodeCache(p + base + 14, 2);
179     D(bug(" patch 1 applied\n"));
180     }
181    
182     // Don't replace ADBOp() (Classic ROM, 6.0.8)
183     static const uint8 dat2[] = {0x21, 0xc0, 0x05, 0xf0};
184     base = find_rsrc_data(p, size, dat2, sizeof(dat2));
185     if (base) {
186     p16 = (uint16 *)(p + base);
187     *p16++ = htons(M68K_NOP);
188     *p16 = htons(M68K_NOP);
189     FlushCodeCache(p + base, 4);
190     D(bug(" patch 2 applied\n"));
191     }
192    
193     #if !EMULATED_68K
194     } else if (CPUIs68060 && (type == 'gpch' && id == 669 || type == 'lpch' && id == 63)) {
195     D(bug(" gpch 669/lpch 63 found\n"));
196    
197     static uint16 ThPatchSpace[1024]; // Replacement routines are constructed here
198     uint16 *q = ThPatchSpace;
199     uint32 start;
200     int i;
201    
202     // Patch Thread Manager thread switcher for 68060 FPU (7.5, 8.0)
203     static const uint8 dat[] = {0x22, 0x6f, 0x00, 0x08, 0x20, 0x2f, 0x00, 0x04, 0x67, 0x18};
204     base = find_rsrc_data(p, size, dat, sizeof(dat));
205     if (base) { // Skip first routine (no FPU -> no FPU)
206    
207     base = find_rsrc_data(p, size - base - 2, dat, sizeof(dat), base + 2);
208     if (base) { // no FPU -> FPU
209    
210     p16 = (uint16 *)(p + base);
211     start = (uint32)q;
212     for (i=0; i<28; i++) *q++ = *p16++;
213     *q++ = htons(0x4a2f); // tst.b 2(sp) (null FPU state or "FPU state saved" flag set?)
214     *q++ = htons(2);
215     *q++ = htons(0x6712); // beq
216     *q++ = htons(0x588f); // addq.l #2,sp (flag set, skip it)
217     *q++ = htons(0xf21f); // fmove.l (sp)+,fpcr (restore FPU registers)
218     *q++ = htons(0x9000);
219     *q++ = htons(0xf21f); // fmove.l (sp)+,fpsr
220     *q++ = htons(0x8800);
221     *q++ = htons(0xf21f); // fmove.l (sp)+,fpiar
222     *q++ = htons(0x8400);
223     *q++ = htons(0xf21f); // fmovem.x (sp)+,fp0-fp7
224     *q++ = htons(0xd0ff);
225     *q++ = htons(0xf35f); // frestore (sp)+
226     *q++ = htons(0x4e75); // rts
227    
228     p16 = (uint16 *)(p + base);
229     *p16++ = htons(M68K_JMP);
230     *p16++ = htons(start >> 16);
231     *p16 = htons(start & 0xffff);
232     FlushCodeCache(p + base, 6);
233     D(bug(" patch 1 applied\n"));
234    
235     static const uint8 dat2[] = {0x22, 0x6f, 0x00, 0x08, 0x20, 0x2f, 0x00, 0x04, 0x67, 0x28};
236     base = find_rsrc_data(p, size, dat2, sizeof(dat2));
237     if (base) { // FPU -> FPU
238    
239     p16 = (uint16 *)(p + base);
240     start = (uint32)q;
241     for (i=0; i<4; i++) *q++ = *p16++;
242     *q++ = htons(0x6736); // beq
243     *q++ = htons(0xf327); // fsave -(sp) (save FPU state frame)
244     *q++ = htons(0x4a2f); // tst.b 2(sp) (null FPU state?)
245     *q++ = htons(2);
246     *q++ = htons(0x6716); // beq
247     *q++ = htons(0xf227); // fmovem.x fp0-fp7,-(sp) (no, save FPU registers)
248     *q++ = htons(0xe0ff);
249     *q++ = htons(0xf227); // fmove.l fpiar,-(sp)
250     *q++ = htons(0xa400);
251     *q++ = htons(0xf227); // fmove.l fpsr,-(sp)
252     *q++ = htons(0xa800);
253     *q++ = htons(0xf227); // fmove.l fpcr,-(sp)
254     *q++ = htons(0xb000);
255     *q++ = htons(0x4879); // pea -1 (push "FPU state saved" flag)
256     *q++ = htons(0xffff);
257     *q++ = htons(0xffff);
258     p16 += 9;
259     for (i=0; i<23; i++) *q++ = *p16++;
260     *q++ = htons(0x4a2f); // tst.b 2(sp) (null FPU state or "FPU state saved" flag set?)
261     *q++ = htons(2);
262     *q++ = htons(0x6712); // beq
263     *q++ = htons(0x588f); // addq.l #2,sp (flag set, skip it)
264     *q++ = htons(0xf21f); // fmove.l (sp)+,fpcr (restore FPU registers)
265     *q++ = htons(0x9000);
266     *q++ = htons(0xf21f); // fmove.l (sp)+,fpsr
267     *q++ = htons(0x8800);
268     *q++ = htons(0xf21f); // fmove.l (sp)+,fpiar
269     *q++ = htons(0x8400);
270     *q++ = htons(0xf21f); // fmovem.x (sp)+,fp0-fp7
271     *q++ = htons(0xd0ff);
272     *q++ = htons(0xf35f); // frestore (sp)+
273     *q++ = htons(0x4e75); // rts
274    
275     p16 = (uint16 *)(p + base);
276     *p16++ = htons(M68K_JMP);
277     *p16++ = htons(start >> 16);
278     *p16 = htons(start & 0xffff);
279     FlushCodeCache(p + base, 6);
280     D(bug(" patch 2 applied\n"));
281    
282     base = find_rsrc_data(p, size - base - 2, dat2, sizeof(dat2), base + 2);
283     if (base) { // FPU -> no FPU
284    
285     p16 = (uint16 *)(p + base);
286     start = (uint32)q;
287     for (i=0; i<4; i++) *q++ = *p16++;
288     *q++ = htons(0x6736); // beq
289     *q++ = htons(0xf327); // fsave -(sp) (save FPU state frame)
290     *q++ = htons(0x4a2f); // tst.b 2(sp) (null FPU state?)
291     *q++ = htons(2);
292     *q++ = htons(0x6716); // beq
293     *q++ = htons(0xf227); // fmovem.x fp0-fp7,-(sp) (no, save FPU registers)
294     *q++ = htons(0xe0ff);
295     *q++ = htons(0xf227); // fmove.l fpiar,-(sp)
296     *q++ = htons(0xa400);
297     *q++ = htons(0xf227); // fmove.l fpsr,-(sp)
298     *q++ = htons(0xa800);
299     *q++ = htons(0xf227); // fmove.l fpcr,-(sp)
300     *q++ = htons(0xb000);
301     *q++ = htons(0x4879); // pea -1 (push "FPU state saved" flag)
302     *q++ = htons(0xffff);
303     *q++ = htons(0xffff);
304     p16 += 9;
305     for (i=0; i<24; i++) *q++ = *p16++;
306    
307     p16 = (uint16 *)(p + base);
308     *p16++ = htons(M68K_JMP);
309     *p16++ = htons(start >> 16);
310     *p16 = htons(start & 0xffff);
311     FlushCodeCache(p + base, 6);
312     D(bug(" patch 3 applied\n"));
313     }
314     }
315     }
316     }
317    
318     // Patch Thread Manager thread switcher for 68060 FPU (additional routines under 8.0 for Mixed Mode Manager)
319     static const uint8 dat3[] = {0x22, 0x6f, 0x00, 0x08, 0x20, 0x2f, 0x00, 0x04, 0x67, 0x40};
320     base = find_rsrc_data(p, size, dat3, sizeof(dat3));
321     if (base) { // Skip first routine (no FPU -> no FPU)
322    
323     base = find_rsrc_data(p, size - base - 2, dat3, sizeof(dat3), base + 2);
324     if (base) { // no FPU -> FPU
325    
326     p16 = (uint16 *)(p + base);
327     start = (uint32)q;
328     for (i=0; i<48; i++) *q++ = *p16++;
329     *q++ = htons(0x4a2f); // tst.b 2(sp) (null FPU state or "FPU state saved" flag set?)
330     *q++ = htons(2);
331     *q++ = htons(0x6712); // beq
332     *q++ = htons(0x588f); // addq.l #2,sp (flag set, skip it)
333     *q++ = htons(0xf21f); // fmove.l (sp)+,fpcr (restore FPU registers)
334     *q++ = htons(0x9000);
335     *q++ = htons(0xf21f); // fmove.l (sp)+,fpsr
336     *q++ = htons(0x8800);
337     *q++ = htons(0xf21f); // fmove.l (sp)+,fpiar
338     *q++ = htons(0x8400);
339     *q++ = htons(0xf21f); // fmovem.x (sp)+,fp0-fp7
340     *q++ = htons(0xd0ff);
341     p16 += 7;
342     for (i=0; i<20; i++) *q++ = *p16++;
343    
344     p16 = (uint16 *)(p + base);
345     *p16++ = htons(M68K_JMP);
346     *p16++ = htons(start >> 16);
347     *p16 = htons(start & 0xffff);
348     FlushCodeCache(p + base, 6);
349     D(bug(" patch 4 applied\n"));
350    
351     static const uint8 dat4[] = {0x22, 0x6f, 0x00, 0x08, 0x20, 0x2f, 0x00, 0x04, 0x67, 0x50};
352     base = find_rsrc_data(p, size, dat4, sizeof(dat4));
353     if (base) { // FPU -> FPU
354    
355     p16 = (uint16 *)(p + base);
356     start = (uint32)q;
357     for (i=0; i<4; i++) *q++ = *p16++;
358     *q++ = htons(0x675e); // beq
359     p16++;
360     for (i=0; i<21; i++) *q++ = *p16++;
361     *q++ = htons(0x4a2f); // tst.b 2(sp) (null FPU state?)
362     *q++ = htons(2);
363     *q++ = htons(0x6716); // beq
364     *q++ = htons(0xf227); // fmovem.x fp0-fp7,-(sp) (no, save FPU registers)
365     *q++ = htons(0xe0ff);
366     *q++ = htons(0xf227); // fmove.l fpiar,-(sp)
367     *q++ = htons(0xa400);
368     *q++ = htons(0xf227); // fmove.l fpsr,-(sp)
369     *q++ = htons(0xa800);
370     *q++ = htons(0xf227); // fmove.l fpcr,-(sp)
371     *q++ = htons(0xb000);
372     *q++ = htons(0x4879); // pea -1 (push "FPU state saved" flag)
373     *q++ = htons(0xffff);
374     *q++ = htons(0xffff);
375     p16 += 7;
376     for (i=0; i<23; i++) *q++ = *p16++;
377     *q++ = htons(0x4a2f); // tst.b 2(sp) (null FPU state or "FPU state saved" flag set?)
378     *q++ = htons(2);
379     *q++ = htons(0x6712); // beq
380     *q++ = htons(0x588f); // addq.l #2,sp (flag set, skip it)
381     *q++ = htons(0xf21f); // fmove.l (sp)+,fpcr (restore FPU registers)
382     *q++ = htons(0x9000);
383     *q++ = htons(0xf21f); // fmove.l (sp)+,fpsr
384     *q++ = htons(0x8800);
385     *q++ = htons(0xf21f); // fmove.l (sp)+,fpiar
386     *q++ = htons(0x8400);
387     *q++ = htons(0xf21f); // fmovem.x (sp)+,fp0-fp7
388     *q++ = htons(0xd0ff);
389     p16 += 7;
390     for (i=0; i<20; i++) *q++ = *p16++;
391    
392     p16 = (uint16 *)(p + base);
393     *p16++ = htons(M68K_JMP);
394     *p16++ = htons(start >> 16);
395     *p16 = htons(start & 0xffff);
396     FlushCodeCache(p + base, 6);
397     D(bug(" patch 5 applied\n"));
398    
399     base = find_rsrc_data(p, size - base - 2, dat4, sizeof(dat4), base + 2);
400     if (base) { // FPU -> no FPU
401    
402     p16 = (uint16 *)(p + base);
403     start = (uint32)q;
404     for (i=0; i<4; i++) *q++ = *p16++;
405     *q++ = htons(0x675e); // beq
406     p16++;
407     for (i=0; i<21; i++) *q++ = *p16++;
408     *q++ = htons(0x4a2f); // tst.b 2(sp) (null FPU state?)
409     *q++ = htons(2);
410     *q++ = htons(0x6716); // beq
411     *q++ = htons(0xf227); // fmovem.x fp0-fp7,-(sp) (no, save FPU registers)
412     *q++ = htons(0xe0ff);
413     *q++ = htons(0xf227); // fmove.l fpiar,-(sp)
414     *q++ = htons(0xa400);
415     *q++ = htons(0xf227); // fmove.l fpsr,-(sp)
416     *q++ = htons(0xa800);
417     *q++ = htons(0xf227); // fmove.l fpcr,-(sp)
418     *q++ = htons(0xb000);
419     *q++ = htons(0x4879); // pea -1 (push "FPU state saved" flag)
420     *q++ = htons(0xffff);
421     *q++ = htons(0xffff);
422     p16 += 7;
423     for (i=0; i<42; i++) *q++ = *p16++;
424    
425     p16 = (uint16 *)(p + base);
426     *p16++ = htons(M68K_JMP);
427     *p16++ = htons(start >> 16);
428     *p16 = htons(start & 0xffff);
429     FlushCodeCache(p + base, 6);
430     D(bug(" patch 6 applied\n"));
431     }
432     }
433     }
434     }
435    
436     FlushCodeCache(ThPatchSpace, 1024);
437    
438     // Patch Thread Manager FPU init for 68060 FPU (7.5, 8.0)
439     static const uint8 dat5[] = {0x4a, 0x28, 0x00, 0xa4, 0x67, 0x0a, 0x4a, 0x2c, 0x00, 0x40};
440     base = find_rsrc_data(p, size, dat5, sizeof(dat5));
441     if (base) {
442     p16 = (uint16 *)(p + base + 6);
443     *p16++ = htons(M68K_JSR);
444     *p16++ = htons((uint32)ThInitFPUPatch >> 16);
445     *p16++ = htons((uint32)ThInitFPUPatch & 0xffff);
446     *p16++ = htons(M68K_NOP);
447     *p16 = htons(M68K_NOP);
448     FlushCodeCache(p + base + 6, 10);
449     D(bug(" patch 7 applied\n"));
450     }
451     #endif
452    
453     } else if (type == 'gpch' && id == 750) {
454     D(bug(" gpch 750 found\n"));
455    
456     // Don't use PTEST instruction in BlockMove() (7.5, 7.6, 7.6.1, 8.0)
457     static const uint8 dat[] = {0xa0, 0x8d, 0x0c, 0x81, 0x00, 0x00, 0x0c, 0x00, 0x65, 0x06, 0x4e, 0x71, 0xf4, 0xf8};
458     base = find_rsrc_data(p, size, dat, sizeof(dat));
459     if (base) {
460     p16 = (uint16 *)(p + base + 8);
461     *p16 = htons(M68K_NOP);
462     FlushCodeCache(p + base + 8, 2);
463     D(bug(" patch 1 applied\n"));
464     }
465    
466     } else if (type == 'lpch' && id == 24) {
467     D(bug(" lpch 24 found\n"));
468    
469     // Don't replace Time Manager (7.0.1, 7.1, 7.5, 7.6, 7.6.1, 8.0)
470     static const uint8 dat[] = {0x70, 0x59, 0xa2, 0x47};
471     base = find_rsrc_data(p, size, dat, sizeof(dat));
472     if (base) {
473     p16 = (uint16 *)(p + base + 2);
474     *p16++ = htons(M68K_NOP);
475     p16 += 3;
476     *p16++ = htons(M68K_NOP);
477     p16 += 7;
478     *p16 = htons(M68K_NOP);
479     FlushCodeCache(p + base + 2, 28);
480     D(bug(" patch 1 applied\n"));
481     }
482    
483     } else if (type == 'lpch' && id == 31) {
484     D(bug(" lpch 31 found\n"));
485    
486     // Don't write to VIA in vSoundDead() (7.0.1, 7.1, 7.5, 7.6, 7.6.1, 8.0)
487     static const uint8 dat[] = {0x20, 0x78, 0x01, 0xd4, 0x08, 0xd0, 0x00, 0x07, 0x4e, 0x75};
488     base = find_rsrc_data(p, size, dat, sizeof(dat));
489     if (base) {
490     p16 = (uint16 *)(p + base);
491     *p16 = htons(M68K_RTS);
492     FlushCodeCache(p + base, 2);
493     D(bug(" patch 1 applied\n"));
494     }
495    
496     // Don't replace SCSI manager (7.1, 7.5, 7.6.1, 8.0)
497     static const uint8 dat2[] = {0x0c, 0x6f, 0x00, 0x0e, 0x00, 0x04, 0x66, 0x0c};
498     base = find_rsrc_data(p, size, dat2, sizeof(dat2));
499     if (base) {
500     p16 = (uint16 *)(p + base);
501     *p16++ = htons(M68K_EMUL_OP_SCSI_DISPATCH);
502     *p16++ = htons(0x2e49); // move.l a1,a7
503     *p16 = htons(M68K_JMP_A0);
504     FlushCodeCache(p + base, 6);
505     D(bug(" patch 2 applied\n"));
506     }
507    
508     #if !EMULATED_68K
509     } else if (CPUIs68060 && type == 'scod' && (id == -16463 || id == -16464)) {
510     D(bug(" scod -16463/-16464 found\n"));
511    
512     // Correct 68060 FP frame handling in Process Manager task switches (7.1, 7.5, 8.0)
513     static const uint8 dat[] = {0xf3, 0x27, 0x4a, 0x17};
514     base = find_rsrc_data(p, size, dat, sizeof(dat));
515     if (base) {
516     p16 = (uint16 *)(p + base);
517     *p16++ = htons(M68K_JMP);
518     *p16++ = htons((uint32)Scod060Patch1 >> 16);
519     *p16 = htons((uint32)Scod060Patch1 & 0xffff);
520     FlushCodeCache(p + base, 6);
521     D(bug(" patch 1 applied\n"));
522     }
523    
524     // Even a null FP frame is 3 longwords on the 68060 (7.1, 7.5, 8.0)
525     static const uint8 dat2[] = {0xf3, 0x5f, 0x4e, 0x75};
526     base = find_rsrc_data(p, size, dat2, sizeof(dat2));
527     if (base) {
528     p16 = (uint16 *)(p + base - 2);
529     *p16++ = htons(M68K_JMP);
530     *p16++ = htons((uint32)Scod060Patch2 >> 16);
531     *p16 = htons((uint32)Scod060Patch2 & 0xffff);
532     FlushCodeCache(p + base - 2, 6);
533     D(bug(" patch 2 applied\n"));
534     }
535     #endif
536    
537     } else if (type == 'thng' && id == -16563) {
538     D(bug(" thng -16563 found\n"));
539    
540     // Set audio component flags (7.5, 7.6, 7.6.1, 8.0)
541     *(uint32 *)(p + componentFlags) = htonl(audio_component_flags);
542     D(bug(" patch 1 applied\n"));
543    
544     } else if (type == 'sift' && id == -16563) {
545     D(bug(" sift -16563 found\n"));
546    
547     // Replace audio component (7.5, 7.6, 7.6.1, 8.0)
548     p16 = (uint16 *)p;
549     *p16++ = htons(0x4e56); *p16++ = htons(0x0000); // link a6,#0
550     *p16++ = htons(0x48e7); *p16++ = htons(0x8018); // movem.l d0/a3-a4,-(sp)
551     *p16++ = htons(0x266e); *p16++ = htons(0x000c); // movea.l 12(a6),a3
552     *p16++ = htons(0x286e); *p16++ = htons(0x0008); // movea.l 8(a6),a4
553     *p16++ = htons(M68K_EMUL_OP_AUDIO);
554     *p16++ = htons(0x2d40); *p16++ = htons(0x0010); // move.l d0,16(a6)
555     *p16++ = htons(0x4cdf); *p16++ = htons(0x1801); // movem.l (sp)+,d0/a3-a4
556     *p16++ = htons(0x4e5e); // unlk a6
557     *p16++ = htons(0x4e74); *p16++ = htons(0x0008); // rtd #8
558     FlushCodeCache(p, 32);
559     D(bug(" patch 1 applied\n"));
560    
561     } else if (type == 'inst' && id == -19069) {
562     D(bug(" inst -19069 found\n"));
563    
564     // Don't replace Microseconds (QuickTime 2.0)
565     static const uint8 dat[] = {0x30, 0x3c, 0xa1, 0x93, 0xa2, 0x47};
566     base = find_rsrc_data(p, size, dat, sizeof(dat));
567     if (base) {
568     p16 = (uint16 *)(p + base + 4);
569     *p16 = htons(M68K_NOP);
570     FlushCodeCache(p + base + 4, 2);
571     D(bug(" patch 1 applied\n"));
572     }
573    
574     } else if (type == 'DRVR' && id == -20066) {
575     D(bug("DRVR -20066 found\n"));
576    
577     // Don't access SCC in .Infra driver
578     static const uint8 dat[] = {0x28, 0x78, 0x01, 0xd8, 0x48, 0xc7, 0x20, 0x0c, 0xd0, 0x87, 0x20, 0x40, 0x1c, 0x10};
579     base = find_rsrc_data(p, size, dat, sizeof(dat));
580     if (base) {
581     p16 = (uint16 *)(p + base + 12);
582     *p16 = htons(0x7a00); // moveq #0,d6
583     FlushCodeCache(p + base + 12, 2);
584     D(bug(" patch 1 applied\n"));
585     }
586    
587     } else if (type == 'ltlk' && id == 0) {
588     D(bug(" ltlk 0 found\n"));
589    
590     // Disable LocalTalk (7.0.1, 7.5, 7.6, 7.6.1, 8.0)
591     p16 = (uint16 *)p;
592     *p16++ = htons(M68K_JMP_A0);
593     *p16++ = htons(0x7000);
594     *p16 = htons(M68K_RTS);
595     FlushCodeCache(p, 6);
596     D(bug(" patch 1 applied\n"));
597     }
598     }