VOGONS


First post, by scruit

User metadata
Rank Newbie
Rank
Newbie

I'm looking to create my own option rom (similar to the roms on expansion cards that capture the boot process and display a message) so I can write out a custom message to the screen during bootup.

I want each of the PCs in my little 'museum' of retro computers to print text describing the machine and its history, with a message like this:

"Scruit's Retro Museum - IBM PS/2 55sx
Press any key for more historical info, otherwise bootup will continue in 10 seconds..."

Then if you press any key you get a paragraph something like:

"This is a IBM PS/ model xxxx that was developed in 19xx and sold by IBM from 19xx to 19xx. It has a 386sx processor and was originally shipped with DOS xxxx and Windows xxxx."

For this I'm aiming at the older PCs, up to 486, maybe pentium.

Anyone know of a good tutorial/demo of how to write a rom like this?

What I have experience with:
- Writing simple assembly language
- Troubleshooting/fixing ROMs in older 8-bit machines
- I have written arduino programs that use memory chips and ROMs, so I'm familiar with the concepts behind address/data lines and the timing of row select / column select / address select / read/write, and parsing timing diagrams from datasheets etc.
- Programming ROMs I've downloaded for use on machines (like XT-IDE)
- Understanding where option roms can like (soemtimes there's sockets on the motherboard, sometimes there's empty sockets on ISA cards etc)
- Some machines have high/low roms versus single roms, depending on address/data line architecture.
- That the option ROMS exist in a specific block in memory and are simply present/addressable by virtue of being installed (starts at 0xc8000?)

The bit I'm missing:
- How does the motherboard recognize that a ROM is intended to be executed?
- Is there a particular byte value at a particular address in the ROM that identifies it as an option rom? Like, it scans all the potential addresses in the bios expansion area and passes control to any blocks that have the correct bye value(s)
- Or does it pass control to each available block in the bios expansion area, and the absence of a ROM there allows it to simply skip that block?

I'm going to spend some time trying to reverse-engineer some option roms I have here. Was hoping to speed that process with a tutorial though.

Thanks!

Reply 1 of 7, by weedeewee

User metadata
Rank l33t
Rank
l33t

look into the XT-IDE bios rom. I'm sure it has all the knowledge you want and way more.
https://www.xtideuniversalbios.org/

Right to repair is fundamental. You own it, you're allowed to fix it.
How To Ask Questions The Smart Way
Do not ask Why !
https://www.vogonswiki.com/index.php/Serial_port

Reply 2 of 7, by douglar

User metadata
Rank Oldbie
Rank
Oldbie

Sounds like a fun project--

https://etherboot.sourceforge.net/doc/html/de … /extension.html

From time immemorial, well actually since the IBM XT appeared on the market, the PC architecture has a mechanism for invoking "extension BIOSes". The original reason for this mechanism was to allow adaptor cards that the main BIOS didn't know how to deal with to carry ROMs with initialisation code or drivers. An early example was the XT hard disk controller. The main BIOS of XTs only knew how to boot from floppies. When an XT hard disk controller is added, the code in the ROM on the controller appears in the memory space of the PC and is called as part of the machine initialisation. Another example is the BIOSes on VGA video adaptor cards, although strictly speaking that is a special case in terms of ROM address. When network adaptors were made for the PC, it was a natural step to put ROMs on them that could contact a server for network booting.

How does the main BIOS know that the code in the ROM is to be executed and why does it not execute some random code by accident? The ROM code has several conditions placed on it.

The ROM must start on a 2kB boundary in the memory space, between 0xC8000 and 0xEE000, although some main BIOSes scan outside these limits.

The first two bytes of the ROM must be 55 AA hex.

The third byte of the ROM should contain the number of bytes in the ROM code divided by 512. So if the ROM code is 16kB long, then this byte would hold 20 hex (32 decimal).

All the bytes in the ROM (specified by the length byte just mentioned) must checksum to 8 bits of binary zero. The sum is formed by 8 bit addition of all the bytes, throwing away the carry. Note that there is not a particular location designated as the "checksum byte". Normally the ROM building process alters an unused byte somewhere to fulfil the checksum condition.

If such a ROM is detected and validated by a scan, then the main BIOS does a far call to ROMSEG:3, where ROMSEG is the segment of the ROM and 3 is the offset to transfer control to the discovered extension BIOS. Typically a network boot ROM does not take full control at this point. Instead the normal procedure to do some initialisation or probing of the hardware and then plant a vector that will be called when the BIOS is ready to boot the OS. The vector used for this purpose is normally interrupt 0x19 although interrupt 0x18 is sometimes used.

For PCI plug and play ROMs things are more complicated.

Reply 3 of 7, by Roman555

User metadata
Rank Oldbie
Rank
Oldbie

IMO it's much easy to achieve the goal just programming config.sys and autoexec.bat

Some priceless information about BIOSes and OpROM:
sites.google.com/site/pinczakko/
github.com/pinczakko/BIOS-Disassembly-Ninjutsu-Uncovered

[ MS6168/PII-350/YMF754/98SE ]
[ 775i65G/E5500/9800Pro/Vortex2/ME ]

Reply 5 of 7, by scruit

User metadata
Rank Newbie
Rank
Newbie
Roman555 wrote on 2022-12-23, 15:19:
IMO it's much easy to achieve the goal just programming config.sys and autoexec.bat […]
Show full quote

IMO it's much easy to achieve the goal just programming config.sys and autoexec.bat

Some priceless information about BIOSes and OpROM:
sites.google.com/site/pinczakko/
github.com/pinczakko/BIOS-Disassembly-Ninjutsu-Uncovered

That would be easier, sure, but not quite as flexible.

If I use dos or windows, sure. I'd like to be able to run different OS's (OS/2 Warp, early linux etc) tough and not have to change the blurb as a result of changing the OS, or even taking the boot disk to a different PC.

Reply 6 of 7, by douglar

User metadata
Rank Oldbie
Rank
Oldbie
scruit wrote on 2022-12-23, 19:13:

..That is perfect... I can work with that! thank you!

Can you put a text mode screen saver in there ? Like maybe "Ascii Invaders" or animated ascii fireworks?

The attachment firework2.gif is no longer available
Last edited by douglar on 2022-12-23, 19:46. Edited 1 time in total.

Reply 7 of 7, by Predator99

User metadata
Rank l33t
Rank
l33t
douglar wrote on 2022-12-23, 14:56:
Sounds like a fun project-- […]
Show full quote

Sounds like a fun project--

https://etherboot.sourceforge.net/doc/html/de … /extension.html

From time immemorial, well actually since the IBM XT appeared on the market, the PC architecture has a mechanism for invoking "extension BIOSes". The original reason for this mechanism was to allow adaptor cards that the main BIOS didn't know how to deal with to carry ROMs with initialisation code or drivers. An early example was the XT hard disk controller. The main BIOS of XTs only knew how to boot from floppies. When an XT hard disk controller is added, the code in the ROM on the controller appears in the memory space of the PC and is called as part of the machine initialisation. Another example is the BIOSes on VGA video adaptor cards, although strictly speaking that is a special case in terms of ROM address. When network adaptors were made for the PC, it was a natural step to put ROMs on them that could contact a server for network booting.

How does the main BIOS know that the code in the ROM is to be executed and why does it not execute some random code by accident? The ROM code has several conditions placed on it.

The ROM must start on a 2kB boundary in the memory space, between 0xC8000 and 0xEE000, although some main BIOSes scan outside these limits.

The first two bytes of the ROM must be 55 AA hex.

The third byte of the ROM should contain the number of bytes in the ROM code divided by 512. So if the ROM code is 16kB long, then this byte would hold 20 hex (32 decimal).

All the bytes in the ROM (specified by the length byte just mentioned) must checksum to 8 bits of binary zero. The sum is formed by 8 bit addition of all the bytes, throwing away the carry. Note that there is not a particular location designated as the "checksum byte". Normally the ROM building process alters an unused byte somewhere to fulfil the checksum condition.

If such a ROM is detected and validated by a scan, then the main BIOS does a far call to ROMSEG:3, where ROMSEG is the segment of the ROM and 3 is the offset to transfer control to the discovered extension BIOS. Typically a network boot ROM does not take full control at this point. Instead the normal procedure to do some initialisation or probing of the hardware and then plant a vector that will be called when the BIOS is ready to boot the OS. The vector used for this purpose is normally interrupt 0x19 although interrupt 0x18 is sometimes used.

For PCI plug and play ROMs things are more complicated.

Indeed, above is everything you need to know 😉

Summarized:
Byte 0 55
Byte 1 AA
Byte 2 Rom size divided by 512
Byte 3 Enter your code here...

The code at ROMSEG:3 is executed by a CALL FAR therefore you must end with a RETF.

You can do funny things with option ROMs. I never tested it but Tronix provided a small tool to convert an ordinary .COM to an option ROM....com2rom.zip
Re: CGA game on option ROM