Skip to content

ROM Definitions

dbalsom edited this page Aug 26, 2024 · 2 revisions

ROM Definitions

MartyPC uses ROM definition files in TOML format to describe the ROMS that can be used.

You can combine multiple romsets into one file, or spread them across multiple files, even in different directories within /media/roms.

A romset is defined by a [[romset]] entry.

MartyPC resolves ROMs required to run a specific machine configuration based on the concept of "feature requests" and "feature providers".

Base machine types will require certain features, and machine configurations can require additional features on top of those.

MartyPC will attempt to resolve the highest-priority ROM set that provides all the requested features.

For example, if you wish to run an IBM 5160 (XT) with a Xebec hard disk controller and an IBM EGA card, that machine configuration will require the following features:

  • ibm_5160
  • ibm_basic
  • expansion
  • ibm_ega
  • ibm_xebec

ROM sets advertise what features they provide in their provides field. If more than one ROM set provides the same feature, the set with the highest priority value will be used.

The following fields are required for each ROM set:

alias    - Defines a name for this ROM set that may be referenced specifically by a configuration
desc     - A human-readable string describing this ROM set.
priority - Breaks ties between matching, complete ROM sets (higher is better)
provides - An array of strings describing what features this ROM set provides
oem      - If true, marks the ROM set as OEM for all its features. (see below)
oem_for  - A list of features for which the ROM set will be marked as OEM.

OEM selection:

The oem and oem_for fields may be used to influence ROM set priority.

Setting oem = true will set the ROM as OEM for all its features.

Using oem_for = ["feature1", "feature2"] will mark the ROM as OEM for only the specified features.

If the 'use_oem' option in main config is set, ROMs that are marked OEM are strongly preferred before any other ROM set. Currently this is implemented by a +100 offset to ROM priority per feature. This means if you place OEM ROMs into the rom folder, they will be used before GLaBIOS will be loaded. If you wish to use GLaBIOS, set prefer_oem to false.

Other fields

checkpoints

These are a list of addresses, levels and strings. When the CPU executes an instruction at the given address, the string is logged to the console, or optionally, the notification system (depending on specified level) This can be useful to watch the POST process. Be careful that you don't create a checkpoint that is reached too often or you will flood the console and take a big performance hit. (you must have RUST_LOG=marty_core::cpu::debug set to see log messages)

Checkpoints are implemented with memory flags so are fairly performant to set, although obviously hitting one has a performance hit if they are logged.

There are five defined 'levels', roughly analogous to Rust log levels:

0 - Error.  Intended for checkpoints you should never reach.
            Will be logged as an Error.
1 - Warning Intended for checkpoints you wish to alert on. Will
            be logged as a Warning.
2 - Debug   Checkpoints you want to see normally but nothing
            special, just passing through. Will be logged as
            Debug.
3 - Info    Checkpoints that are in normal control flow and
            would be noisy to display always. Logged as Info.
4 - Trace   Checkpoints that are in normal control flow and 
            would be very noisy. Logged as Trace.

The default checkpoint level, if not provided, is Debug.

patches

When the trigger address is reached, the specified bytes will be written to the specified addr, even if it is ROM.

addr may be anywhere in memory - it does not have to be an address in the ROM that defines the patch.

ROM Patching must be enabled in the main configuration for this to have any effect. Set patch_roms = true under [machine] in martypc.toml.

reload

Reload the ROM from disk and re-map into memory when the machine is restarted. Useful for ROM developers.

Defining a ROM entry

Individual ROMS are defined within the rom array within a romset.

A ROM can be identified by either its md5 hash, in which case, filename is ignored, or by filename, in which case hash is ignored. If you specify both, hash takes precedence. Filename may be case sensitive depending on operating system. It is generally recommended to specify ROMs by hash, unless you are a ROM developer and are replacing the same ROM filename often.

md5      - Specifies the MD5 hash of the ROM. Required if filename is not present.

filename - Specifies the filename of the ROM. Required if md5 is not present.

addr  - (REQUIRED) Specifies where the ROM should be mapped in the machine's 
        address space. 

size  - (OPTIONAL) Size of the ROM. If it is present, the ROM image will
        be truncated to this size before being mapped.

org   - (OPTIONAL) Default is "Normal". Specifies the ROM organization.
        Valid values are:
         Normal   - just your standard, linear array of bytes.
         Reversed - bytes in the ROM image are reversed. (IBM EGA ROM)
         InterleavedEven - represents the even bytes in an interleaved set
         InterleavedOdd  - represents the odd bytes in an interleaved set

chip  - (OPTIONAL) String identifying the chip this ROM represents. 
        Variants of a ROM (different dumps, sizes, orgs, etc.) may be 
        specified by including multiple rom entries with the same "chip" string. 
        MartyPC will use the first matching ROM of any duplicate "chip" 
        definitions.
        If you don't know the official chip name you can just make up any
        valid string.

Example ROM Set Definition

[[romset]]
alias = "ibm5160_82_v1_wbasic"
datestr = "11/08/82"
priority = 1
provides = ["bios", "ibm5160", "ibm_basic", "expansion"]
oem = true
rom = [
    { md5 = "e816a89768a1bf4b8d52b454d5c9d1e1", addr = 0xF0000, size = 32768, chip = "basic+u19" },
    { md5 = "1a2ac1ae0fe0f7783197e78da8b3126c", addr = 0xF8000, size = 32768, chip = "u18" },
]

Here a ROM set named ibm5160_82_v1_wbasic is defined. It has a low priority, so other ROM sets that provide the same features may be preferred.

(The newer, 1986 BIOS will have a higher priority)

The ROM set provides the features bios, ibm5160, ibm_basic, and expansion

  • The bios feature should be provided by any complete BIOS rom set. We can't boot without a BIOS!

  • The ibm5160 feature indicates that this BIOS provides functionality for the base "ibm5160" machine type.

  • The ibm_basic feature is an optional feature. It indicates that the Microsoft ROM Basic is provided.

    A missing optional feature will not prevent the emulator from starting.

  • The expansion feature indicates that this ROM set supports loading of BIOS expansion ROMs.

    Only some early IBM 5150 BIOS versions did not support BIOS expansion ROMs, so you cannot use an EGA card or hard disk with them. These ROM sets will not provide the expansion feature.