ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/rsrc_patches.cpp
Revision: 1.8
Committed: 2001-02-02T20:52:57Z (23 years, 3 months ago) by cebix
Branch: MAIN
CVS Tags: snapshot-17022001, snapshot-29052001, release-0_9-1
Changes since 1.7: +1 -1 lines
Log Message:
- bumped version number to 0.9
- updated copyright dates

File Contents

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