ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/SheepShaver/src/rsrc_patches.cpp
Revision: 1.16
Committed: 2005-07-02T17:51:43Z (19 years, 5 months ago) by gbeauche
Branch: MAIN
Changes since 1.15: +6 -0 lines
Log Message:
Issue a SysError(dsOldSystem) if we are trying to use MacOS < 8.1.0 with a
NewWorld ROM. That may be 8.1.0 included but original iMac had a NewWorld
ROM compatible system.

Otherwise we will crash because the boot routine is trying to execute code
through unitialized descriptor that points to 0x13ff, which is obviously
wrong (and unaligned on word-boundaries for 68k code).

File Contents

# User Rev Content
1 cebix 1.1 /*
2     * rsrc_patches.cpp - Resource patches
3     *
4 gbeauche 1.15 * SheepShaver (C) 1997-2005 Christian Bauer and Marc Hellwig
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 <stdio.h>
22     #include <stdlib.h>
23     #include <string.h>
24    
25     #include "sysdeps.h"
26     #include "rsrc_patches.h"
27     #include "cpu_emulation.h"
28     #include "emul_op.h"
29     #include "xlowmem.h"
30     #include "macos_util.h"
31     #include "rom_patches.h"
32     #include "main.h"
33     #include "audio.h"
34 gbeauche 1.8 #include "audio_defs.h"
35 gbeauche 1.7 #include "thunks.h"
36 cebix 1.1
37     #define DEBUG 0
38     #include "debug.h"
39    
40    
41     // Sound input driver
42     static const uint8 sound_input_driver[] = { // .AppleSoundInput driver header
43     // Driver header
44     0x4d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
45     0x00, 0x24, // Open() offset
46     0x00, 0x28, // Prime() offset
47     0x00, 0x2c, // Control() offset
48     0x00, 0x38, // Status() offset
49     0x00, 0x5e, // Close() offset
50     0x10, 0x2e, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x53, 0x6f, 0x75, 0x6e, 0x64, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x00, // ".AppleSoundInput"
51    
52     // Open()
53     M68K_EMUL_OP_SOUNDIN_OPEN >> 8, M68K_EMUL_OP_SOUNDIN_OPEN & 0xff,
54     0x4e, 0x75, // rts
55    
56     // Prime()
57     M68K_EMUL_OP_SOUNDIN_PRIME >> 8, M68K_EMUL_OP_SOUNDIN_PRIME & 0xff,
58     0x60, 0x0e, // bra IOReturn
59    
60     // Control()
61     M68K_EMUL_OP_SOUNDIN_CONTROL >> 8, M68K_EMUL_OP_SOUNDIN_CONTROL & 0xff,
62     0x0c, 0x68, 0x00, 0x01, 0x00, 0x1a, // cmp.w #1,$1a(a0)
63     0x66, 0x04, // bne IOReturn
64     0x4e, 0x75, // rts
65    
66     // Status()
67     M68K_EMUL_OP_SOUNDIN_STATUS >> 8, M68K_EMUL_OP_SOUNDIN_STATUS & 0xff,
68    
69     // IOReturn
70     0x32, 0x28, 0x00, 0x06, // move.w 6(a0),d1
71     0x08, 0x01, 0x00, 0x09, // btst #9,d1
72     0x67, 0x0c, // beq 1
73     0x4a, 0x40, // tst.w d0
74     0x6f, 0x02, // ble 2
75     0x42, 0x40, // clr.w d0
76     0x31, 0x40, 0x00, 0x10, //2 move.w d0,$10(a0)
77     0x4e, 0x75, // rts
78     0x4a, 0x40, //1 tst.w d0
79     0x6f, 0x04, // ble 3
80     0x42, 0x40, // clr.w d0
81     0x4e, 0x75, // rts
82     0x2f, 0x38, 0x08, 0xfc, //3 move.l $8fc,-(sp)
83     0x4e, 0x75, // rts
84    
85     // Close()
86     M68K_EMUL_OP_SOUNDIN_CLOSE >> 8, M68K_EMUL_OP_SOUNDIN_CLOSE & 0xff,
87     0x4e, 0x75, // rts
88     };
89    
90    
91     /*
92     * Search resource for byte string, return offset (or 0)
93     */
94    
95     static uint32 find_rsrc_data(const uint8 *rsrc, uint32 max, const uint8 *search, uint32 search_len, uint32 ofs = 0)
96     {
97     while (ofs < max - search_len) {
98     if (!memcmp(rsrc + ofs, search, search_len))
99     return ofs;
100     ofs++;
101     }
102     return 0;
103     }
104    
105    
106     /*
107     * Resource patches via vCheckLoad
108     */
109    
110 gbeauche 1.4 // 680x0 code pattern matching helper
111     #define PM(N, V) (p[N] == htons(V))
112    
113 cebix 1.1 void CheckLoad(uint32 type, int16 id, uint16 *p, uint32 size)
114     {
115     uint16 *p16;
116     uint32 base;
117     D(bug("vCheckLoad %c%c%c%c (%08x) ID %d, data %p, size %d\n", type >> 24, (type >> 16) & 0xff, (type >> 8) & 0xff, type & 0xff, type, id, p, size));
118    
119     // Don't modify resources in ROM
120 gbeauche 1.12 if ((uintptr)p >= (uintptr)ROMBaseHost && (uintptr)p <= (uintptr)(ROMBaseHost + ROM_SIZE))
121 cebix 1.1 return;
122    
123     if (type == FOURCC('b','o','o','t') && id == 3) {
124     D(bug("boot 3 found\n"));
125     size >>= 1;
126     while (size--) {
127 gbeauche 1.4 if (PM(0,0x2e49)) {
128 cebix 1.1 // Set boot stack pointer (7.5.2, 7.5.3, 7.5.5, 7.6, 7.6.1, 8.0, 8.1, 8.5, 8.6)
129 gbeauche 1.4 p[0] = htons(M68K_EMUL_OP_FIX_BOOTSTACK);
130 cebix 1.1 D(bug(" patch 1 applied\n"));
131 gbeauche 1.4 } else if (PM(0,0x4267) && PM(1,0x3f01) && PM(2,0x3f2a) && PM(3,0x0006) && PM(4,0x6100)) {
132 cebix 1.1 // Check when ntrb 17 is installed (for native Resource Manager patch) (7.5.3, 7.5.5)
133 gbeauche 1.4 p[7] = htons(M68K_EMUL_OP_NTRB_17_PATCH3);
134 cebix 1.1 D(bug(" patch 2 applied\n"));
135 gbeauche 1.4 } else if (PM(0,0x3f2a) && PM(1,0x0006) && PM(2,0x3f2a) && PM(3,0x0002) && PM(4,0x6100)) {
136 cebix 1.1 // Check when ntrb 17 is installed (for native Resource Manager patch) (7.6, 7.6.1, 8.0, 8.1)
137 gbeauche 1.4 p[7] = htons(M68K_EMUL_OP_NTRB_17_PATCH);
138 cebix 1.1 D(bug(" patch 3 applied\n"));
139 gbeauche 1.11 } else if (PM(0,0x3f2a) && PM(1,0x0006) && PM(2,0x3f2a) && PM(3,0x0002) && PM(4,0x61ff) && PM(8,0x245f)) {
140 cebix 1.1 // Check when ntrb 17 is installed (for native Resource Manager patch) (8.5, 8.6)
141 gbeauche 1.4 p[8] = htons(M68K_EMUL_OP_NTRB_17_PATCH);
142 cebix 1.1 D(bug(" patch 4 applied\n"));
143 gbeauche 1.11 } else if (PM(0,0x3f2a) && PM(1,0x0006) && PM(2,0x3f2a) && PM(3,0x0002) && PM(4,0x61ff) && PM(7,0x301f)) {
144     // Check when ntrb 17 is installed (for native Resource Manager patch) (9.0)
145     p[7] = htons(M68K_EMUL_OP_NTRB_17_PATCH4);
146     p[8] = htons(ntohs(p[8]) & 0xf0ff); // bra
147     D(bug(" patch 8 applied\n"));
148 gbeauche 1.4 } else if (PM(0,0x0c39) && PM(1,0x0001) && PM(2,0xf800) && PM(3,0x0008) && PM(4,0x6f00)) {
149 cebix 1.1 // Don't read from 0xf8000008 (8.5 with Zanzibar ROM, 8.6)
150 gbeauche 1.4 p[0] = htons(M68K_NOP);
151     p[1] = htons(M68K_NOP);
152     p[2] = htons(M68K_NOP);
153     p[3] = htons(M68K_NOP);
154     p[4] = htons(0x6000); // bra
155 cebix 1.1 D(bug(" patch 5 applied\n"));
156 gbeauche 1.4 } else if (PM(0,0x2f3c) && PM(1,0x6b72) && PM(2,0x6e6c) && PM(3,0x4267) && PM(4,0xa9a0) && PM(5,0x265f) && PM(6,0x200b) && PM(7,0x6700)) {
157 cebix 1.1 // Don't replace nanokernel ("krnl" resource) (8.6)
158 gbeauche 1.4 p[0] = htons(M68K_NOP);
159     p[1] = htons(M68K_NOP);
160     p[2] = htons(M68K_NOP);
161     p[3] = htons(M68K_NOP);
162     p[4] = htons(M68K_NOP);
163     p[7] = htons(0x6000); // bra
164 cebix 1.1 D(bug(" patch 6 applied\n"));
165 gbeauche 1.4 } else if (PM(0,0xa8fe) && PM(1,0x3038) && PM(2,0x017a) && PM(3,0x0c40) && PM(4,0x8805) && PM(5,0x6710)) {
166 cebix 1.1 // No SCSI (calls via 0x205c jump vector which is not initialized in NewWorld ROM 1.6) (8.6)
167     if (ROMType == ROMTYPE_NEWWORLD) {
168 gbeauche 1.4 p[5] = htons(0x6010); // bra
169 cebix 1.1 D(bug(" patch 7 applied\n"));
170     }
171 gbeauche 1.16 } else if (PM(0,0x2f3c) && PM(1,0x7665) && PM(2,0x7273) && PM(3,0x3f3c) && PM(4,0x0001) && PM(10,0x2041) && PM(11,0x2248) && PM(12,0x2050) && PM(20,0x7066) && PM(21,0xa9c9)) {
172     // Check when vers 1 is installed (for safe abort if MacOS < 8.1 is used with a NewWorld ROM)
173     p[10] = htons(M68K_EMUL_OP_CHECK_SYSV);
174     p[11] = htons(0x4a81); // tst.l d1
175     p[12] = htons(0x670e); // beq.s <SysError #dsOldSystem>
176     D(bug(" patch 9 applied\n"));
177 cebix 1.1 }
178     p++;
179     }
180    
181     } else if (type == FOURCC('g','n','l','d') && id == 0) {
182     D(bug("gnld 0 found\n"));
183    
184     // Patch native Resource Manager after ntrbs are installed (7.5.2)
185     static const uint8 dat[] = {0x4e, 0xba, 0x00, 0x9e, 0x3e, 0x00, 0x50, 0x4f, 0x67, 0x04};
186     base = find_rsrc_data((uint8 *)p, size, dat, sizeof(dat));
187     if (base) {
188 gbeauche 1.4 p16 = (uint16 *)((uintptr)p + base + 6);
189 cebix 1.1 *p16 = htons(M68K_EMUL_OP_NTRB_17_PATCH2);
190     D(bug(" patch 1 applied\n"));
191     }
192    
193 gbeauche 1.11 } else if (type == FOURCC('p','t','c','h') && id == 156) {
194     D(bug("ptch 156 found\n"));
195     size >>= 1;
196     while (size--) {
197     if (PM(0,0x4e56) && PM(1,0xfffa) && PM(2,0x48e7) && PM(3,0x1f18) && PM(4,0x7800) && PM(5,0x267c) && PM(6,0x6900) && PM(7,0x0000)) {
198     // Don't call FE0A opcode (9.0)
199     p[0] = htons(0x7000); // moveq #0,d0
200     p[1] = htons(M68K_RTS);
201     D(bug(" patch 1 applied\n"));
202     break;
203     }
204     p++;
205     }
206    
207 cebix 1.1 } else if (type == FOURCC('p','t','c','h') && id == 420) {
208     D(bug("ptch 420 found\n"));
209     size >>= 1;
210     while (size--) {
211 gbeauche 1.4 if (PM(0,0xa030) && PM(1,0x5240) && PM(2,0x303c) && PM(3,0x0100) && PM(4,0xc06e) && PM(5,0xfef6)) {
212 cebix 1.1 // Disable VM (7.5.2, 7.5.3, 7.5.5, 7.6, 7.6.1)
213 gbeauche 1.4 p[1] = htons(M68K_NOP);
214     p[2] = htons(M68K_NOP);
215     p[3] = htons(M68K_NOP);
216     p[4] = htons(M68K_NOP);
217     p[5] = htons(M68K_NOP);
218     p[6] = htons(M68K_NOP);
219     p[7] = htons(M68K_NOP);
220     p[8] = htons(M68K_NOP);
221     p[9] = htons(M68K_NOP);
222     p[10] = htons(M68K_NOP);
223     p[11] = htons(M68K_NOP);
224 cebix 1.1 D(bug(" patch 1 applied\n"));
225     break;
226 gbeauche 1.4 } else if (PM(0,0xa030) && PM(1,0x5240) && PM(2,0x7000) && PM(3,0x302e) && PM(4,0xfef6) && PM(5,0x323c) && PM(6,0x0100)) {
227 cebix 1.1 // Disable VM (8.0, 8.1)
228 gbeauche 1.4 p[8] = htons(M68K_NOP);
229     p[15] = htons(M68K_NOP);
230 cebix 1.1 D(bug(" patch 2 applied\n"));
231     break;
232 gbeauche 1.4 } else if (PM(0,0xa030) && PM(1,0x5240) && PM(2,0x7000) && PM(3,0x302e) && PM(4,0xfecc) && PM(5,0x323c) && PM(6,0x0100)) {
233 cebix 1.1 // Disable VM (8.5, 8.6)
234 gbeauche 1.4 p[8] = htons(M68K_NOP);
235     p[15] = htons(M68K_NOP);
236 cebix 1.1 D(bug(" patch 3 applied\n"));
237     break;
238     }
239     p++;
240     }
241    
242     } else if (type == FOURCC('g','p','c','h') && id == 16) {
243     D(bug("gpch 16 found\n"));
244     size >>= 1;
245     while (size--) {
246 gbeauche 1.4 if (PM(0,0x6700) && PM(13,0x7013) && PM(14,0xfe0a)) {
247 cebix 1.1 // Don't call FE0A in Shutdown Manager (7.6.1, 8.0, 8.1, 8.5)
248 gbeauche 1.4 p[0] = htons(0x6000);
249 cebix 1.1 D(bug(" patch 1 applied\n"));
250     break;
251     }
252     p++;
253     }
254    
255     } else if (type == FOURCC('g','p','c','h') && id == 650) {
256     D(bug("gpch 650 found\n"));
257     size >>= 1;
258     while (size--) {
259 gbeauche 1.4 if (PM(0,0x6600) && PM(1,0x001a) && PM(2,0x2278) && PM(3,0x0134)) {
260 cebix 1.1 // We don't have SonyVars (7.5.2)
261 gbeauche 1.4 p[0] = htons(0x6000);
262 cebix 1.1 D(bug(" patch 1 applied\n"));
263 gbeauche 1.4 } else if (PM(0,0x6618) && PM(1,0x2278) && PM(2,0x0134)) {
264 cebix 1.1 // We don't have SonyVars (7.5.3)
265 gbeauche 1.4 p[-6] = htons(M68K_NOP);
266     p[-3] = htons(M68K_NOP);
267     p[0] = htons(0x6018);
268 cebix 1.1 D(bug(" patch 2 applied\n"));
269 gbeauche 1.4 } else if (PM(0,0x666e) && PM(1,0x2278) && PM(2,0x0134)) {
270 cebix 1.1 // We don't have SonyVars (7.5.5)
271 gbeauche 1.4 p[-6] = htons(M68K_NOP);
272     p[-3] = htons(M68K_NOP);
273     p[0] = htons(0x606e);
274 cebix 1.1 D(bug(" patch 3 applied\n"));
275 gbeauche 1.4 } else if (PM(0,0x6400) && PM(1,0x011c) && PM(2,0x2278) && PM(3,0x0134)) {
276 cebix 1.1 // We don't have SonyVars (7.6.1, 8.0, 8.1, 8.5, 8.6)
277 gbeauche 1.4 p[0] = htons(0x6000);
278 cebix 1.1 D(bug(" patch 4 applied\n"));
279 gbeauche 1.4 } else if (PM(0,0x6400) && PM(1,0x00e6) && PM(2,0x2278) && PM(3,0x0134)) {
280 cebix 1.1 // We don't have SonyVars (7.6)
281 gbeauche 1.4 p[0] = htons(0x6000);
282 cebix 1.1 D(bug(" patch 5 applied\n"));
283     }
284     p++;
285     }
286    
287     } else if (type == FOURCC('g','p','c','h') && id == 655) {
288     D(bug("gpch 655 found\n"));
289     size >>= 1;
290     while (size--) {
291 gbeauche 1.4 if (PM(0,0x83a8) && PM(1,0x0024) && PM(2,0x4e71)) {
292 cebix 1.1 // Don't write to GC interrupt mask (7.6, 7.6.1, 8.0, 8.1 with Zanzibar ROM)
293 gbeauche 1.4 p[0] = htons(M68K_NOP);
294     p[1] = htons(M68K_NOP);
295 cebix 1.1 D(bug(" patch 1 applied\n"));
296 gbeauche 1.4 } else if (PM(0,0x207c) && PM(1,0xf300) && PM(2,0x0034)) {
297 cebix 1.1 // Don't read PowerMac ID (7.6, 7.6.1, 8.0, 8.1 with Zanzibar ROM)
298 gbeauche 1.4 p[0] = htons(0x303c); // move.w #id,d0
299     p[1] = htons(0x3020);
300     p[2] = htons(M68K_RTS);
301 cebix 1.1 D(bug(" patch 2 applied\n"));
302 gbeauche 1.4 } else if (PM(0,0x13fc) && PM(1,0x0081) && PM(2,0xf130) && PM(3,0xa030)) {
303 cebix 1.1 // Don't write to hardware (7.6, 7.6.1, 8.0, 8.1 with Zanzibar ROM)
304 gbeauche 1.4 p[0] = htons(M68K_NOP);
305     p[1] = htons(M68K_NOP);
306     p[2] = htons(M68K_NOP);
307     p[3] = htons(M68K_NOP);
308 cebix 1.1 D(bug(" patch 3 applied\n"));
309 gbeauche 1.4 } else if (PM(0,0x4e56) && PM(1,0x0000) && PM(2,0x227c) && PM(3,0xf800) && PM(4,0x0000)) {
310 cebix 1.1 // OpenFirmare? (7.6.1, 8.0, 8.1 with Zanzibar ROM)
311 gbeauche 1.4 p[0] = htons(M68K_RTS);
312 cebix 1.1 D(bug(" patch 4 applied\n"));
313 gbeauche 1.4 } else if (PM(0,0x4e56) && PM(1,0xfffc) && PM(2,0x48e7) && PM(3,0x0300) && PM(4,0x598f) && PM(5,0x2eb8) && PM(6,0x01dc)) {
314 cebix 1.1 // Don't write to SCC (7.6.1, 8.0, 8.1 with Zanzibar ROM)
315 gbeauche 1.4 p[0] = htons(M68K_RTS);
316 cebix 1.1 D(bug(" patch 5 applied\n"));
317 gbeauche 1.4 } else if (PM(0,0x4e56) && PM(1,0x0000) && PM(2,0x227c) && PM(3,0xf300) && PM(4,0x0034)) {
318 cebix 1.1 // Don't write to GC (7.6.1, 8.0, 8.1 with Zanzibar ROM)
319 gbeauche 1.4 p[0] = htons(M68K_RTS);
320 cebix 1.1 D(bug(" patch 6 applied\n"));
321 gbeauche 1.4 } else if (PM(0,0x40e7) && PM(1,0x007c) && PM(2,0x0700) && PM(3,0x48e7) && PM(4,0x00c0) && PM(5,0x2078) && PM(6,0x0dd8) && PM(7,0xd1e8) && PM(8,0x0044) && PM(9,0x8005) && PM(11,0x93c8) && PM(12,0x2149) && PM(13,0x0024)) {
322 cebix 1.1 // Don't replace NVRAM routines (7.6, 7.6.1, 8.0, 8.1 with Zanzibar ROM)
323 gbeauche 1.4 p[0] = htons(M68K_RTS);
324 cebix 1.1 D(bug(" patch 7 applied\n"));
325 gbeauche 1.4 } else if (PM(0,0x207c) && PM(1,0x50f1) && PM(2,0xa101) && (PM(3,0x08d0) || PM(3,0x0890))) {
326 cebix 1.1 // Don't write to 0x50f1a101 (8.1 with Zanzibar ROM)
327 gbeauche 1.4 p[3] = htons(M68K_NOP);
328     p[4] = htons(M68K_NOP);
329 cebix 1.1 D(bug(" patch 8 applied\n"));
330     }
331     p++;
332     }
333    
334     } else if (type == FOURCC('g','p','c','h') && id == 750) {
335     D(bug("gpch 750 found\n"));
336     size >>= 1;
337     while (size--) {
338 gbeauche 1.4 if (PM(0,0xf301) && PM(1,0x9100) && PM(2,0x0c11) && PM(3,0x0044)) {
339 cebix 1.1 // Don't read from 0xf3019100 (MACE ENET) (7.6, 7.6.1, 8.0, 8.1)
340 gbeauche 1.4 p[2] = htons(M68K_NOP);
341     p[3] = htons(M68K_NOP);
342     p[4] = htons(0x6026);
343 cebix 1.1 D(bug(" patch 1 applied\n"));
344 gbeauche 1.4 } else if (PM(0,0x41e8) && PM(1,0x0374) && PM(2,0xfc1e)) {
345 cebix 1.1 // Don't call FC1E opcode (7.6, 7.6.1, 8.0, 8.1, 8.5, 8.6)
346 gbeauche 1.4 p[2] = htons(M68K_NOP);
347 cebix 1.1 D(bug(" patch 2 applied\n"));
348 gbeauche 1.4 } else if (PM(0,0x700a) && PM(1,0xfe0a)) {
349 cebix 1.1 // Don't call FE0A opcode (7.6, 7.6.1, 8.0, 8.1, 8.5, 8.6)
350 gbeauche 1.4 p[1] = htons(0x7000);
351 cebix 1.1 D(bug(" patch 3 applied\n"));
352 gbeauche 1.4 } else if (PM(0,0x6c00) && PM(1,0x016a) && PM(2,0x2278) && PM(3,0x0134)) {
353 gbeauche 1.3 // We don't have SonyVars (8.6)
354 gbeauche 1.4 p[-4] = htons(0x21fc); // move.l $40810000,($0000)
355     p[-3] = htons(0x4081);
356     p[-2] = htons(0x0000);
357     p[-1] = htons(0x0000);
358     p[0] = htons(0x6000);
359 gbeauche 1.3 D(bug(" patch 4 applied\n"));
360 cebix 1.1 }
361     p++;
362     }
363    
364     } else if (type == FOURCC('g','p','c','h') && id == 999) {
365     D(bug("gpch 999 found\n"));
366     size >>= 1;
367     while (size--) {
368 gbeauche 1.4 if (PM(0,0xf301) && PM(1,0x9100) && PM(2,0x0c11) && PM(3,0x0044)) {
369 cebix 1.1 // Don't read from 0xf3019100 (MACE ENET) (8.5, 8.6)
370 gbeauche 1.4 p[2] = htons(M68K_NOP);
371     p[3] = htons(M68K_NOP);
372     p[4] = htons(0x6026);
373 cebix 1.1 D(bug(" patch 1 applied\n"));
374     }
375     p++;
376     }
377    
378     } else if (type == FOURCC('g','p','c','h') && id == 3000) {
379     D(bug("gpch 3000 found\n"));
380     size >>= 1;
381     while (size--) {
382 gbeauche 1.4 if (PM(0,0xf301) && PM(1,0x9100) && PM(2,0x0c11) && PM(3,0x0044)) {
383 cebix 1.1 // Don't read from 0xf3019100 (MACE ENET) (8.1 with NewWorld ROM)
384 gbeauche 1.4 p[2] = htons(M68K_NOP);
385     p[3] = htons(M68K_NOP);
386     p[4] = htons(0x6026);
387 cebix 1.1 D(bug(" patch 1 applied\n"));
388     }
389     p++;
390     }
391    
392     } else if (type == FOURCC('l','t','l','k') && id == 0) {
393     D(bug("ltlk 0 found\n"));
394     #if 1
395     size >>= 1;
396     while (size--) {
397 gbeauche 1.4 if (PM(0,0xc2fc) && PM(1,0x0fa0) && PM(2,0x82c5)) {
398 cebix 1.1 // Prevent division by 0 in speed test (7.5.2, 7.5.3, 7.5.5, 7.6, 7.6.1, 8.0, 8.1)
399 gbeauche 1.4 p[2] = htons(0x7200);
400 cebix 1.1 WriteMacInt32(0x1d8, 0x2c00);
401     WriteMacInt32(0x1dc, 0x2c00);
402     D(bug(" patch 1 applied\n"));
403 gbeauche 1.4 } else if (PM(0,0x1418) && PM(1,0x84c1)) {
404 cebix 1.1 // Prevent division by 0 (7.5.2, 7.5.3, 7.5.5, 7.6, 7.6.1, 8.0, 8.1)
405 gbeauche 1.4 p[1] = htons(0x7400);
406 cebix 1.1 D(bug(" patch 2 applied\n"));
407 gbeauche 1.4 } else if (PM(0,0x2678) && PM(1,0x01dc) && PM(2,0x3018) && PM(3,0x6708) && PM(4,0x1680) && PM(5,0xe058) && PM(6,0x1680)) {
408 cebix 1.1 // Don't write to SCC (7.5.2, 7.5.3, 7.5.5, 7.6, 7.6.1, 8.0, 8.1)
409 gbeauche 1.4 p[4] = htons(M68K_NOP);
410     p[6] = htons(M68K_NOP);
411 cebix 1.1 D(bug(" patch 3 applied\n"));
412 gbeauche 1.4 } else if (PM(0,0x2278) && PM(1,0x01dc) && PM(2,0x12bc) && PM(3,0x0006) && PM(4,0x4e71) && PM(5,0x1292)) {
413 cebix 1.1 // Don't write to SCC (7.5.2, 7.5.3, 7.5.5, 7.6, 7.6.1, 8.0, 8.1)
414 gbeauche 1.4 p[2] = htons(M68K_NOP);
415     p[3] = htons(M68K_NOP);
416     p[5] = htons(M68K_NOP);
417 cebix 1.1 D(bug(" patch 4 applied\n"));
418 gbeauche 1.4 } else if (PM(0,0x2278) && PM(1,0x01dc) && PM(2,0x12bc) && PM(3,0x0003) && PM(4,0x4e71) && PM(5,0x1281)) {
419 cebix 1.1 // Don't write to SCC (7.5.2, 7.5.3, 7.5.5, 7.6, 7.6.1, 8.0, 8.1)
420 gbeauche 1.4 p[2] = htons(M68K_NOP);
421     p[3] = htons(M68K_NOP);
422     p[5] = htons(M68K_NOP);
423 cebix 1.1 D(bug(" patch 5 applied\n"));
424 gbeauche 1.4 } else if (PM(0,0x0811) && PM(1,0x0000) && PM(2,0x51c8) && PM(3,0xfffa)) {
425 cebix 1.1 // Don't test SCC (7.5.2, 7.5.3, 7.5.5, 7.6, 7.6.1, 8.0, 8.1)
426 gbeauche 1.4 p[0] = htons(M68K_NOP);
427     p[1] = htons(M68K_NOP);
428 cebix 1.1 D(bug(" patch 6 applied\n"));
429 gbeauche 1.4 } else if (PM(0,0x4a2a) && PM(1,0x063e) && PM(2,0x66fa)) {
430 cebix 1.1 // Don't wait for SCC (7.5.2, 7.5.3, 7.5.5)
431 gbeauche 1.4 p[2] = htons(M68K_NOP);
432 cebix 1.1 D(bug(" patch 7 applied\n"));
433 gbeauche 1.4 } else if (PM(0,0x4a2a) && PM(1,0x03a6) && PM(2,0x66fa)) {
434 cebix 1.1 // Don't wait for SCC (7.6, 7.6.1, 8.0, 8.1)
435 gbeauche 1.4 p[2] = htons(M68K_NOP);
436 cebix 1.1 D(bug(" patch 8 applied\n"));
437     }
438     p++;
439     }
440     #else
441     // Disable LocalTalk
442 gbeauche 1.4 p[0] = htons(M68K_JMP_A0);
443     p[1] = htons(0x7000); // moveq #0,d0
444     p[2] = htons(M68K_RTS);
445 cebix 1.1 D(bug(" patch 1 applied\n"));
446     #endif
447    
448     } else if (type == FOURCC('n','s','r','d') && id == 1) {
449     D(bug("nsrd 1 found\n"));
450 gbeauche 1.6 if (p[(0x378 + 0x570) >> 1] == htons(0x7c08) && p[(0x37a + 0x570) >> 1] == htons(0x02a6)) {
451 cebix 1.1 // Don't overwrite our serial drivers (8.0, 8.1)
452 gbeauche 1.6 p[(0x378 + 0x570) >> 1] = htons(0x4e80); // blr
453     p[(0x37a + 0x570) >> 1] = htons(0x0020);
454 cebix 1.1 D(bug(" patch 1 applied\n"));
455 gbeauche 1.6 } else if (p[(0x378 + 0x6c0) >> 1] == htons(0x7c08) && p[(0x37a + 0x6c0) >> 1] == htons(0x02a6)) {
456 cebix 1.1 // Don't overwrite our serial drivers (8.5, 8.6)
457 gbeauche 1.6 p[(0x378 + 0x6c0) >> 1] = htons(0x4e80); // blr
458     p[(0x37a + 0x6c0) >> 1] = htons(0x0020);
459 cebix 1.1 D(bug(" patch 2 applied\n"));
460 gbeauche 1.13 } else if (p[(0x374 + 0x510) >> 1] == htons(0x7c08) && p[(0x376 + 0x510) >> 1] == htons(0x02a6)) {
461     // Don't overwrite our serial drivers (9.0)
462     p[(0x374 + 0x510) >> 1] = htons(0x4e80); // blr
463     p[(0x376 + 0x510) >> 1] = htons(0x0020);
464     D(bug(" patch 3 applied\n"));
465 cebix 1.1 }
466    
467     } else if (type == FOURCC('c','i','t','t') && id == 45) {
468     D(bug("citt 45 found\n"));
469     size >>= 1;
470     while (size--) {
471 gbeauche 1.4 if (PM(0,0x203c) && PM(1,0x0100) && PM(2,0x0000) && PM(3,0xc0ae) && PM(4,0xfffc)) {
472 cebix 1.1 // Don't replace SCSI Manager (8.1, 8.5, 8.6)
473 gbeauche 1.6 p[5] = htons((ntohs(p[5]) & 0xff) | 0x6000); // beq
474 cebix 1.1 D(bug(" patch 1 applied\n"));
475     break;
476     }
477     p++;
478     }
479    
480     } else if (type == FOURCC('t','h','n','g')) {
481     // Collect info about used audio sifters
482 gbeauche 1.12 uint32 thing = Host2MacAddr((uint8 *)p);
483 gbeauche 1.8 uint32 c_type = ReadMacInt32(thing);
484     uint32 sub_type = ReadMacInt32(thing + 4);
485 cebix 1.1 if (c_type == FOURCC('s','d','e','v') && sub_type == FOURCC('s','i','n','g')) {
486 gbeauche 1.8 WriteMacInt32(thing + 4, FOURCC('a','w','g','c'));
487 cebix 1.1 D(bug("thng %d, type %c%c%c%c (%08x), sub type %c%c%c%c (%08x), data %p\n", id, c_type >> 24, (c_type >> 16) & 0xff, (c_type >> 8) & 0xff, c_type & 0xff, c_type, sub_type >> 24, (sub_type >> 16) & 0xff, (sub_type >> 8) & 0xff, sub_type & 0xff, sub_type, p));
488 gbeauche 1.8 AddSifter(ReadMacInt32(thing + componentResType), ReadMacInt16(thing + componentResID));
489     if (ReadMacInt32(thing + componentPFCount))
490     AddSifter(ReadMacInt32(thing + componentPFResType), ReadMacInt16(thing + componentPFResID));
491 cebix 1.1 }
492    
493     } else if (type == FOURCC('s','i','f','t') || type == FOURCC('n','i','f','t')) {
494     // Patch audio sifters
495     if (FindSifter(type, id)) {
496     D(bug("sifter found\n"));
497 gbeauche 1.4 p[0] = htons(0x4e56); p[1] = htons(0x0000); // link a6,#0
498     p[2] = htons(0x48e7); p[3] = htons(0x8018); // movem.l d0/a3-a4,-(a7)
499     p[4] = htons(0x266e); p[5] = htons(0x000c); // movea.l $c(a6),a3
500     p[6] = htons(0x286e); p[7] = htons(0x0008); // movea.l $8(a6),a4
501     p[8] = htons(M68K_EMUL_OP_AUDIO_DISPATCH);
502     p[9] = htons(0x2d40); p[10] = htons(0x0010); // move.l d0,$10(a6)
503     p[11] = htons(0x4cdf); p[12] = htons(0x1801); // movem.l (a7)+,d0/a3-a4
504     p[13] = htons(0x4e5e); // unlk a6
505     p[14] = htons(0x4e74); p[15] = htons(0x0008); // rtd #8
506 cebix 1.1 D(bug(" patch applied\n"));
507     }
508    
509     } else if (type == FOURCC('D','R','V','R') && (id == -16501 || id == -16500)) {
510     D(bug("DRVR -16501/-16500 found\n"));
511     // Install sound input driver
512     memcpy(p, sound_input_driver, sizeof(sound_input_driver));
513     D(bug(" patch 1 applied\n"));
514    
515     } else if (type == FOURCC('I','N','I','T') && id == 1 && size == (2416 >> 1)) {
516     D(bug("INIT 1 (size 2416) found\n"));
517     size >>= 1;
518     while (size--) {
519 gbeauche 1.4 if (PM(0,0x247c) && PM(1,0xf301) && PM(2,0x9000)) {
520 cebix 1.1 // Prevent "MacOS Licensing Extension" from accessing hardware (7.6)
521 gbeauche 1.4 p[22] = htons(0x6028);
522 cebix 1.1 D(bug(" patch 1 applied\n"));
523     break;
524     }
525     p++;
526     }
527 gbeauche 1.3
528     } else if (type == FOURCC('s','c','o','d') && id == -16465) {
529     D(bug("scod -16465 found\n"));
530    
531     // Don't crash in Process Manager on reset/shutdown (8.6)
532     static const uint8 dat[] = {0x4e, 0x56, 0x00, 0x00, 0x48, 0xe7, 0x03, 0x18, 0x2c, 0x2e, 0x00, 0x10};
533     base = find_rsrc_data((uint8 *)p, size, dat, sizeof(dat));
534     if (base) {
535 gbeauche 1.4 p16 = (uint16 *)((uintptr)p + base);
536     p16[0] = htons(0x7000); // moveq #0,d0
537     p16[1] = htons(M68K_RTS);
538 gbeauche 1.3 D(bug(" patch 1 applied\n"));
539     }
540 gbeauche 1.10
541     } else if (type == FOURCC('N','O','b','j') && id == 100) {
542     D(bug("NObj 100 found\n"));
543    
544     // Don't access VIA registers in MacBench 5.0
545     static const uint8 dat1[] = {0x7c, 0x08, 0x02, 0xa6, 0xbf, 0x01, 0xff, 0xe0, 0x90, 0x01, 0x00, 0x08};
546     base = find_rsrc_data((uint8 *)p, size, dat1, sizeof(dat1));
547     if (base) {
548     p[(base + 0x00) >> 1] = htons(0x3860); // li r3,0
549     p[(base + 0x02) >> 1] = htons(0x0000);
550     p[(base + 0x04) >> 1] = htons(0x4e80); // blr
551     p[(base + 0x06) >> 1] = htons(0x0020);
552     D(bug(" patch 1 applied\n"));
553     }
554     static const uint8 dat2[] = {0x7c, 0x6c, 0x1b, 0x78, 0x7c, 0x8b, 0x23, 0x78, 0x38, 0xc0, 0x3f, 0xfd};
555     base = find_rsrc_data((uint8 *)p, size, dat2, sizeof(dat2));
556     if (base) {
557     p[(base + 0x00) >> 1] = htons(0x3860); // li r3,0
558     p[(base + 0x02) >> 1] = htons(0x0000);
559     p[(base + 0x04) >> 1] = htons(0x4e80); // blr
560     p[(base + 0x06) >> 1] = htons(0x0020);
561     D(bug(" patch 2 applied\n"));
562     }
563 gbeauche 1.14
564     } else if (type == FOURCC('C','O','D','E') && id == 27 && size == 25024) {
565     D(bug("CODE 27 found [Apple Personal Diagnostics]\n"));
566    
567     // Don't access FCBs directly in Apple Personal Diagnostics (MacOS 9)
568     // FIXME: this should not be called in the first place, use UTResolveFCB?
569     static const uint8 dat[] = {0x2d, 0x78, 0x03, 0x4e, 0xff, 0xf8, 0x20, 0x6e, 0xff, 0xf8};
570     base = find_rsrc_data((uint8 *)p, size, dat, sizeof(dat));
571     if (base
572     && ReadMacInt16(0x3f6) == 4 /* FSFCBLen */
573     && p[(base + 0x1a) >> 1] == htons(0x605e)
574     && p[(base + 0x80) >> 1] == htons(0x7000))
575     {
576     p[(base + 0x1a) >> 1] = htons(0x6064);
577     D(bug(" patch1 applied\n"));
578     }
579 cebix 1.1 }
580     }
581    
582    
583     /*
584     * Native Resource Manager patches
585     */
586    
587     #ifdef __BEOS__
588     static
589 gbeauche 1.2 #else
590     extern "C"
591 cebix 1.1 #endif
592 gbeauche 1.5 void check_load_invoc(uint32 type, int16 id, uint32 h)
593 cebix 1.1 {
594 gbeauche 1.5 if (h == 0)
595 cebix 1.1 return;
596 gbeauche 1.5 uint32 p = ReadMacInt32(h);
597     if (p == 0)
598 cebix 1.1 return;
599 gbeauche 1.5 uint32 size = ReadMacInt32(p - 2 * 4) & 0xffffff;
600 cebix 1.1
601 gbeauche 1.12 CheckLoad(type, id, (uint16 *)Mac2HostAddr(p), size);
602 cebix 1.1 }
603    
604     #ifdef __BEOS__
605     static asm void **get_resource(register uint32 type, register int16 id)
606     {
607     // Create stack frame
608     mflr r0
609     stw r0,8(r1)
610     stwu r1,-(56+12)(r1)
611    
612     // Save type/ID
613     stw r3,56(r1)
614     stw r4,56+4(r1)
615    
616     // Call old routine
617     lwz r0,XLM_GET_RESOURCE
618     lwz r2,XLM_RES_LIB_TOC
619     mtctr r0
620     bctrl
621     lwz r2,XLM_TOC // Get TOC
622     stw r3,56+8(r1) // Save handle
623    
624     // Call CheckLoad
625     lwz r3,56(r1)
626     lwz r4,56+4(r1)
627     lwz r5,56+8(r1)
628     bl check_load_invoc
629     lwz r3,56+8(r1) // Restore handle
630    
631     // Return to caller
632     lwz r0,56+12+8(r1)
633     mtlr r0
634     addi r1,r1,56+12
635     blr
636     }
637    
638     static asm void **get_1_resource(register uint32 type, register int16 id)
639     {
640     // Create stack frame
641     mflr r0
642     stw r0,8(r1)
643     stwu r1,-(56+12)(r1)
644    
645     // Save type/ID
646     stw r3,56(r1)
647     stw r4,56+4(r1)
648    
649     // Call old routine
650     lwz r0,XLM_GET_1_RESOURCE
651     lwz r2,XLM_RES_LIB_TOC
652     mtctr r0
653     bctrl
654     lwz r2,XLM_TOC // Get TOC
655     stw r3,56+8(r1) // Save handle
656    
657     // Call CheckLoad
658     lwz r3,56(r1)
659     lwz r4,56+4(r1)
660     lwz r5,56+8(r1)
661     bl check_load_invoc
662     lwz r3,56+8(r1) // Restore handle
663    
664     // Return to caller
665     lwz r0,56+12+8(r1)
666     mtlr r0
667     addi r1,r1,56+12
668     blr
669     }
670    
671     static asm void **get_ind_resource(register uint32 type, register int16 index)
672     {
673     // Create stack frame
674     mflr r0
675     stw r0,8(r1)
676     stwu r1,-(56+12)(r1)
677    
678     // Save type/index
679     stw r3,56(r1)
680     stw r4,56+4(r1)
681    
682     // Call old routine
683     lwz r0,XLM_GET_IND_RESOURCE
684     lwz r2,XLM_RES_LIB_TOC
685     mtctr r0
686     bctrl
687     lwz r2,XLM_TOC // Get TOC
688     stw r3,56+8(r1) // Save handle
689    
690     // Call CheckLoad
691     lwz r3,56(r1)
692     lwz r4,56+4(r1)
693     lwz r5,56+8(r1)
694     bl check_load_invoc
695     lwz r3,56+8(r1) // Restore handle
696    
697     // Return to caller
698     lwz r0,56+12+8(r1)
699     mtlr r0
700     addi r1,r1,56+12
701     blr
702     }
703    
704     static asm void **get_1_ind_resource(register uint32 type, register int16 index)
705     {
706     // Create stack frame
707     mflr r0
708     stw r0,8(r1)
709     stwu r1,-(56+12)(r1)
710    
711     // Save type/index
712     stw r3,56(r1)
713     stw r4,56+4(r1)
714    
715     // Call old routine
716     lwz r0,XLM_GET_1_IND_RESOURCE
717     lwz r2,XLM_RES_LIB_TOC
718     mtctr r0
719     bctrl
720     lwz r2,XLM_TOC // Get TOC
721     stw r3,56+8(r1) // Save handle
722    
723     // Call CheckLoad
724     lwz r3,56(r1)
725     lwz r4,56+4(r1)
726     lwz r5,56+8(r1)
727     bl check_load_invoc
728     lwz r3,56+8(r1) // Restore handle
729    
730     // Return to caller
731     lwz r0,56+12+8(r1)
732     mtlr r0
733     addi r1,r1,56+12
734     blr
735     }
736    
737     static asm void **r_get_resource(register uint32 type, register int16 id)
738     {
739     // Create stack frame
740     mflr r0
741     stw r0,8(r1)
742     stwu r1,-(56+12)(r1)
743    
744     // Save type/ID
745     stw r3,56(r1)
746     stw r4,56+4(r1)
747    
748     // Call old routine
749     lwz r0,XLM_R_GET_RESOURCE
750     lwz r2,XLM_RES_LIB_TOC
751     mtctr r0
752     bctrl
753     lwz r2,XLM_TOC // Get TOC
754     stw r3,56+8(r1) // Save handle
755    
756     // Call CheckLoad
757     lwz r3,56(r1)
758     lwz r4,56+4(r1)
759     lwz r5,56+8(r1)
760     bl check_load_invoc
761     lwz r3,56+8(r1) // Restore handle
762    
763     // Return to caller
764     lwz r0,56+12+8(r1)
765     mtlr r0
766     addi r1,r1,56+12
767     blr
768     }
769     #else
770     // Routines in asm_linux.S
771     extern "C" void get_resource(void);
772     extern "C" void get_1_resource(void);
773     extern "C" void get_ind_resource(void);
774     extern "C" void get_1_ind_resource(void);
775     extern "C" void r_get_resource(void);
776     #endif
777    
778     void PatchNativeResourceManager(void)
779     {
780     D(bug("PatchNativeResourceManager\n"));
781    
782     // Patch native GetResource()
783 gbeauche 1.5 uint32 upp = ReadMacInt32(0x1480);
784     if ((upp & 0xffc00000) == ROM_BASE)
785 cebix 1.1 return;
786 gbeauche 1.12 uint32 tvec = ReadMacInt32(upp + 5 * 4);
787     D(bug(" GetResource() entry %08x, TOC %08x\n", ReadMacInt32(tvec), ReadMacInt32(tvec + 4)));
788     WriteMacInt32(XLM_RES_LIB_TOC, ReadMacInt32(tvec + 4));
789     WriteMacInt32(XLM_GET_RESOURCE, ReadMacInt32(tvec));
790 gbeauche 1.3 #if EMULATED_PPC
791 gbeauche 1.12 WriteMacInt32(tvec, NativeFunction(NATIVE_GET_RESOURCE));
792 gbeauche 1.3 #else
793 cebix 1.1 #ifdef __BEOS__
794     uint32 *tvec2 = (uint32 *)get_resource;
795 gbeauche 1.12 WriteMacInt32(tvec, tvec2[0]);
796     WriteMacInt32(tvec + 4, tvec2[1]);
797 cebix 1.1 #else
798 gbeauche 1.12 WriteMacInt32(tvec, (uint32)get_resource);
799 cebix 1.1 #endif
800 gbeauche 1.3 #endif
801 cebix 1.1
802     // Patch native Get1Resource()
803 gbeauche 1.5 upp = ReadMacInt32(0x0e7c);
804 gbeauche 1.12 tvec = ReadMacInt32(upp + 5 * 4);
805     D(bug(" Get1Resource() entry %08x, TOC %08x\n", ReadMacInt32(tvec), ReadMacInt32(tvec + 4)));
806     WriteMacInt32(XLM_GET_1_RESOURCE, ReadMacInt32(tvec));
807 gbeauche 1.3 #if EMULATED_PPC
808 gbeauche 1.12 WriteMacInt32(tvec, NativeFunction(NATIVE_GET_1_RESOURCE));
809 gbeauche 1.3 #else
810 cebix 1.1 #ifdef __BEOS__
811     tvec2 = (uint32 *)get_1_resource;
812 gbeauche 1.12 WriteMacInt32(tvec, tvec2[0]);
813     WriteMacInt32(tvec + 4, tvec2[1]);
814 cebix 1.1 #else
815 gbeauche 1.12 WriteMacInt32(tvec, (uint32)get_1_resource);
816 cebix 1.1 #endif
817 gbeauche 1.3 #endif
818 cebix 1.1
819     // Patch native GetIndResource()
820 gbeauche 1.5 upp = ReadMacInt32(0x1474);
821 gbeauche 1.12 tvec = ReadMacInt32(upp + 5 * 4);
822     D(bug(" GetIndResource() entry %08x, TOC %08x\n", ReadMacInt32(tvec), ReadMacInt32(tvec + 4)));
823     WriteMacInt32(XLM_GET_IND_RESOURCE, ReadMacInt32(tvec));
824 gbeauche 1.3 #if EMULATED_PPC
825 gbeauche 1.12 WriteMacInt32(tvec, NativeFunction(NATIVE_GET_IND_RESOURCE));
826 gbeauche 1.3 #else
827 cebix 1.1 #ifdef __BEOS__
828     tvec2 = (uint32 *)get_ind_resource;
829 gbeauche 1.12 WriteMacInt32(tvec, tvec2[0]);
830     WriteMacInt32(tvec + 4, tvec2[1]);
831 cebix 1.1 #else
832 gbeauche 1.12 WriteMacInt32(tvec, (uint32)get_ind_resource);
833 cebix 1.1 #endif
834 gbeauche 1.3 #endif
835 cebix 1.1
836     // Patch native Get1IndResource()
837 gbeauche 1.5 upp = ReadMacInt32(0x0e38);
838 gbeauche 1.12 tvec = ReadMacInt32(upp + 5 * 4);
839     D(bug(" Get1IndResource() entry %08x, TOC %08x\n", ReadMacInt32(tvec), ReadMacInt32(tvec + 4)));
840     WriteMacInt32(XLM_GET_1_IND_RESOURCE, ReadMacInt32(tvec));
841 gbeauche 1.3 #if EMULATED_PPC
842 gbeauche 1.12 WriteMacInt32(tvec, NativeFunction(NATIVE_GET_1_IND_RESOURCE));
843 gbeauche 1.3 #else
844 cebix 1.1 #ifdef __BEOS__
845     tvec2 = (uint32 *)get_1_ind_resource;
846 gbeauche 1.12 WriteMacInt32(tvec, tvec2[0]);
847     WriteMacInt32(tvec + 4, tvec2[1]);
848 cebix 1.1 #else
849 gbeauche 1.12 WriteMacInt32(tvec, (uint32)get_1_ind_resource);
850 cebix 1.1 #endif
851 gbeauche 1.3 #endif
852 cebix 1.1
853     // Patch native RGetResource()
854 gbeauche 1.5 upp = ReadMacInt32(0x0e30);
855 gbeauche 1.12 tvec = ReadMacInt32(upp + 5 * 4);
856     D(bug(" RGetResource() entry %08x, TOC %08x\n", ReadMacInt32(tvec), ReadMacInt32(tvec + 4)));
857     WriteMacInt32(XLM_R_GET_RESOURCE, ReadMacInt32(tvec));
858 gbeauche 1.3 #if EMULATED_PPC
859 gbeauche 1.12 WriteMacInt32(tvec, NativeFunction(NATIVE_R_GET_RESOURCE));
860 gbeauche 1.3 #else
861 cebix 1.1 #ifdef __BEOS__
862     tvec2 = (uint32 *)r_get_resource;
863 gbeauche 1.12 WriteMacInt32(tvec, tvec2[0]);
864     WriteMacInt32(tvec + 4, tvec2[1]);
865 cebix 1.1 #else
866 gbeauche 1.12 WriteMacInt32(tvec, (uint32)r_get_resource);
867 gbeauche 1.3 #endif
868 cebix 1.1 #endif
869     }