I was having trouble getting DOS apps to run properly in Dosbox, which is optimized for running games. QEMU, on the other hand, is nice and accurate (albeit a little slower) and not too hard to set up.
$ qemu-img create freedos.img 1000M $ qemu-system-i386 -hda freedos.img -cdrom FD12CD.iso -boot d (run the installer...) $ qemu-system-i386 -hda freedos.img -boot c
This works on Mac or Linux. You do of course need to have a printer set up already (network or local.)
#!/usr/bin/env python3 import io import os import subprocess """ DOS printing adapter Opens a fifo named "print_pipe" and prints text from it every time a form feed (^L, 0x0C) is received. Example usage: $ ./printer.py & $ qemu-system-i386 -hda freedos.img -boot c -parallel file:print_pipe Make sure your software sends a form feed. In DBASE III+, this is configured in the report options. TODO: print buf after a timeout, even if there's no form feed. """ def _adjacent_to_script(f): base = os.path.dirname(os.path.realpath(__file__)) return os.path.join(base, f) def send_to_printer(s): print('Printing page(s)...') subprocess.run(['lpr'], input=s, text=True, check=True) if __name__ == '__main__': pipe_name = _adjacent_to_script('print_pipe') os.mkfifo(pipe_name) try: buf = io.StringIO() with open(pipe_name, 'r', encoding='cp437') as pipe: while True: c = pipe.read(1) if c == '\x0c': # form feed send_to_printer(buf.getvalue()) buf.close() buf = io.StringIO() else: buf.write(c) finally: os.remove(pipe_name)