Copper bars
Mode 13h raster bars: every scanline rewrites one DAC entry while the beam passes, under a sine scroller.
How it’s made: the whole program →Add-on
DOS-era PC video, emulated at the register level, with a beam-accurate CRT.
v0.2.2 EUPL-1.2
VGA (mode 13h, Mode X, 16-colour planar, text), EGA, CGA with composite artifact colours and snow, Hercules, Tandy 1000 and VESA SVGA. Your game is ordinary Rust; what is emulated is the display adapter, its memory, its registers, its timing and the electron beam reading it out while you write.
[dependencies]
game-toolkit-dosvideo = "0.2"Play
Built for the browser from v0.2.2. Click into a running demo for keyboard input.
Features
VGA, EGA, CGA, Hercules, Tandy 1000 and VESA SVGA (VBE 1.2 and 2.0), each with its own memory layout, BIOS modes and quirks.
Writes land while the beam scans. Raster bars, split screens and tearing happen for the same reasons they did in 1992.
Program it through OUT 3C8h and pokes into A000:0000, or through helpers that do the same thing with less typing.
VGA monitor, TV, green and amber phosphor presets, composite artifact colours and CGA snow.
One square wave, no volume control, and all the tricks: PWM samples and synthie tracker songs on a single channel.
Code
use game_toolkit_dosvideo::prelude::*;
struct Hello;
impl DosGame for Hello {
fn init(dos: &mut Dos) -> anyhow::Result<Self> {
dos.set_mode(0x13); // INT 10h, AX=0013h
Ok(Self)
}
fn step(&mut self, dos: &mut Dos) {
// while (inp(0x3DA) & 8); while (!(inp(0x3DA) & 8));
dos.wait_vretrace();
dos.set_palette(1, [63, 0, 0]); // OUT 3C8h / 3C9h
dos.fill(0xA0000 + 100 * 320, 320, 1); // a red line in A000:7D00
if dos.key(sc::ESC) {
dos.exit();
}
}
}
fn main() -> anyhow::Result<()> {
run::<Hello>(DosConfig::new("hello", Adapter::Vga))
}Gallery
More