Skip to content

AWARD 4.5x hacking notes

oerg866 edited this page Aug 9, 2026 · 5 revisions

AWARD BIOS v4.5x hacking notes

This document contains information used to construct modifications in BIOSes on vintage motherboards.

It is the knowledge base for the BIOS modifications released here:

https://github.com/oerg866/TRW-BiosMods

New Setup Structure

The "New Setup Structure" usually starts at 0xF85C in the F Segment and contains the following items:

  • 0xBB identifier
    • F85D: Bios Setup Menu List Pointer
    • F85F: Rom Table Pointer (Chipset register configuration list)
    • F861: Rom Table End Pointer
    • F863: "Auto Table" pointer - obsolete and unused IIRC?
    • F865: "Auto Table" end pointer
    • F867: "Auto Table" String list pointer

Rom Table (Chipset Configuration Register List)

This is an array of Register list entries of the following format:

Offset Type Description
0 BYTE "Register Type" (?) - Not sure what this is. Seems to be 2 for most things, but I've seen 3 as well (might be for Power management regs)
1 BYTE Index - Register index in PCI config space.
2 BYTE PCI Device Identifier - For PCI this is 5 bits device, 3 bits function (always on bus 0). Not sure of the format for ISA devices.
3 WORD Mask Mask of the bits that will be affected by this write. Example: FB would affect all bytes except bit 2 (1111 1X11). Note that this is a word, but for PCI config writes only the least significant byte will be used. I think this can theoretically also be used for 16 bit ISA writes, but I'm not sure.
5 WORD Value The value to write to the register. It will be ANDed with the Mask and ORed with the previous value in the register.

The size of this structure is 7 bytes and is not padded.

How this table is referenced

Note: The "New Setup Structure" is not usually how the BIOS retreives this table. This structure is there for automatic processing with tools such as CBROM and MODBIN, not for the BIOS' own operation.

It's sadly more "hardcoded" than that.

image

This is example code pulled from a BIOS ROM.

To relocate this table, both the vector table and the code must be updated.

PCI Bus Configuration

PCI Slot table

This table is standardized for all BIOSes that support PCI 2.0.

At FE90 in the F segment you will find the 0xBB marker, along with an offset in the F segment to the PCI slot list.

    CK_ORG    0FE90H
    db        0bbh				
    extrn     Pci_Slot_Cfg:near		
    dw        offset DGROUP:Pci_Slot_Cfg

The corresponding table would look like this:

    db        0bh
    db        0dh
    db 	      0fh
    db        11h
    db        0ffh

Where there's 1 byte per slot ID and a list end marker (0xff).

Exception: ASUS PVI-486SP3 - The slot table does exist, but it is empty?!

TODO: Why? I assume ASUS is doing some ASUSian custom shenanigans here - MODBIN also shows the PCI slot table as empty. I have not yet been able to locate where.

Interesting factoid: The latest BIOS version for that board does have an intact interrupt table.

PCI Interrupt table

The expectation AWDBEDIT makes is that this table is standardized in the configuration vectors of the AWARD BIOS, at F_SEG:0FE99h.

The leaked AWARD 4.51PG source code confirms this suspicion, prepends it with the 0xAA identification marker.

However, this was previously not the case, as earlier 4.51 variants prove (e.g. SOYO 4SAW).

Generally, there seems to be no standardized way of finding this table, other than finding the code that loads it.

Text rendering

There are two major text rendering functions in any AWARD 4.5x BIOS:

  • Show_String
  • Show_CS_String

They take two parameters, the Segment and Offset of the string to show.

The difference between the two is that Show_String uses the ds (data segment) register as input parameter for the segment, whereas Show_CS_String uses the cs (code segment) register (really, it is just a wrapper that saves ds and then sets it to the value of ds before calling the regular Show_String).

Control codes

The text can have control codes (ASCII < 0x20) in it, which allow you to modify text attributes or do other actions during the printing of the string.

The following table lists them for AWARD 4.50 / 4.51 (later BIOSes may differ slightly).

Code Name Description
0x00 V_DONE End of string marker.
0x01 V_DONE1 End of string marker (OR blank entry marker, see details below.)
0x02 V_BORDER Draw border on the screen.
0x03 V_CLEAR Clear rectangle on the screen.
0x04 V_STRSHOW Prints another sub-string and continues.
0x05 V_POS Set absolute cursor position.
0x06 V_HILITE Draws text with intensity bit set.
0x07 V_REVERSE Draws text with "REVERSE" color of current color scheme (usually inverted to the regular color).
0x08 V_NORMAL Resets text attributes (color, etc.) to normal.
0x09 V_BLINK Draws text with BLINK attribute.
0x0A V_WARN Draws text with "WARN" color of current color scheme.
0x0B V_NEWLINE Moves cursor to the beginning of the next line.
0x0C V_ADDX Add to X position.
0x0D V_SUBX Subtract from X position.
0x0E V_ADDY Add to Y position.
0x0F V_SUBY Subtract from Y position.
0x10 V_CALLROUTINE Calls a subroutine.

Offset parameters for control codes

Some control codes take an offset as part of the parameters. This is always an offset within the segment of the string that is currently being displayed.

There is no way to reference data in another segment within the strings.

0x01 (V_DONE1)

This is another end of text marker, except for setup menu entry text.

In case of a setup menu entry, this indicates the current item should be skipped in the selection, i.e. not selectable.

0x02 (V_BORDER)

Draws a border on the screen.

Parameters
BYTE 0x02 (V_BORDER)
BYTE Left X position
BYTE Left Y position
BYTE Right X position
BYTE Right Y position
BYTE Border type (Bitfield)
Bit Border Type
0x01 ║ Double Border
0x02 ? Empty Border (?)
0x04 │ Line Border
0x08 ? "NO BORDER" (?)
0x10 Shadow Border (Late 4.51PG ONLY)

I don't know why this is a bit field because other than shadow border, these seem mutually exclusive :thinking_face:

0x03 (V_CLEAR)

TODO

0x04 (V_STRSHOW)

Calls the string printing function with another string. Frequently used to print the same string for multiple different options where part of the string remains identical between them all to save space.

Parameters
BYTE 0x04 (V_STRSHOW)
BYTE X Position
(0xFF = at current position)
BYTE Y Position
(0xFF = at current position)
WORD Offset of substring to insert.

0x05 (V_POS)

Set absolute cursor position.

Parameters
BYTE 0x05 (V_POS)
BYTE X Position
BYTE Y Position

0x0C (V_ADDX), 0x0D (V_SUBXX), 0x0E (V_ADDY), 0x0F (V_SUBY)

Adds or subtracts from cursor X or Y position.

Parameters
BYTE 0x0C (V_ADDX), 0x0D (V_SUBXX), 0x0E (V_ADDY), 0x0F (V_SUBY)
BYTE Value to add/subtract

0x10 (V_CALLROUTINE)

Calls a subroutine before resuming printing

Parameters
BYTE 0x05 (V_POS)
WORD Offset of routine to call

Setup Menu

Menu Item entries

MenuItem            struc ; (sizeof=0x19, mappedto_17)
ItemStatus          dw ?
ItemName            dw ?                    ; offset
ChipsetReg          dw ?
ChipsetRegMask      dw ?
CMOSLoc             db ?
CMOSMask            dw ?
FirstItemString     dw ?                    ; offset
MinVal              dw ?
MaxVal              dw ?
ItemX               db ?
ItemY               db ?
PowerOnDefault      dw ?
SetupDefault        dw ?
HelpString          dw ?                    ; offset
MenuItem            ends

CMOS Layout (typical)

Byte Description
0x00-0x3F General BIOS Setup
0x00 RTC Seconds
0x01 RTA Seconds
0x02 RTC Minutes
0x03 RTA Minutes
0x04 RTC Hours
0x05 RTA Hours
0x06 Day of week
0x07 Day of month
0x08 Month
0x09 Year
0x0A-0x0C free ?
0x0D used but unknown
0x0E Status (memory, keyboard, checksum, equipment)
0x0F something related to ACPI?
0x10 Floppy disk configuration
0x11 General BIOS settings (HDD Block Mode, A20 gate config, numlock)
0x12 Drive 1/2 (C/D) present
0x13 General BIOS settings (Floppy seek, Typematic)
0x14 Installed Equipment
0x15-0x16 WORD: Base Memory
0x17-0x18 WORD: Extended memory
0x19 Drive 1 (C) type
0x1A Drive 2 (D) type
0x1B ?, on later BIOSes: processor number feature, needs more resarch
0x1C-0x1D password hash?
0x1E-0x25 USER Drive 1 (48) Configuration
WORD: Cylinders
BYTE: Heads
WORD: Precomp
WORD: Landing
BYTE: Sectors
0x26-0x2D USER Drive 2 (49) Configuration
0x2E-0x2F CMOS checksum?
0x30-0x31 WORD: Extended memory (again? what's the difference?)
0x32 Century
0x33 ?
0x34-0x36 free?
0x37 ?
0x38 Off-board EMS size
0x39 Off-board EMS I/O Port
0x3A Off-board EMS page
0x3B Cache control, Weitek Coprocessor Config(?)
0x3C General BIOS Settings (OS for DRAM > 64MB, Report no FDD for Win95)
0x3D CPU Type / Index & Flags
bit 7: Has L1 Cache
bit 6: Has x2 multiplier (very old bioses)
bit 6-1: CPU type
bit 0: Has FPU
0x3E General BIOS settings (Halt on, swap floppy drive)
0x3F CPU Feature Flags
0x40-0x66 Board-specific Setup These are rough estimates and will vary from BIOS to BIOS
0x40 Chipset Features
0x41 Chipset Features (cont.) / Memory Timing Config
0x42 Chipset Features (cont.)
0x43 Chipset Features (cont.)
0x45-0x46 IDE/IO-Controller Config
0x47 USB Controller Config
0x50 Power Management Config
(For AMD K7: MSR Config)
0x53 ACPI Suspend Config
0x58-0x5A Old BIOSes: IDE/IO-Controller Config
0x60 PCI Features Config
0x62 Jumperless CPU Config
0x63 Jumperless CPU Config (also: ICW195 Clockgen config)
0x67-0x7F General BIOS setup (cont.)
0x67 User Drive 3 Type
0x68-0x6F User Drive 3 Configuration
0x70 User Drive 4 Type
0x71-0x79 User Drive 4 Configuration
0x7A-0x7F ?

Generally, it can be said that between 0x40 and 0x66 is fair game for a BIOS to claim as its setup data.

For hacking, it's not really trivial to find a byte to put your own menu item data.

CMOS CPU feature flags + Override

There is a lot of information out there, a lot of it congregated by Jan Steunebrink, but from what I've gathered this is the complete list of flags possible:

Note These are for 486 era BIOSes
Bit 7 Has x3 Multiplier
Bit 6 Has x2 Multiplier
Bit 5 Has x4 Multiplier ('95+)
Bit 4 Green CPU / Has SMI
Bit 3 Has Write-Back Cache (very late'94+)
Bit 2 CMOS override (not sure but I think it's a clear-CMOS thing)
Bit 1 Warm boot flag
Bit 0 CMOS checksum error (this was deprecated at some point)

Clone this wiki locally