VOGONS


AMI Color BIOS (1993 and earlier) modification in hex editor

Topic actions

Reply 80 of 84, by feipoa

User metadata
Rank l33t++
Rank
l33t++
analog_programmer wrote on 2025-09-07, 06:10:

Look, if you want Python 3.6 compatibility version -

That's not what I said.

feipoa wrote on 2025-09-07, 05:11:

I am also OK with trying the workarounds in Ubuntu 18.04.

...meaning, I'm perfectly OK to trying snap versions for newer Python3 versions (3.8-3.10), I just haven't gotten to this yet.

My previous post was saying that I can understand how there is interest in new software for older operating systems, nothing more.

analog_programmer wrote on 2025-09-07, 06:10:

Do you see how responsive and helpful I am trying to be, even without "please, could you fix it for me?" :) And I still haven't received a single positive feedback comment for the stupid script.

There have only been 6 downloads of your script zip file, and some of those 6 may be duplicates. I don't think many people have gotten to this yet. Don't expect quick turnarounds on vintage computer hobby things like this.

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

Reply 81 of 84, by 8bitbubsy

User metadata
Rank Member
Rank
Member

Did anyone manage to find out where the "BIOS defaults" values are stored in an AMIBIOS ROM file? I need to modify a BIOS ROM (11/11/92) that has memory parity check enabled by default, which makes the system crash with a parity error. Kind of annoying having to remember to disable this every time CMOS is invalidated/lost.

EDIT: OK, I was able to locate and change some of the default CMOS values in the ROM.
In my AMI BIOS ROM file, there's a table at offset 0x873C that looks like this:

0x11 0xFF 0xBB 0xAB
0x13 0xFF 0xB8 0x30
0x2D 0xFF 0x7D 0x71
[...]

Every entry has four bytes in the table. First byte is the actual CMOS register to write to, second byte is some kind of mask (0xFF = no mask), third byte is the actual register bits, fourth byte is unknown (seems to be unused or used for something completely different, I didn't have to change those). Then follows a new entry, for CMOS register 0x13. Get it? 😀

So to figure out what bit bytes to change, I used this reference: https://bochs.sourceforge.io/techspec/CMOS-reference.txt
Let's say I wanted to disable memory parity. According to the reference, that setting lies in bit 4 of CMOS register 0x11 (the very first entry in our table). 0xBB is its bits value, that is 10111011 in binary. Bit 4 is set to 1 there, so I just changed it to 0 instead. That would mean changing byte 0x873E in the ROM from 0xBB to 0xAB (4th bit cleared).

Make sure to update the checksum word at 0xFF50 before writing ROM to EPROM chip. If you use the C programming language, then this snippet should be quick n' simple (little-endian code for now):

uint16_t *p16 = (uint16_t *)biosROM;

uint16_t checksum = 0;
for (int32_t i = 0; i < 65536/2; i++)
checksum += p16[i];

p16[0xFF50/2] -= checksum;

-

So how did I find out that the "BIOS defaults" CMOS table was at offset 0x873C? Surely this differs from ROM to ROM? Well, that's the complicated part.
I disassembled the BIOS ROM, looked for "out 0x71,al" instructions, and was able to locate the WriteToCMOS routine. I then searched for all its function calls, and found something like this (modified for clarity):

		mov cx,8982h ; number of CMOS entries to change (absolute offset in ROM)
jcxz .done
mov si,873Ch ; offset to CMOS table (absolute offset in ROM)
.loop: mov al,cs:[si]
or al,80h ; set "NMI disable" bit
call ReadFromCMOS
; ---------------
mov ah,cs:[si+2]
mov dl,cs:[si+1]
and ah,dl
not dl
and al,dl
or ah,al
mov al,cs:[si]
or al,80h ; set "NMI disable" bit
call WriteToCMOS
; ---------------
add si,4
loop .loop
.done:

So there you go. 😅

386:
- CPU: 386DX-40 + 40MHz FPU + 128kB L1 cache
- RAM: 8MB (0 waitstates @ 40MHz)
- VGA: Diamond SpeedSTAR VGA (ET4000AX 1MB ISA)
- Audio: Sound Blaster Pro 2.0 + GUS 1MB
- ISA PS/2 mouse card
- MR BIOS

Reply 82 of 84, by maxtherabbit

User metadata
Rank l33t
Rank
l33t

cool I guess, but how frequently are your CMOS options really invalidated or lost?

Reply 83 of 84, by jakethompson1

User metadata
Rank l33t
Rank
l33t
8bitbubsy wrote on 2025-10-17, 13:19:

Every entry has four bytes in the table. First byte is the actual CMOS register to write to, second byte is some kind of mask (0xFF = no mask), third byte is the actual register bits, fourth byte is unknown (seems to be unused or used for something completely different, I didn't have to change those). Then follows a new entry, for CMOS register 0x13. Get it? 😀

Hello,

You should find of the third and fourth byte, one is the "BIOS" default setting (performance) and the other is the "power-on" default setting (compatibility). I don't remember which is which.
You should find that at 0x8296 is a pointer to 0x873C (or somewhere nearby) for your BIOS. I suspect this pointer is what AMIBCP would use to find the defaults table. See Re: AMI Color BIOS (1993 and earlier) modification in hex editor

Reply 84 of 84, by 8bitbubsy

User metadata
Rank Member
Rank
Member
maxtherabbit wrote on 2025-10-18, 13:42:

cool I guess, but how frequently are your CMOS options really invalidated or lost?

Well, I have a small external battery connected with a short wire, and sometimes (though very rarely) when I mess around in the computer it gets disconnected. Also, If I store the computer somewhere for many years and the battery goes low, I could've forgotten about the memory parity thing. I just think it's more practical that it's off by default (and now I have made the setting hidden as well).

jakethompson1 wrote on 2025-10-19, 03:40:

Hello,

You should find of the third and fourth byte, one is the "BIOS" default setting (performance) and the other is the "power-on" default setting (compatibility). I don't remember which is which.
You should find that at 0x8296 is a pointer to 0x873C (or somewhere nearby) for your BIOS. I suspect this pointer is what AMIBCP would use to find the defaults table. See Re: AMI Color BIOS (1993 and earlier) modification in hex editor

Ah I see, thanks for the info!

----

Maybe a bit off-topic, but I was able to integrate XTIDE Universal BIOS into my 128kB BIOS, and I'm really happy about that! The BIOS ROM has a VGA BIOS at 0x00000 and an SCSI Adaptec BIOS at 0x08000. This motherboard has no onboard SCSI, so I swapped the data at 0x08000 for XTIDE. At first it didn't work, then I saw a hidden "SCSI Onboard" setting in the BIOS. I toggled its visibility and renamed it to "XTIDE Universal BIOS", and now it works! And I can even turn it off/on in the BIOS.

386:
- CPU: 386DX-40 + 40MHz FPU + 128kB L1 cache
- RAM: 8MB (0 waitstates @ 40MHz)
- VGA: Diamond SpeedSTAR VGA (ET4000AX 1MB ISA)
- Audio: Sound Blaster Pro 2.0 + GUS 1MB
- ISA PS/2 mouse card
- MR BIOS