mathr / blog / #

Lua on FreeDOS

I have a 30-year-old PC that I last used in 2008, at which time it was running SmallLinux2. That project is abandoned, modern Linux no longer supports the hardware, and I forgot the password, so I reinstalled the machine with FreeDOS 1.3, which is still actively developed and worked fine. I used a USB floppy disk drive on my modern Linux machine to write the 6 high density floppy disks needed to install it - make sure to verify the disks or the installer may give up with an uninformative error message if a disk has an error, and you'll have to start from the beginning again.

FreeDOS 386 version took about 15MB of the 386's 50MB hard drive. FreeDOS recommends OpenWATCOM C compiler, but the DOS installer is 80MB. So I went with Borland Turbo C 2.01, repacking the TC folder of the 11MB megapack zip so it would fit on a single floppy; I figured if I need the 24MB of sample code I would transfer it later as needed. You can try the IDE tc.exe on the Internet Archive page (DOSBOX in a web browser).

Programming in (pre-C89) C is a bit thankless, so I decided to install Lua. I tried to compile in the src folder with c:\tc\tcc.exe -c *.c. Straight away I got an error about "line 1 macro expansion too long" or similar, running "unix2dos" on the source files on Linux and copying across made that go away, but there were lots of errors. Eventually I worked out that Borland Turbo C's offsetof() implementation was broken, so I replaced that with a #define OFFSETOF(T,f) ... (see attached patch file for full details). Remaining errors involved missing locale.h, so I stubbed out the required functionality at the end of luaconf.h (and touched locale.h so that it could be included). I also needed to #define CLOCKS_PER_SEC CLK_TCK. Another few things: no long long, Windows-style \ path separator, ...

I got it compiling eventually (had to add the directory c:\tc to the path), but it wouldn't link, because the _TEXT was bigger than 64kB or something. I recompiled with Huge model (32bit pointers in all circumstances) using -ms- -mh flags, then it failed to link because lua.obj and luac.obj both defined main, and there were missing symbols for locale functions (this tale is a little out of temporal order...). As I was editing luaconf.h to stub out locale functions, the 386 crashed hard, then subsequent reboots failed with memory parity errors, even after powering off overnight in case it was overheating. The machine is broken :(

I didn't have a backup of the code changes, but I did have notes on paper, so I recreated the code diff in an emulator:

qemu-img create -f qcow2 C.img 1G
cp FD13-FloppyEdition/144m/x86* .
mv x86BOOT.img A0.img
mv x86DSK01.img A1.img
mv x86DSK02.img A2.img
mv x86DSK03.img A3.img
mv x86DSK04.img A4.img
mv x86DSK05.img A5.img
qemu-system-i386 -cpu 486 -m 16M -hdc C.img -fda A0.img -boot a
# install FreeDOS 1.3
# use ctrl-alt-2, "change floppy0 A1.img", ctrl-alt-1 to change disks
# to transfer from vm
guestmount --format=qcow2 -a C.img -m /dev/sda1 --ro /mnt/c
guestunmount /mnt/c
# to transfer to vm
# I used physical floppy disk with qemu-system-i386 ... -fda /dev/sdX

To prepare Lua sources (on Linux) for compilation in DOS:

tar xaf lua-5.4.4.tar.gz
cd lua-5.4.4
patch -p1 < ../lua-5.4.4-for-dos-with-borland-turbo-c-2.01.patch
cd src
touch locale.h
unix2dos *
cd ../..
mv lua-5.4.4 lua
zip -9 -r lua

To compile the prepared Lua sources in DOS:

# add c:\tc to existing path
cd c:\lua\src
tcc -w- -ms- -mh -I. -c *.c
del luac.obj
tcc -w- -ms- -mh -elua.exe *.obj
del lua.obj
tcc -w- -ms- -mh -I. -c luac.c
tcc -w- -ms- -mh -eluac.exe *.obj
cd ..
mkdir bin
move src/lua.exe bin
move src/luac.exe bin
cd bin
for i = 1,10 do print(i) end
# ctrl-c to exit

Download the patch: lua-5.4.4-for-dos-with-borland-turbo-c-2.01.patch

If anyone knows a cause or fix for this error on a Commodore 386 with a Phoenix BIOS from 1991 (4MB RAM, 50MB HDD, 20MHz CPU, no FPU), I'd love to know:

064K Base Memory, 00000K extended
Memory parity failure at 010000-01FFFF
 Decreasing available memory
Memory parity failure at 100000-10FFFF
 Decreasing available memory
Invalid configuration information
I/O card parity interrupt at F000:B9A6
 Type (S)hut of NMI, (R)eboot, other keys to continue