# romdef.toml
# Main ROM definition file for MartyPC.
#
# You can create your own ROM definition files. MartyPC will attempt to load
# all toml files found in the rom directory.
# 
# If you find ROM variants that should be here, please let me know!
#
# ----------------------------------------------------------------------------
# Defining a ROM set
# ----------------------------------------------------------------------------
# Each [[romset]] entry defines a single ROM set.
# MartyPC resolves ROMs required to run a specific machine configuration based
# on the concept of "feature requests" and "feature providers".
# 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 feature strings:
#  "ibm_5160"
#  "ibm_basic"
#  "expansion"
#  "ibm_ega"
#  "ibm_xebec"
# 
# ROM sets advertise what features they provide in their "provides" field. 
# MartyPC will load ROM sets that provide the requested features. If more than
# one ROM set provides the same feature, the set with the highest 'priority'
# value will be used.
#
#
# The following fiels are required for each ROM set:
# alias    - Defines a name for this ROM set that may be referenced specifically
#            (ie, in the rom_override config setting)
# 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.
#
# ----------------------------------------------------------------------------
# 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 analagoys 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 with 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.
#
#               A 'reset' address can be specified, that when reached will
#               restore the original bytes at 'addr'. This is useful for
#               patching code that is verified by CRC or checksum later.
#               (not yet implemented)
#
#               ROM Patching must be enabled in the main configuration for 
#               this to have any effect.
#
# reload      - Reload the ROM from disk and re-map into memory when
#               the machine is restarted. Useful for ROM developers.
#

# ----------------------------------------------------------------------------
# Defining a ROM entry
# ----------------------------------------------------------------------------
# 'rom' array:
#
# 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.
#
# 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. 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.

[[romset]]
alias = "ibm_xebec"
desc = "IBM/Xebec MFM Hard Disk Controller v3"
priority = 1
provides = ["ibm_xebec"]
oem = true
requires = ["expansion"]
rom = [
    { md5 = "66631d1a095d8d0d54cc917fbdece684", addr = 0xC8000, size = 4096 }
]
checkpoint = [
    { addr = 0xC8003, lvl = 3, desc = "HDC Expansion Init" },
    { addr = 0xC8117, lvl = 3, desc = "HDC Disk Reset" },
    { addr = 0xC8596, lvl = 3, desc = "HDC Status Timeout" },
    { addr = 0xC8192, lvl = 3, desc = "HDC Bootstrap Loader" },
    { addr = 0xC81FF, lvl = 3, desc = "HDC Boot From Fixed Disk" },
]

[[romset]]
alias = "xtide"
desc = "XTIDE Universal BIOS"
priority = 10
provides = ["xtide"]
oem = false
requires = ["expansion"]
rom = [
    { filename = "ide_xtl.bin", addr = 0xC8000, size = 12288 }
]
checkpoint = []
