ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/rom_patches.cpp
(Generate patch)

Comparing BasiliskII/src/rom_patches.cpp (file contents):
Revision 1.8 by cebix, 1999-10-25T08:07:46Z vs.
Revision 1.17 by gbeauche, 2000-09-22T17:17:21Z

# Line 1 | Line 1
1   /*
2   *  rom_patches.cpp - ROM patches
3   *
4 < *  Basilisk II (C) 1997-1999 Christian Bauer
4 > *  Basilisk II (C) 1997-2000 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
# Line 34 | Line 34
34   #include "prefs.h"
35   #include "rom_patches.h"
36  
37 < #define DEBUG 1
37 > #define DEBUG 0
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 >
47 > static uint32 sony_offset;              // ROM offset of .Sony driver
48 > static uint32 serd_offset;              // ROM offset of SERD resource (serial drivers)
49 > static uint32 microseconds_offset;      // ROM offset of Microseconds() replacement routine
50 > static uint32 debugutil_offset;         // ROM offset of DebugUtil() replacement routine
51  
52   // Prototypes
53   uint16 ROMVersion;
54  
55  
56   /*
57 + *      Convenience functions for retrieving a particular 16-bit word from
58 + *      a 32-bit word value.
59 + *      
60 + *      gb-- probably put those elsewhere...
61 + */
62 +
63 + #define HiWord(X) (((X) >> 16) & 0xffff)
64 + #define LoWord(X) ((X) & 0xffff)
65 +
66 +
67 + /*
68   *  Search ROM for byte string, return ROM offset (or 0)
69   */
70  
# Line 84 | Line 93 | static uint32 find_rom_resource(uint32 s
93  
94          if (!cont)
95                  rsrc_ptr = x;
96 +        else
97 +                rsrc_ptr = ReadMacInt32(ROMBaseMac + rsrc_ptr + 8);
98  
99          for (;;) {
100                  lp = ROMBaseMac + rsrc_ptr;
# Line 142 | Line 153 | again:
153  
154  
155   /*
156 + *  Print ROM information to stream,
157 + */
158 +
159 + static void list_rom_resources(void)
160 + {
161 +        printf("ROM Resources:\n");
162 +        printf("Offset\t Type\tID\tSize\tName\n");
163 +        printf("------------------------------------------------\n");
164 +
165 +        uint32 lp = ROMBaseMac + ReadMacInt32(ROMBaseMac + 0x1a);
166 +        uint32 rsrc_ptr = ReadMacInt32(lp);
167 +
168 +        for (;;) {
169 +                lp = ROMBaseMac + rsrc_ptr;
170 +                uint32 data = ReadMacInt32(lp + 12);
171 +
172 +                char name[32];
173 +                int name_len = ReadMacInt8(lp + 23), i;
174 +                for (i=0; i<name_len; i++)
175 +                        name[i] = ReadMacInt8(lp + 24 + i);
176 +                name[i] = 0;
177 +
178 +                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);
179 +
180 +                rsrc_ptr = ReadMacInt32(lp + 8);
181 +                if (!rsrc_ptr)
182 +                        break;
183 +        }
184 +        printf("\n");
185 + }
186 +
187 + // Mapping of Model IDs to Model names
188 + struct mac_desc {
189 +        char *name;
190 +        int32 id;
191 + };
192 +
193 + static mac_desc MacDesc[] = {
194 +        {"Classic"                              , 1},
195 +        {"Mac XL"                               , 2},
196 +        {"Mac 512KE"                    , 3},
197 +        {"Mac Plus"                             , 4},
198 +        {"Mac SE"                               , 5},
199 +        {"Mac II"                               , 6},
200 +        {"Mac IIx"                              , 7},
201 +        {"Mac IIcx"                             , 8},
202 +        {"Mac SE/030"                   , 9},
203 +        {"Mac Portable"                 , 10},
204 +        {"Mac IIci"                             , 11},
205 +        {"Mac IIfx"                             , 13},
206 +        {"Mac Classic"                  , 17},
207 +        {"Mac IIsi"                             , 18},
208 +        {"Mac LC"                               , 19},
209 +        {"Quadra 900"                   , 20},
210 +        {"PowerBook 170"                , 21},
211 +        {"Quadra 700"                   , 22},
212 +        {"Classic II"                   , 23},
213 +        {"PowerBook 100"                , 24},
214 +        {"PowerBook 140"                , 25},
215 +        {"Quadra 950"                   , 26},
216 +        {"Mac LCIII/Performa 450", 27},
217 +        {"PowerBook Duo 210"    , 29},
218 +        {"Centris 650"                  , 30},
219 +        {"PowerBook Duo 230"    , 32},
220 +        {"PowerBook 180"                , 33},
221 +        {"PowerBook 160"                , 34},
222 +        {"Quadra 800"                   , 35},
223 +        {"Quadra 650"                   , 36},
224 +        {"Mac LCII"                             , 37},
225 +        {"PowerBook Duo 250"    , 38},
226 +        {"Mac IIvi"                             , 44},
227 +        {"Mac IIvm/Performa 600", 45},
228 +        {"Mac IIvx"                             , 48},
229 +        {"Color Classic/Performa 250", 49},
230 +        {"PowerBook 165c"               , 50},
231 +        {"Centris 610"                  , 52},
232 +        {"Quadra 610"                   , 53},
233 +        {"PowerBook 145"                , 54},
234 +        {"Mac LC520"                    , 56},
235 +        {"Quadra/Centris 660AV" , 60},
236 +        {"Performa 46x"                 , 62},
237 +        {"PowerBook 180c"               , 71},
238 +        {"PowerBook 520/520c/540/540c", 72},
239 +        {"PowerBook Duo 270c"   , 77},
240 +        {"Quadra 840AV"                 , 78},
241 +        {"Performa 550"                 , 80},
242 +        {"PowerBook 165"                , 84},
243 +        {"PowerBook 190"                , 85},
244 +        {"Mac TV"                               , 88},
245 +        {"Mac LC475/Performa 47x", 89},
246 +        {"Mac LC575"                    , 92},
247 +        {"Quadra 605"                   , 94},
248 +        {"Quadra 630"                   , 98},
249 +        {"Mac LC580"                    , 99},
250 +        {"PowerBook Duo 280"    , 102},
251 +        {"PowerBook Duo 280c"   , 103},
252 +        {"PowerBook 150"                , 115},
253 +        {"unknown", -1}
254 + };
255 +
256 + static void print_universal_info(uint32 info)
257 + {
258 +        uint8 id = ReadMacInt8(info + 18);
259 +        uint16 hwcfg = ReadMacInt16(info + 16);
260 +        uint16 rom85 = ReadMacInt16(info + 20);
261 +
262 +        // Find model name
263 +        char *name = "unknown";
264 +        for (int i=0; MacDesc[i].id >= 0; i++)
265 +                if (MacDesc[i].id == id + 6) {
266 +                        name = MacDesc[i].name;
267 +                        break;
268 +                }
269 +
270 +        printf("%08x %02x\t%04x\t%04x\t%s\n", info - ROMBaseMac, id, hwcfg, rom85, name);
271 + }
272 +
273 + static void list_universal_infos(void)
274 + {
275 +        uint32 ofs = 0x3000;
276 +        for (int i=0; i<0x2000; i+=2, ofs+=2)
277 +                if (ReadMacInt32(ROMBaseMac + ofs) == 0xdc000505) {
278 +                        ofs -= 16;
279 +                        uint32 q;
280 +                        for (q=ofs; q > 0 && ReadMacInt32(ROMBaseMac + q) != ofs - q; q-=4) ;
281 +                        if (q > 0) {
282 +                                printf("Universal Table at %08x:\n", q);
283 +                                printf("Offset\t ID\tHWCfg\tROM85\tModel\n");
284 +                                printf("------------------------------------------------\n");
285 +                                while ((ofs = ReadMacInt32(ROMBaseMac + q))) {
286 +                                        print_universal_info(ROMBaseMac + ofs + q);
287 +                                        q += 4;
288 +                                }
289 +                        }
290 +                        break;
291 +                }
292 +        printf("\n");
293 + }
294 +
295 + static void print_rom_info(void)
296 + {
297 +        printf("\nROM Info:\n");
298 +        printf("Checksum    : %08x\n", ReadMacInt32(ROMBaseMac));
299 +        printf("Version     : %04x\n", ROMVersion);
300 +        printf("Sub Version : %04x\n", ReadMacInt16(ROMBaseMac + 18));
301 +        printf("Resource Map: %08x\n", ReadMacInt32(ROMBaseMac + 26));
302 +        printf("Trap Tables : %08x\n\n", ReadMacInt32(ROMBaseMac + 34));
303 +        if (ROMVersion == ROM_VERSION_32) {
304 +                list_rom_resources();
305 +                list_universal_infos();
306 +        }
307 + }
308 +
309 +
310 + /*
311   *  Driver stubs
312   */
313  
# Line 539 | Line 705 | static const uint8 adbop_patch[] = {   //
705  
706   void InstallDrivers(uint32 pb)
707   {
708 <        D(bug("InstallDrivers\n"));
708 >        D(bug("InstallDrivers, pb %08x\n", pb));
709          M68kRegisters r;
710  
711          // Install Microseconds() replacement routine
# Line 547 | Line 713 | void InstallDrivers(uint32 pb)
713          r.d[0] = 0xa093;
714          Execute68kTrap(0xa247, &r);             // SetOSTrapAddress()
715  
716 +        // Install DebugUtil() replacement routine
717 +        r.a[0] = ROMBaseMac + debugutil_offset;
718 +        r.d[0] = 0xa08d;
719 +        Execute68kTrap(0xa247, &r);             // SetOSTrapAddress()
720 +
721          // Install disk driver
722          r.a[0] = ROMBaseMac + sony_offset + 0x100;
723          r.d[0] = (uint32)DiskRefNum;
# Line 642 | Line 813 | void InstallSERD(void)
813  
814   void PatchAfterStartup(void)
815   {
645        // 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
816   #if SUPPORTS_EXTFS
817          // Install external file system
818          InstallExtFS();
# Line 664 | Line 829 | bool CheckROM(void)
829          // Read version
830          ROMVersion = ntohs(*(uint16 *)(ROMBaseHost + 8));
831  
832 < #if REAL_ADDRESSING
833 <        // Real addressing mode requires a 32-bit clean ROM
832 > #if REAL_ADDRESSING || DIRECT_ADDRESSING
833 >        // Real and direct addressing modes require a 32-bit clean ROM
834          return ROMVersion == ROM_VERSION_32;
835   #else
836          // Virtual addressing mode works with 32-bit clean Mac II ROMs and Classic ROMs
# Line 782 | Line 947 | static bool patch_rom_classic(void)
947          *wp++ = htons(M68K_RTS);
948          microseconds_offset = (uint8 *)wp - ROMBaseHost;
949          *wp++ = htons(M68K_EMUL_OP_MICROSECONDS);
950 +        *wp++ = htons(M68K_RTS);
951 +
952 +        // Replace DebugUtil
953 +        debugutil_offset = (uint8 *)wp - ROMBaseHost;
954 +        *wp++ = htons(M68K_EMUL_OP_DEBUGUTIL);
955          *wp = htons(M68K_RTS);
956  
957          // Replace SCSIDispatch()
# Line 1044 | Line 1214 | static bool patch_rom_32(void)
1214          *wp = htons(M68K_RTS);
1215  
1216          // Fake CPU speed test (SetupTimeK)
1217 +        // *** increased jl : MacsBug uses TimeDBRA for kbd repeat timing
1218          wp = (uint16 *)(ROMBaseHost + 0x800);
1219          *wp++ = htons(0x31fc);                  // move.w       #xxx,TimeDBRA
1220 <        *wp++ = htons(100);
1220 >        *wp++ = htons(10000);
1221          *wp++ = htons(0x0d00);
1222          *wp++ = htons(0x31fc);                  // move.w       #xxx,TimeSCCDBRA
1223 <        *wp++ = htons(100);
1223 >        *wp++ = htons(10000);
1224          *wp++ = htons(0x0d02);
1225          *wp++ = htons(0x31fc);                  // move.w       #xxx,TimeSCSIDBRA
1226 <        *wp++ = htons(100);
1226 >        *wp++ = htons(10000);
1227          *wp++ = htons(0x0b24);
1228          *wp++ = htons(0x31fc);                  // move.w       #xxx,TimeRAMDBRA
1229 <        *wp++ = htons(100);
1229 >        *wp++ = htons(10000);
1230          *wp++ = htons(0x0cea);
1231          *wp = htons(M68K_RTS);
1232  
1233   #if REAL_ADDRESSING
1234          // Move system zone to start of Mac RAM
1235 <        lp = (uint32 *)(ROMBaseHost + 0x50a);
1236 <        *lp++ = htonl(RAMBaseMac);
1237 <        *lp = htonl(RAMBaseMac + 0x1800);
1235 >        wp = (uint16 *)(ROMBaseHost + 0x50a);
1236 >        *wp++ = htons(HiWord(RAMBaseMac + 0x2000));
1237 >        *wp++ = htons(LoWord(RAMBaseMac + 0x2000));
1238 >        *wp++ = htons(HiWord(RAMBaseMac + 0x3800));
1239 >        *wp = htons(LoWord(RAMBaseMac + 0x3800));
1240   #endif
1241  
1242   #if !ROM_IS_WRITE_PROTECTED
1243 < #if defined(AMIGA)
1243 > #if defined(AMIGA) || defined(USE_SCRATCHMEM_SUBTERFUGE)
1244          // Set fake handle at 0x0000 to scratch memory area (so broken Mac programs won't write into Mac ROM)
1245 <        extern uint32 ScratchMem;
1245 >        extern uint8 *ScratchMem;
1246 >        const uint32 ScratchMemBase = Host2MacAddr(ScratchMem);
1247          wp = (uint16 *)(ROMBaseHost + 0xccaa);
1248          *wp++ = htons(0x203c);                  // move.l       #ScratchMem,d0
1249 <        *wp++ = htons(ScratchMem >> 16);
1250 <        *wp = htons(ScratchMem);
1249 >        *wp++ = htons(ScratchMemBase >> 16);
1250 >        *wp = htons(ScratchMemBase);
1251   #else
1252   #error System specific handling for writable ROM is required here
1253   #endif
# Line 1085 | Line 1259 | static bool patch_rom_32(void)
1259          *wp++ = htons(M68K_NOP);
1260          *wp = htons(M68K_NOP);
1261   #endif
1262 <
1262 >        
1263 > #if REAL_ADDRESSING && !defined(AMIGA)
1264 >        // gb-- Temporary hack to get rid of crashes in Speedometer
1265 >        wp = (uint16 *)(ROMBaseHost + 0xdba2);
1266 >        if (ntohs(*wp) == 0x662c)               // bne.b        #$2c
1267 >                *wp = htons(0x602c);            // bra.b        #$2c
1268 > #endif
1269 >        
1270          // Don't write to VIA in InitTimeMgr
1271          wp = (uint16 *)(ROMBaseHost + 0xb0e2);
1272          *wp++ = htons(0x4cdf);                  // movem.l      (sp)+,d0-d5/a0-a4
# Line 1303 | Line 1484 | static bool patch_rom_32(void)
1484                  }
1485          }
1486  
1487 +        // Don't set MemoryDispatch() to unimplemented trap
1488 +        static const uint8 memdisp_dat[] = {0x30, 0x3c, 0xa8, 0x9f, 0xa7, 0x46, 0x30, 0x3c, 0xa0, 0x5c, 0xa2, 0x47};
1489 +        base = find_rom_data(0x4f100, 0x4f180, memdisp_dat, sizeof(memdisp_dat));
1490 +        D(bug("memdisp %08lx\n", base));
1491 +        if (base) {     // ROM15/22/23/26/27/32
1492 +                wp = (uint16 *)(ROMBaseHost + base + 10);
1493 +                *wp = htons(M68K_NOP);
1494 +        }
1495 +
1496          // Patch .EDisk driver (don't scan for EDisks in the area ROMBase..0xe00000)
1497 <        uint32 edisk_offset = find_rom_resource('DRVR', 51);
1497 >        uint32 edisk_offset = find_rom_resource(FOURCC('D','R','V','R'), 51);
1498          if (edisk_offset) {
1499                  static const uint8 edisk_dat[] = {0xd5, 0xfc, 0x00, 0x01, 0x00, 0x00, 0xb5, 0xfc, 0x00, 0xe0, 0x00, 0x00};
1500                  base = find_rom_data(edisk_offset, edisk_offset + 0x10000, edisk_dat, sizeof(edisk_dat));
# Line 1317 | Line 1507 | static bool patch_rom_32(void)
1507          }
1508  
1509          // Replace .Sony driver
1510 <        sony_offset = find_rom_resource('DRVR', 4);
1510 >        sony_offset = find_rom_resource(FOURCC('D','R','V','R'), 4);
1511          D(bug("sony %08lx\n", sony_offset));
1512          memcpy(ROMBaseHost + sony_offset, sony_driver, sizeof(sony_driver));
1513  
# Line 1336 | Line 1526 | static bool patch_rom_32(void)
1526          memcpy(ROMBaseHost + sony_offset + 0xa00, CDROMIcon, sizeof(CDROMIcon));
1527  
1528          // Install SERD patch and serial drivers
1529 <        serd_offset = find_rom_resource('SERD', 0);
1529 >        serd_offset = find_rom_resource(FOURCC('S','E','R','D'), 0);
1530          D(bug("serd %08lx\n", serd_offset));
1531          wp = (uint16 *)(ROMBaseHost + serd_offset + 12);
1532          *wp++ = htons(M68K_EMUL_OP_SERD);
# Line 1369 | Line 1559 | static bool patch_rom_32(void)
1559          *wp++ = htons(M68K_RTS);
1560          microseconds_offset = (uint8 *)wp - ROMBaseHost;
1561          *wp++ = htons(M68K_EMUL_OP_MICROSECONDS);
1562 +        *wp++ = htons(M68K_RTS);
1563 +
1564 +        // Replace DebugUtil
1565 +        debugutil_offset = (uint8 *)wp - ROMBaseHost;
1566 +        *wp++ = htons(M68K_EMUL_OP_DEBUGUTIL);
1567          *wp = htons(M68K_RTS);
1568  
1569          // Replace SCSIDispatch()
# Line 1404 | Line 1599 | static bool patch_rom_32(void)
1599          *wp++ = htons(base >> 16);
1600          *wp = htons(base & 0xffff);
1601  
1407        // Install MemoryDispatch() replacement routine (activated in PatchAfterStartup())
1408        memory_dispatch_offset = sony_offset + 0xc20;
1409        wp = (uint16 *)(ROMBaseHost + memory_dispatch_offset);
1410        *wp++ = htons(M68K_EMUL_OP_MEMORY_DISPATCH);
1411        *wp = htons(M68K_RTS);
1412
1602   #if EMULATED_68K
1603          // Replace BlockMove()
1604          wp = (uint16 *)(ROMBaseHost + find_rom_trap(0xa02e));   // BlockMove()
# Line 1418 | Line 1607 | static bool patch_rom_32(void)
1607          *wp = htons(M68K_RTS);
1608   #endif
1609  
1610 +        // Look for double PACK 4 resources
1611 +        if ((base = find_rom_resource(FOURCC('P','A','C','K'), 4)) == 0) return false;
1612 +        if ((base = find_rom_resource(FOURCC('P','A','C','K'), 4, true)) == 0 && FPUType == 0)
1613 +                printf("WARNING: This ROM seems to require an FPU\n");
1614 +
1615          // Patch VIA interrupt handler
1616          wp = (uint16 *)(ROMBaseHost + 0x9bc4);  // Level 1 handler
1617          *wp++ = htons(0x7002);          // moveq        #2,d0 (always 60Hz interrupt)
# Line 1435 | Line 1629 | static bool patch_rom_32(void)
1629  
1630   bool PatchROM(void)
1631   {
1632 <        // Print ROM info
1633 <        D(bug("ROM Info:\n"));
1634 <        D(bug("Checksum: %08lx\n", ReadMacInt32(ROMBaseMac)));
1441 <        D(bug("Version: %04x\n", ROMVersion));
1442 <        D(bug("Sub Version: %04x\n", ReadMacInt16(ROMBaseMac + 18)));
1632 >        // Print some information about the ROM
1633 >        if (PrintROMInfo)
1634 >                print_rom_info();
1635  
1636          // Patch ROM depending on version
1637          switch (ROMVersion) {
# Line 1455 | Line 1647 | bool PatchROM(void)
1647                          return false;
1648          }
1649  
1458 #ifdef M68K_BREAKPOINT
1650          // Install breakpoint
1651 <        uint16 *wp = (uint16 *)(ROMBaseHost + M68K_BREAKPOINT);
1652 <        *wp = htons(M68K_EMUL_BREAK);
1653 < #endif
1651 >        if (ROMBreakpoint) {
1652 >                uint16 *wp = (uint16 *)(ROMBaseHost + ROMBreakpoint);
1653 >                *wp = htons(M68K_EMUL_BREAK);
1654 >        }
1655  
1656          // Clear caches as we loaded and patched code
1657          FlushCodeCache(ROMBaseHost, ROMSize);

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines