I'm writing a NASM-compatible assembler targeting the Intel 8086, and I'm looking for an existing open source program written in assembly, with which I can showcase the capabilities (and understand the shortcomings) of my assembler. My plan with the source code is to convert it to NASM syntax manually, and then compile it with both NASM and my assembler, look at the difference, and see which subset of NASM is still missing or incorrect in my assembler.
I'm specifically looking for:
It should be an existing program for DOS 8086 or DOS 286, whose assembly source is available, and doesn't contain newer-than-286 instructions, protected mode instructions or floating point instructions. (Programs requiring a 386 or 8087 are not suitable.)
Preferably, the executable program should be a DOS .com file. My assembler doesn't support DOS .exe directly, but an .exe shorter than 64 KiB can be arranged by emitting the .exe header with dw instructions.
Preferably, the executable program size should be between 10 and 50 KiB, ideally near 30 KiB. There are some boot sector games by Oscar Toledo G., e.g. F-Bird and others by the same GitHub user, but they are only 512 bytes or less.
Any assembler dialect is fine, I will convert it to NASM manually.
The source code shouldn't make heavy use of assembler macros. (Conditional assembly and symbolic constants (e.g. NASM
%define answer 42
) are fine though.) Thus GW-BASIC dated 1983-02-10 is not a good candidate, because it uses lots of MASM macros.The full source code (accounting for every single byte of the program file) should be available. It's OK if a few bytes are missing, I can add them from the disassembly.
Preferably the program shouldn't be a development tool (e.g. assembler, compiler, linker or interpreter), an operating system (e.g. msdos.sys, command.com, himem.sys) or a system maintenance tool (e.g. format.com, chkdsk.com, antivirus), but it should be a game or some other interactive productivity tool (e.g. text editor, picture editor, e-learning tool). This way it can be showcased in a DOS emulator as something directly useful on its own.
I was considering:
The game Arcade Volleyball: it's a timeless enjoyable game, it matches the desired file size), but its source code is not available, and the DOS port was written in Turbo C, not in assembly.
The game Paranoid: it's a timeless enjoyable game, the program file is a 26 KiB .com file, and it doesn't use 386 instructions. Unfortunately it's not open source.
Volkov Commander 4.05: it's very well-known, its built-in text editor can handle files larger than 64 KiB, the program file is a 47 KiB .com file, and it doesn't use 386 instructions. Unfortunately it's not open source.
As an FYI I elaborate here a bit what kind of testing I'm doing:
Mostly I write single-line unit tests checking whether a single assembly instruction compiles and what machine code it generates.
I also write multi-line unit tests with labels and various distances. Such a test checks that a short jump (with 1-byte offset) is generated for a label which is not too far away (about at most +-127 bytes). These optimizations depend on the
-O...
flag specified in the command-line, so I check the machine code output against the expected bytes in multiple optimization levels.My goal is that my assembler to be compatible with NASM, and if different versions of NASM behave differently, then my assembler should match what NASM 0.98.39 compiled for a Linux i386 host does. Thus I also run the unit tests above with various versions of NASM and compare the machine code output. I don't compare the warning or error messages though.
Accepted behaviors of my assembler in general: (1) both my assembler and NASM 0.98.39 succeed for a particular input + command-line pair, and produce identical machine code in the output file; (2) either NASM 0.98.39 or my assembler fails (with non-zero exit code) for a particular input + command-line pair. An example for (2): my assembler fails if it encounters
%macro
. Another example for (2): NASM fails fordb $*3
.I'd like to have as few failures (and as many matches) as possible, within my design limitations. An example design limitation of my assembler: it supports only
bits 16
, notbits 32
orbits 64
. Sometimes I relax a small design limitation, but the one above is unlikely to change.