dos_env
Tool
tools/emu/dos_env(library, Emulators). A small DOS, BIOS and PC for tools/emu/dos_emu/, so a whole 16-bit program can run headless.
A library: other tools and your own scripts import it. Source on GitHub.
Its own help
This is the help text in the tool itself, as ./gameframe tool dos_env prints it.
text
A small DOS, BIOS and PC for tools/emu/dos_emu/, so a whole 16-bit program can run headless.
from dos_emu import DosEmu, ProgramStopped
from dos_env import DosEnv
emu = DosEmu('target/game/GAME.EXE')
env = DosEnv(emu, root='target/game', overlay='derived/run') # files, KERNEL, ports, BIOS
try:
emu.run_range(emu.entry, '1000:ca59') # from the program's entry to a chosen point
emu.run_to('1000:ca59') # then carry on (run_range resets the stack)
except ProgramStopped as stop:
print('exit code', stop.args[0])
print(env.log[-20:]) # what the program asked of DOS, in order
What it provides:
- DOS (INT 21h): files under `root` (names matched without case). A file the program writes
is saved to `overlay` when closed (and kept in `env.written`); root is never written, and
a file only opened read/write (Pascal's default) is not saved at all. Later opens read the
overlay's copy first. handles, seek, find first/next with the
DTA, current drive and directory, date and time (fixed: `env.clock`, so runs repeat
exactly), version 5.0, interrupt vectors (kept in a table; nothing is ever called through
them), device information, and exit (ends the run with ProgramStopped(exit code)).
- DPMI16 KERNEL imports (Borland Pascal 7, Windows 3.x): GlobalAlloc / GlobalLock (64 KB
selectors in a row, 8 apart, for blocks over 64 KB), GlobalFree, GetFreeSpace, InitTask.
- Ports: VGA status (0x3DA) alternates so retrace waits end; the DAC (0x3C8/0x3C9) is kept
in `env.dac` (256 x RGB, 6-bit); PIT, PIC, keyboard, joystick, Sound Blaster and AdLib
ports answer with safe constant values. Every port write is counted in `env.ports`.
- BIOS: INT 10h (video modes, recorded in `env.video_mode`), INT 16h (no key waiting),
INT 33h (no mouse), INT 1Ah and the tick count at 0040:006C (`env.ticks`, one tick per
128 reads of it, so wait-for-the-next-tick loops end).
- DPMI (INT 31h): descriptors, DOS memory, interrupt and exception vectors, version, memory
information; calls into real mode are skipped. INT 2Fh answers "nothing installed".
- The timer: IRQ 0 goes to INT 8's handler (the program's, or the BIOS's, which counts the
tick) at the rate the program sets on the PIT, counted in instructions: `ips` per second
(default 25 million, a fast 486). `env.irq0_count` counts deliveries.
Anything else stops the run with its name (the emulator's own message), so you know what to
add. It does not emulate sound output, a real keyboard (use env.keys), or DPMI services
beyond what is listed.Named by
Skills: re-observe, re-emulate, re-verify.