Figured out the AMI pre-Color string encoding

This commit is contained in:
RichardG867
2022-03-15 18:18:46 -03:00
parent a5b1b6a84b
commit ee63d6e865
2 changed files with 19 additions and 83 deletions

View File

@@ -83,13 +83,12 @@ python3 -m biostools -a roms/0 | tee bioslist.csv
### AMI
* **Pre-Color** (1990 and older) BIOSes have a dynamically-generated string that is not easily extractable; the analyzer will attempt to reconstruct it around the limited data contained in the ROM in a best-effort basis.
* The string on **UEFI** is a hidden string located within the AMIBIOS 8-based Compatibility Support Module (CSM). A missing string may indicate a lack of CSM.
* The string on **UEFI** is a hidden string located within the AMIBIOS 8-based Compatibility Support Module (CSM). A missing string may indicate a missing CSM.
### Award
* The core version can be followed by `(Phoenix)` on BIOSes which identify as **Phoenix AwardBIOS**, or `(Workstation)` on ones which identify as **Award WorkstationBIOS**.
* OEM modifications which interfere with detection: **Sukjung** (string)
* OEM modifications which may interfere with detection: **Sukjung** (string)
### IBM

View File

@@ -332,9 +332,7 @@ class AMIAnalyzer(Analyzer):
self._precolor_block_pattern = re.compile(b'''\(C\)(?:[0-9]{4}(?:AMI,404-263-8181|TGem-HCS,PSC,JGS)|( Access Methods Inc\.))''')
# "Date:-" might not have a space after it (Intel AMI)
self._precolor_date_pattern = re.compile(b'''(?:(?: Date:- ?|AMI- )[0-9]{2}/[0-9]{2}/[0-9]{2}|DDaattee(?:::| )--(?: )?([0-9])\\1([0-9])\\2//([0-9])\\3([0-9])\\4//([0-9])\\5([0-9])\\6)''')
# "286/386/386sx/486-BIOS" are known ("386sx" = TriGem), others are what-if
self._precolor_chipset_pattern = re.compile(b'''(SETUP PROGRAM FOR [\\x20-\\x7E]+)|(EMI 386 CHIPSET SETUP UTILITY)|(VLSI BIOS, 286 CHIPSET)|(CHIP & TECH SETUP PROGRAM)|( 286 BIOS)|(386 BIOS, NO CHIPSET)|([0-9]86(?:[DdSs][Xx]|[Ss][Ll][Cc]?)?-BIOS \(C\))''')
self._precolor_extsetup_pattern = re.compile(b'''EXTENDED (?:CMOS )?SETUP PROGRAM''')
self._precolor_string_pattern = re.compile(b'''\\xFE{4}((?:[\\x00-\\xFF]{4}\\x96){2}[\\x00-\\xFF]{6})''')
self._precolor_signon_pattern = re.compile(b'''BIOS \(C\).*(?:AMI|American Megatrends Inc), for ([\\x0D\\x0A\\x20-\\x7E]+)''')
self.register_check_list([
@@ -420,90 +418,29 @@ class AMIAnalyzer(Analyzer):
# Access Methods doesn't have the setup type and chipset.
if not match.group(1):
# Reconstruct string, starting with the setup type.
if b'ROM DIAGNOSTICS.(C)' in file_data:
self.string = 'D'
elif self._precolor_extsetup_pattern.search(file_data):
self.string = 'E'
else:
self.string = 'S'
# Add chipset. Known undetectable codes due
# to a lack of BIOS images or marker strings:
# - 307 (C&T CS8236)
# - GS2 (GoldStar)
# - INT (Intel 82335)
# - PAQ (Compaq)
# - S24 (??? Morse KP286)
# - SUN (Suntac)
# - VLX (VLSI 386?)
chipset = '???'
match = self._precolor_chipset_pattern.search(file_data)
# Locate the encoded string.
match = self._precolor_string_pattern.search(file_data)
if match:
setup_program_for = match.group(1) # "SETUP PROGRAM FOR"
if setup_program_for:
#if b' C&T ' in setup_program_for: # not necessary with fallback below
# chipset = 'C&T'
if b' INTEL 386 ' in setup_program_for:
chipset = '343'
elif b' NEAT ' in setup_program_for:
if b'NEATsx Memory Controller Identifier' in file_data:
chipset = 'NSX'
else:
chipset = 'NET'
elif b' OPTI ' in setup_program_for:
chipset = 'OPB'
elif b' SCAT ' in setup_program_for:
chipset = 'SC2'
elif b' SIS ' in setup_program_for:
chipset = 'SIS'
else:
# Your guess is as good as mine.
chipset = setup_program_for[18:21].decode('cp437', 'ignore')
if chipset != 'C&T':
self.signon = 'DEBUG:UnknownSetup:' + setup_program_for.decode('cp437', 'ignore')
else:
bios_id_index = match.start(5) # " 286 BIOS"
if bios_id_index > -1:
bios_id = file_data[bios_id_index - 10:bios_id_index + 1]
if b'ACER 1207 ' in bios_id:
chipset = 'AR2'
elif b'HT-11 ' in bios_id:
chipset = 'H12'
elif b'HT-1X ' in bios_id:
chipset = 'H1X'
elif b'NEAT ' in bios_id: # assumed; not bootable on 86Box
chipset = 'NET'
elif b'SCAT ' in bios_id:
chipset = 'SC2'
elif b'WIN ' in bios_id: # Winbond; not bootable on 86Box, source is a MAME comment
chipset = '286'
else:
self.signon = 'DEBUG:UnknownChipset:' + bios_id.decode('cp437', 'ignore')
elif match.group(2): # "EMI 386 CHIPSET SETUP UTILITY"
chipset = 'EMI'
elif match.group(3): # "VLSI BIOS, 286 CHIPSET"
chipset = 'VL2'
elif match.group(4): # "CHIP & TECH SETUP PROGRAM"
chipset = 'C&T'
elif match.group(6): # "386 BIOS, NO CHIPSET"
chipset = 'INT'
else:
x86_bios = match.group(7) # "[234]86-BIOS (C)"
if x86_bios:
chipset = x86_bios[:3].decode('cp437', 'ignore')
self.string += chipset + '-'
# Extract string.
self.string = ''
for c in match.group(1):
c = ~c & 0xff
c = ((c << 5) | (c >> 3)) & 0xff
self.string += chr(c)
return True
else:
# Fallback if we can't find the encoded string.
self.string = '????-'
# Add vendor ID.
self.string += codecs.encode(file_data[id_block_index - 0xbb:id_block_index - 0xb9], 'hex').decode('ascii', 'ignore').upper()
# Add date. Use the entry point date instead of the identification block one, as it
# appears the entry point one is displayed on screen. (Shuttle 386SX, TriGem 486-BIOS)
# Add date.
self.string += '-' + util.read_string(file_data[id_block_index + 0x9c:id_block_index + 0xa4]).replace('/', '').strip()
# Invalidate string if the identification block
# doesn't appear to be valid. (Intel AMI post-Color)
if self.string[:10] in ('S???-0000-', 'S???-0166-') and file_data[id_block_index - 0xb9:id_block_index - 0xb7] != b'\x00\x01':
# Invalidate string if the identification block doesn't
# appear to be valid. (Intel AMI post-Color without string)
if self.string[:10] in ('????-0000-', '????-0166-'):
self.string = ''
return True
elif check_match.group(1): # 8088-BIOS header