VOGONS


Reply 20 of 40, by maxtherabbit

User metadata
Rank l33t
Rank
l33t
TheMobRules wrote on 2023-08-04, 02:08:

[*][2128-212C] Result of reading port 22h bit 0 must be 1[/list]

Now, I'm not sure what the last two options mean, but in any case my assumption was that one of those checks was failing, so I wrote a small assembly program that tests those values and bingo! The last one, where port 22h is read and a value of 1 is expected in bit 0 did not pass.

Since the value read from 22h is immediately discarded and not used anywhere else, this check must not affect anything else in the code. So, the patch was easy: I just replaced the JZ instruction that jumps away with a couple of NOPs, since the 1T timing for Cache Burst Read should be easily achievable with 15ns:

Perhaps they intended it to be a read of port 23h (checking bit 0 of whatever register index was previously selected)?

Reply 21 of 40, by jesolo

User metadata
Rank l33t
Rank
l33t

A huge thank you to JakeThompson & TheMobRules.

Being an accountant by profession with zero programming knowledge made it easy for me also understand how to edit the AMIBIOS for my OPTI 495XLC chipset-based motherboards (after a bit of trial and error using PCem).
My idea is to use the BIOS image from another motherboard manufacturer (A-Trend) on my Jetway motherboard - the reason for this has to do with the turbo switch functionality and the fact that it doesn't work at all when the PC is in "protected mode" (with EMM386.EXE load). I'm not sure whether this actually has to do with the chipset or whether this is something in the BIOS. I'm hoping to confirm this by trying out the other BIOS image. In other words, I want to see whether the A-Trend BIOS works "better" but, it has some options hidden which are unhidden on my Jetway motherboard and hence, why this post is quite helpful.

Apart from that, the Jetway BIOS just works very weird by disabling the turbo function when the turbo header is shorted but then disables (switches "off") the turbo LED (and enables the turbo function when the header is not shorted and then switches "on" the turbo LED). It's supposed to work the other way around. There must a register somewhere in the BIOS where one can flip this as I've seen in some of the MR BIOS documentation that they released different BIOS versions that also flipped the turbo switch functionality around.

Reply 22 of 40, by TheMobRules

User metadata
Rank Oldbie
Rank
Oldbie
maxtherabbit wrote on 2023-08-04, 12:59:

Perhaps they intended it to be a read of port 23h (checking bit 0 of whatever register index was previously selected)?

That could indeed be the case, however in the chipset docs they clearly mention the need for writing to 22h before every access due to the index being reset after every read/write:

SiS wrote:

The index is reset after each data access. Every data access to port 23h must be preceded by an index write to port 22h, even if the same register is being accessed.

Then I thought it may be related to Cyrix CPUs, since it uses the same pair of I/O ports as the SiS chipset (22h/23h) for accessing some CPU registers (although a different range of values), and in other sections of the BIOS I noticed that reads of port 22h appeared to be followed by access of some Cyrix configuration control registers. However in the Cyrix 5x86 CPU BIOS Writer's Guide it says that:

Cyrix wrote:

Each port-23h data transfer must be preceded by a port-22h register index selection, otherwise the second and later port-23h operations are directed off-chip and produce external I/O cycles. Reads of I/O port 22h are always directed off-chip.

My guess right now is that the AMI BIOS is using port 22h as some undocumented status register (the range of values is probably restricted to avoid conflicts with the registers for both the SiS chipset and Cyrix CPUs). If that's the case, then what would be that last check that is performed to allow setting the Cache Burst Read Cycle to 1T? Well, the answer may be in the datasheet for the slightly older SiS460 chipset, direct ancestor of the SiS471. Here's what it says about reg. 51h:

The attachment SiS460_reg51.jpg is no longer available

Identical to the 471, with the exception that the Cache Burst Read Cycle should only be set to 1 (2T) for 386 CPUs which the 460 supports.

Knowing this, my (very speculative) theory about this is: with the SiS 460 and 471 chipset being so similar in terms of register configuration, this SiS 471 AMI BIOS probably inherited lots of legacy code from older 460 BIOS (the presence of stuff like 80286 or 486SLC/DLC in the table of supported CPUs could also be an indication of copy-pasting code from previous BIOSes by the developers). So, that section that gates the Cache Burst Read Cycle setting behind some checks would be a leftover from an older SiS460 BIOS that went unnoticed during testing (which given the problems with some of the other timing settings would be consistent with subpar QA on AMI's side).

Reply 23 of 40, by TheMobRules

User metadata
Rank Oldbie
Rank
Oldbie
jesolo wrote on 2023-08-05, 21:19:
A huge thank you to JakeThompson & TheMobRules. […]
Show full quote

A huge thank you to JakeThompson & TheMobRules.

Being an accountant by profession with zero programming knowledge made it easy for me also understand how to edit the AMIBIOS for my OPTI 495XLC chipset-based motherboards (after a bit of trial and error using PCem).
My idea is to use the BIOS image from another motherboard manufacturer (A-Trend) on my Jetway motherboard - the reason for this has to do with the turbo switch functionality and the fact that it doesn't work at all when the PC is in "protected mode" (with EMM386.EXE load). I'm not sure whether this actually has to do with the chipset or whether this is something in the BIOS. I'm hoping to confirm this by trying out the other BIOS image. In other words, I want to see whether the A-Trend BIOS works "better" but, it has some options hidden which are unhidden on my Jetway motherboard and hence, why this post is quite helpful.

Apart from that, the Jetway BIOS just works very weird by disabling the turbo function when the turbo header is shorted but then disables (switches "off") the turbo LED (and enables the turbo function when the header is not shorted and then switches "on" the turbo LED). It's supposed to work the other way around. There must a register somewhere in the BIOS where one can flip this as I've seen in some of the MR BIOS documentation that they released different BIOS versions that also flipped the turbo switch functionality around.

The turbo function is controlled by the OPTI chipset. My first suggestion would be to take a look at the datasheet if you haven't yet (attached below), section 4.15. Interestingly, it mentions that turbo mode is only supported when using 386 CPUs as the pin controlling it has another purpose for 486. It doesn't seem to mention anything about protected mode though. What's the setup your testing with?

Reply 24 of 40, by maxtherabbit

User metadata
Rank l33t
Rank
l33t
TheMobRules wrote on 2023-08-05, 23:11:

they clearly mention the need for writing to 22h before every access due to the index being reset after every read/write

that's quite unusual behaviour

Reply 25 of 40, by jesolo

User metadata
Rank l33t
Rank
l33t
TheMobRules wrote on 2023-08-06, 00:10:
jesolo wrote on 2023-08-05, 21:19:
A huge thank you to JakeThompson & TheMobRules. […]
Show full quote

A huge thank you to JakeThompson & TheMobRules.

Being an accountant by profession with zero programming knowledge made it easy for me also understand how to edit the AMIBIOS for my OPTI 495XLC chipset-based motherboards (after a bit of trial and error using PCem).
My idea is to use the BIOS image from another motherboard manufacturer (A-Trend) on my Jetway motherboard - the reason for this has to do with the turbo switch functionality and the fact that it doesn't work at all when the PC is in "protected mode" (with EMM386.EXE load). I'm not sure whether this actually has to do with the chipset or whether this is something in the BIOS. I'm hoping to confirm this by trying out the other BIOS image. In other words, I want to see whether the A-Trend BIOS works "better" but, it has some options hidden which are unhidden on my Jetway motherboard and hence, why this post is quite helpful.

Apart from that, the Jetway BIOS just works very weird by disabling the turbo function when the turbo header is shorted but then disables (switches "off") the turbo LED (and enables the turbo function when the header is not shorted and then switches "on" the turbo LED). It's supposed to work the other way around. There must a register somewhere in the BIOS where one can flip this as I've seen in some of the MR BIOS documentation that they released different BIOS versions that also flipped the turbo switch functionality around.

The turbo function is controlled by the OPTI chipset. My first suggestion would be to take a look at the datasheet if you haven't yet (attached below), section 4.15. Interestingly, it mentions that turbo mode is only supported when using 386 CPUs as the pin controlling it has another purpose for 486. It doesn't seem to mention anything about protected mode though. What's the setup your testing with?

I currently have a Cyrix 486DLC 40 MHz installed with 8 MB RAM and a Tseng Labs ET4000 16-bit ISA graphics card.
I must be honest; I haven't yet tried to test a real 486 in this PC to see if the turbo functionality work. My intention with this setup was to recreate my original PC that I bought back in 1993 (it came with the Cyrix CPU on the Jetway motherboard - J-402B).
But, here's the interesting part:
In protected mode the turbo button doesn't work. However, when I press Ctrl + Alt + -, it does slow down the system.
In real mode, the turbo button does work, together with the keyboard shortcut.

To quickly summarise. The original BIOS became corrupted some years ago and I tried for a long time to find a suitable replacement. Eventually a user with a 486 only version of the motherboard (which I now suspect is model number J-403) provided a BIOS which has the same options as my BIOS did and, for the most part, works perfectly. The only odd behaviour is the turbo functionality. More in this post: Help me identify and obtain a BIOS for my old 3/486 VL motherboard

What I've done now was to look for similar BIOS revisions. I eventually found one from the "BEK-tronic BEK-3739" motherboard (from TheRetroWeb). The only issue I had with this BIOS is that a lot of the options were hidden but, now I found a way to unhide them and make it "appear" like my BIOS (and what I also see in the manual). Unfortunately, with this BIOS, both in protected and real mode, the turbo switch doesn't function (the keyboard shortcut does). This is despite the Turbo Switch function being enabled in the Advanced CMOS Setup.

Reply 26 of 40, by ahyeadude

User metadata
Rank Member
Rank
Member

Thanks @jakethompson1 for this great guide. I used it to successfully add PS2 mouse support to my 386sx board.

I decided to nerd out today and create a AMIBIOS checksum calculator in python based on your find. It can also calculate the 2-byte addition required to make the checksum equal to zero so that it passes that check.

Example output on my PS2 modified bios:

Checksum does not equal zero!!!
Checksum: 16
2 byte addition needed to validate checksum: F0 FF

I then added F0 FF to the middle of large blank area of the bios at 0x6000. Can run it again to verify:

Checksum equals zero
Checksum: 0

I flashed and it works great. Nice to know if there is a bit-flip down the road (unlikely, I know) the bios should catch it.

Python file attached.

Reply 27 of 40, by Anonymous Coward

User metadata
Rank l33t
Rank
l33t

I'm a little late to the party, but thanks for making this checksum calculator. I prefer to have the checksum recalculated rather than disabled entirely.

In case anyone else tries this out, I think I may have found one small bug in the program. In order to get it to work with my ROM image, I had to remove all the blank spaces from the file name.

"Will the highways on the internets become more few?" -Gee Dubya
V'Ger XT|Upgraded AT|Ultimate 386|Super VL/EISA 486|SMP VL/EISA Pentium

Reply 28 of 40, by analog_programmer

User metadata
Rank Oldbie
Rank
Oldbie
ahyeadude wrote on 2023-10-29, 20:27:
I decided to nerd out today and create a AMIBIOS checksum calculator in python based on your find. It can also calculate the 2-b […]
Show full quote

I decided to nerd out today and create a AMIBIOS checksum calculator in python based on your find. It can also calculate the 2-byte addition required to make the checksum equal to zero so that it passes that check.

Example output on my PS2 modified bios:

Checksum does not equal zero!!!
Checksum: 16
2 byte addition needed to validate checksum: F0 FF

I then added F0 FF to the middle of large blank area of the bios at 0x6000. Can run it again to verify:

Checksum equals zero
Checksum: 0

I flashed and it works great. Nice to know if there is a bit-flip down the road (unlikely, I know) the bios should catch it.

Hi, ahyeadude. Your AMI "color" BIOS checksum calculator python script works very well. I slightly modified your code, so the script now also reads old values of checksum bytes from BIOS-dump file at address 0000:FF50 and then, if the checksum is not zero calculates new values for them. I made this just for convenience of hex-editing the two bytes at address FF50 instead of throwing some byte values in empty BIOS blocks. If you allow me, I'll share the modified code for your script.

The outputs from modified version look like this:

Checksum bytes at address 0000:FF50 (hex): D7 A6
Checksum does not equal zero!!!
Checksum (integer): 40453
2 byte addition needed to validate checksum (hex): FB 61
Hex-edit checksum bytes at address 0000:FF50 with these values (hex): D2 08
Checksum bytes at address 0000:FF50 (hex): D2 08
Checksum equals zero.
Checksum (integer): 0
Last edited by analog_programmer on 2024-07-16, 14:34. Edited 1 time in total.

from СМ630 to Ryzen gen. 3
engineer's five pennies: this world goes south since everything's run by financiers and economists
this isn't voice chat, yet some people, overusing online communications, "talk" and "hear voices"

Reply 30 of 40, by ahyeadude

User metadata
Rank Member
Rank
Member
analog_programmer wrote on 2024-07-16, 06:05:
Hi, ahyeadude. Your AMI "color" BIOS checksum calculator python script works very well. I slightly modified your code, so the sc […]
Show full quote
ahyeadude wrote on 2023-10-29, 20:27:
I decided to nerd out today and create a AMIBIOS checksum calculator in python based on your find. It can also calculate the 2-b […]
Show full quote

I decided to nerd out today and create a AMIBIOS checksum calculator in python based on your find. It can also calculate the 2-byte addition required to make the checksum equal to zero so that it passes that check.

Example output on my PS2 modified bios:

Checksum does not equal zero!!!
Checksum: 16
2 byte addition needed to validate checksum: F0 FF

I then added F0 FF to the middle of large blank area of the bios at 0x6000. Can run it again to verify:

Checksum equals zero
Checksum: 0

I flashed and it works great. Nice to know if there is a bit-flip down the road (unlikely, I know) the bios should catch it.

Hi, ahyeadude. Your AMI "color" BIOS checksum calculator python script works very well. I slightly modified your code, so the script now also reads old values of checksum bytes from BIOS-dump file at address 0000:55FF and then, if the checksum is not zero calculates new values for them. I made this just for convenience of hex-editing the two bytes at address 55FF instead of throwing some byte values in empty BIOS blocks. If you allow me, I'll share the modified code for your script.

The outputs from modified version look like this:

Checksum bytes at address 0000:FF50 (hex): D7 A6
Checksum does not equal zero!!!
Checksum (integer): 40453
2 byte addition needed to validate checksum (hex): FB 61
Hex-edit checksum bytes at address 0000:FF50 with these values (hex): D2 08
Checksum bytes at address 0000:FF50 (hex): D2 08
Checksum equals zero.
Checksum (integer): 0

Cool, I didn't realize there was a designated spot for the checksum bytes. You can for sure post it.

Thanks!

Reply 31 of 40, by Anonymous Coward

User metadata
Rank l33t
Rank
l33t

I'm not much of a software guy, but if you could get the script to actually patch the ROM image automatically, that would be ever better!

"Will the highways on the internets become more few?" -Gee Dubya
V'Ger XT|Upgraded AT|Ultimate 386|Super VL/EISA 486|SMP VL/EISA Pentium

Reply 32 of 40, by analog_programmer

User metadata
Rank Oldbie
Rank
Oldbie
ahyeadude wrote on 2024-07-16, 14:08:

Cool, I didn't realize there was a designated spot for the checksum bytes. You can for sure post it.

Thanks!

Thank you! Actually the checksum bytes address is FF50 and this is mentioned by thread's author jakethompson1 and TheMobRules on the first page.

Here it is the modified python 3 code:

#!/usr/bin/env python3
#
# loads amibios and calculates checksum (16 bit sequential) and value needed to validate (if checksum != 0)

import sys

try:
bios_file = sys.argv[1]
with open(bios_file, mode='rb') as file:
bios_data = file.read()
file.seek(65360, 0)
first_chk_word_byte = file.read(1)
second_chk_word_byte = file.read(1)
print(
f'Checksum bytes at address 0000:FF50 (hex): '
f'{first_chk_word_byte.hex().upper()} {second_chk_word_byte.hex().upper()}'
)
except:
print('Usage: amichksumcalc.py path_to_rom_file.bin')
sys.exit()

block_count = int(len(bios_data) / 16)
checksum = 0
for block in range(0, block_count):
bios_block = bios_data[block * 16: block * 16 + 16]
block_checksum = 0
for byte_pair in range(0, 8):
byte_pair_hex = (bios_block[byte_pair * 2 + 1: byte_pair * 2 + 2].hex() +
bios_block[byte_pair * 2:byte_pair * 2 + 1].hex())
byte_pair_dec = int(byte_pair_hex, 16)
block_checksum += byte_pair_dec
block_checksum %= 65536
checksum += block_checksum
checksum %= 65536
if checksum != 0:
print('Checksum does not equal zero!!!')
print(f'Checksum (integer): {str(checksum)}')
two_byte_addition = int(65536 - checksum).to_bytes(2, "little").hex(" ").upper()
print(f'2 byte addition needed to validate checksum (hex): {two_byte_addition}')
new_first_byte = (int(bytearray.fromhex(two_byte_addition)[0]) +
int.from_bytes(first_chk_word_byte, "little"))
correction = new_first_byte.to_bytes(2, "little").hex(" ").upper()
new_second_byte = (int(bytearray.fromhex(two_byte_addition)[1]) +
int(bytearray.fromhex(correction)[1]) +
int.from_bytes(second_chk_word_byte, "little"))
print(
f'Hex-edit checksum bytes at address 0000:FF50 with these values (hex): '
f'{new_first_byte.to_bytes(2, "little").hex(" ").upper().split(" ")[0]} '
f'{new_second_byte.to_bytes(2, "little").hex(" ").upper().split(" ")[0]}'
)
else:
print('Checksum equals zero.')
print(f'Checksum (integer): {str(checksum)}')

I've tested the code with a couple of 386/486 AMI BIOSes and for me it works fine. I'm sure it can be written in more efficient an clean way, but this is my "quick and dirty" solution for now. Any feedback will be appreciated.

Anonymous Coward wrote on 2024-07-16, 14:24:

I'm not much of a software guy, but if you could get the script to actually patch the ROM image automatically, that would be ever better!

Sure, it's possible. I also thought about this, but for now (for tests) I prefer to manually hex-edit the BIOS dumps.

P.S. I'm attaching the modified ahyeadude's python script in а zip-file, so that fellow forum members don't bother copy-pasting the code from this post.

The attachment amichksumcalc.zip is no longer available

from СМ630 to Ryzen gen. 3
engineer's five pennies: this world goes south since everything's run by financiers and economists
this isn't voice chat, yet some people, overusing online communications, "talk" and "hear voices"

Reply 33 of 40, by feipoa

User metadata
Rank l33t++
Rank
l33t++
analog_programmer wrote on 2024-07-16, 06:05:
Hi, ahyeadude. Your AMI "color" BIOS checksum calculator python script works very well. I slightly modified your code, so the sc […]
Show full quote
ahyeadude wrote on 2023-10-29, 20:27:
I decided to nerd out today and create a AMIBIOS checksum calculator in python based on your find. It can also calculate the 2-b […]
Show full quote

I decided to nerd out today and create a AMIBIOS checksum calculator in python based on your find. It can also calculate the 2-byte addition required to make the checksum equal to zero so that it passes that check.

Example output on my PS2 modified bios:

Checksum does not equal zero!!!
Checksum: 16
2 byte addition needed to validate checksum: F0 FF

I then added F0 FF to the middle of large blank area of the bios at 0x6000. Can run it again to verify:

Checksum equals zero
Checksum: 0

I flashed and it works great. Nice to know if there is a bit-flip down the road (unlikely, I know) the bios should catch it.

Hi, ahyeadude. Your AMI "color" BIOS checksum calculator python script works very well. I slightly modified your code, so the script now also reads old values of checksum bytes from BIOS-dump file at address 0000:FF50 and then, if the checksum is not zero calculates new values for them. I made this just for convenience of hex-editing the two bytes at address FF50 instead of throwing some byte values in empty BIOS blocks. If you allow me, I'll share the modified code for your script.

The outputs from modified version look like this:

Checksum bytes at address 0000:FF50 (hex): D7 A6
Checksum does not equal zero!!!
Checksum (integer): 40453
2 byte addition needed to validate checksum (hex): FB 61
Hex-edit checksum bytes at address 0000:FF50 with these values (hex): D2 08
Checksum bytes at address 0000:FF50 (hex): D2 08
Checksum equals zero.
Checksum (integer): 0

Indeed, this seems cleaner. Thanks!

I also think an option to have the script modify the BIOS would be a nice to have. e.g. "do you want this programme to amend your BIOS with this information: Y or N?"

Plan your life wisely, you'll be dead before you know it.

Reply 34 of 40, by analog_programmer

User metadata
Rank Oldbie
Rank
Oldbie
feipoa wrote on 2024-07-18, 07:07:

I also think an option to have the script modify the BIOS would be a nice to have. e.g. "do you want this programme to amend your BIOS with this information: Y or N?"

Thanks for the suggestion. I can add autopatching for BIOS-dump file after manual confirmation, but first I want to be sure, that my part of the code for calculating the new values of two checksum bytes at address 0000:FF50 works correctly (I've used some messy data type conversions, 'cause I wanted to reuse original ahyeadude's algorithm and code for calculation of the two bytes addition, which is proven to work correctly).

    new_first_byte = (int(bytearray.fromhex(two_byte_addition)[0]) +
int.from_bytes(first_chk_word_byte, "little"))
correction = new_first_byte.to_bytes(2, "little").hex(" ").upper()
new_second_byte = (int(bytearray.fromhex(two_byte_addition)[1]) +
int(bytearray.fromhex(correction)[1]) +
int.from_bytes(second_chk_word_byte, "little"))
Calculating the new values of two checksum bytes

from СМ630 to Ryzen gen. 3
engineer's five pennies: this world goes south since everything's run by financiers and economists
this isn't voice chat, yet some people, overusing online communications, "talk" and "hear voices"

Reply 35 of 40, by Deunan

User metadata
Rank Oldbie
Rank
Oldbie

I'm not sure why the script breaks up the BIOS into 16-byte blocks? Also, it can be made a little bit smaller if arrays are used, here's what I wrote for my own needs:

import sys
from array import array

if len (sys.argv) <= 1:
print ("Usage: chks16 <BIOS ROM image>")
exit ()

data = array ('H')

with open (sys.argv [1], 'rb') as f:
data.fromfile (f, 0x8000)

c = 0
for i in range (0x8000):
c += data [i]
c &= 0xFFFF

print ("Checksum (16-bit): 0x{:04X}".format (c))

That's obviously a simpler version that assumes 64k sized BIOS but changing that, and adding a correction value printout would be just a few more lines. I just like to keep things simple.

Reply 36 of 40, by analog_programmer

User metadata
Rank Oldbie
Rank
Oldbie

Deunan, I think ahyeadude made his more complex solution because of the console messages representation. I just decided to use his code with some useful addition.

P.S. Ah I see, you mean the part for the checksum calculations. Maybe a matter of problem solving approach 😀 Your code works fine too.

from СМ630 to Ryzen gen. 3
engineer's five pennies: this world goes south since everything's run by financiers and economists
this isn't voice chat, yet some people, overusing online communications, "talk" and "hear voices"

Reply 37 of 40, by ahyeadude

User metadata
Rank Member
Rank
Member

Yea, i did it in blocks because it was easier to manually check the calculation to debug. Absolutely not required.

Another way to modfiy the checksum word without modifying my code would be to zero it out in a hex editor before hand then run the calculator.

Reply 39 of 40, by jakethompson1

User metadata
Rank Oldbie
Rank
Oldbie
Anonymous Coward wrote on 2024-07-19, 00:37:

Would any of you guys happen to know how the checksum works on an Award V4.5x BIOS?

See discussion about the 1994 bug: Fix for Award BIOS Year 2094 bug
It's a single byte sum with the value stored in the last byte of the ROM.
However, as I found, sometimes there are parts of the ROM not covered by the checksum in the compressed ones.