2021-06-04 01:55:59 +00:00
//
// ROMCatalogue.cpp
// Clock Signal
//
// Created by Thomas Harte on 01/06/2021.
// Copyright © 2021 Thomas Harte. All rights reserved.
//
# include "ROMCatalogue.hpp"
2021-06-04 02:39:18 +00:00
# include <algorithm>
2021-06-04 01:55:59 +00:00
# include <cassert>
2023-04-30 21:17:40 +00:00
# include <cstdlib>
2021-06-06 22:15:00 +00:00
# include <iomanip>
2021-06-07 00:02:13 +00:00
# include <locale>
2021-06-06 22:15:00 +00:00
# include <sstream>
2021-06-04 01:55:59 +00:00
using namespace ROM ;
2021-06-06 18:24:38 +00:00
namespace {
constexpr Name MaxName = Name : : SpectrumPlus3 ;
}
2021-06-04 02:39:18 +00:00
Request : : Request ( Name name , bool optional ) {
node . name = name ;
node . is_optional = optional ;
}
2021-06-04 01:55:59 +00:00
2021-06-04 23:03:07 +00:00
Request Request : : append ( Node : : Type type , const Request & rhs ) {
2021-06-20 02:13:17 +00:00
// If either side is empty, act appropriately.
if ( node . empty ( ) & & ! rhs . node . empty ( ) ) {
return rhs ;
}
if ( rhs . node . empty ( ) ) {
return * this ;
}
// Just copy in the RHS child nodes if types match.
2021-06-04 23:03:07 +00:00
if ( node . type = = type & & rhs . node . type = = type ) {
Request new_request = * this ;
new_request . node . children . insert ( new_request . node . children . end ( ) , rhs . node . children . begin ( ) , rhs . node . children . end ( ) ) ;
2021-06-07 02:36:26 +00:00
new_request . node . sort ( ) ;
2021-06-04 23:03:07 +00:00
return new_request ;
}
2021-06-07 00:25:26 +00:00
// Possibly: left is appropriate request and rhs is just one more thing?
if ( node . type = = type & & rhs . node . type = = Node : : Type : : One ) {
Request new_request = * this ;
new_request . node . children . push_back ( rhs . node ) ;
2021-06-07 02:36:26 +00:00
new_request . node . sort ( ) ;
2021-06-07 00:25:26 +00:00
return new_request ;
}
// Or: right is appropriate request and this is just one more thing?
if ( rhs . node . type = = type & & node . type = = Node : : Type : : One ) {
Request new_request = rhs ;
new_request . node . children . push_back ( node ) ;
2021-06-07 02:36:26 +00:00
new_request . node . sort ( ) ;
2021-06-07 00:25:26 +00:00
return new_request ;
}
2021-06-04 23:03:07 +00:00
// Otherwise create a new parent node.
Request parent ;
parent . node . type = type ;
parent . node . children . push_back ( this - > node ) ;
parent . node . children . push_back ( rhs . node ) ;
return parent ;
}
2021-06-04 01:55:59 +00:00
Request Request : : operator & & ( const Request & rhs ) {
2021-06-04 23:03:07 +00:00
return append ( Node : : Type : : All , rhs ) ;
2021-06-04 01:55:59 +00:00
}
Request Request : : operator | | ( const Request & rhs ) {
2021-06-04 23:03:07 +00:00
return append ( Node : : Type : : Any , rhs ) ;
2021-06-04 01:55:59 +00:00
}
2021-06-04 22:54:50 +00:00
bool Request : : validate ( Map & map ) const {
return node . validate ( map ) ;
2021-06-04 01:55:59 +00:00
}
std : : vector < ROM : : Description > Request : : all_descriptions ( ) const {
2021-06-04 02:39:18 +00:00
std : : vector < Description > result ;
2021-06-04 01:55:59 +00:00
node . add_descriptions ( result ) ;
return result ;
}
2021-06-04 02:39:18 +00:00
void Request : : Node : : add_descriptions ( std : : vector < Description > & result ) const {
2021-06-04 01:55:59 +00:00
if ( type = = Type : : One ) {
result . push_back ( name ) ;
return ;
}
2021-06-06 01:09:35 +00:00
for ( const auto & child : children ) {
child . add_descriptions ( result ) ;
2021-06-04 01:55:59 +00:00
}
}
2021-06-06 01:09:35 +00:00
Request Request : : subtract ( const ROM : : Map & map ) const {
Request copy ( * this ) ;
if ( copy . node . subtract ( map ) ) {
copy . node . name = Name : : None ;
copy . node . type = Node : : Type : : One ;
}
return copy ;
}
bool Request : : Node : : subtract ( const ROM : : Map & map ) {
switch ( type ) {
case Type : : One :
return map . find ( name ) ! = map . end ( ) ;
default : {
bool has_all = true ;
bool has_any = false ;
auto iterator = children . begin ( ) ;
while ( iterator ! = children . end ( ) ) {
const bool did_subtract = iterator - > subtract ( map ) ;
has_all & = did_subtract ;
has_any | = did_subtract ;
if ( did_subtract ) {
iterator = children . erase ( iterator ) ;
} else {
+ + iterator ;
}
}
return ( type = = Type : : All & & has_all ) | | ( type = = Type : : Any & & has_any ) ;
}
}
}
bool Request : : empty ( ) {
return node . type = = Node : : Type : : One & & node . name = = Name : : None ;
}
2021-06-04 22:54:50 +00:00
bool Request : : Node : : validate ( Map & map ) const {
// Leaf nodes are easy: check that the named ROM is present,
// unless it's optional, in which case it is always valid.
//
// If it is present, make sure it's the proper size.
if ( type = = Type : : One ) {
auto rom = map . find ( name ) ;
if ( rom = = map . end ( ) ) {
return is_optional ;
}
const Description description ( name ) ;
rom - > second . resize ( description . size ) ;
return true ;
}
// This is a collection node then. Check for both any or all
// simultaneously, since all nodes will need to be visited
// regardless of any/all in order to ensure proper sizing.
bool has_all = true ;
bool has_any = false ;
for ( const auto & child : children ) {
const bool is_valid = child . validate ( map ) ;
has_all & = is_valid ;
has_any | = is_valid ;
}
return ( type = = Type : : Any & & has_any ) | | ( type = = Type : : All & & has_all ) ;
}
2021-06-05 01:53:56 +00:00
void Request : : visit (
2021-06-07 00:25:26 +00:00
const std : : function < void ( ListType , size_t ) > & enter_list ,
2021-06-05 01:53:56 +00:00
const std : : function < void ( void ) > & exit_list ,
const std : : function < void ( ROM : : Request : : ListType , const ROM : : Description & , bool , size_t ) > & add_item
) const {
node . visit ( enter_list , exit_list , add_item ) ;
}
2021-06-06 22:28:02 +00:00
void Request : : visit (
const std : : function < void ( LineItem , ListType , int , const ROM : : Description * , bool , size_t ) > & add_item
) const {
int indentation_level = 0 ;
node . visit (
2021-06-07 00:25:26 +00:00
[ & indentation_level , & add_item ] ( ROM : : Request : : ListType type , size_t size ) {
add_item ( LineItem : : NewList , type , indentation_level , nullptr , false , size ) ;
2021-06-06 22:28:02 +00:00
+ + indentation_level ;
} ,
[ & indentation_level ] {
- - indentation_level ;
} ,
[ & indentation_level , & add_item ] ( ROM : : Request : : ListType type , const ROM : : Description & rom , bool is_optional , size_t remaining ) {
add_item ( LineItem : : Description , type , indentation_level , & rom , is_optional , remaining ) ;
}
) ;
}
2021-06-05 01:53:56 +00:00
void Request : : Node : : visit (
2021-06-07 00:25:26 +00:00
const std : : function < void ( ListType , size_t ) > & enter_list ,
2021-06-05 01:53:56 +00:00
const std : : function < void ( void ) > & exit_list ,
const std : : function < void ( ROM : : Request : : ListType type , const ROM : : Description & , bool is_optional , size_t remaining ) > & add_item
) const {
switch ( type ) {
case Type : : One :
2021-06-07 00:25:26 +00:00
enter_list ( ListType : : Single , 1 ) ;
2021-06-05 01:53:56 +00:00
add_item ( ROM : : Request : : ListType : : Any , Description ( name ) , is_optional , 0 ) ;
exit_list ( ) ;
break ;
case Type : : Any :
case Type : : All : {
const ListType list_type = type = = Type : : Any ? ListType : : Any : ListType : : All ;
2021-06-07 00:25:26 +00:00
enter_list ( list_type , children . size ( ) ) ;
2021-06-05 01:53:56 +00:00
for ( size_t index = 0 ; index < children . size ( ) ; index + + ) {
auto & child = children [ index ] ;
if ( child . type = = Type : : One ) {
add_item ( list_type , Description ( child . name ) , child . is_optional , children . size ( ) - 1 - index ) ;
} else {
child . visit ( enter_list , exit_list , add_item ) ;
}
}
exit_list ( ) ;
} break ;
}
}
2021-06-06 18:24:38 +00:00
std : : vector < Description > ROM : : all_descriptions ( ) {
std : : vector < Description > result ;
for ( int name = 1 ; name < = MaxName ; name + + ) {
result . push_back ( Description ( ROM : : Name ( name ) ) ) ;
}
return result ;
}
2021-06-04 02:39:18 +00:00
std : : optional < Description > Description : : from_crc ( uint32_t crc32 ) {
2021-06-06 18:24:38 +00:00
for ( int name = 1 ; name < = MaxName ; name + + ) {
2021-06-04 02:39:18 +00:00
const Description candidate = Description ( ROM : : Name ( name ) ) ;
const auto found_crc = std : : find ( candidate . crc32s . begin ( ) , candidate . crc32s . end ( ) , crc32 ) ;
if ( found_crc ! = candidate . crc32s . end ( ) ) {
return candidate ;
}
}
return std : : nullopt ;
}
2021-06-06 22:15:00 +00:00
std : : string Description : : description ( int flags ) const {
std : : stringstream output ;
2021-06-06 22:28:02 +00:00
// If there are no CRCs, don't output them.
2023-04-30 21:17:40 +00:00
if ( crc32s . empty ( ) ) flags & = ~ DescriptionFlag : : CRC ;
2021-06-06 22:28:02 +00:00
2021-06-06 22:15:00 +00:00
// Print the file name(s) and the descriptive name.
if ( flags & DescriptionFlag : : Filename ) {
flags & = ~ DescriptionFlag : : Filename ;
2023-05-16 20:40:09 +00:00
output < < machine_name < < ' / ' ;
2021-06-06 22:15:00 +00:00
if ( file_names . size ( ) = = 1 ) {
output < < file_names [ 0 ] ;
} else {
output < < " { " ;
bool is_first = true ;
for ( const auto & file_name : file_names ) {
if ( ! is_first ) output < < " or " ;
output < < file_name ;
is_first = false ;
}
output < < " } " ;
}
output < < " ( " < < descriptive_name ;
if ( ! flags ) {
output < < " ) " ;
return output . str ( ) ;
}
output < < " ; " ;
} else {
output < < descriptive_name ;
if ( ! flags ) {
return output . str ( ) ;
}
output < < " ( " ;
}
// Print the size.
if ( flags & DescriptionFlag : : Size ) {
flags & = ~ DescriptionFlag : : Size ;
output < < size < < " bytes " ;
if ( ! flags ) {
output < < " ) " ;
return output . str ( ) ;
}
output < < " ; " ;
}
// Print the CRC(s).
if ( flags & DescriptionFlag : : CRC ) {
flags & = ~ DescriptionFlag : : CRC ;
output < < ( ( crc32s . size ( ) > 1 ) ? " usual crc32s: " : " usual crc32: " ) ;
bool is_first = true ;
for ( const auto crc32 : crc32s ) {
if ( ! is_first ) output < < " , " ;
is_first = false ;
output < < std : : hex < < std : : setfill ( ' 0 ' ) < < std : : setw ( 8 ) < < crc32 ;
}
if ( ! flags ) {
output < < " ) " ;
return output . str ( ) ;
}
}
return output . str ( ) ;
}
2021-06-07 00:02:13 +00:00
std : : wstring Request : : description ( int description_flags , wchar_t bullet_point ) {
std : : wstringstream output ;
visit (
2023-04-30 21:17:40 +00:00
[ & output , description_flags , bullet_point ] ( ROM : : Request : : LineItem item , ROM : : Request : : ListType type , int indentation_level , const ROM : : Description * description , bool is_optional , size_t remaining ) {
2021-06-07 00:02:13 +00:00
if ( indentation_level ) {
output < < std : : endl ;
for ( int c = 0 ; c < indentation_level ; c + + ) output < < ' \t ' ;
output < < bullet_point < < ' ' ;
}
switch ( item ) {
case ROM : : Request : : LineItem : : NewList :
2021-06-07 00:25:26 +00:00
if ( remaining > 1 ) {
if ( ! indentation_level ) output < < " " ;
switch ( type ) {
default :
case ROM : : Request : : ListType : : All : output < < " all of: " ; break ;
case ROM : : Request : : ListType : : Any :
if ( remaining = = 2 ) {
output < < " either of: " ;
} else {
output < < " any of: " ;
}
break ;
}
} else {
output < < " : " ;
2021-06-07 00:02:13 +00:00
}
break ;
2023-04-30 21:17:40 +00:00
case ROM : : Request : : LineItem : : Description : {
2021-06-07 00:02:13 +00:00
if ( is_optional ) output < < " optionally, " ;
2023-04-30 21:17:40 +00:00
const auto text = description - > description ( description_flags ) ;
std : : wstring wide_text ( text . size ( ) , L ' ' ) ;
std : : mbstowcs ( wide_text . data ( ) , text . data ( ) , text . size ( ) ) ;
output < < wide_text ;
2021-06-07 00:02:13 +00:00
if ( remaining ) {
output < < " ; " ;
if ( remaining = = 1 ) {
output < < ( ( type = = ROM : : Request : : ListType : : All ) ? " and " : " or " ) ;
}
} else {
output < < " . " ;
}
2023-04-30 21:17:40 +00:00
} break ;
2021-06-07 00:02:13 +00:00
}
}
) ;
return output . str ( ) ;
}
2021-06-04 01:55:59 +00:00
Description : : Description ( Name name ) {
switch ( name ) {
default : assert ( false ) ; break ;
2021-06-04 23:19:55 +00:00
case Name : : AMSDOS : * this = Description ( name , " AmstradCPC " , " the Amstrad Disk Operating System " , " amsdos.rom " , 16 * 1024 , 0x1fe22ecdu ) ; break ;
case Name : : CPC464Firmware : * this = Description ( name , " AmstradCPC " , " the CPC 464 firmware " , " os464.rom " , 16 * 1024 , 0x815752dfu ) ; break ;
case Name : : CPC464BASIC : * this = Description ( name , " AmstradCPC " , " the CPC 464 BASIC ROM " , " basic464.rom " , 16 * 1024 , 0x7d9a3bacu ) ; break ;
case Name : : CPC664Firmware : * this = Description ( name , " AmstradCPC " , " the CPC 664 firmware " , " os664.rom " , 16 * 1024 , 0x3f5a6dc4u ) ; break ;
case Name : : CPC664BASIC : * this = Description ( name , " AmstradCPC " , " the CPC 664 BASIC ROM " , " basic664.rom " , 16 * 1024 , 0x32fee492u ) ; break ;
2021-06-05 02:43:26 +00:00
case Name : : CPC6128Firmware : * this = Description ( name , " AmstradCPC " , " the CPC 6128 firmware " , " os6128.rom " , 16 * 1024 , 0x0219bb74u ) ; break ;
case Name : : CPC6128BASIC : * this = Description ( name , " AmstradCPC " , " the CPC 6128 BASIC ROM " , " basic6128.rom " , 16 * 1024 , 0xca6af63du ) ; break ;
2021-06-04 23:19:55 +00:00
2021-07-16 01:09:20 +00:00
case Name : : AmigaKickstart10 :
* this = Description ( name , " Amiga " , " the Kickstart 1.0 ROM " , " Kickstart-v1.0-1985-Commodore-A1000-NTSC.rom " , 256 * 1024 , 0x299790ffu ) ;
break ;
case Name : : AmigaKickstart11 :
* this = Description ( name , " Amiga " , " the Kickstart 1.1 ROM " , " Kickstart-v1.1-rev31.34-1985-Commodore-A1000.NTSC.rom " , 256 * 1024 , 0xd060572au ) ;
break ;
case Name : : AmigaKickstart12 :
* this = Description ( name , " Amiga " , " the Kickstart 1.2 ROM " , " Kickstart-v1.2-rev33.166-1986-Commodore-A1000.rom " , 256 * 1024 , 0x9ed783d0u ) ;
break ;
case Name : : AmigaA500Kickstart13 :
* this = Description ( name , " Amiga " , " the A500/A1000/A2000/CDTV Kickstart 1.3 ROM " , " Kickstart-v1.3-rev34.5-1987-Commodore-A500-A1000-A2000-CDTV.rom " , 256 * 1024 , 0xc4f0f55fu ) ;
break ;
case Name : : AmigaA3000Kickstart13 :
* this = Description ( name , " Amiga " , " the A3000 Kickstart 1.3 ROM " , " Kickstart-v1.3-rev34.5-1987-Commodore-A3000.rom " , 256 * 1024 , 0xe0f37258u ) ;
break ;
case Name : : AmigaKickstart20 :
* this = Description ( name , " Amiga " , " the Kickstart 2.0 ROM " , " Kickstart-v2.0-rev36.143-1990-Commodore-A3000.rom " , 512 * 1024 , 0xb333d3c6u ) ;
break ;
case Name : : AmigaA500PlusKickstart204 :
* this = Description ( name , " Amiga " , " the A500+ Kickstart 2.04 ROM " , " Kickstart-v2.04-rev37.175-1991-Commodore-A500plus.rom " , 512 * 1024 , 0xc3bdb240u ) ;
break ;
case Name : : AmigaA600Kickstart205 :
* this = Description ( name , " Amiga " , " the Kickstart 2.05 ROM " , " Kickstart-v2.05-rev37.299-1991-Commodore-A600.rom " , 512 * 1024 , 0x83028fb5u ) ;
break ;
case Name : : AmigaA500Kickstart31 :
* this = Description ( name , " Amiga " , " the A500/A600/A2000 Kickstart 3.1 ROM " , " Kickstart-v3.1-rev40.63-1993-Commodore-A500-A600-A2000.rom " , 512 * 1024 , 0xfc24ae0du ) ;
break ;
2021-08-07 20:56:18 +00:00
case Name : : AmigaDiagROM121 :
* this = Description ( name , " Amiga " , " DiagROM 1.2.1 " , " 16bit.bin " , 512 * 1024 , 0xf2ac0a3b ) ;
break ;
2021-07-16 01:09:20 +00:00
2021-06-04 23:19:55 +00:00
case Name : : AppleIIEnhancedE : * this = Description ( name , " AppleII " , " the Enhanced Apple IIe ROM " , " apple2e.rom " , 32 * 1024 , 0x65989942u ) ; break ;
case Name : : AppleIIe : * this = Description ( name , " AppleII " , " the Apple IIe ROM " , " apple2eu.rom " , 32 * 1024 , 0xe12be18du ) ; break ;
case Name : : AppleIIPlus : * this = Description ( name , " AppleII " , " the Apple II+ ROM " , " apple2.rom " , 12 * 1024 , 0xf66f9c26u ) ; break ;
case Name : : AppleIIOriginal : * this = Description ( name , " AppleII " , " the original Apple II ROM " , " apple2o.rom " , 12 * 1024 , 0xba210588u ) ; break ;
case Name : : AppleIICharacter : * this = Description ( name , " AppleII " , " the basic Apple II character ROM " , " apple2-character.rom " , 2 * 1024 , 0x64f415c6u ) ; break ;
case Name : : AppleIIeCharacter : * this = Description ( name , " AppleII " , " the Apple IIe character ROM " , " apple2eu-character.rom " , 4 * 1024 , 0x816a86f1u ) ; break ;
case Name : : AppleIIEnhancedECharacter :
* this = Description ( name , " AppleII " , " the Enhanced Apple IIe character ROM " , " apple2e-character.rom " , 4 * 1024 , 0x2651014du ) ;
2021-06-04 01:55:59 +00:00
break ;
2022-08-22 02:03:52 +00:00
case Name : : AppleIISCSICard :
* this = Description ( name , " AppleII " , " the Apple II SCSI card ROM " , " scsi.rom " , 16 * 1024 , 0x5aff85d3u ) ;
break ;
2021-06-04 23:19:55 +00:00
case Name : : AppleIIgsROM00 : /* TODO */
case Name : : AppleIIgsROM01 : * this = Description ( name , " AppleIIgs " , " the Apple IIgs ROM01 " , " apple2gs.rom " , 128 * 1024 , 0x42f124b0u ) ; break ;
case Name : : AppleIIgsROM03 : * this = Description ( name , " AppleIIgs " , " the Apple IIgs ROM03 " , " apple2gs.rom2 " , 256 * 1024 , 0xde7ddf29u ) ; break ;
case Name : : AppleIIgsCharacter : * this = Description ( name , " AppleIIgs " , " the Apple IIgs character ROM " , " apple2gs.chr " , 4 * 1024 , 0x91e53cd8u ) ; break ;
case AppleIIgsMicrocontrollerROM03 :
* this = Description ( name , " AppleIIgs " , " the Apple IIgs ROM03 ADB microcontroller ROM " , " 341s0632-2 " , 4 * 1024 , 0xe1c11fb0u ) ;
2021-06-04 01:55:59 +00:00
break ;
2021-06-04 23:19:55 +00:00
case Name : : DiskIIBoot16Sector :
* this = Description ( name , " DiskII " , " the Disk II 16-sector boot ROM " , " boot-16.rom " , 256 , 0xce7144f6u ) ;
2021-06-04 01:55:59 +00:00
break ;
2021-06-04 23:19:55 +00:00
case Name : : DiskIIStateMachine16Sector :
* this = Description ( name , " DiskII " , " the Disk II 16-sector state machine ROM " , " state-machine-16.rom " , 256 , std : : initializer_list < uint32_t > { 0x9796a238 , 0xb72a2c70 } ) ;
2021-06-04 01:55:59 +00:00
break ;
2021-06-04 23:19:55 +00:00
case Name : : DiskIIBoot13Sector :
* this = Description ( name , " DiskII " , " the Disk II 13-sector boot ROM " , " boot-13.rom " , 256 , 0xd34eb2ffu ) ;
2021-06-04 01:55:59 +00:00
break ;
2021-06-04 23:19:55 +00:00
case Name : : DiskIIStateMachine13Sector :
* this = Description ( name , " DiskII " , " the Disk II 13-sector state machine ROM " , " state-machine-13.rom " , 256 , 0x62e22620u ) ;
2021-06-04 01:55:59 +00:00
break ;
2021-06-20 02:59:09 +00:00
case Name : : EnterpriseEXOS10 : {
const std : : initializer_list < std : : string > filenames = { " exos10.bin " , " Exos (198x)(Enterprise).bin " } ;
* this = Description ( name , " Enterprise " , " the Enterprise EXOS ROM v1.0 " , filenames , 32 * 1024 , 0x30b26387u ) ;
} break ;
case Name : : EnterpriseEXOS20 : {
const std : : initializer_list < std : : string > filenames = { " exos20.bin " , " Expandible OS v2.0 (1984)(Intelligent Software).bin " } ;
* this = Description ( name , " Enterprise " , " the Enterprise EXOS ROM v2.0 " , filenames , 32 * 1024 , 0xd421795fu ) ;
} break ;
case Name : : EnterpriseEXOS21 : {
const std : : initializer_list < std : : string > filenames = { " exos21.bin " , " Expandible OS v2.1 (1985)(Intelligent Software).bin " } ;
* this = Description ( name , " Enterprise " , " the Enterprise EXOS ROM v2.1 " , filenames , 32 * 1024 , 0x982a3b44u ) ;
} break ;
case Name : : EnterpriseEXOS23 : {
const std : : initializer_list < std : : string > filenames = { " exos23.bin " , " Expandible OS v2.3 (1987)(Intelligent Software).bin " } ;
* this = Description ( name , " Enterprise " , " the Enterprise EXOS ROM v2.1 " , filenames , 64 * 1024 , 0x24838410u ) ;
} break ;
case Name : : EnterpriseBASIC10 : {
const std : : initializer_list < std : : string > filenames = { " basic10.bin " } ;
* this = Description ( name , " Enterprise " , " the Enterprise BASIC ROM v1.0 " , filenames , 16 * 1024 , 0xd62e4fb7u ) ;
} break ;
case Name : : EnterpriseBASIC10Part1 : {
const std : : initializer_list < std : : string > filenames = { " BASIC 1.0 - EPROM 1-2 (198x)(Enterprise).bin " } ;
* this = Description ( name , " Enterprise " , " the Enterprise BASIC ROM v1.0, Part 1 " , filenames , 8193 , 0x37bf48e1u ) ;
} break ;
case Name : : EnterpriseBASIC10Part2 : {
const std : : initializer_list < std : : string > filenames = { " BASIC 1.0 - EPROM 2-2 (198x)(Enterprise).bin " } ;
* this = Description ( name , " Enterprise " , " the Enterprise BASIC ROM v1.0, Part 2 " , filenames , 8193 , 0xc5298c79u ) ;
} break ;
case Name : : EnterpriseBASIC11 : {
const std : : initializer_list < std : : string > filenames = { " basic11.bin " } ;
* this = Description ( name , " Enterprise " , " the Enterprise BASIC ROM v1.1 " , filenames , 16 * 1024 , 0x683cf455u ) ;
} break ;
case Name : : EnterpriseBASIC11Suffixed : {
const std : : initializer_list < std : : string > filenames = { " BASIC 1.1 - EPROM 1.1 (198x)(Enterprise).bin " } ;
* this = Description ( name , " Enterprise " , " the Enterprise BASIC ROM v1.1, with trailing byte " , filenames , 16385 , 0xc96b7602u ) ;
} break ;
case Name : : EnterpriseBASIC21 : {
const std : : initializer_list < std : : string > filenames = {
" basic21.bin " ,
" BASIC Interpreter v2.1 (1985)(Intelligent Software).bin " ,
" BASIC Interpreter v2.1 (1985)(Intelligent Software)[a].bin "
} ;
const std : : initializer_list < uint32_t > crcs = { 0x55f96251 , 0x683cf455 } ;
* this = Description ( name , " Enterprise " , " the Enterprise BASIC ROM v2.1 " , filenames , 16 * 1024 , crcs ) ;
2021-06-15 01:17:09 +00:00
} break ;
2021-06-21 00:30:54 +00:00
case Name : : EnterpriseEPDOS : {
const std : : initializer_list < std : : string > filenames = { " epdos.bin " , " EPDOS v1.7 (19xx)(Haluska, Laszlo).bin " } ;
* this = Description ( name , " Enterprise " , " the Enterprise EPDOS ROM " , filenames , 32 * 1024 , 0x201319ebu ) ;
} break ;
case Name : : EnterpriseEXDOS : {
const std : : initializer_list < std : : string > filenames = { " exdos.bin " , " EX-DOS EPROM (198x)(Enterprise).bin " } ;
2021-06-30 01:04:53 +00:00
* this = Description ( name , " Enterprise " , " the Enterprise EXDOS ROM " , filenames , 16 * 1024 , 0xe6daa0e9u ) ;
2021-06-21 00:30:54 +00:00
} break ;
2021-06-04 23:24:57 +00:00
case Name : : Macintosh128k : * this = Description ( name , " Macintosh " , " the Macintosh 128k ROM " , " mac128k.rom " , 64 * 1024 , 0x6d0c8a28u ) ; break ;
case Name : : Macintosh512k : * this = Description ( name , " Macintosh " , " the Macintosh 512k ROM " , " mac512k.rom " , 64 * 1024 , 0xcf759e0d ) ; break ;
case Name : : MacintoshPlus : {
2021-06-06 18:24:38 +00:00
const std : : initializer_list < uint32_t > crcs = { 0x4fa5b399 , 0x7cacd18f , 0xb2102e8e } ;
* this = Description ( name , " Macintosh " , " the Macintosh Plus ROM " , " macplus.rom " , 128 * 1024 , crcs ) ;
2021-06-04 23:24:57 +00:00
} break ;
2021-06-04 01:55:59 +00:00
2021-06-07 00:34:55 +00:00
case Name : : AtariSTTOS100 : * this = Description ( name , " AtariST " , " the UK TOS 1.00 ROM " , " tos100.img " , 192 * 1024 , 0x1a586c64u ) ; break ;
case Name : : AtariSTTOS104 : * this = Description ( name , " AtariST " , " the UK TOS 1.04 ROM " , " tos104.img " , 192 * 1024 , 0xa50d1d43u ) ; break ;
2021-06-04 01:55:59 +00:00
2021-06-04 23:24:57 +00:00
case Name : : ColecoVisionBIOS :
* this = Description ( name , " ColecoVision " , " the ColecoVision BIOS " , " coleco.rom " , 8 * 1024 , 0x3aa93ef3u ) ;
break ;
2021-06-04 01:55:59 +00:00
2021-06-04 23:24:57 +00:00
case Name : : ZX80 : * this = Description ( name , " ZX8081 " , " the ZX80 BASIC ROM " , " zx80.rom " , 4 * 1024 , 0x4c7fc597u ) ; break ;
case Name : : ZX81 : * this = Description ( name , " ZX8081 " , " the ZX81 BASIC ROM " , " zx81.rom " , 8 * 1024 , 0x4b1dd6ebu ) ; break ;
2021-06-04 01:55:59 +00:00
2021-06-04 23:45:47 +00:00
case Name : : Spectrum48k : * this = Description ( name , " ZXSpectrum " , " the 48kb ROM " , " 48.rom " , 16 * 1024 , 0xddee531fu ) ; break ;
case Name : : Spectrum128k : * this = Description ( name , " ZXSpectrum " , " the 128kb ROM " , " 128.rom " , 32 * 1024 , 0x2cbe8995u ) ; break ;
2023-05-12 18:14:45 +00:00
case Name : : SpecrumPlus2 : * this = Description ( name , " ZXSpectrum " , " the +2 ROM " , " plus2.rom " , 32 * 1024 , 0xe7a517dcu ) ; break ;
2021-06-04 23:45:47 +00:00
case Name : : SpectrumPlus3 : {
2021-06-06 18:24:38 +00:00
const std : : initializer_list < uint32_t > crcs = { 0x96e3c17a , 0xbe0d9ec4 } ;
* this = Description ( name , " ZXSpectrum " , " the +2a/+3 ROM " , " plus3.rom " , 64 * 1024 , crcs ) ;
2021-06-04 23:45:47 +00:00
} break ;
2021-06-04 01:55:59 +00:00
2023-05-12 18:14:45 +00:00
case Name : : AcornBASICII : * this = Description ( name , " Electron " , " the Acorn BASIC II ROM " , " basic.rom " , 16 * 1024 , 0x79434781u ) ; break ;
case Name : : PRESADFSSlot1 : * this = Description ( name , " Electron " , " the E00 ADFS ROM, first slot " , " ADFS-E00_1.rom " , 16 * 1024 , 0x51523993u ) ; break ;
2021-06-04 23:45:47 +00:00
case Name : : PRESADFSSlot2 : * this = Description ( name , " Electron " , " the E00 ADFS ROM, second slot " , " ADFS-E00_2.rom " , 16 * 1024 , 0x8d17de0eu ) ; break ;
2023-05-12 18:14:45 +00:00
case Name : : AcornADFS : * this = Description ( name , " Electron " , " the Acorn ADFS ROM " , " adfs.rom " , 16 * 1024 , 0x3289bdc6u ) ; break ;
2021-06-05 02:25:11 +00:00
case Name : : Acorn1770DFS : * this = Description ( name , " Electron " , " the 1770 DFS ROM " , " DFS-1770-2.20.rom " , 16 * 1024 , 0xf3dc9bc5u ) ; break ;
2021-06-04 23:45:47 +00:00
case Name : : PRESAdvancedPlus6 :
2021-06-05 02:25:11 +00:00
* this = Description ( name , " Electron " , " the 8kb Advanced Plus 6 ROM " , " AP6v133.rom " , 8 * 1024 , 0xe0013cfcu ) ;
2021-06-04 23:45:47 +00:00
break ;
case Name : : AcornElectronMOS100 :
* this = Description ( name , " Electron " , " the Electron MOS ROM v1.00 " , " os.rom " , 16 * 1024 , 0xbf63fb1fu ) ;
break ;
2021-06-04 01:55:59 +00:00
2024-03-31 01:49:21 +00:00
case Name : : AcornArthur030 :
* this = Description ( name , " Archimedes " , " Arthur v0.30 " , " ROM030 " , 512 * 1024 , 0x5df8ed42u ) ;
break ;
case Name : : AcornRISCOS200 :
* this = Description ( name , " Archimedes " , " RISC OS v2.00 " , " ROM200 " , 512 * 1024 , 0x89c4ad36u ) ;
break ;
2024-03-12 02:19:14 +00:00
case Name : : AcornRISCOS311 :
* this = Description ( name , " Archimedes " , " RISC OS v3.11 " , " ROM311 " , 2 * 1024 * 1024 , 0x54c0c963u ) ;
break ;
2024-03-03 02:44:27 +00:00
case Name : : AcornRISCOS319 :
* this = Description ( name , " Archimedes " , " RISC OS v3.19 " , " ROM319 " , 2 * 1024 * 1024 , 0x00c7a3d3u ) ;
break ;
2021-06-04 23:45:47 +00:00
case Name : : MasterSystemJapaneseBIOS : * this = Description ( name , " MasterSystem " , " the Japanese Master System BIOS " , " japanese-bios.sms " , 8 * 1024 , 0x48d44a13u ) ; break ;
2023-05-12 18:14:45 +00:00
case Name : : MasterSystemWesternBIOS : * this = Description ( name , " MasterSystem " , " the European/US Master System BIOS " , " bios.sms " , 8 * 1024 , 0x0072ed54u ) ; break ;
2021-06-04 23:45:47 +00:00
case Name : : Commodore1540 : * this = Description ( name , " Commodore1540 " , " the 1540 ROM " , " 1540.bin " , 16 * 1024 , 0x718d42b1u ) ; break ;
case Name : : Commodore1541 : * this = Description ( name , " Commodore1540 " , " the 1541 ROM " , " 1541.bin " , 16 * 1024 , 0xfb760019 ) ; break ;
case Name : : Vic20BASIC : * this = Description ( name , " Vic20 " , " the VIC-20 BASIC ROM " , " basic.bin " , 8 * 1024 , 0xdb4c43c1u ) ; break ;
case Name : : Vic20EnglishCharacters : * this = Description ( name , " Vic20 " , " the English-language VIC-20 character ROM " , " characters-english.bin " , 4 * 1024 , 0x83e032a6u ) ; break ;
case Name : : Vic20EnglishPALKernel : * this = Description ( name , " Vic20 " , " the English-language PAL VIC-20 kernel ROM " , " kernel-pal.bin " , 8 * 1024 , 0x4be07cb4u ) ; break ;
case Name : : Vic20EnglishNTSCKernel : * this = Description ( name , " Vic20 " , " the English-language NTSC VIC-20 kernel ROM " , " kernel-ntsc.bin " , 8 * 1024 , 0xe5e7c174u ) ; break ;
case Name : : Vic20DanishCharacters : * this = Description ( name , " Vic20 " , " the Danish VIC-20 character ROM " , " characters-danish.bin " , 4 * 1024 , 0x7fc11454u ) ; break ;
case Name : : Vic20DanishKernel : * this = Description ( name , " Vic20 " , " the Danish VIC-20 kernel ROM " , " kernel-danish.bin " , 8 * 1024 , 0x02adaf16u ) ; break ;
case Name : : Vic20JapaneseCharacters : * this = Description ( name , " Vic20 " , " the Japanese VIC-20 character ROM " , " characters-japanese.bin " , 4 * 1024 , 0xfcfd8a4bu ) ; break ;
case Name : : Vic20JapaneseKernel : * this = Description ( name , " Vic20 " , " the Japanese VIC-20 kernel ROM " , " kernel-japanese.bin " , 8 * 1024 , 0x336900d7u ) ; break ;
case Name : : Vic20SwedishCharacters : * this = Description ( name , " Vic20 " , " the Swedish VIC-20 character ROM " , " characters-swedish.bin " , 4 * 1024 , 0xd808551du ) ; break ;
case Name : : Vic20SwedishKernel : * this = Description ( name , " Vic20 " , " the Swedish VIC-20 kernel ROM " , " kernel-swedish.bin " , 8 * 1024 , 0xb2a60662u ) ; break ;
2021-06-04 23:50:49 +00:00
case Name : : OricColourROM : * this = Description ( name , " Oric " , " the Oric colour ROM " , " colour.rom " , 128 , 0xd50fca65u ) ; break ;
case Name : : OricBASIC10 : * this = Description ( name , " Oric " , " Oric BASIC 1.0 " , " basic10.rom " , 16 * 1024 , 0xf18710b4u ) ; break ;
case Name : : OricBASIC11 : * this = Description ( name , " Oric " , " Oric BASIC 1.1 " , " basic11.rom " , 16 * 1024 , 0xc3a92befu ) ; break ;
case Name : : OricPravetzBASIC : * this = Description ( name , " Oric " , " Pravetz BASIC " , " pravetz.rom " , 16 * 1024 , 0x58079502u ) ; break ;
case Name : : OricByteDrive500 : * this = Description ( name , " Oric " , " the Oric Byte Drive 500 ROM " , " bd500.rom " , 8 * 1024 , 0x61952e34u ) ; break ;
case Name : : OricJasmin : * this = Description ( name , " Oric " , " the Oric Jasmin ROM " , " jasmin.rom " , 2 * 1024 , 0x37220e89u ) ; break ;
case Name : : OricMicrodisc : * this = Description ( name , " Oric " , " the Oric Microdisc ROM " , " microdisc.rom " , 8 * 1024 , 0xa9664a9cu ) ; break ;
case Name : : Oric8DOSBoot : * this = Description ( name , " Oric " , " the 8DOS boot ROM " , " 8dos.rom " , 512 , 0x49a74c06u ) ; break ;
2023-11-17 22:15:57 +00:00
case Name : : PCCompatibleGLaBIOS :
* this = Description ( name , " PCCompatible " , " 8088 GLaBIOS 0.2.5 " , " GLABIOS_0.2.5_8T.ROM " , 8 * 1024 , 0x9576944cu ) ;
break ;
2023-12-07 03:56:09 +00:00
case Name : : PCCompatibleGLaTICK :
* this = Description ( name , " PCCompatible " , " AT GLaTICK 0.8.5 " , " GLaTICK_0.8.5_AT.ROM " , 2 * 1024 , 0x371ea3f1u ) ;
break ;
2023-11-17 22:15:57 +00:00
case Name : : PCCompatiblePhoenix80286BIOS :
* this = Description ( name , " PCCompatible " , " Phoenix 80286 BIOS 3.05 " , " Phoenix 80286 ROM BIOS Version 3.05.bin " , 32 * 1024 , 0x8d0d318au ) ;
break ;
2023-12-06 14:34:04 +00:00
case Name : : PCCompatibleCGAFont :
* this = Description ( name , " PCCompatible " , " IBM's CGA font " , " CGA.F08 " , 8 * 256 , 0xa362ffe6u ) ;
break ;
2023-11-22 19:11:22 +00:00
case Name : : PCCompatibleMDAFont :
* this = Description ( name , " PCCompatible " , " IBM's MDA font " , " EUMDA9.F14 " , 14 * 256 , 0x7754882au ) ;
break ;
2023-12-27 15:05:41 +00:00
case Name : : PCCompatibleEGABIOS :
* this = Description ( name , " PCCompatible " , " IBM's EGA BIOS " , " ibm_6277356_ega_card_u44_27128.bin " , 16 * 1024 , 0x2f2fbc40u ) ;
break ;
case Name : : PCCompatibleVGABIOS :
* this = Description ( name , " PCCompatible " , " IBM's VGA BIOS " , " ibm_vga.bin " , 32 * 1024 , 0x03b3f90du ) ;
break ;
2023-01-11 03:15:01 +00:00
// TODO: CRCs below are incomplete, at best.
2023-01-10 23:17:17 +00:00
case Name : : MSXGenericBIOS : * this = Description ( name , " MSX " , " a generix MSX BIOS " , " msx.rom " , 32 * 1024 , 0x94ee12f3u ) ; break ;
2021-06-04 23:50:49 +00:00
case Name : : MSXJapaneseBIOS : * this = Description ( name , " MSX " , " a Japanese MSX BIOS " , " msx-japanese.rom " , 32 * 1024 , 0xee229390u ) ; break ;
case Name : : MSXAmericanBIOS : * this = Description ( name , " MSX " , " an American MSX BIOS " , " msx-american.rom " , 32 * 1024 , 0u ) ; break ;
case Name : : MSXEuropeanBIOS : * this = Description ( name , " MSX " , " a European MSX BIOS " , " msx-european.rom " , 32 * 1024 , 0u ) ; break ;
case Name : : MSXDOS : * this = Description ( name , " MSX " , " the MSX-DOS ROM " , " disk.rom " , 16 * 1024 , 0x721f61dfu ) ; break ;
2021-06-07 00:34:55 +00:00
2023-01-10 23:17:17 +00:00
case Name : : MSX2GenericBIOS : * this = Description ( name , " MSX " , " a generic MSX2 BIOS " , " msx2.rom " , 32 * 1024 , 0x6cdaf3a5u ) ; break ;
2023-01-11 18:14:42 +00:00
case Name : : MSX2Extension : * this = Description ( name , " MSX " , " the MSX2 extension ROM " , " msx2ext.rom " , 16 * 1024 , 0x66237ecfu ) ; break ;
2023-05-13 03:33:28 +00:00
case Name : : MSXMusic : * this = Description ( name , " MSX " , " the MSX-MUSIC / FM-PAC ROM " , " fmpac.rom " , 64 * 1024 , 0x0e84505du ) ; break ;
2023-01-10 23:17:17 +00:00
2024-12-09 03:03:44 +00:00
case Name : : Plus4KernelPALv3 :
* this = Description ( name , " Plus4 " , " the C16+4 kernel, PAL-G revision 3 " , " kernal.318004-03.bin " , 16 * 1024 , 0x77bab934u ) ;
break ;
case Name : : Plus4KernelPALv4 :
* this = Description ( name , " Plus4 " , " the C16+4 kernel, PAL-G revision 4 " , " kernal.318004-04.bin " , 16 * 1024 , 0xbe54ed79u ) ;
break ;
case Name : : Plus4KernelPALv5 :
* this = Description ( name , " Plus4 " , " the C16+4 kernel, PAL-G revision 5 " , " kernal.318004-05.bin " , 16 * 1024 , 0x71c07bd4u ) ;
break ;
case Name : : Plus4BASIC :
* this = Description ( name , " Plus4 " , " the C16+4 BASIC ROM " , " basic.318006-01.bin " , 16 * 1024 , 0x74eaae87u ) ;
break ;
2021-06-07 00:34:55 +00:00
case Name : : SinclairQLJS :
* this = Description ( name , " SinclairQL " , " the Sinclair QL 'JS' ROM " , " js.rom " , 48 * 1024 , 0x0f95aab5u ) ;
break ;
2021-06-04 23:45:47 +00:00
}
}