DOSContainer logo DOSContainer

Defining compatibility as data

📅 2025-05-24  · ✍️ Bas v.d. Wiel  ·  🏷 design

One major issue for DOSContainer is to figure out the optimum between what you have on your desk and what the software you’re building actually supports. In a previous version of the codebase I had started a convoluted decision tree of if/then/else/unless logic. That stopped scaling after two versions of DOS, while I intend to support dozens so something had to give. The alternative? Modeling compatibility as data!

Currently DOSContainer is gearing up to release 1.00 which will only support PC-DOS 1.00 on the surface. Inside the codebase, however, I’m already working with versions 1.00, 1.10 and 2.00 to prove the design. These three versions already have a few quirks between them and the hardware they run on that will exclude certain combinations. Modeling how to handle this is crucial to the future of DOSContainer.

The key to compatibility right now is this struct:

pub struct OsSupport {
    pub version: OsShortName,
    pub min_ram_kib: u32,
    pub supported_cpu_families: &'static [CpuFamily],
    pub supported_floppies: &'static [FloppyType],
    pub supported_video: &'static [VideoDevice],
}

This is a data structure that tells DOSContainer which operating system, identified by an OsShortName, is compatible with which types of hardware. At this point in time this boils down to a simple list of such structs, filled out for the three versions of PC-DOS I already mentioned. This may change later on, but for now it’s hard-coded and built into the application at compile time. As an example, this is the data for PC-DOS 1.00:

OsSupport {
    version: OsShortName::IBMDOS100,
    min_ram_kib: 64,
    supported_cpu_families: &[CpuFamily::I8088],
    supported_floppies: &[FloppyType::F525_160],
    supported_video: &[VideoDevice::CGA, VideoDevice::MDA, VideoDevice::HCG],
},

This version of DOS would only really run on the IBM 5150 with its original IBM-sanctioned hardware. That means that if you have anything other than a 5150, it’ll fail. The only exception I was able to test through emulation was the Hercules graphics card. 86Box in 5150 mode would still boot this DOS version with a Hercules card. Giving it EGA or VGA would simply freeze it. Now I haven’t been able to find anything definitive on this using real hardware (and I don’t have any real hardware to test), so the jury is still out. As a test case for DOSContainer this does fly: we’re excluding newer systems with better graphics or floppy drives here.

Testing whether a version of DOS will run on a particular HwSpec now comes down to running both the spec and the compatibility struct through a reasonably simple function:

pub fn is_compatible(hwspec: &HwSpec, os: &OsSupport) -> bool {
    hwspec.ram() >= os.min_ram_kib
        && os.supported_cpu_families.contains(&hwspec.cpu().family())
        && hwspec
            .floppy_type()
            .as_ref()
            .map_or(false, |f| os.supported_floppies.contains(f))
        && !hwspec.video().is_empty()
        && hwspec
            .video()
            .iter()
            .any(|v| os.supported_video.contains(v))
}

You pass in references to a HwSpec and an OsSupport struct, and the function will determine whether their contents have overlap. If they don’t, the result will be false and the combination is determined to be incompatible. Obviously this function and the OsSupport struct are up for extension in later versions, but conceptually this is how things will work for now.

Next step: strain the contents of Manifest through a similar sieve to figure out which DOS versions the application/game and its layers will support. The final result will give DOSContainer the ability to determine whether building a Manifest will be viable to build for a particular HwSpec or not.

Now if multiple combinations are viable, I’m envisioning a scoring system to components to determine the optimal combination. In such a system VGA could be given a weight of 5 where CGA would be a 2, for example, which yields different scores for different combinations of hardware/software and highest score wins out.

Tags: