EN /HU | Login

DOSLIB

DOSLIB is the code that the DOS programs DOSINST, GMENU, BMAGIC and TTGWIKI share (C++, Open Watcom, 16-bit DOS and Win32), and the rules their code follows. Each program has it in its SOURCE/lib folder as a git subtree, so it builds on its own.

What is in it

Folder What
core No I/O: strings and 8.3 names, INI files, UTF-8 and code page 437, the code pages 437 and 852 with one byte a character (code_page), CRC-32, the shared Error.
platform The interfaces of the machine: Screen, Keyboard, Mouse, Clock, FileSystem, Network, ...
platform/dos, platform/win32 Their implementations: video memory, BIOS, INT 33h, the Watcom C library; the Win32 console.
net An FTP client on the Network interface.
ui Drawing on a Screen, the BIOS key codes, a list cursor.
testing The hooks of the test builds (scripted keys, screen dump), and test doubles for the unit tests on the host.
tools The Watcom build helper, the layer check, the unit test runner, the formatter.

Layers

A program is built in layers; each uses only the ones below it, and only through their interfaces:

TXT
main_*.cpp     the machine: picks the platform implementations
app/           puts the layers together
controller/    keys and commands -> service calls
view/          draws
service/       what the program does
repository/    interfaces of the storage; repository/<kind>/ implements them
model/         the data and its rules, no I/O
platform/      the program's own machine interfaces and their implementations
lib/           DOSLIB

tools/check_layers.py checks it in CI: which folder may include which, that the DOS and Windows headers are only in the platform code, no goto, no exit() outside main. Everything above the platform also compiles on the host, so it is unit tested there, without DOSBox.

The code

  • C++98, the part Open Watcom compiles: classes, pure virtual interfaces, references, simple templates; no exceptions, RTTI, STL or C++11.
  • Interfaces are named by what they are (FileSystem), implementations by how (DosFileSystem, FakeFileSystem). Dependencies come in through the constructor; only app/ and main_*.cpp create concrete objects.
  • Failures are a bool and a shared Error; no global state outside the platform code.
  • Files snake_case, types PascalCase, functions camelCase, members name_; clang-format 18 with the repository's .clang-format.

Updating a program

SH
git subtree pull --prefix=SOURCE/lib ssh://git@git.teletypegames.org:2222/dos/doslib master --squash

A change made in a program's SOURCE/lib goes back with git subtree push --prefix=SOURCE/lib ... master.

Open Watcom notes

  • The 16-bit compiler of the large model crashes on a module name longer than 25 characters; the build cuts it with -nm.
  • A static object over 32 KB ends up in the EXE file: big objects are allocated on the heap.
  • On 16 bits the layers cost size (far pointers, constructors, virtual tables): GMENU grew from 30 to 45 KB, DOSINST from 77 to 90 KB.