diff --git a/machines/machinefactory.cpp b/machines/machinefactory.cpp index 28ded1b..f278470 100644 --- a/machines/machinefactory.cpp +++ b/machines/machinefactory.cpp @@ -51,23 +51,343 @@ map> gMachineSettings; /** Power Macintosh ROM identification map. - Maps Bootstrap string located at offset 0x30D064 (PCI Macs) - or 0x30C064 (Nubus Macs) to machine name and description. + Maps rom info to machine name and description. */ -static const map> rom_identity = { - {0x416C6368, {"pm6400", "Performa 6400"}}, // Alchemy - //{"Come", "PowerBook 2400"}, // Comet - {0x436F7264, {"pm5200", "Power Mac 5200/6200 series"}}, // Cordyceps - {0x47617A65, {"pm6500", "Power Mac 6500"}}, // Gazelle - {0x476F7373, {"pmg3dt", "Power Mac G3 Beige"}}, // Gossamer - {0x47525820, {"pbg3", "PowerBook G3 Wallstreet"}}, - //{"Hoop", "PowerBook 3400"}, // Hooper - {0x50425820, {"pb-preg3", "PowerBook Pre-G3"}}, - {0x50444D20, {"pm6100", "Nubus Power Mac"}}, // Piltdown Man (6100/7100/8100) - {0x50697020, {"pippin", "Bandai Pippin"}}, // Pippin - //{"Powe", "Generic Power Mac"}, // Power Mac? - {0x544E5420, {"pm7200", "Power Mac 7xxxx/8xxx series"}}, // Trinitrotoluene :-) - {0x5A616E7A, {"pm4400", "Power Mac 4400/7220"}}, // Zanzibar + +typedef struct { + uint32_t firmware_version; + uint32_t firmware_size_k; + uint32_t ow_expected_checksum; + uint32_t nw_product_id; + uint32_t nw_subconfig_expected_checksum; // checksum of the system config section but without the firmware version and date + const char *id_str; // Bootstrap string located at offset 0x30D064 (PCI Macs) or 0x30C064 (Nubus Macs) to machine name and description. + const char *nw_firmware_updater_name; + const char *nw_openfirmware_name; + const char *dppc_machine; + const char *dppc_description; + const char *rom_description; +} rom_info; + +static rom_info rom_identity[] = { + { 0x00696000, 64, 0x28ba61ce, 0, 0, nullptr , 0, 0, nullptr , nullptr , "Macintosh 128K" }, + { 0x00696000, 64, 0x28ba4e50, 0, 0, nullptr , 0, 0, nullptr , nullptr , "Macintosh 512K" }, + { 0x00756000, 128, 0x4d1eeee1, 0, 0, nullptr , 0, 0, nullptr , nullptr , "MacPlus v1" }, + { 0x00756000, 128, 0x4d1eeae1, 0, 0, nullptr , 0, 0, nullptr , nullptr , "MacPlus v2" }, + { 0x00756000, 128, 0x4d1f8172, 0, 0, nullptr , 0, 0, nullptr , nullptr , "MacPlus v3" }, + { 0x01780000, 256, 0x97221136, 0, 0, nullptr , 0, 0, nullptr , nullptr , "Mac II FDHD & IIx & IIcx" }, + { 0x01780000, 256, 0x9779d2c4, 0, 0, nullptr , 0, 0, nullptr , nullptr , "MacII (800k v2)" }, + { 0x01780000, 256, 0x97851db6, 0, 0, nullptr , 0, 0, nullptr , nullptr , "MacII (800k v1)" }, + { 0x02760000, 256, 0xb2e362a8, 0, 0, nullptr , 0, 0, nullptr , nullptr , "Mac SE" }, + { 0x02760000, 256, 0xb306e171, 0, 0, nullptr , 0, 0, nullptr , nullptr , "Mac SE FDHD" }, + { 0x02760000, 512, 0xa49f9914, 0, 0, nullptr , 0, 0, nullptr , nullptr , "Classic (with XO ROMDisk)" }, + { 0x037a0000, 256, 0x96ca3846, 0, 0, nullptr , 0, 0, nullptr , nullptr , "Mac Portable" }, + { 0x037a11f1, 256, 0x96645f9c, 0, 0, nullptr , 0, 0, nullptr , nullptr , "PowerBook 100" }, + { 0x067c10f1, 512, 0x368cadfe, 0, 0, nullptr , 0, 0, nullptr , nullptr , "Mac IIci" }, + { 0x067c11f2, 512, 0x4147dd77, 0, 0, nullptr , 0, 0, nullptr , nullptr , "Mac IIfx" }, + { 0x067c12f1, 512, 0x36b7fb6c, 0, 0, nullptr , 0, 0, nullptr , nullptr , "Mac IIsi" }, + { 0x067c13f1, 512, 0x350eacf0, 0, 0, nullptr , 0, 0, nullptr , nullptr , "Mac LC" }, + { 0x067c15f1, 1024, 0x420dbff3, 0, 0, nullptr , 0, 0, nullptr , nullptr , "Quadra 700&900 & PB140&170" }, + { 0x067c16f1, 512, 0x3193670e, 0, 0, nullptr , 0, 0, nullptr , nullptr , "Classic II" }, + { 0x067c17f2, 1024, 0x3dc27823, 0, 0, nullptr , 0, 0, nullptr , nullptr , "Quadra 950" }, + { 0x067c18f1, 1024, 0xe33b2724, 0, 0, nullptr , 0, 0, nullptr , nullptr , "Powerbook 160 & 165c & 180 & 180c" }, + { 0x067c19f2, 512, 0x35c28f5f, 0, 0, nullptr , 0, 0, nullptr , nullptr , "Mac LCII" }, + { 0x067c20f2, 1024, 0x4957eb49, 0, 0, nullptr , 0, 0, nullptr , nullptr , "MacIIvx & IIvi" }, + { 0x067c21f5, 1024, 0xecfa989b, 0, 0, nullptr , 0, 0, nullptr , nullptr , "Powerbook 210,230,250" }, + { 0x067c22f2, 1024, 0xec904829, 0, 0, nullptr , 0, 0, nullptr , nullptr , "LCIII (older)" }, + { 0x067c22f3, 1024, 0xecbbc41c, 0, 0, nullptr , 0, 0, nullptr , nullptr , "Mac LCIII" }, + { 0x067c23f1, 1024, 0xf1a6f343, 0, 0, nullptr , 0, 0, nullptr , nullptr , "Centris 610,650, Quadra 800" }, + { 0x067c23f2, 1024, 0xf1acad13, 0, 0, nullptr , 0, 0, nullptr , nullptr , "Quadra 610,650,maybe 800" }, + { 0x067c24f2, 1024, 0xecd99dc0, 0, 0, nullptr , 0, 0, nullptr , nullptr , "Color Classic" }, + { 0x067c25f1, 1024, 0xede66cbd, 0, 0, nullptr , 0, 0, nullptr , nullptr , "Color Classic II & LC 550 & Performa 275,550,560 & Macintosh TV"}, + { 0x067c26f1, 1024, 0xff7439ee, 0, 0, nullptr , 0, 0, nullptr , nullptr , "Quadra 605" }, + { 0x067c27f2, 1024, 0x0024d346, 0, 0, nullptr , 0, 0, nullptr , nullptr , "Powerbook Duo 270" }, + { 0x067c29f2, 1024, 0x015621d7, 0, 0, nullptr , 0, 0, nullptr , nullptr , "Powerbook 280&280c" }, + { 0x067c30f1, 2048, 0xb6909089, 0, 0, nullptr , 0, 0, nullptr , nullptr , "PowerBook 520&520c&540&540c" }, + { 0x067c30f2, 2048, 0xb57687a5, 0, 0, nullptr , 0, 0, nullptr , nullptr , "Pb550c" }, + { 0x067c31f1, 1024, 0xfda22562, 0, 0, nullptr , 0, 0, nullptr , nullptr , "Powerbook 150" }, + { 0x067c32f1, 1024, 0x06684214, 0, 0, nullptr , 0, 0, nullptr , nullptr , "Quadra 630" }, + { 0x067c32f2, 1024, 0x064dc91d, 0, 0, nullptr , 0, 0, nullptr , nullptr , "Performa 580 & 588" }, + { 0x077d10f3, 2048, 0x5bf10fd1, 0, 0, nullptr , 0, 0, nullptr , nullptr , "Quadra 660av & 840av" }, + + { 0x077d20f2, 4096, 0x9feb69b3, 0, 0, "Boot PDM 601 1.0", 0, 0, "pm6100" , "Nubus Power Mac" , "Power Mac 6100 & 7100 & 8100" }, // Piltdown Man + { 0x077d22f1, 4096, 0x9c7c98f7, 0, 0, "Boot PDM 601 1.0", 0, 0, "pm9150" , "Nubus Power Mac" , "Workgroup Server 9150-80" }, // Piltdown Man + { 0x077d23f1, 4096, 0x9b7a3aad, 0, 0, "Boot PDM 601 1.1", 0, 0, "pm7100" , "Nubus Power Mac" , "Power Mac 7100 (newer)" }, // Piltdown Man + { 0x077d25f1, 4096, 0x9b037f6f, 0, 0, "Boot PDM 601 1.1", 0, 0, "pm9150" , "Nubus Power Mac" , "Workgroup Server 9150-120" }, // Piltdown Man + { 0x077d26f1, 4096, 0x63abfd3f, 0, 0, "Boot Cordyceps 6", 0, 0, "pm5200" , "Power Mac 5200/6200 series" , "Power Mac & Performa 5200,5300,6200,6300" }, // Cordyceps + { 0x077d28a5, 4096, 0x67a1aa96, 0, 0, "..0.....Boot TNT", 0, 0, nullptr , nullptr , "TNT A5c1" }, + { 0x077d28f1, 4096, 0x96cd923d, 0, 0, "Boot TNT 0.1p..]", 0, 0, "pm7200" , "Power Mac 7xxxx/8xxx series", "Power Mac 7200&7500&8500&9500 v1" }, // TNT Trinitrotoluene + { 0x077d28f2, 4096, 0x9630c68b, 0, 0, "Boot TNT 0.1p..]", 0, 0, "pm7200" , "Power Mac 7xxxx/8xxx series", "Power Mac 7200&7500&8500&9500 v2, SuperMac S900" }, // TNT Trinitrotoluene + { 0x077d28f2, 4096, 0x962f6c13, 0, 0, "Boot TNT 0.1p..]", 0, 0, nullptr , "Apple Network Server series", "Apple Network Server 500" }, // TNT Trinitrotoluene // Shiner + { 0x077d29f1, 4096, 0x6f5724c0, 0, 0, "Boot Alchemy 0.1", 0, 0, "pm6400" , "Performa 6400" , "PM 5400, Performa 6400" }, // Alchemy + { 0x077d2af2, 4096, 0x83c54f75, 0, 0, "Boot PBX 603 0.0", 0, 0, "pb-preg3", "PowerBook Pre-G3" , "Powerbook 2300 & PB5x0 PPC Upgrade" }, + { 0x077d2bf1, 2048, 0x4d27039c, 0, 0, nullptr , 0, 0, nullptr , nullptr , "Powerbook 190cs" }, + { 0x077d2cc6, 4096, 0x2bf65931, 0, 0, "Boot Pip 0.1p..]", 0, 0, "pippin" , "Bandai Pippin" , "Bandai Pippin (Kinka Dev)" }, + { 0x077d2cf2, 4096, 0x2bef21b7, 0, 0, "Boot Pip 0.1p..]", 0, 0, "pippin" , "Bandai Pippin" , "Bandai Pippin (Kinka 1.0)" }, + { 0x077d2cf5, 4096, 0x3e10e14c, 0, 0, "Boot Pip 0.1p..]", 0, 0, "pippin" , "Bandai Pippin" , "Bandai Pippin (Kinka 1.2)" }, + { 0x077d2cf8, 4096, 0x3e6b3ee4, 0, 0, "Boot Pip 0.1p..]", 0, 0, "pippin" , "Bandai Pippin" , "Bandai Pippin (Kinka 1.3)" }, + { 0x077d32f3, 4096, 0x838c0831, 0, 0, "Boot PBX 603 0.0", 0, 0, "pb-preg3", "PowerBook Pre-G3" , "PowerBook 1400" }, + { 0x077d32f3, 4096, 0x83a21950, 0, 0, "Boot PBX 603 0.0", 0, 0, "pb-preg3", "PowerBook Pre-G3" , "PowerBook 1400cs" }, + { 0x077d34f2, 4096, 0x960e4be9, 0, 0, "Boot TNT 0.1p..]", 0, 0, "pm7300" , "Power Mac 7xxxx/8xxx series", "Power Mac 7300 & 7600 & 8600 & 9600 (v1)" }, // TNT Trinitrotoluene + { 0x077d34f5, 4096, 0x960fc647, 0, 0, "Boot TNT 0.1p..]", 0, 0, "pm8600" , "Power Mac 7xxxx/8xxx series", "Power Mac 8600 & 9600 (v2)" }, // TNT Trinitrotoluene + { 0x077d35f2, 4096, 0x6e92fe08, 0, 0, "Boot Gazelle 0.1", 0, 0, "pm6500" , "Power Mac 6500" , "Power Mac 6500, Twentieth Anniversary Macintosh" }, // Gazelle + { 0x077d36f1, 4096, 0x276ec1f1, 0, 0, "Boot PSX 0.1p..]", 0, 0, nullptr , nullptr , "PowerBook 2400, 2400c, 3400, 3400c" }, // Comet, Hooper + { 0x077d36f5, 4096, 0x2560f229, 0, 0, "Boot PSX 0.1p..]", 0, 0, nullptr , nullptr , "PowerBook G3 Kanga" }, + { 0x077d39b7, 4096, 0x4604518f, 0, 0, "Boot PEX 0.1p..]", 0, 0, nullptr , nullptr , "PowerExpress TriPEx" }, + { 0x077d39f1, 4096, 0x46001f1b, 0, 0, "Boot PEX 0.1p..]", 0, 0, nullptr , nullptr , "Power Express (9700 Prototype)" }, + { 0x077d3af2, 4096, 0x58f03416, 0, 0, "Boot Zanzibar 0.", 0, 0, "pm4400" , "Power Mac 4400/7220" , "Motorola 4400, 7220" }, // Zanzibar + { 0x077d40f2, 4096, 0x79d68d63, 0, 0, "Boot Gossamer 0.", 0, 0, "pmg3dt" , "Power Mac G3 Beige" , "Power Mac G3 desktop" }, // Gossamer + { 0x077d41f5, 4096, 0xcbb01212, 0, 0, "Boot GRX 0.1p..]", 0, 0, "pbg3" , "PowerBook G3 Wallstreet" , "PowerBook G3 Wallstreet" }, + { 0x077d41f6, 4096, 0xb46ffb63, 0, 0, "Boot GRX 0.1p..]", 0, 0, "pbg3" , "PowerBook G3 Wallstreet" , "PowerBook G3 Wallstreet PDQ" }, + { 0x077d45f1, 4096, 0x78fdb784, 0, 0, "Boot Gossamer 0.", 0, 0, "pmg3dt" , "Power Mac G3 Beige" , "PowerMac G3 Minitower (beige 266MHz), Beige G3 233"}, // Gossamer + { 0x077d45f2, 4096, 0x78f57389, 0, 0, "Boot Gossamer 0.", 0, 0, "pmg3dt" , "Power Mac G3 Beige" , "Power Mac G3 (v3)" }, // Gossamer + { 0x077d45f3, 4096, 0x78e842a8, 0, 0, "Boot Gossamer 0.", 0, 0, "pmg3dt" , "Power Mac G3 Beige" , "Power Mac G3 (v4)" }, // Gossamer ? + { 0x077d45f3, 4096, 0x78eb4234, 0, 0, "Boot Gossamer 0.", 0, 0, "pmg3dt" , "Power Mac G3 Beige" , "Power Mac G3 (v4)" }, // Gossamer Speedbump 9cc0e3e01bb02691b497d792ea3e9403 + + { 0x077d44f1, 4096, 0xfd86d120, 0, 0, "NewWorld v1.0.p.", 0, 0, nullptr , "NewWorld Mac" , "Mac OS ROM file 1.1" }, // 1998-07-21 - Mac OS 8.1 (iMac, Rev A Bundle) + { 0x077d44f3, 4096, 0xfd12b69e, 0, 0, "NewWorld v1.0.p.", 0, 0, nullptr , "NewWorld Mac" , "Mac OS ROM file 1.1.2" }, // 1998-08-27 - Mac OS 8.5 (Retail CD), iMac Update 1.0 + { 0x077d44f4, 4096, 0xfcaad843, 0, 0, "NewWorld v1.0.p.", 0, 0, nullptr , "NewWorld Mac" , "Mac OS ROM file 1.1.5" }, // 1998-09-19 - Mac OS 8.5 (iMac, Rev B Bundle) + { 0x077d44f1, 4096, 0xd36ba902, 0, 0, "NewWorld v1.0.p.", 0, 0, nullptr , "NewWorld Mac" , "Mac OS ROM file 1.2" }, // 1998-12-03 - Power Macintosh G3 (Blue and White) Mac OS 8.5.1 Bundle, Macintosh Server G3 (Blue and White) Mac OS 8.5.1 Bundle + { 0x077d44f1, 4096, 0xd377adb7, 0, 0, "NewWorld v1.0.p.", 0, 0, nullptr , "NewWorld Mac" , "Mac OS ROM file 1.2.1" }, // 1999-01-22 - Mac OS 8.5.1 (Colors iMac 266 MHz Bundle), iMac Update 1.1 + { 0x077d44b5, 4096, 0xc804f7f4, 0, 0, "NewWorld v1.0.p.", 0, 0, nullptr , "NewWorld Mac" , "Mac OS ROM file 1.4" }, // 1999-04-05 - Mac OS 8.6 (Retail CD), Mac OS 8.6 (Colors iMac 333 MHz Bundle), Power Macintosh G3 (Blue and White) Mac OS 8.6 Bundle + { 0x077d44b5, 4096, 0xc7cb0323, 0, 0, "NewWorld v1.0.p.", 0, 0, nullptr , "NewWorld Mac" , "Mac OS ROM file 1.6" }, // 1999-05-14 - Macintosh PowerBook G3 Series 8.6 Bundle, Mac OS ROM Update 1.0 + { 0x077d44f1, 4096, 0xc75c6aab, 0, 0, "NewWorld v1.0.p.", 0, 0, nullptr , "NewWorld Mac" , "Mac OS ROM file 1.7.1" }, // 1999-08-23 - Mac OS 8.6 bundled on Power Mac G4 (PCI) + { 0x077d44f1, 4096, 0xc753c667, 0, 0, "NewWorld v1.0.p.", 0, 0, nullptr , "NewWorld Mac" , "Mac OS ROM file 1.8.1" }, // 1999-08-28 - Mac OS 8.6 Power Mac G4 ROM 1.8.1 Update + { 0x077d45f3, 4096, 0xcde9cda4, 0, 0, "NewWorld v1.0...", 0, 0, nullptr , "NewWorld Mac" , "Mac OS ROM file 2.3.1" }, // 1999-09-13 - Mac OS 8.6 bundled on iMac (Slot Loading), iBook + { 0x077d45f3, 4096, 0xce8a3b5c, 0, 0, "NewWorld v1.0...", 0, 0, nullptr , "NewWorld Mac" , "Mac OS ROM file 2.5.1" }, // 1999-09-17 - Mac OS 8.6 bundled on Power Mac G4 (AGP) + { 0x077d45f4, 4096, 0xce1fd217, 0, 0, "NewWorld v1.0...", 0, 0, nullptr , "NewWorld Mac" , "Mac OS ROM file 3.0" }, // 1999-09-27 - Retail Mac OS 9.0 installed on Power Macintosh G3 (Blue and White), Retail Mac OS 9.0 installed on iMac, Mac OS 9.0 bundled on PowerBook G3 Bronze + { 0x077d45f5, 4096, 0xce1cf7f7, 0, 0, "NewWorld v1.0...", 0, 0, nullptr , "NewWorld Mac" , "Mac OS ROM file 3.1.1" }, // 1999-10-28 - Mac OS 9.0 bundled on iBook, Mac OS 9.0 bundled on Power Mac G4 (AGP Graphics):iMac (Slot-Loading) + { 0x077d45f6, 4096, 0xb9eb8c3d, 0, 0, "NewWorld v1.0...", 0, 0, nullptr , "NewWorld Mac" , "Mac OS ROM file 3.5" }, // 2000-01-29 - Mac OS 9.0.2 bundled on Power Mac G4 (AGP) and iBook, Mac OS 9.0.2 installed on PowerBook (FireWire) + { 0x077d45f6, 4096, 0xb8c832f3, 0, 0, "NewWorld v1.0...", 0, 0, nullptr , "NewWorld Mac" , "Mac OS ROM file 3.6" }, // 2000-02-17 - Mac OS 9.0.3 bundled with iMac (Slot Loading) + { 0x077d45f6, 4096, 0xb8b2c971, 0, 0, "NewWorld v1.0...", 0, 0, nullptr , "NewWorld Mac" , "Mac OS ROM file 3.7" }, // 2000-03-15 - 9.0.4 Retail CD + { 0x077d45f6, 4096, 0xb8bea8b3, 0, 0, "NewWorld v1.0...", 0, 0, nullptr , "NewWorld Mac" , "Mac OS ROM file 3.8" }, // 2000-05-22 - 9.0.4 Ethernet Update + { 0x077d45f6, 4096, 0xc90b6289, 0, 0, "NewWorld v1.0...", 0, 0, nullptr , "NewWorld Mac" , "Mac OS ROM file 4.6.1" }, // 2000-06-18 - Mac OS 9.04 Mac OS 9.0.4 bundled on iMac (Summer 2000), Power Mac G4 (Summer 2000) + { 0x077d45f6, 4096, 0xc92f71d3, 0, 0, "NewWorld v1.0...", 0, 0, nullptr , "NewWorld Mac" , "Mac OS ROM file 4.9.1" }, // 2000-06-28 - Mac OS 9.0.4 bundled on Power Mac G4 MP (Summer 2000) (CPU software 2.3), Power Mac G4 (Gigabit Ethernet) + { 0x077d45f6, 4096, 0xc8e1be97, 0, 0, "NewWorld v1.0...", 0, 0, nullptr , "NewWorld Mac" , "Mac OS ROM file 5.2.1" }, // 2000-07-12 - Mac OS 9.0.4 installed on Power Mac G4 Cube (CPU software 2.4) + { 0x077d45f6, 4096, 0xce2a2a5b, 0, 0, "NewWorld v1.0...", 0, 0, nullptr , "NewWorld Mac" , "Mac OS ROM file 5.3.1" }, // 2000-08-14 - Mac OS 9.0.4 bundled on iBook (Summer 2000) (CPU software 2.5) + { 0x077d45f6, 4096, 0xce1b9fd2, 0, 0, "NewWorld v1.0...", 0, 0, nullptr , "NewWorld Mac" , "Mac OS ROM file 5.5.1" }, // 2000-08-25 - Mac OS 9.0.4 from International G4 Cube Install CD + { 0x077d45f6, 4096, 0xe20aa0d0, 0, 0, "NewWorld v1.0...", 0, 0, nullptr , "NewWorld Mac" , "Mac OS ROM file 6.1" }, // 2000-11-03 - 9.1 Universal Update + { 0x077d45f6, 4096, 0xeacb3ca4, 0, 0, "NewWorld v1.0...", 0, 0, nullptr , "NewWorld Mac" , "Mac OS ROM file 6.7.1" }, // 2000-12-01 - Mac OS 9.1 installed on Power Mac G4 (Digital Audio) + { 0x077d45f6, 4096, 0xea00f1b7, 0, 0, "NewWorld v1.0...", 0, 0, nullptr , "NewWorld Mac" , "Mac OS ROM file 7.5.1" }, // 2001-02-07 - 9.1 iMac 2001 + { 0x077d45f6, 4096, 0xeece7cd0, 0, 0, "NewWorld v1.0...", 0, 0, nullptr , "NewWorld Mac" , "Mac OS ROM file 7.8.1" }, // 2001-04-10 - bundled on iBook (Dual USB) (CPU Software 3.5) + { 0x077d45f6, 4096, 0xeed28047, 0, 0, "NewWorld v1.0...", 0, 0, nullptr , "NewWorld Mac" , "Mac OS ROM file 7.9.1" }, // 2001-04-24 - Mac OS 9.1 bundled on PowerBook G4 + { 0x077d45f6, 4096, 0xee6bc7d9, 0, 0, "NewWorld v1.0...", 0, 0, nullptr , "NewWorld Mac" , "Mac OS ROM file 8.0" }, // - Mac OS 9.2 Power Mac G4 Install CD + { 0x077d45f6, 4096, 0xed7f9fc2, 0, 0, "NewWorld v1.0...", 0, 0, nullptr , "NewWorld Mac" , "Mac OS ROM file 8.3.1" }, // 2001-07-18 - Mac OS 9.2 installed on iMac (Summer 2001), Mac OS 9.2 installed on Power Mac G4 (QuickSilver) + { 0x077d45f6, 4096, 0xed26a1ef, 0, 0, "NewWorld v1.0...", 0, 0, nullptr , "NewWorld Mac" , "Mac OS ROM file 8.4" }, // 2001-07-30 - Mac OS 9.2.1 Update CD + { 0x077d45f6, 4096, 0xec849611, 0, 0, "NewWorld v1.0...", 0, 0, nullptr , "NewWorld Mac" , "Mac OS ROM file 8.6.1" }, // 2001-09-25 - Mac OS 9.2.1 bundled on iBook G3 (Late 2001) + { 0x077d45f6, 4096, 0xecc44a65, 0, 0, "NewWorld v1.0...", 0, 0, nullptr , "NewWorld Mac" , "Mac OS ROM file 8.7" }, // 2001-11-07 - Mac OS 9.2.2 Update SMI + { 0x077d45f6, 4096, 0xec96aeb6, 0, 0, "NewWorld v1.0...", 0, 0, nullptr , "NewWorld Mac" , "Mac OS ROM file 8.8" }, // 2001-11-26 - Mac OS 9.2.2 Update CD + { 0x077d45f6, 4096, 0xec93ab73, 0, 0, "NewWorld v1.0...", 0, 0, nullptr , "NewWorld Mac" , "Mac OS ROM file 8.9.1" }, // 2001-12-11 - Mac OS 9.2.2 bundled on iBook (CPU Software 4.4) + { 0x077d45f6, 4096, 0xec86128e, 0, 0, "NewWorld v1.0...", 0, 0, nullptr , "NewWorld Mac" , "Mac OS ROM file 9.0.1" }, // 2001-12-19 - Mac OS 9.2.2 bundled on iMac (2001) + { 0x077d45f6, 4096, 0xecef6af1, 0, 0, "NewWorld v1.0...", 0, 0, nullptr , "NewWorld Mac" , "Mac OS ROM file 9.1.1" }, // 2002-04-08 - Mac OS 9.2.2 bundled on iMac G4 + { 0x077d45f6, 4096, 0xecc6f29a, 0, 0, "NewWorld v1.0...", 0, 0, nullptr , "NewWorld Mac" , "Mac OS ROM file 9.2.1" }, // 2002-04-17 - Mac OS 9.2.2 bundled on eMac (CPU Software 4.9) + { 0x077d45f6, 4096, 0xecd3453f, 0, 0, "NewWorld v1.0...", 0, 0, nullptr , "NewWorld Mac" , "Mac OS ROM file 9.3.1" }, // 2002-04-18 - Mac OS 9.2.2 bundled on PowerBook G4 (CPU Software 5.0) + { 0x077d45f6, 4096, 0xecaf0460, 0, 0, "NewWorld v1.0...", 0, 0, nullptr , "NewWorld Mac" , "Mac OS ROM file 9.5.1" }, // 2002-07-18 - Mac OS 9.2.2 bundled on iMac (17" Flat Panel) (CPU Software 5.3) + { 0x077d45f6, 4096, 0xecbd9bd2, 0, 0, "NewWorld v1.0...", 0, 0, nullptr , "NewWorld Mac" , "Mac OS ROM file 9.6.1" }, // 2002-09-03 - Mac OS 9.2.2 (CPU Software 5.4) + { 0x077d45f6, 4096, 0xecb7c4f9, 0, 0, "NewWorld v1.0...", 0, 0, nullptr , "NewWorld Mac" , "Mac OS ROM file 9.7.1" }, // 2002-10-11 - Mac OS 9.2.2 bundled on PowerBook (Titanium, 1GHz) + { 0x077d45f6, 4096, 0xecb96443, 0, 0, "NewWorld v1.0...", 0, 0, nullptr , "NewWorld Mac" , "Mac OS ROM file 9.8.1" }, // 2003-01-10 - Mac OS 9.2.2 + { 0x077d45f6, 4096, 0xecb8e951, 0, 0, "NewWorld v1.0...", 0, 0, nullptr , "NewWorld Mac" , "Mac OS ROM file 10.1.1" }, // 2003-03-17 - Mac OS 9.2.2 bundled on eMac 800MHz (CPU Software 5.7) + { 0x077d45f6, 4096, 0xecb73ad5, 0, 0, "NewWorld v1.0...", 0, 0, nullptr , "NewWorld Mac" , "Mac OS ROM file 10.2.1" }, // 2003-04-03 - Mac OS 9.2.2 Retail International CD + + { 0x10f1, 1024, 0, 0, 0, 0, nullptr , nullptr , nullptr , nullptr , "PowerBook G3 Lombard" }, // PowerBook1,1 + { 0x11f4, 1024, 0, 0, 0, 0, nullptr , nullptr , "pmg3nw" , "Power Mac Yosemite" , "Power Mac B&W G3" }, // PowerMac1,1 + { 0x13f2, 1024, 0, 0, 0, 0, nullptr , nullptr , nullptr , nullptr , "iMac (233 MHz) (Bondi Blue)" }, // iMac,1 + { 0x13f3, 1024, 0, 0, 0, 0, nullptr , nullptr , nullptr , nullptr , "iMac (266,333 MHz) (Tray Loading)" }, // iMac,1 + + { 0, 1024, 0, 0x008100, 0x266f2e55, 0, "Kihei" , "P7" , nullptr , nullptr , "iMac G3 (Slot Loading)" }, // PowerMac2,1 // 2001-09-14 419f1 + { 0, 1024, 0, 0x008100, 0x55402f54, 0, "Kihei" , "P7" , nullptr , nullptr , "iMac G3 (Slot Loading)" }, // PowerMac2,1 + { 0, 1024, 0, 0x008100, 0xf88e2d56, 0, "P7" , "P7" , nullptr , nullptr , "iMac G3 (Slot Loading)" }, // PowerMac2,1 + { 0, 1024, 0, 0x008200, 0x141d2d96, 0, "P51" , "P51" , nullptr , nullptr , "iMac G3 (Summer 2000)" }, // PowerMac2,2 + { 0, 1024, 0, 0x008200, 0x41ef2e95, 0, "Perigee" , "P51" , nullptr , nullptr , "iMac G3 (Summer 2000)" }, // PowerMac2,2 + { 0, 1024, 0, 0x008201, 0x4a862e17, 0, "P51_15" , "P51" , nullptr , nullptr , "iMac G3 (Summer 2000)" }, // PowerMac2,2 + { 0, 1024, 0, 0x008201, 0x78582f16, 0, "Perigee_15" , "P51" , nullptr , nullptr , "iMac G3 (Summer 2000)" }, // PowerMac2,2 + { 0, 1024, 0, 0x010100, 0, 0, nullptr , "P52" , nullptr , nullptr , "iMac G3 (2001)" }, // PowerMac4,1 + { 0, 1024, 0, 0x010101, 0x9a7a2c2c, 0, "P52" , nullptr , nullptr , nullptr , "iMac G3 (2001)" }, // PowerMac4,1 + { 0, 1024, 0, 0x010101, 0xc84c2d2b, 0, "Apogee" , nullptr , nullptr , nullptr , "iMac G3 (2001)" }, // PowerMac4,1 + { 0, 1024, 0, 0x010200, 0xe27f2d68, 0, "Tessera" , "P80" , nullptr , nullptr , "iMac G4 (Flat Panel)" }, // PowerMac4,2 + { 0, 1024, 0, 0x010202, 0xc32928ab, 0, "P80" , nullptr , nullptr , nullptr , "iMac G4 (Flat Panel)" }, // PowerMac4,2 + { 0, 1024, 0, 0x010202, 0xe3512d6a, 0, "Insp" , nullptr , nullptr , nullptr , "iMac G4 (Flat Panel)" }, // PowerMac4,2 + { 0, 1024, 0, 0x010202, 0xfaf12da6, 0, "P80|Insp" , nullptr , nullptr , nullptr , "iMac G4 (Flat Panel)" }, // PowerMac4,2 // 2002-04-08 440f1 + { 0, 1024, 0, 0x010203, 0, 0, nullptr , "P80" , nullptr , nullptr , "iMac G4 (Flat Panel)" }, // PowerMac4,2 + { 0, 1024, 0, 0x010300, 0xe27f2d68, 0, "Infinity" , nullptr , nullptr , nullptr , nullptr }, // PowerMac4,3 + { 0, 1024, 0, 0x010400, 0xa0972cec, 0, "Beyond" , "P62" , nullptr , nullptr , "eMac G4" }, // PowerMac4,4 + { 0, 1024, 0, 0x010400, 0xa7cd2b85, 0, "P62" , "P62" , nullptr , nullptr , "eMac G4" }, // PowerMac4,4 + { 0, 1024, 0, 0x010400, 0xe72d2d73, 0, "NorthnLites" , "P62" , nullptr , nullptr , "eMac G4" }, // PowerMac4,4 + { 0, 1024, 0, 0x010401, 0, 0, nullptr , "P86" , nullptr , nullptr , "eMac G4" }, // PowerMac4,4 + { 0, 1024, 0, 0x010402, 0, 0, nullptr , "P86" , nullptr , nullptr , "eMac G4" }, // PowerMac4,4 + { 0, 1024, 0, 0x010500, 0xa90624c6, 0, "P79" , "P79" , nullptr , nullptr , "iMac G4 17 inch (Flat Panel)" }, // PowerMac4,5 + { 0, 1024, 0, 0x010500, 0xf1332daa, 0, "Taliesin" , "P79" , nullptr , nullptr , "iMac G4 17 inch (Flat Panel)" }, // PowerMac4,5 + { 0, 1024, 0, 0x010500, 0xd6d825c5, 0, "P79|Taliesin", "P79" , nullptr , nullptr , "iMac G4 17 inch (Flat Panel)" }, // PowerMac4,5 // 2002-07-23 445f3 + { 0, 1024, 0, 0x018101, 0, 0, nullptr , "Q26" , nullptr , nullptr , "iMac G4/1.0 17 inch (Flat Panel)" }, // PowerMac6,1 + { 0, 1024, 0, 0x018102, 0xcd1f2ca7, 0, "P87" , "Q26" , nullptr , nullptr , "iMac G4/1.0 17 inch (Flat Panel)" }, // PowerMac6,1 + { 0, 1024, 0, 0x018301, 0, 0, nullptr , "Q59" , nullptr , nullptr , "iMac G4/1.0 (Flat Panel - USB 2.0)" }, // PowerMac6,3 + { 0, 1024, 0, 0x018401, 0, 0, nullptr , "Q86" , nullptr , nullptr , "eMac G4 (2005)" }, // PowerMac6,4 + { 0, 1024, 0, 0x018402, 0, 0, nullptr , "Q86" , nullptr , nullptr , "eMac G4 (2005)" }, // PowerMac6,4 + { 0, 1024, 0, 0x018403, 0, 0, nullptr , "Q86" , nullptr , nullptr , "eMac G4 (2005)" }, // PowerMac6,4 + { 0, 1024, 0, 0x020101, 0xfcaf4eb7, 0, "Q45" , "Q45" , nullptr , nullptr , "iMac G5" }, // PowerMac8,1 + { 0, 1024, 0, 0x020101, 0xfd1f4eb8, 0, "Q45" , "Q45" , nullptr , nullptr , "iMac G5" }, // PowerMac8,1 + { 0, 1024, 0, 0x020102, 0, 0, nullptr , "Q45" , nullptr , nullptr , "iMac G5" }, // PowerMac8,1 + { 0, 1024, 0, 0x020109, 0x00064ebf, 0, "Q45p" , nullptr , nullptr , nullptr , "iMac G5" }, // PowerMac8,1 + { 0, 1024, 0, 0x020109, 0x00764ec0, 0, "Q45p" , nullptr , nullptr , nullptr , "iMac G5" }, // PowerMac8,1 + { 0, 1024, 0, 0x020109, 0x24372c87, 0, "Q45p" , nullptr , nullptr , nullptr , "iMac G5" }, // PowerMac8,1 + { 0, 1024, 0, 0x020109, 0x24932c8b, 0, "Q45p" , nullptr , nullptr , nullptr , "iMac G5" }, // PowerMac8,1 + { 0, 1024, 0, 0x020201, 0, 0, nullptr , "Q45C" , nullptr , nullptr , "iMac G5 (Ambient Light Sensor)" }, // PowerMac8,2 + { 0, 1024, 0, 0x020f01, 0x20ef2c7f, 0, "Q45xa" , nullptr , nullptr , nullptr , nullptr }, // PowerMac8,15 + { 0, 1024, 0, 0x020f01, 0x214b2c83, 0, "Q45xa" , nullptr , nullptr , nullptr , nullptr }, // PowerMac8,15 + { 0, 1024, 0, 0x020f01, 0xeace56ae, 0, "Neoa" , nullptr , nullptr , nullptr , nullptr }, // PowerMac8,15 + { 0, 1024, 0, 0x020f02, 0x21582c80, 0, "Q45xb" , nullptr , nullptr , nullptr , nullptr }, // PowerMac8,15 + { 0, 1024, 0, 0x020f02, 0x21b42c84, 0, "Q45xb" , nullptr , nullptr , nullptr , nullptr }, // PowerMac8,15 + { 0, 1024, 0, 0x020f02, 0xf92756d2, 0, "Neob" , nullptr , nullptr , nullptr , nullptr }, // PowerMac8,15 + { 0, 1024, 0, 0x020f03, 0x21c12c81, 0, "Q45xc" , nullptr , nullptr , nullptr , nullptr }, // PowerMac8,15 + { 0, 1024, 0, 0x020f03, 0x221d2c85, 0, "Q45xc" , nullptr , nullptr , nullptr , nullptr }, // PowerMac8,15 + { 0, 1024, 0, 0x020f03, 0x9e7f55ef, 0, "Neoc" , nullptr , nullptr , nullptr , nullptr }, // PowerMac8,15 + { 0, 1024, 0, 0x028101, 0xf4dc2533, 0, nullptr , "Q88" , nullptr , nullptr , "Mac mini G4" }, // PowerMac10,1 // 2005-03-23 489f4 + { 0, 1024, 0, 0x028201, 0xf4dc2533, 0, nullptr , "Q88" , nullptr , nullptr , "Mac mini G4 1.5GHz Radeon 9200" }, // PowerMac10,2 // 2005-07-12 494f1 + { 0, 1024, 0, 0x030101, 0, 0, nullptr , "M23" , nullptr , nullptr , "iMac G5 (iSight)" }, // PowerMac12,1 + { 0, 1024, 0, 0x108100, 0x71fd2fc9, 0, "P1" , "P1" , nullptr , nullptr , "iBook G3 (Original/Clamshell)" }, // PowerBook2,1 + { 0, 1024, 0, 0x108100, 0x9fcf30c8, 0, "P1" , "P1" , nullptr , nullptr , "iBook G3 (Original/Clamshell)" }, // PowerBook2,1 + { 0, 1024, 0, 0x108100, 0xcea031c7, 0, "P1" , "P1" , nullptr , nullptr , "iBook G3 (Original/Clamshell)" }, // PowerBook2,1 + { 0, 1024, 0, 0x108101, 0x72902fcb, 0, "P1_05" , "P1" , nullptr , nullptr , "iBook G3 (Original/Clamshell)" }, // PowerBook2,1 + { 0, 1024, 0, 0x108101, 0xa06230ca, 0, "P1_05" , "P1" , nullptr , nullptr , "iBook G3 (Original/Clamshell)" }, // PowerBook2,1 // 2001-03-20 417f4 + { 0, 1024, 0, 0x108101, 0xcf3331c9, 0, "P1_05" , "P1" , nullptr , nullptr , "iBook G3 (Original/Clamshell)" }, // PowerBook2,1 + { 0, 1024, 0, 0x108102, 0x7de22ffd, 0, "P1_1" , "P1" , nullptr , nullptr , "iBook G3 (Original/Clamshell)" }, // PowerBook2,1 + { 0, 1024, 0, 0x108102, 0xabb430fc, 0, "P1_1" , "P1" , nullptr , nullptr , "iBook G3 (Original/Clamshell)" }, // PowerBook2,1 + { 0, 1024, 0, 0x108102, 0xda8531fb, 0, "P1_1" , "P1" , nullptr , nullptr , "iBook G3 (Original/Clamshell)" }, // PowerBook2,1 + { 0, 1024, 0, 0x108200, 0x7bdc2fd9, 0, "P1_5" , "P1_5" , nullptr , nullptr , "iBook G3 366 MHz CD (Firewire/Clamshell)" }, // PowerBook2,2 + { 0, 1024, 0, 0x108200, 0xa9ae30d8, 0, "Midway" , "P1_5" , nullptr , nullptr , "iBook G3 366 MHz CD (Firewire/Clamshell)" }, // PowerBook2,2 + { 0, 1024, 0, 0x108201, 0x9745301a, 0, "P1_5DVD" , "P1_5" , nullptr , nullptr , "iBook G3 466 MHz DVD (Firewire/Clamshell)" }, // PowerBook2,2 + { 0, 1024, 0, 0x108201, 0xc5173119, 0, "MidwayDVD" , "P1_5" , nullptr , nullptr , "iBook G3 466 MHz DVD (Firewire/Clamshell)" }, // PowerBook2,2 + { 0, 1024, 0, 0x110100, 0x5f1c2fe5, 0, "Marble" , "P29" , nullptr , nullptr , "iBook G3 (Dual USB Snow)" }, // PowerBook4,1 + { 0, 1024, 0, 0x110100, 0x69e42f6e, 0, "P29" , "P29" , nullptr , nullptr , "iBook G3 (Dual USB Snow)" }, // PowerBook4,1 + { 0, 1024, 0, 0x110100, 0x97b6306d, 0, "Marble" , "P29" , nullptr , nullptr , "iBook G3 (Dual USB Snow)" }, // PowerBook4,1 + { 0, 1024, 0, 0x110101, 0x44852fa6, 0, "MarbleLite" , nullptr , nullptr , nullptr , "iBook G3 (Dual USB Snow)" }, // PowerBook4,1 + { 0, 1024, 0, 0x110102, 0x60192fe8, 0, "MarbleFat" , "P29" , nullptr , nullptr , "iBook G3 (Dual USB Snow)" }, // PowerBook4,1 + { 0, 1024, 0, 0x110102, 0x6b1d2f73, 0, "P29Fat" , "P29" , nullptr , nullptr , "iBook G3 (Dual USB Snow)" }, // PowerBook4,1 + { 0, 1024, 0, 0x110102, 0x98ef3072, 0, "MarbleFat" , "P29" , nullptr , nullptr , "iBook G3 (Dual USB Snow)" }, // PowerBook4,1 + { 0, 1024, 0, 0x110103, 0x58762f44, 0, "P29fat100" , "P29" , nullptr , nullptr , "iBook G3 (Dual USB Snow)" }, // PowerBook4,1 + { 0, 1024, 0, 0x110103, 0x86483043, 0, "Mrblfat100" , "P29" , nullptr , nullptr , "iBook G3 (Dual USB Snow)" }, // PowerBook4,1 + { 0, 1024, 0, 0x110200, 0x4c372fb6, 0, "Diesel" , "P54" , nullptr , nullptr , "iBook G3/600 14-Inch (Early 2002 Snow)" }, // PowerBook4,2 + { 0, 1024, 0, 0x110200, 0x573b2f41, 0, "P54" , "P54" , nullptr , nullptr , "iBook G3/600 14-Inch (Early 2002 Snow)" }, // PowerBook4,2 + { 0, 1024, 0, 0x110300, 0x58e12d5c, 0, "P72" , "P72" , nullptr , nullptr , "iBook G3 (Snow)" }, // PowerBook4,3 // 2002-11-11 454f1 + { 0, 1024, 0, 0x110300, 0xb98a30be, 0, "Nectr" , "P72" , nullptr , nullptr , "iBook G3 (Snow)" }, // PowerBook4,3 + { 0, 1024, 0, 0x110301, 0x594a2d5d, 0, "P73" , "P73" , nullptr , nullptr , "iBook G3 (Snow)" }, // PowerBook4,3 + { 0, 1024, 0, 0x110302, 0x59b32d5e, 0, "P72x" , "P73" , nullptr , nullptr , "iBook G3 (Snow)" }, // PowerBook4,3 // 2003-03-15 464f1 + { 0, 1024, 0, 0x110302, 0x3eb82d1d, 0, "P72x" , "P73" , nullptr , nullptr , "iBook G3 (Snow)" }, // PowerBook4,3 + { 0, 1024, 0, 0x110303, 0x3f212d1e, 0, "P73x" , "P73" , nullptr , nullptr , "iBook G3 (Snow)" }, // PowerBook4,3 + { 0, 1024, 0, 0x118101, 0, 0, nullptr , "P99" , nullptr , nullptr , "PowerBook G4 (Aluminum)" }, // PowerBook6,1 + { 0, 1024, 0, 0x118202, 0, 0, nullptr , "Q54" , nullptr , nullptr , "PowerBook G4 1.0 12 inch (DVI - Aluminum)" }, // PowerBook6,2 + { 0, 1024, 0, 0x118302, 0, 0, nullptr , "P72D" , nullptr , nullptr , "iBook G4 (Original - Opaque)" }, // PowerBook6,3 + { 0, 1024, 0, 0x11830c, 0, 0, nullptr , "P73D" , nullptr , nullptr , "iBook G4 (Original - Opaque)" }, // PowerBook6,3 + { 0, 1024, 0, 0x118402, 0, 0, nullptr , "Q54A" , nullptr , nullptr , "PowerBook G4 1.33 12 inch (Aluminum)" }, // PowerBook6,4 + { 0, 1024, 0, 0x118502, 0x033929a6, 0, nullptr , "Q72" , nullptr , nullptr , "iBook G4 (Early 2004)" }, // PowerBook6,5 // 2004-04-06 485f0 + { 0, 1024, 0, 0x118504, 0, 0, nullptr , "Q72A" , nullptr , nullptr , "iBook G4" }, // PowerBook6,5 + { 0, 1024, 0, 0x118509, 0, 0, nullptr , "Q73" , nullptr , nullptr , "iBook G4" }, // PowerBook6,5 + { 0, 1024, 0, 0x11850b, 0x067f29b0, 0, nullptr , "Q73A" , nullptr , nullptr , "iBook G4" }, // PowerBook6,5 // 2004-09-23 487f1 + { 0, 1024, 0, 0x118603, 0, 0, nullptr , "U210" , nullptr , nullptr , nullptr }, // PowerBook6,6 + { 0, 1024, 0, 0x118701, 0, 0, nullptr , "Q72B" , nullptr , nullptr , "iBook G4 12-Inch (Mid-2005 - Opaque)" }, // PowerBook6,7 + { 0, 1024, 0, 0x118709, 0, 0, nullptr , "Q73B" , nullptr , nullptr , "iBook G4 12-Inch (Mid-2005 - Opaque)" }, // PowerBook6,7 + { 0, 1024, 0, 0x11870c, 0, 0, nullptr , "Q73B-Best", nullptr , nullptr , "iBook G4 12-Inch (Mid-2005 - Opaque)" }, // PowerBook6,7 + { 0, 1024, 0, 0x118801, 0, 0, nullptr , "Q54B" , nullptr , nullptr , "PowerBook G4 1.5 12 inch (Aluminum)" }, // PowerBook6,8 + { 0, 1024, 0, 0x20c100, 0x85e72bd1, 0, "P5" , "P5" , nullptr , nullptr , "Power Mac G4 (AGP Graphics) Sawtooth" }, // PowerMac3,1 + { 0, 1024, 0, 0x20c100, 0xb3b92cd0, 0, "Sawtooth" , "P5" , nullptr , nullptr , "Power Mac G4 (AGP Graphics) Sawtooth" }, // PowerMac3,1 + { 0, 1024, 0, 0x20c100, 0xe28a2dcf, 0, "Sawtooth" , "P5" , nullptr , nullptr , "Power Mac G4 (AGP Graphics) Sawtooth" }, // PowerMac3,1 + { 0, 1024, 0, 0x20c101, 0x8d142cda, 0, "Mystic" , "P5" , nullptr , nullptr , "Power Mac G4 (AGP Graphics) Sawtooth" }, // PowerMac3,1 // 2000-02-17 324f1 + { 0, 1024, 0, 0x20c101, 0x5e432bdb, 0, "Mystic" , "P5" , nullptr , nullptr , "Power Mac G4 (AGP Graphics) Sawtooth" }, // PowerMac3,1 // 2001-10-11 428f1 + { 0, 1024, 0, 0x20c101, 0x30712adc, 0, "P10" , "P5" , nullptr , nullptr , "Power Mac G4 (AGP Graphics) Sawtooth" }, // PowerMac3,1 + { 0, 1024, 0, 0x20c300, 0x66752b5c, 0, "P15" , "P5" , nullptr , nullptr , "Power Macintosh Mac G4 (Gigabit)" }, // PowerMac3,3 + { 0, 1024, 0, 0x20c300, 0x94472c5b, 0, "Clockwork" , "P5" , nullptr , nullptr , "Power Macintosh Mac G4 (Gigabit)" }, // PowerMac3,3 + { 0, 1024, 0, 0x20c400, 0x47fe2da3, 0, "P21" , "P21" , nullptr , nullptr , "Power Mac G4 (Digital Audio)" }, // PowerMac3,4 + { 0, 1024, 0, 0x20c400, 0x75d02ea2, 0, "Tangent" , "P21" , nullptr , nullptr , "Power Mac G4 (Digital Audio)" }, // PowerMac3,4 // 2001-10-11 428f1 + { 0, 1024, 0, 0x20c400, 0x6ea22e91, 0, "P21|Tangent" , "P21" , nullptr , nullptr , "Power Mac G4 (Digital Audio)" }, // PowerMac3,4 // 2000-12-04 410f1 + { 0, 1024, 0, 0x20c500, 0x4b5e2dab, 0, "P57" , "P57" , nullptr , nullptr , "Power Mac G4 Quicksilver" }, // PowerMac3,5 + { 0, 1024, 0, 0x20c500, 0x75d02ea2, 0, "NiChrome" , "P57" , nullptr , nullptr , "Power Mac G4 Quicksilver" }, // PowerMac3,5 + { 0, 1024, 0, 0x20c500, 0x79302eaa, 0, "NiChrome" , "P57" , nullptr , nullptr , "Power Mac G4 Quicksilver" }, // PowerMac3,5 // 2001-08-16 425f1 + { 0, 1024, 0, 0x20c600, 0x6e5a2d67, 0, "P58_133" , "P58" , nullptr , nullptr , "Power Mac G4 (Mirrored Drive Doors)" }, // PowerMac3,6 // 2002-09-30 448f2 + { 0, 1024, 0, 0x20c600, 0x79302eaa, 0, "Moj" , "P58" , nullptr , nullptr , "Power Mac G4 (Mirrored Drive Doors)" }, // PowerMac3,6 + { 0, 1024, 0, 0x20c601, 0x20df2ca4, 0, "P58_167" , "P58" , nullptr , nullptr , "Power Mac G4 (Mirrored Drive Doors)" }, // PowerMac3,6 + { 0, 1024, 0, 0x20c602, 0x6f2c2d69, 0, nullptr , "P58" , nullptr , nullptr , "Power Mac G4 (FW 800)" }, // PowerMac3,6 // 2003-01-15 457f1 + { 0, 1024, 0, 0x20c603, 0x21b12ca6, 0, nullptr , "P58" , nullptr , nullptr , "Power Mac G4 (FW 800)" }, // PowerMac3,6 // 2003-02-20 460f1 + { 0, 1024, 0, 0x214100, 0x4af52b1c, 0, "P9" , "P9" , nullptr , nullptr , "Power Mac G4 Cube" }, // PowerMac5,1 + { 0, 1024, 0, 0x214100, 0x78c72c1b, 0, "Trinity" , "P9" , nullptr , nullptr , "Power Mac G4 Cube" }, // PowerMac5,1 // 2000-07-10 332f1 // 2001-09-14 419f1 + { 0, 1024, 0, 0x214100, 0x78c72c1b, 0, "Kubrick" , "P9" , nullptr , nullptr , "Power Mac G4 Cube" }, // PowerMac5,1 // 2000-07-10 332f1 // 2001-09-14 419f1 + { 0, 1024, 0, 0x214100, 0x8cab2cd9, 0, "Kubrick" , "P9" , nullptr , nullptr , "Power Mac G4 Cube" }, // PowerMac5,1 + { 0, 1024, 0, 0x21c200, 0x25142c89, 0, "Q37high" , "Q37" , nullptr , nullptr , "Power Mac G5 1.6 (PCI)" }, // PowerMac7,2 + { 0, 1024, 0, 0x21c200, 0x25702c8d, 0, "Q37high" , "Q37" , nullptr , nullptr , "Power Mac G5 1.6 (PCI)" }, // PowerMac7,2 + { 0, 1024, 0, 0x21c200, 0xa5b7555f, 0, "Q37high" , "Q37" , nullptr , nullptr , "Power Mac G5 1.6 (PCI)" }, // PowerMac7,2 + { 0, 1024, 0, 0x21c201, 0x336d2cad, 0, "Q37med" , "Q37" , nullptr , nullptr , "Power Mac G5 1.6 (PCI)" }, // PowerMac7,2 + { 0, 1024, 0, 0x21c201, 0x33c92cb1, 0, "Q37med" , "Q37" , nullptr , nullptr , "Power Mac G5 1.6 (PCI)" }, // PowerMac7,2 + { 0, 1024, 0, 0x21c201, 0x514d2dbb, 0, "P76" , "Q37" , nullptr , nullptr , "Power Mac G5 1.6 (PCI)" }, // PowerMac7,2 + { 0, 1024, 0, 0x21c201, 0xb4105583, 0, "Q37med" , "Q37" , nullptr , nullptr , "Power Mac G5 1.6 (PCI)" }, // PowerMac7,2 + { 0, 1024, 0, 0x21c202, 0x596854a0, 0, "Q37low" , "Q37low" , nullptr , nullptr , "Power Mac G5 1.6 (PCI)" }, // PowerMac7,2 + { 0, 1024, 0, 0x21c202, 0xd8c62bca, 0, "Q37low" , "Q37low" , nullptr , nullptr , "Power Mac G5 1.6 (PCI)" }, // PowerMac7,2 // 2004-09-21 515f2 + { 0, 1024, 0, 0x21c203, 0x343f2caf, 0, "Q37A" , "Q37low" , nullptr , nullptr , "Power Mac G5 1.6 (PCI)" }, // PowerMac7,2 + { 0, 1024, 0, 0x21c203, 0x349b2cb3, 0, "Q37A" , "Q37low" , nullptr , nullptr , "Power Mac G5 1.6 (PCI)" }, // PowerMac7,2 + { 0, 1024, 0, 0x21c203, 0xb4e25585, 0, "Q37A" , "Q37low" , nullptr , nullptr , "Power Mac G5 1.6 (PCI)" }, // PowerMac7,2 + { 0, 1024, 0, 0x21c204, 0xa8955568, 0, "Q37C" , "Q77hi" , nullptr , nullptr , "Power Mac G5 1.6 (PCI)" }, // PowerMac7,2 + { 0, 1024, 0, 0x21c204, 0xa930556d, 0, "Q37C" , "Q77hi" , nullptr , nullptr , "Power Mac G5 1.6 (PCI)" }, // PowerMac7,2 + { 0, 1024, 0, 0x21c301, 0xb6cf558d, 0, "Q77best" , "Q77hi" , nullptr , nullptr , "Power Macintosh G5 Dual Processor" }, // PowerMac7,3 + { 0, 1024, 0, 0x21c301, 0xb76a5592, 0, "Q77best" , "Q77hi" , nullptr , nullptr , "Power Macintosh G5 Dual Processor" }, // PowerMac7,3 + { 0, 1024, 0, 0x21c302, 0xa7635563, 0, "Q77mid" , "Q77" , nullptr , nullptr , "Power Macintosh G5 Dual Processor" }, // PowerMac7,3 + { 0, 1024, 0, 0x21c303, 0xb5bc5587, 0, "Q77good" , "Q77good" , nullptr , nullptr , "Power Macintosh G5 Dual Processor" }, // PowerMac7,3 + { 0, 1024, 0, 0x21c304, 0xb80a5590, 0, "Q77better" , "Q77better", nullptr , nullptr , "Power Macintosh G5 Dual Processor" }, // PowerMac7,3 + { 0, 1024, 0, 0x21c304, 0xb8a55595, 0, "Q77better" , "Q77better", nullptr , nullptr , "Power Macintosh G5 Dual Processor" }, // PowerMac7,3 + { 0, 1024, 0, 0x21c305, 0, 0, nullptr , "M18wl" , nullptr , nullptr , "Power Macintosh G5 Dual Processor" }, // PowerMac7,3 + { 0, 1024, 0, 0x21c306, 0, 0, nullptr , "Q87good" , nullptr , nullptr , "Power Macintosh G5 Dual Processor" }, // PowerMac7,3 + { 0, 1024, 0, 0x21c307, 0, 0, nullptr , "Q77better", nullptr , nullptr , "Power Macintosh G5 Dual Processor" }, // PowerMac7,3 + { 0, 1024, 0, 0x21c308, 0, 0, nullptr , "Q77hi" , nullptr , nullptr , "Power Macintosh G5 Dual Processor" }, // PowerMac7,3 + { 0, 1024, 0, 0x224102, 0, 0, nullptr , "Q78" , nullptr , nullptr , "Power Macintosh G5 1.8 (PCI)" }, // PowerMac9,1 + { 0, 1024, 0, 0x224108, 0x84d94d6f, 0, "Q78EVT" , nullptr , nullptr , nullptr , "Power Macintosh G5 1.8 (PCI)" }, // PowerMac9,1 + { 0, 1024, 0, 0x224109, 0x82b74d9f, 0, "Q78p" , nullptr , nullptr , nullptr , "Power Macintosh G5 1.8 (PCI)" }, // PowerMac9,1 + { 0, 1024, 0, 0x224109, 0x86774da9, 0, "Q78p" , nullptr , nullptr , nullptr , "Power Macintosh G5 1.8 (PCI)" }, // PowerMac9,1 + { 0, 1024, 0, 0x22c101, 0, 0, nullptr , "M18" , nullptr , nullptr , nullptr }, // PowerMac11,1 + { 0, 1024, 0, 0x22c102, 0, 0, nullptr , "M20wl" , nullptr , nullptr , nullptr }, // PowerMac11,1 + { 0, 1024, 0, 0x22c201, 0, 0, nullptr , "Q63Proto" , nullptr , nullptr , "Power Mac G5 Quad Core Proto" }, // PowerMac11,2 + { 0, 1024, 0, 0x22c202, 0xb7fe51fc, 0, nullptr , "Q63" , nullptr , nullptr , "Power Mac G5 Quad Core" }, // PowerMac11,2 // 2005-09-30 527f1 + { 0, 1024, 0, 0x30c100, 0x0c653168, 0, "P8" , "P8" , nullptr , nullptr , "PowerBook G3 (FireWire) Pismo" }, // PowerBook3,1 + { 0, 1024, 0, 0x30c100, 0x3a373267, 0, "Pismo" , "P8" , nullptr , nullptr , "PowerBook G3 (FireWire) Pismo" }, // PowerBook3,1 // 2001-03-21 418f5 + { 0, 1024, 0, 0x30c100, 0x69083366, 0, "Pismo" , "P8" , nullptr , nullptr , "PowerBook G3 (FireWire) Pismo" }, // PowerBook3,1 + { 0, 1024, 0, 0x30c1ff, 0xcb8e3457, 0, "Pismo66" , nullptr , nullptr , nullptr , "PowerBook G3 (FireWire) Pismo" }, // PowerBook3,1 + { 0, 1024, 0, 0x30c200, 0, 0, nullptr , "P12" , nullptr , nullptr , "PowerBook G4 (Original - Titanium)" }, // PowerBook3,2 + { 0, 1024, 0, 0x30c201, 0x33b22dc6, 0, "P12" , "P12" , nullptr , nullptr , "PowerBook G4 (Original - Titanium)" }, // PowerBook3,2 + { 0, 1024, 0, 0x30c201, 0x61842ec5, 0, "Mercury" , "P12" , nullptr , nullptr , "PowerBook G4 (Original - Titanium)" }, // PowerBook3,2 + { 0, 1024, 0, 0x30c300, 0x3e4f2dd5, 0, "P25_100" , "P25" , nullptr , nullptr , "PowerBook G4 (Gigabit - Titanium)" }, // PowerBook3,3 + { 0, 1024, 0, 0x30c300, 0x63762eca, 0, "Onyx" , "P25" , nullptr , nullptr , "PowerBook G4 (Gigabit - Titanium)" }, // PowerBook3,3 + { 0, 1024, 0, 0x30c300, 0x6c212ed4, 0, "Onix100" , "P25" , nullptr , nullptr , "PowerBook G4 (Gigabit - Titanium)" }, // PowerBook3,3 + { 0, 1024, 0, 0x30c301, 0x4c2b2df8, 0, "P25" , "P25" , nullptr , nullptr , "PowerBook G4 (Gigabit - Titanium)" }, // PowerBook3,3 + { 0, 1024, 0, 0x30c301, 0x79fd2ef7, 0, "Onix" , "P25" , nullptr , nullptr , "PowerBook G4 (Gigabit - Titanium)" }, // PowerBook3,3 + { 0, 1024, 0, 0x30c302, 0x7e6c2f0a, 0, "OnixStar" , nullptr , nullptr , nullptr , "PowerBook G4 (Gigabit - Titanium)" }, // PowerBook3,3 + { 0, 1024, 0, 0x30c400, 0x7a002ef7, 0, "Ivry" , "P59" , nullptr , nullptr , "PowerBook G4 (DVI - Titanium)" }, // PowerBook3,4 + { 0, 1024, 0, 0x30c400, 0x91952f11, 0, "P59_667" , "P59" , nullptr , nullptr , "PowerBook G4 (DVI - Titanium)" }, // PowerBook3,4 + { 0, 1024, 0, 0x30c402, 0x92672f13, 0, "P59_800" , nullptr , nullptr , nullptr , "PowerBook G4 (DVI - Titanium)" }, // PowerBook3,4 + { 0, 1024, 0, 0x30c403, 0x92d02f14, 0, "P59_DVT" , nullptr , nullptr , nullptr , "PowerBook G4 (DVI - Titanium)" }, // PowerBook3,4 + { 0, 1024, 0, 0x30c404, 0x93392f15, 0, "P59_DualFan" , "P59DF" , nullptr , nullptr , "PowerBook G4 (DVI - Titanium)" }, // PowerBook3,4 + { 0, 1024, 0, 0x30c500, 0, 0, nullptr , "P88" , nullptr , nullptr , "PowerBook G4 (Titanum)" }, // PowerBook3,5 + { 0, 1024, 0, 0x30c501, 0, 0, nullptr , "P881G" , nullptr , nullptr , "PowerBook G4 (Titanum)" }, // PowerBook3,5 + { 0, 1024, 0, 0x314100, 0x6ece5388, 0, "P84i" , nullptr , nullptr , nullptr , "PowerBook G4 1.0 17 inch (Aluminum)" }, // PowerBook5,1 + { 0, 1024, 0, 0x314103, 0x5c13264b, 0, nullptr , "P84" , nullptr , nullptr , "PowerBook G4 1.0 17 inch (Aluminum)" }, // PowerBook5,1 // 2003-02-18 462f1 + { 0, 1024, 0, 0x314202, 0, 0, nullptr , "Q16-EVT" , nullptr , nullptr , "PowerBook G4 15 inch (FW 800 - Aluminum)" }, // PowerBook5,2 + { 0, 1024, 0, 0x314301, 0, 0, nullptr , "Q41" , nullptr , nullptr , "PowerBook G4 1.33 17 inch (Aluminum)" }, // PowerBook5,3 + { 0, 1024, 0, 0x314401, 0, 0, nullptr , "Q16A" , nullptr , nullptr , "PowerBook G4 15 inch (Aluminum)" }, // PowerBook5,4 + { 0, 1024, 0, 0x314501, 0, 0, nullptr , "Q41A" , nullptr , nullptr , "PowerBook G4 1.5 17 inch (Aluminum)" }, // PowerBook5,5 + { 0, 1024, 0, 0x314601, 0, 0, nullptr , "Q16B" , nullptr , nullptr , "PowerBook G4 15 inch (Aluminum)" }, // PowerBook5,6 + { 0, 1024, 0, 0x314701, 0, 0, nullptr , "Q41B" , nullptr , nullptr , "PowerBook G4 1.67 17 inch (Aluminum)" }, // PowerBook5,7 + { 0, 1024, 0, 0x314801, 0x35c72568, 0, nullptr , "Q16C" , nullptr , nullptr , "PowerBook G4 DLSD" }, // PowerBook5,8 // 2005-09-22 495f3 + { 0, 1024, 0, 0x314801, 0, 0, nullptr , "Q41C" , nullptr , nullptr , "PowerBook G4 DLSD" }, // PowerBook5,8 + { 0, 1024, 0, 0x314802, 0, 0, nullptr , "Q16CBest" , nullptr , nullptr , "PowerBook G4 DLSD" }, // PowerBook5,8 + { 0, 1024, 0, 0x314901, 0x35c72568, 0, nullptr , "Q41C" , nullptr , nullptr , "PowerBook G4 1.67 17 inch (DLSD/HiRes - Aluminum)" }, // PowerBook5,9 // 2005-10-05 496f0 + { 0, 1024, 0, 0x318100, 0x6ca8272f, 0, "P99" , nullptr , nullptr , nullptr , "PowerBook G4 867 12 inch (Aluminum)" }, // PowerBook6,1 + { 0, 1024, 0, 0x31c101, 0xbb11558a, 0, "Q51p" , "Q51" , nullptr , nullptr , nullptr }, // PowerBook7,1 + { 0, 1024, 0, 0x31c101, 0xbc5d558d, 0, "Q51p" , "Q51" , nullptr , nullptr , nullptr }, // PowerBook7,1 + { 0, 1024, 0, 0x31c201, 0xbb11558a, 0, "Q43p" , "Q43" , nullptr , nullptr , nullptr }, // PowerBook7,2 + { 0, 1024, 0, 0x31c201, 0xbc5d558d, 0, "Q43p" , "Q43" , nullptr , nullptr , nullptr }, // PowerBook7,2 + { 0, 1024, 0, 0x380101, 0, 0, nullptr , "T3" , nullptr , nullptr , nullptr }, // PowerBook32,1 + { 0, 1024, 0, 0x380201, 0, 0, nullptr , "M22" , nullptr , nullptr , nullptr }, // PowerBook32,2 + { 0, 1024, 0, 0x404100, 0x268f2cab, 0, "P69" , "P69" , nullptr , nullptr , "Xserve G4 1.0 GHz" }, // RackMac1,1 + { 0, 1024, 0, 0x404200, 0, 0, nullptr , "Q28" , nullptr , nullptr , "Xserve G4 1.33 GHz (Slot Load)" }, // RackMac1,2 // 465f3 + { 0, 1024, 0, 0x40c100, 0xc2f855a9, 0, "Q42" , "Q42" , nullptr , nullptr , "Xserve G5 (PCI-X)" }, // RackMac3,1 + { 0, 1024, 0, 0x40c101, 0xc28755a8, 0, "Q42B" , "Q42" , nullptr , nullptr , "Xserve G5 (PCI-X)" }, // RackMac3,1 + { 0, 1024, 0, 0x414101, 0, 0, nullptr , "Q42C" , nullptr , nullptr , nullptr }, // RackMac5,1 + + { 0 } }; static const map PropHelp = { @@ -119,6 +439,26 @@ static const map PropHelp = { {"adb_devices", "specifies which ADB device(s) to attach"}, }; +static uint32_t adler32(char *buf, size_t len) { + uint32_t sum1 = 1; + uint32_t sum2 = 0; + while (len--) { + sum1 = (sum1 + *(uint8_t*)buf++) % 65521; + sum2 = (sum2 + sum1) % 65521; + } + return sum1 + 65536 * sum2; +} + +static uint32_t oldworldchecksum(char *buf, size_t len) { + uint32_t ck = 0; + while (len) { + ck += READ_WORD_BE_A(buf); + buf += 2; + len -= 2; + } + return ck; +} + bool MachineFactory::add(const string& machine_id, MachineDescription desc) { if (get_registry().find(machine_id) != get_registry().end()) { @@ -310,120 +650,315 @@ void MachineFactory::register_settings(const PropMap& props) { } -string MachineFactory::machine_name_from_rom(string& rom_filepath) { +size_t MachineFactory::read_boot_rom(string& rom_filepath, char *rom_data) +{ ifstream rom_file; size_t file_size; - uint32_t config_info_offset, rom_id; - char rom_id_str[17]; - - string machine_name = ""; rom_file.open(rom_filepath, ios::in | ios::binary); if (rom_file.fail()) { LOG_F(ERROR, "Could not open the specified ROM file."); + file_size = 0; goto bail_out; } rom_file.seekg(0, rom_file.end); file_size = rom_file.tellg(); - rom_file.seekg(0, rom_file.beg); - - if (file_size != 0x400000UL) { - LOG_F(ERROR, "Unxpected ROM File size. Expected size is 4 megabytes."); + if (file_size < 64 * 1024 || file_size > 4 * 1024 * 1024) { + LOG_F(ERROR, "Unexpected ROM file size: %zu bytes. Expected size is 1 or 4 megabytes.", file_size); + file_size = 0; goto bail_out; } - /* read config info offset from file */ - config_info_offset = 0; - rom_file.seekg(0x300080, ios::beg); - rom_file.read((char*)&config_info_offset, 4); - config_info_offset = READ_DWORD_BE_A(&config_info_offset); - - /* rewind to ConfigInfo.BootstrapVersion field */ - rom_file.seekg(0x300064 + config_info_offset, ios::beg); - - /* read BootstrapVersion as C string */ - rom_file.read(rom_id_str, 16); - rom_id_str[16] = 0; - LOG_F(INFO, "ROM BootstrapVersion: %s", rom_id_str); - - if (strncmp(rom_id_str, "Boot", 4) != 0) { - LOG_F(ERROR, "Invalid BootstrapVersion string."); - goto bail_out; + if (rom_data) { + rom_file.seekg(0, ios::beg); + rom_file.read(rom_data, file_size); } - /* convert BootstrapVersion string to ROM ID */ - rom_id = (rom_id_str[5] << 24) | (rom_id_str[6] << 16) | - (rom_id_str[7] << 8) | rom_id_str[8]; - - LOG_F(INFO, "The machine is identified as... %s", - std::get<1>(rom_identity.at(rom_id))); - - machine_name = std::get<0>(rom_identity.at(rom_id)); - bail_out: rom_file.close(); + return file_size; +} + +string MachineFactory::machine_name_from_rom(char *rom_data, size_t rom_size) { + uint32_t date = 0; + uint16_t major_version = 0; + uint16_t minor_version = 0; + uint32_t firmware_version = 0; + uint32_t nw_product_id = 0; + uint32_t ow_checksum_stored = 0; uint32_t ow_checksum_calculated = 0; + uint32_t nw_start_checksum_stored = 0; uint32_t nw_start_checksum_calculated = 0; + uint32_t nw_config_checksum_stored = 0; uint32_t nw_config_checksum_calculated = 0; + uint32_t nw_recovery_checksum_stored = 0; uint32_t nw_recovery_checksum_calculated = 0; + uint32_t nw_romimage_checksum_stored = 0; uint32_t nw_romimage_checksum_calculated = 0; + uint16_t nw_config_signature = 0; + bool has_nw_config = false; + bool is_nw = false; + uint32_t nw_subconfig_checksum_calculated = 0; + + char expected_ow[24]; + char expected_start[24]; + char expected_config[24]; + char expected_recovery[24]; + char expected_romimage[24]; + auto checksum_verbosity = loguru::Verbosity_INFO; + expected_ow[0] = expected_start[0] = expected_config[0] = expected_recovery[0] = expected_romimage[0] = 0; + + uint32_t config_info_offset; + char rom_id_str[17]; + rom_id_str[0] = '\0'; + + int match_pass; + int num_matches = 0; + int best_match_count = 0; + string machine_name = ""; + + bool print_all_info = false; + + /* read firmware version from file */ + date = READ_DWORD_BE_A(&rom_data[8]); + nw_config_signature = READ_WORD_BE_A(&rom_data[0x3f00]); + has_nw_config = nw_config_signature == 0xc99c || nw_config_signature == 0xc03c; + if (has_nw_config || (date > 0x19990000 && date < 0x20060000)) { + is_nw = true; + firmware_version = READ_DWORD_BE_A(&rom_data[4]); + { + nw_recovery_checksum_calculated = adler32(&rom_data[0x8000], 0x77ffc); + nw_recovery_checksum_stored = READ_DWORD_BE_A(&rom_data[0x7fffc]); + nw_romimage_checksum_calculated = adler32(&rom_data[0x80000], 0x7fffc); + nw_romimage_checksum_stored = READ_DWORD_BE_A(&rom_data[0xffffc]); + } + + if (has_nw_config) { + nw_start_checksum_calculated = adler32(&rom_data[0], 0x3efc); + nw_start_checksum_stored = READ_DWORD_BE_A(&rom_data[0x3efc]); + nw_config_checksum_calculated = adler32(&rom_data[0x3f00], 0x7c); + nw_config_checksum_stored = READ_DWORD_BE_A(&rom_data[0x3f7c]); + nw_subconfig_checksum_calculated = adler32(&rom_data[0x3f0c], 0x70); + nw_product_id = (READ_WORD_BE_A(&rom_data[0x3f02]) << 8) | rom_data[0x3f13]; + } + else { + firmware_version &= 0xffff; // the upper 2 bytes might be a machine type: 0=iMac, 1=PowerMac, 2=PowerBook + nw_start_checksum_calculated = adler32(&rom_data[0], 0x3ffc); + nw_start_checksum_stored = READ_DWORD_BE_A(&rom_data[0x3ffc]); + nw_config_checksum_calculated = 0; + nw_config_checksum_stored = 0; + nw_subconfig_checksum_calculated = 0; + nw_product_id = 0; + } + if (nw_start_checksum_calculated != nw_start_checksum_stored) + snprintf(expected_start, sizeof(expected_start), " (expected 0x%04x)", nw_start_checksum_stored); + if (nw_config_checksum_calculated != nw_config_checksum_stored) + snprintf(expected_config, sizeof(expected_config), " (expected 0x%04x)", nw_config_checksum_stored); + if (nw_recovery_checksum_calculated != nw_recovery_checksum_stored) + snprintf(expected_recovery, sizeof(expected_recovery), " (expected 0x%04x)", nw_recovery_checksum_stored); + if (nw_romimage_checksum_calculated != nw_romimage_checksum_stored) + snprintf(expected_romimage, sizeof(expected_romimage), " (expected 0x%04x)", nw_romimage_checksum_stored); + } + else { + date = 0; + major_version = READ_WORD_BE_A(&rom_data[8]); + minor_version = READ_WORD_BE_A(&rom_data[0x12]); + firmware_version = (major_version << 16) | minor_version; + ow_checksum_calculated = oldworldchecksum(&rom_data[4], std::min(rom_size - 4, (size_t)0x2ffffc)); + ow_checksum_stored = READ_DWORD_BE_A(&rom_data[0]); + if (ow_checksum_calculated != ow_checksum_stored) + snprintf(expected_ow, sizeof(expected_ow), " (expected 0x%04x)", ow_checksum_stored); + + if (firmware_version > 0x077d10f3) { + /* read ConfigInfo offset from file */ + config_info_offset = READ_DWORD_BE_A(&rom_data[0x300080]); + + /* read ConfigInfo.BootstrapVersion field as C string */ + memcpy(rom_id_str, &rom_data[0x300064 + config_info_offset], 16); + rom_id_str[16] = 0; + for (int i = 0; i < 16; i++) + if (rom_id_str[i] < ' ' || rom_id_str[i] > '~') + rom_id_str[i] = '.'; + } + } + + + for (match_pass = 0; match_pass < 2; match_pass++) { + int match_index = 0; + for (rom_info *info = &rom_identity[0]; info->firmware_size_k; info++) { + if ( + (info->firmware_version && info->firmware_version == firmware_version) || + (info->nw_product_id && info->nw_product_id == nw_product_id ) + ) { + int match_count = 1 + + (info->ow_expected_checksum && info->ow_expected_checksum == ow_checksum_stored ) + + (info->ow_expected_checksum && info->ow_expected_checksum == ow_checksum_calculated ) + + (info->nw_subconfig_expected_checksum && info->nw_subconfig_expected_checksum == nw_subconfig_checksum_calculated ) + + (info->id_str && strcmp(rom_id_str, info->id_str) == 0) + ; + + if (!match_pass) { + if (match_count >= best_match_count) { + if (match_count > best_match_count) { + best_match_count = match_count; + num_matches = 0; + } + num_matches++; + } + } else { + if (num_matches == 0) { + LOG_F(ERROR, "Unknown ROM"); + print_all_info = true; + break; + } + + if (match_count == best_match_count) { + match_index++; + LOG_F(INFO, "Found match (%d/%d):", match_index, num_matches); + if (info->rom_description) + LOG_F(INFO, " ROM description: %s", info->rom_description); + if (info->dppc_description) + LOG_F(INFO, " Machine identified from ROM: %s", info->dppc_description); + if ( + info->nw_firmware_updater_name && info->nw_openfirmware_name && + strcmp(info->nw_firmware_updater_name, info->nw_openfirmware_name) == 0 + ) { + LOG_F(INFO, " Code Name: %s", info->nw_firmware_updater_name); + } else { + if (info->nw_firmware_updater_name) + LOG_F(INFO, " Code Name (from Firmware Updater): %s", info->nw_firmware_updater_name); + if (info->nw_openfirmware_name) + LOG_F(INFO, " Code Name (from Open Firmware): %s", info->nw_openfirmware_name); + } + if (info->nw_product_id) { + LOG_F(INFO, " Product ID: 0x%04x.%02x = %s%d,%d", + nw_product_id >> 8, nw_product_id & 0xff, + (nw_product_id >> 20) == 0 ? "PowerMac" : + (nw_product_id >> 20) == 1 ? "PowerBook" : + (nw_product_id >> 20) == 2 ? "PowerMac" : + (nw_product_id >> 20) == 3 ? "PowerBook" : + (nw_product_id >> 20) == 4 ? "RackMac" : "???", + (nw_product_id >> 14) & 31, + (nw_product_id >> 8) & 31 + ); + } + if (info->nw_subconfig_expected_checksum) { + LOG_F(INFO, " Config Checksum: 0x%08x", nw_subconfig_checksum_calculated); + } + if (rom_size != info->firmware_size_k * 1024) { + LOG_F(ERROR, " Unexpected ROM file size: %zu bytes. Expected size is %d %s.", + rom_size, + info->firmware_size_k & 0x3ff ? + info->firmware_size_k : + info->firmware_size_k / 1024, + info->firmware_size_k & 0x3ff ? "kiB" : "MiB" + ); + } + if (info->dppc_machine) { + if (machine_name.empty()) { + machine_name = info->dppc_machine; + } + } else + LOG_F(ERROR, " This ROM is not supported."); + } + } // if match_pass + } // if match + } // for rom_info + } // for match_pass + + if (1 || print_all_info) { + if (is_nw) { + LOG_F(INFO, "Info from ROM:"); + LOG_F(INFO, " ROM Date: %04x-%02x-%02x", date >> 16, (date >> 8) & 0xff, date & 0xff); + if (firmware_version < 0xffff) + LOG_F(INFO, " ROM Version: %x.%03x", (firmware_version >> 12) & 15, firmware_version & 0xfff); + else + LOG_F(INFO, " ROM Version: %x.%x.%03x", firmware_version >> 16, (firmware_version >> 12) & 15, firmware_version & 0xfff); + if (has_nw_config) { + LOG_F(INFO, " Product ID: 0x%04x.%02x 0x%08x = %s%d,%d", + nw_product_id >> 8, nw_product_id & 0xff, + nw_subconfig_checksum_calculated, + (nw_product_id >> 20) == 0 ? "PowerMac" : + (nw_product_id >> 20) == 1 ? "PowerBook" : + (nw_product_id >> 20) == 2 ? "PowerMac" : + (nw_product_id >> 20) == 3 ? "PowerBook" : + (nw_product_id >> 20) == 4 ? "RackMac" : "???", + (nw_product_id >> 14) & 31, + (nw_product_id >> 8) & 31 + ); + } + } else { + LOG_F(INFO, " ROM Version: %04x.%04x", major_version, minor_version); + if (rom_id_str[0]) + LOG_F(INFO, " ConfigInfo.BootstrapVersion: \"%s\"", rom_id_str); + } + } + + if (expected_ow[0] || expected_start[0] || expected_config[0] || expected_recovery[0] || expected_romimage[0]) + checksum_verbosity = loguru::Verbosity_ERROR; + + if (1 || print_all_info || checksum_verbosity != loguru::Verbosity_INFO) { + if (is_nw) { + if (has_nw_config) { + VLOG_F(checksum_verbosity, " ROM Checksums: 0x%08x%s, 0x%08x%s, 0x%08x%s, 0x%08x%s", + nw_start_checksum_calculated, expected_start, + nw_config_checksum_calculated, expected_config, + nw_recovery_checksum_calculated, expected_recovery, + nw_romimage_checksum_calculated, expected_romimage + ); + } + else { + VLOG_F(checksum_verbosity, " ROM Checksums: 0x%08x%s, 0x%08x%s, 0x%08x%s", + nw_start_checksum_calculated, expected_start, + nw_recovery_checksum_calculated, expected_recovery, + nw_romimage_checksum_calculated, expected_romimage + ); + } + } + else { + VLOG_F(checksum_verbosity, " ROM Checksum: 0x%08x%s", + ow_checksum_calculated, expected_ow + ); + } + } + return machine_name; } /* Read ROM file content and transfer it to the dedicated ROM region */ -int MachineFactory::load_boot_rom(string& rom_filepath) { - ifstream rom_file; - size_t file_size; +int MachineFactory::load_boot_rom(char *rom_data, size_t rom_size) { int result = 0; uint32_t rom_load_addr; //AddressMapEntry *rom_reg; - rom_file.open(rom_filepath, ios::in | ios::binary); - if (rom_file.fail()) { - LOG_F(ERROR, "Could not open the specified ROM file."); - rom_file.close(); - return -1; - } - - rom_file.seekg(0, rom_file.end); - file_size = rom_file.tellg(); - rom_file.seekg(0, rom_file.beg); - - if (file_size == 0x400000UL) { // Old World ROMs + if (rom_size == 0x400000UL) { // Old World ROMs rom_load_addr = 0xFFC00000UL; - } else if (file_size == 0x100000UL) { // New World ROMs + } else if (rom_size == 0x100000UL) { // New World ROMs rom_load_addr = 0xFFF00000UL; } else { - LOG_F(ERROR, "Unxpected ROM File size: %zu bytes.", file_size); + LOG_F(ERROR, "Unexpected ROM File size: %zu bytes.", rom_size); result = -1; } if (!result) { - unsigned char* sysrom_mem = new unsigned char[file_size]; - - rom_file.seekg(0, ios::beg); - rom_file.read((char*)sysrom_mem, file_size); - MemCtrlBase* mem_ctrl = dynamic_cast( gMachineObj->get_comp_by_type(HWCompType::MEM_CTRL)); if ((/*rom_reg = */mem_ctrl->find_rom_region())) { - mem_ctrl->set_data(rom_load_addr, sysrom_mem, (uint32_t)file_size); + mem_ctrl->set_data(rom_load_addr, (uint8_t*)rom_data, (uint32_t)rom_size); } else { LOG_F(ERROR, "Could not locate physical ROM region!"); result = -1; } - - delete[] sysrom_mem; } - rom_file.close(); - return result; } -int MachineFactory::create_machine_for_id(string& id, string& rom_filepath) { - if (MachineFactory::create(id) < 0 || load_boot_rom(rom_filepath) < 0) { +int MachineFactory::create_machine_for_id(string& id, char *rom_data, size_t rom_size) { + if (MachineFactory::create(id) < 0) { + return -1; + } + if (load_boot_rom(rom_data, rom_size) < 0) { return -1; } - return 0; } diff --git a/machines/machinefactory.h b/machines/machinefactory.h index 3f872e3..63588fd 100644 --- a/machines/machinefactory.h +++ b/machines/machinefactory.h @@ -54,10 +54,11 @@ public: static bool add(const std::string& machine_id, MachineDescription desc); - static std::string machine_name_from_rom(std::string& rom_filepath); + static size_t read_boot_rom(std::string& rom_filepath, char *rom_data); + static std::string machine_name_from_rom(char *rom_data, size_t rom_size); static int create(std::string& mach_id); - static int create_machine_for_id(std::string& id, std::string& rom_filepath); + static int create_machine_for_id(std::string& id, char *rom_data, size_t rom_size); static void register_device_settings(const std::string &name); static int register_machine_settings(const std::string& id); @@ -71,7 +72,7 @@ private: static void create_device(std::string& dev_name, DeviceDescription& dev); static void print_settings(const PropMap& p); static void list_device_settings(DeviceDescription& dev); - static int load_boot_rom(std::string& rom_filepath); + static int load_boot_rom(char *rom_data, size_t rom_size); static void register_settings(const PropMap& p); static std::map & get_registry() { diff --git a/main.cpp b/main.cpp index 50120e9..b132396 100644 --- a/main.cpp +++ b/main.cpp @@ -89,7 +89,7 @@ public: const WorkingDirectoryValidator WorkingDirectory; -void run_machine(std::string machine_str, std::string bootrom_path, uint32_t execution_mode, uint32_t profiling_interval_ms); +void run_machine(std::string machine_str, char *rom_data, size_t rom_size, uint32_t execution_mode, uint32_t profiling_interval_ms); int main(int argc, char** argv) { @@ -178,17 +178,27 @@ int main(int argc, char** argv) { loguru::init(argc, argv); } + auto rom_data = std::unique_ptr(new char[4 * 1024 * 1024]); + memset(&rom_data[0], 0, 4 * 1024 * 1024); + size_t rom_size = MachineFactory::read_boot_rom(bootrom_path, &rom_data[0]); + if (!rom_size) { + return 1; + } + + string machine_str_from_rom = MachineFactory::machine_name_from_rom(&rom_data[0], rom_size); + if (machine_str_from_rom.empty()) { + LOG_F(ERROR, "Could not autodetect machine from ROM."); + } else { + LOG_F(INFO, "Machine detected from ROM as: %s", machine_str_from_rom.c_str()); + } if (*machine_opt) { LOG_F(INFO, "Machine option was passed in: %s", machine_str.c_str()); } else { - machine_str = MachineFactory::machine_name_from_rom(bootrom_path); + machine_str = machine_str_from_rom; + } if (machine_str.empty()) { - LOG_F(ERROR, "Could not autodetect machine"); + LOG_F(ERROR, "Must specificy a machine or provide a supported ROM."); return 1; - } - else { - LOG_F(INFO, "Machine was autodetected as: %s", machine_str.c_str()); - } } // Hook to allow properties to be read from the command-line, regardless @@ -249,7 +259,7 @@ int main(int argc, char** argv) { signal(SIGABRT, sigabrt_handler); while (true) { - run_machine(machine_str, bootrom_path, execution_mode, profiling_interval_ms); + run_machine(machine_str, &rom_data[0], rom_size, execution_mode, profiling_interval_ms); if (power_off_reason == po_restarting) { LOG_F(INFO, "Restarting..."); power_on = true; @@ -272,8 +282,13 @@ int main(int argc, char** argv) { return 0; } -void run_machine(std::string machine_str, std::string bootrom_path, uint32_t execution_mode, uint32_t profiling_interval_ms) { - if (MachineFactory::create_machine_for_id(machine_str, bootrom_path) < 0) { +void run_machine(std::string machine_str, char *rom_data, size_t rom_size, uint32_t execution_mode, + uint32_t +#ifdef CPU_PROFILING + profiling_interval_ms +#endif +) { + if (MachineFactory::create_machine_for_id(machine_str, rom_data, rom_size) < 0) { return; }