Forgetting about the not-so-successful OS X port for the moment, I started work on a BSD port. I like BSD and so happen to have two BSD machines available, but one is running FreeNAS and the other is running NetBSD on SPARC. The FreeNAS box doesn’t have the GNU toolchain installed by default, nor did I wish to install it since I use it for storage only. The NetBSD box is a totally different architecture, so it is out of the question. I do have an old x86 box somewhere running NetBSD, but rather than fire it up I instead opted to use a FreeBSD 9.1 VM I had lying around for such occasions.
Unlike OS X, I expected the BSD port to be relatively easy. For the most part, that turned out to be true. Like OS X, I knew I had to change the system call mechanism from passing arguments in registers to using the stack. The one snag I hit was BSD requires 4-bytes of spill space after all parameters are pushed onto the stack, but before the system call is made. The FreeBSD Developers’ Handbook has information on this (http://www.freebsd.org/doc/en/books/developers-handbook/book.html#x86-system-calls). To make things simple, the handbook recommends wrapping the int 0x80 call in a wrapper routine to avoid having to deal with the 4-byte spill area.
After modifying the hardware.s module to pass arguments via the stack (most of which I had done previously in the OS X port attempt), FreeBSD mostly worked. The biggest problem I ran into was using sigaction. In absence of being able to register interrupts like you could on the 6809, the Linux port uses sigaction and setitimer to implement a game timer to control things such as creature movements. For some reason, on BSD, the timer wasn’t working. After a lot of digging, I discovered that there are three BSD sigaction system calls – 0x2e 0x156, and 0x1a0. I was originally using 0x2e, which didn’t work. Once I switched over to using 0x1a0, the timer routine started working. The difference between the system calls is 0x2e and 0x156 are for compatibility and compatibility 4, respectively, each of which require a #define to be set. The 0x1a0 system call is standard and so is always available. With this change in place, only a few more code changes were required, most of which were just oversights from the Linux port that BSD detected (for example, using the full eax register value rather than just al).
You can find the binaries for BSD, as well as the source code, here:
With the BSD port working, it’s now time to revisit the OS X port.