More ports… more tradewars…

more etc…

Some of the stuff is getting ironed out, it plays better for sure.

I had to start separating things out to make some older C compilers happy…

I still do not understand how ‘float’ types keep changing sizes between 16bit/32bit compilers…. Was there ever ANY consistent floating point types in C between 16/32bit? It really sucks to have binary data and find out you cannot ‘read’ it…..

Did people just force people to dump their data into ASCII, and reload it into 32bit formats, and tell everyone to ONLY use 32bit?

I know I’m like 15 years late to this party, as everyone is going through the win32 to win64 thing… Although I’m surprised Tradewars C’s win64 version runs happily with a win32 generated data file…….

Oh and ports in this version:

MS-DOS (realmode)
Win16 (QuickC for Windows’s QuickWin)
Win32 (Visual C++ 1.0’s CLI libc.lib exe… )
Win64 (Visual Studio 2008 cli)
Linux (x86 built with debian -static…..)
OS/2 (16 bit built with Microsoft C 6)

Although it supports multiple users, it’s still a single player game… I suppose it shouldn’t be too hard to constantly check the user record & sector record of where they are with stuff changing…..?

Anyways my work is here:

Boring weekend…

Ok so I had a boring weekend…. And it’s spilled over to today.

I’m getting burnt out but what happened is I found out that Turbo Pascal 5.5 is now FREE!

Which I thought was VERY cool.. So after a while of googling around for neat & interesting Pascal stuff, I came across this BBS door game, called TradeWars, that included the source!

While going through the source it seemed it could be easily ported to C so I started late Friday (or was it Saturday AM?)…

Anyways I’d feel safe with a tentative ‘public’ release of the source..

My C is based on the Pascal, which is in turn based on the BASIC code.. I’ve tried to keep it true to the pascal so there is a LOT of 2 letter variables, and a lot of WTF’s? BUT I did add comments as I was going through it.

It *SHOULD* be somewhat portable C, and I haven’t included binaries just yet… It’s still a work in progress, but I wanted to let out a WIP thing…

You can find the project here:

Oh and a screenshot:

Trade Wars C 0.7 on Windows 3.0
Trade Wars C 0.7 on Windows 3.0

It builds on both 16bit & 32bit machines… Once I get it far more fleshed out & running then I’ll sanitize the data as for now it’s using the same data & message files…

Zork via FORTRAN

I don’t know why I even started down this path, but anyways I felt the urge today to break out some Fortran.  The problem is that I acquired Microsoft Fortran 5.0 in university, however… it’s on 5 1/4” diskettes!!!

So that wasn’t going to happen.

So I figured there had to be some kind of GNU Fortran compiler, and there is.. G77.  However it needs to be tied into a release of GCC.  Which sounds great, but I was hoping to build this on a few different platforms, and on my AMD 64 platform it’s GCC 3.3 (SUA), and on my NeXT it’s 2.5.8..  Even in the notes it says you’ll need about 100MB of space to build it, which is also a nice way of saying it’ll take FOREVER.

Then I remembered something we used on the RS/6000 because it was more ‘combatable’ then the Microsoft stuff, as it was derived from the first Unix Fortran compilers… f2c.

First you’ll need the source, which thankfully is still up on the original site  This part is a bit tedious as the source is not in a single easy to get file.  You’ll need to get the source from here.  Once you’ve downloaded the files, I’d recommend saving them somewhere else.. You don’t want to have to right click like wild to get them…  Alternatively I’ll host them all here to save someone all that effort.

Building f2c is really quite simple on any UNIX’like platform.  First you’ll need the f2c source, and unpack it somewhere….  Then you *MAY* have to adjust the makefile.u for the CC/CFLAGS variables as your C compiler may not be gcc or cc, also you may or may not want the –O flags (optimize).  On my NeXT I turned off the optimizations, since this is a 33Mhz machine, and I don’t want to wait all day, and I ran it with –O0 -pipe.  Then just simply run

make –f makefile.u f2c

bash-2.01$ make -f makefile.u f2c
cc -c -O0 -pipe main.c
cc -c -O0 -pipe init.c
cc -c -O0 -pipe gram.c
cc -c -O0 -pipe lex.c
cc -c -O0 -pipe proc.c
cc -c -O0 -pipe equiv.c
cc -c -O0 -pipe data.c
cc -c -O0 -pipe format.c
cc -c -O0 -pipe expr.c
cc -c -O0 -pipe exec.c
cc -c -O0 -pipe intr.c
cc -c -O0 -pipe io.c
cc -c -O0 -pipe misc.c
cc -c -O0 -pipe error.c
cc -c -O0 -pipe mem.c
cc -c -O0 -pipe names.c
cc -c -O0 -pipe output.c
cc -c -O0 -pipe p1output.c
cc -c -O0 -pipe pread.c
cc -c -O0 -pipe put.c
cc -c -O0 -pipe putpcc.c
cc -c -O0 -pipe vax.c
cc -c -O0 -pipe formatdata.c
cc -c -O0 -pipe parse_args.c
cc -c -O0 -pipe niceprintf.c
cc -c -O0 -pipe cds.c
if cc sysdeptest.c; then echo ‘/*OK*/’ > sysdep.hd; elif cc -DNO_MKDTEMP sysdept
est.c; then echo ‘#define NO_MKDTEMP’ >sysdep.hd; else echo ‘#define NO_MKDTEMP’
>sysdep.hd; echo ‘#define NO_MKSTEMP’ >>sysdep.hd; fi
ld: Undefined symbols:
rm -f a.out
cc -c -O0 -pipe sysdep.c
cc -c -O0 -pipe version.c
cc  main.o init.o gram.o lex.o proc.o equiv.o data.o format.o  expr.o exec.o int
r.o io.o misc.o error.o mem.o names.o  output.o p1output.o pread.o put.o putpcc.
o vax.o formatdata.o  parse_args.o niceprintf.o cds.o sysdep.o version.o  -o f2c

All being well, you’ll have a new & exciting f2c executable.  I manually just copy the f2c into /usr/local/bin & the f2c.h to /usr/local/include.

Next you’ll need the f2c io library.  Thankfully this one IS zipped up and it’s available here.  Alternatively I’ve got a copy here (better). *NOTE that the ‘official’ version of the lib doesn’t extract to a sub directory… Grr  Extract the library source, and again you may need to modify the makefile to suit your compiler (CC/CFLAGS).  Then go ahead and make the library.

make –f makefile.u

cc -c -DSkip_f2c_Undefs -O0 -pipe etime_.c
ld -r -x -o etime_.o
mv etime_.o
ar r libf2c.a f77vers.o i77vers.o main.o s_rnge.o abort_.o exit_.o getarg_.o iar
gc_.o getenv_.o signal_.o s_stop.o s_paus.o system_.o cabs.o ctype.o derf_.o der
fc_.o erf_.o erfc_.o sig_die.o uninit.o pow_ci.o pow_dd.o pow_di.o pow_hh.o pow_
ii.o pow_ri.o pow_zi.o pow_zz.o c_abs.o c_cos.o c_div.o c_exp.o c_log.o c_sin.o
c_sqrt.o z_abs.o z_cos.o z_div.o z_exp.o z_log.o z_sin.o z_sqrt.o r_abs.o r_acos
.o r_asin.o r_atan.o r_atn2.o r_cnjg.o r_cos.o r_cosh.o r_dim.o r_exp.o r_imag.o
r_int.o r_lg10.o r_log.o r_mod.o r_nint.o r_sign.o r_sin.o r_sinh.o r_sqrt.o r_
tan.o r_tanh.o d_abs.o d_acos.o d_asin.o d_atan.o d_atn2.o d_cnjg.o d_cos.o d_co
sh.o d_dim.o d_exp.o d_imag.o d_int.o d_lg10.o d_log.o d_mod.o d_nint.o d_prod.o
d_sign.o d_sin.o d_sinh.o d_sqrt.o d_tan.o d_tanh.o i_abs.o i_dim.o i_dnnt.o i_
indx.o i_len.o i_mod.o i_nint.o i_sign.o lbitbits.o lbitshft.o h_abs.o h_dim.o h
_dnnt.o h_indx.o h_len.o h_mod.o h_nint.o h_sign.o l_ge.o l_gt.o l_le.o l_lt.o h
l_ge.o hl_gt.o hl_le.o hl_lt.o ef1asc_.o ef1cmc_.o f77_aloc.o s_cat.o s_cmp.o s_
copy.o backspac.o close.o dfe.o dolio.o due.o endfile.o err.o fmt.o fmtlib.o fte
ll_.o iio.o ilnw.o inquire.o lread.o lwrite.o open.o rdfmt.o rewind.o rsfe.o rsl
i.o rsne.o sfe.o sue.o typesize.o uio.o util.o wref.o wrtfmt.o wsfe.o wsle.o wsn
e.o xwsne.o dtime_.o etime_.o
ar: creating libf2c.a
ranlib libf2c.a

This will take longer then f2c.. Or at least it did on my NeXT.

Then I just copied the library libf2c.a into /usr/local/lib then ran ranlib over the library again.

Ok now we should be able to build a FORTRAN program.  Let’s try something small.

      program hello
      print *, ‘Hello!’

I’ve tried to preserve the leading 6 blank spaces.  You should be able to copy the above program, and save it as hello.f  Now we should be able to translate, compile and run the program!

bash-2.01$ f2c hello.f
   MAIN hello:
bash-2.01$ cc hello.c -lf2c -o hello
bash-2.01$ file hello
hello:  Mach-O executable (for architecture m68k) not stripped
bash-2.01$ ./hello

Awesome!  Now let’s try something much bigger, say some old Fortran source to the old ‘dungeon’ game, better known as Zork!  This source is available all over the place as dungeon-2.5.6.tar.gz, and I’ll provide a link as well here.

Download, and extract the files (gzip –dc dungeon-2.5.6.tar.gz|tar –xvf –) and you’ll have your dungeon directory.  Building this should be pretty simple, if the above program built and ran without errors.  On my SUA (Vista) machine, I had to force the –I/usr/local/include flags to find the f2c.h..  So you may need some tweaking it all depends.

Again on my NeXT I changed the CFLAGS to –O0 –pipe.  On my Vista SUA I had to specify that CC=gcc.

Once done, go ahead and run make.

\ar d libdungeon.a dmain.o np2.o
\ranlib libdungeon.a
cc -s -o dungeon dmain.o np2.o -L. -ldungeon -lf2c -lm
f2c -A -C -Nn802 textcnv.f
cc -O0 -pipe -c textcnv.c
cc -o textcnv textcnv.o –lf2c

If all went well that should be how the last lines look.  We should now have a dungeon executable!

bash-2.01$ file dungeon
dungeon:        Mach-O executable (for architecture m68k)


So let’s enter the game, shall we?

bash-2.01$ ./dungeon
Welcome to Dungeon.                    This version created 30-AUG-90.
You are in an open field west of a big white house with a boarded
front door.
There is a small mailbox here.

So, now we have built the f2c translation package, and managed to build a trivial hello world program, and something a little more complex like Dungeon/Zork.

Now I can play with my numerical recipes book with my pseudo Fortran kit.

Quake for the MIPS (NT4)

Well I started this off hoping I could get Quake running on Windows NT 3.1 … I’m almost there I have the null version running just fine. However I’m not all that great with DIB programming so I was looking thru SDL and saw that it has a WINDIB driver!

So with a LOT of tweaking through SDL 1.2.13 I got it to compile with Visual C++ 1.0!! However it is lacking one critical call, the CreateDIBSection api call in GDI is not present in NT 3.1. So remembering all the MIPS stuff as of late, and that I have Visual C++ 4.0 which should easily support this call, I first got it running with Visual C++ 2.0 on the i386 (Under XP of all things). So it was just a matter of building the source, and making sure there is no errors, uploading it to the emulator, and rebuilding for the MIPS.

And after 30 minutes, I got my exe, and it ran!

Quake 1.06 on the MIPS/NT
Quake 1.06 on the MIPS/NT

I’ve included a link for any other MIPS people out there that want to play quake. I haven’t built the networking as I was having issues with my network earlier and couldn’t get it working…

The exe is available here.

And the source code with all the bits is right here.

In this build I’m not building SDL as a DLL or static library, but rather compiling Quake right into the source. Now that SDL is running on the MIPS, and possibly other Win32 OS’s (I have yet to test Win32s… I suspect the inherent threading in SDL will prevent it, but could the DBI calls be made directly stripping out SDL…?) but who knows, I think anything past 3.51 would work.

SoftPC –AT Version 3

Ok, so I’ve been on this MIPS kick as of late.. Me & Antoni just split the cost of Visual C++ 4.0 for the MIPS…  All being well it’ll arrive on Wednesday and we can do some more stuff.  As I understand it, Visual C++ 4.0 was THE compiler for Windows 95 people at the time, and it will have all the controls & stuff that Visual C++ 2.0 simply does NOT have.

Anyways while I was playing with my virtual MIPS machine, I decided to try the MS-DOS emulation out..  I had heard that they had a pretty advanced emulator to run stuff.  So I downloaded a new version of MSD, and was really surprised at the CPU that it was emulating… a 486!  And this is on a MIPS machine, I had to wonder why they couldn’t have continued this for the x64 product…


Anyways ok so it’s a 486, but can it play DOOM?

doom under MIPS NT (1)

Much to my amazement, the answer is YES.  Ok the pallet is all screwed up, and yes it is SLOW.. It reminds me of a 386, but it’s actually running!

Now I was interested, I opened up the ntvdm.exe in notepad to reveal it’s origin:

SoftPC-AT Version 3

(C)Copyright Insignia Solutions Inc. 1987-1992

@(#)sun4_a3cpu.c    1.2 5/24/91 Copyright Insignia Solutions Ltd.

Now what is really interested is this bit.. It only appears in the MIPS binary:

This version is subject to confidentiality provisions and should not be distributed. %s %s%s Copyright %s, an unpublished work by Insignia Solutions Inc.%s %s %s Copyright %s by Insignia Solutions Inc. All rights reserved.

Otherwise there is a LOT of mentions of D:\nt\private\mvdm\  I guess it’s about their build process since the DDK is nt\public.

Anyways I thought it was really interesting to see just how involved the NTVDM was on the RISC cpu’s.  I think there is no doubt that the Connectix product was faster, and of course on Ghz+ machines its usable.  Not to mention once Connectix made a native version of Virtual PC for Windows… It’s really not that surprising why Microsoft snatched the product up!

Somewhere around here I have SoftPC 3.0 for the Apple Macintosh… I wonder if it can load doom?

SimpleIRC & ROIDS for the MIPS!


Well I’ve been looking for an IRC client for the MIPS and I’ve come up with nothing… And looking for source to much of anything win32 is LONG past something that will compile with Visual C++ 2.0 …

However I did find this simple library built by Andrew Cater:

So with very little understanding of how IRC actually works I was able to build a SUPER simple client.  Please note that it’s so simple the / commands that you’ve come to love are not implemented…!  You get one shot for your name/nick/server & channel.. But hey the exe is like 70kb for the MIPS/x64 and 35 for the i386.

sirc and roids MIPS in action
sirc and roids MIPS in action

You can find it’s source & binaries right here.

Also Antoni Sawicki has given me a BUNCH of leads on old public source, and binaries, namely ROIDS the first real graphical game we seem to have now for the MIPS.  The source was a part of a PDTools thing that Dec had put together, however a lot of it will build for both i386 & MIPS. I’ve extracted the source for roids here.

I don’t want to over promise but I’ll see if I can get quake to build some time in the next week.. I don’t know if I can get any graphics out of it, but it’d be fun for a server at least…  Windows NT 4.0 sp1 should have DirectX 2.0 …  The pinball game is quite playable (although the colors are all screwed up, due to a pallet glitch in the emulator) so we shall see.


FWIW I was checking links, and Tom’s site has moved to, which of course itself is now gone.  However with a lot of leg work, I did manage to snag the source to a few versions, and put them onto my CVS server, linked here: on  And of course you can replicate it via CVS.

As mentioned over here, the steps basically are:

cvs -d:pserver:[email protected]:/frontvm login
cvs -d:pserver:[email protected]:/frontvm checkout frontvm
cvs -d:pserver:[email protected]:/frontvm log -h | grep -P '^\t' | awk '{print $1}' | sort|uniq| sed -e 's/://g'

With the last step showing you the various commit levels….
In this case they are:

  • frontvm-20040517
  • frontvm2-20061120
  • frontvm3-20060613
  • frontvm3-20060623

So to checkout the first and oldest code I’ve found, you would execute:

cvs -d:pserver:[email protected]:/frontvm checkout -r frontvm-20040517 frontvm

And there you go.

The Frontier wiki is still here.

Packages so far on Uwisc 4.3BSD

I’ve been compiling quite a bit of stuff.. Looking back it was something I intended to do back in October of 2007… Well no time like the present then! I’ve done my best to include all the relevant bits for each of the following packages. It’s entirely possible I’ve missed stuff, so feel free to re-build the stuff as you wish. Some of the packages require you to build them with GCC as the default CC won’t work. However if you are going to build it yourself you won’t be able to jump to gcc as it requires gperf which in turn requires a working c++ compiler. So far here are the following packages:


All of these can be downloaded from here. I’m keeping all the source code (unaltered) in tap format for the SIMH emulator right here.

To get the C compilers going I had to build gcc 1.42 with the system compiler (cc/PCC) then use that version of GCC to build the next version. Once I had gcc 2.5.8 building, then I was able to build binutils 2.8.1 without issues, then rebuild gcc 2.5.8 to use binutils instead of the default system assembler so that I could build lynx and it wouldn’t barf because of the massive switch statement…

And no, -J didn’t help.

Speaking of lynx the search ability is broken because the function simply isn’t in 4.3 BSD (bsearch), and for pine, I had to make a fake tmpfile function that uses the /tmp/pinebox directory.

The gcc 2.5.8 package includes the C++ components, and I’m pretty sure I did with as well. I’m not sure if GCC 3.x kept the VAX cpu so I haven’t pushed forward, but seeing that the cc1 exe is over 1mb it doesn’t seem worth it to push ahead.

I’ll have to see about including more games. The selection in this 4.3 release is kind of weak,

aardvark* boggle* [email protected] monop* snake*adventure* ching* hangman* quiz* snscore*backgammon* cribbage* hunt* robots* teachgammon*battlestar* doctor* lib/ rogue* trek*bogdict* fortune* mille* sail* zork*

I’ll have to see what’s missing from where.. Also I notice that the arrow key bindings in terraterm are not working… I’ll have to dive into that as well. It may end up with a new re-relase of the emulator or a patch thing. I’ll have to see.

I should add a quick note on how to unpack these tap files. First you will need bzip2 on your native pc. You should be able to get one here.

Now just uncompress the file..

C:\Program Files (x86)\uwiscbsd>bzip2 -d lynx-2.8.2.binary.BSD-4.3.Uwisc.tap.bz2

Now you need to go to the SIMH console window. It will say something like this in it:

VAX780 simulator V3.8-1
Listening on port 42221 (socket 376)
Waiting for console Telnet connection

Hit Control+E and it’ll interrupt the simulator. Then we need to attach the tap file like so:

Simulation stopped, PC: 800018A3 (MTPR #0,#12)
sim> att ts0 lynx-2.8.2.binary.BSD-4.3.Uwisc.tap
sim> c

the att command will attach the tap file to the ts0 device. the c will tell the simulator to continue. Now just switch to a tty windows (or attach a pty), then it’s a simple matter of running the following commands:

myname# cd /
myname# mt rew
myname# tar -xvmf /dev/rmt12
x /usr/local/bin/gzip, 66560 bytes, 130 tape blocks
x /usr/local/bin/lynx, 949248 bytes, 1854 tape blocks
x /usr/local/lib/lynx.cfg, 97203 bytes, 190 tape blocks
myname# rehash

Thats about all it takes, now you can run lynx. If you so wish, you can run back to the SIMH console, and tell it to “det ts0” which will detach the tape image.

Amiga Days

Do you remember the Commodore Amiga?

I certainly do!

While I was busy fiddling with my Commodore 64, a friend of mine got an Amiga in high school. The 64 was cool, but I was simply blown away by the Amiga. To say there was a gulf between the 8 bit machine, and the quasi 32/16 bit machine would be a massive understatement. His Amiga 2000 could do all kinds of neat things, from talk, run IBM XT software at 100% speed via a “bridge board”, not to mention play super snazzy games. It took me a few years to save up to buy my very own Amiga 500, and once I was ready I didn’t have enough money for a bus ride home, so I walked the FIVE miles home toting my Amiga! I was so happy to say the least!! (At least it was summer, it was flat, and there weren’t any tropical waves/hurricanes around…)

While there are a few emulation alternatives for running the old m68000 software on all kinds of machines, I’m going to talk about AROS today.

AROS is to AmigaDOS what Wine is to Windows. Once it became clear that Commodore was going to die, and that AmigaDOS and the Amiga were lost a few brave people decided that they had to take matters into their own hands. Sadly there was lots of in fighting, a tradition of the comp.sys.amiga.advocacy news group where some people get too tied into little details and let little things (like the rise of Microsoft Windows) pass them by. At any rate, Aaron Digulla knuckled down, and start to write a bug for bug clone of AmigaDOS 3.1 in C to run on the IBM PC. The result of which is AROS. It currently will either run hosted on Linux/NetBSD or natively on the i386. There is a port to the Amd64 undergoing right now. AROS even has SDL support.

So this got me thinking..

What if I were to remove all the OpenGL calls from GLFrontier, and ran it as a strictly 2d app on AROS?

So I took the first step, and I trimmed out the OpenGL support from Tom’s fix of Frontier, so it’s completely SDL 2d friendly, and cross compiled it to AROS. I built the first pass on MinGW, and got frame rates of upwards of 1000 on Vista 64!

Now for the fun part of building an AROS version. While there is now a native GCC for AROS it cannot compile the assembly listing from GLFrontier.. I suspect it’s a heap overflow. This means you have to cross compile. I have cygwin installed in a Windows 2000 VM I use with Virtual PC 2007. I’m not sure if cygwin installs on Vista, let alone Vista 64, however I do suspect it MAY have issues… I keep my dev stuff in a VM so I can move it around without losing my settings.

I downloaded and unpacked the following files into my cygwin installation:


And the SDL include directory from cygwin.. I think its SDL version 1.2

I did have to find all the ‘exe’ files and make sure they were chmoded +x as the compiler would not run (chmod +x /usr/local/bin/exe /usr/local/i386-aros/bin/ /usr/local/lib/gcc-lib/i386-aros/3.3.1/*exe ). Once you are ready you should be able to build files with


I’m not sure how to build stripped files, but I suspect it’s out there somewhere. At any rate, I did this to compile my SDL 2d version of FrontierGL:

$ cd as68k

$ make
gcc -O2 -g -Wall -c -o output.o output.c
gcc -O2 -g -Wall -c -o output_c.o output_c.c
gcc -O2 -g -Wall -c -o output_i386.o output_i386.c
output_i386.c:981:1: warning: “_S” redefined
In file included from output_i386.c:6:
/usr/include/ctype.h:35:1: warning: this is the location of the previous definition
output_i386.c: In function

output_i386.c:1373: warning: 'out_reg' might be used uninitialized in this function
output_i386.c: In function
output_i386.c:1474: warning: ‘reg3’ might be used uninitialized in this function
output_i386.c:1474: warning: ‘out_reg’ might be used uninitialized in this function
gcc -O2 -g -Wall -c -o as68k.o as68k.c
as68k.c: In function `asm_pass1′:
as68k.c:663: warning: ‘size’ might be used uninitialized in this function
as68k.c:671: warning: ‘coutput_label’ might be used uninitialized in this function
gcc -O2 -g -Wall -c -o dict.o dict.c
gcc -O2 -g -Wall output.o output_c.o output_i386.o as68k.o dict.o -o as68k

$ cd ..

$ as68k/as68k.exe –output-i386 fe2.s
Pass 1
Pass 2
Done! 539337 bytes and 759 relocations.

$ i386-aros-gcc -c fe2.s.S

$ i386-aros-gcc -O2 -I /usr/local/i386-aros/sys-include/sdl -c audio.c
audio.c: In function

audio.c:334: warning: passing arg 5 of
SDL_LoadWAV_RW’ from incompatible pointer type

$ cd src

$ i386-aros-gcc -O2 -I /usr/local/i386-aros/sys-include/sdl -c hostcall.c

$ i386-aros-gcc -O2 -I /usr/local/i386-aros/sys-include/sdl -c input.c

$ i386-aros-gcc -O2 -I /usr/local/i386-aros/sys-include/sdl -c keymap.c

$ i386-aros-gcc -O2 -I /usr/local/i386-aros/sys-include/sdl -c main.c

$ i386-aros-gcc -O2 -I /usr/local/i386-aros/sys-include/sdl -c screen.c
screen.c: In function `draw_control_panel’:
screen.c:274: warning: assignment makes integer from pointer without a cast

$ i386-aros-gcc -O2 -I /usr/local/i386-aros/sys-include/sdl -c shortcut.c

$ i386-aros-gcc *.o ../fe2.s.o -lsdl -o ../frontier

$ cd ..

$ file frontier
frontier: ELF 32-bit LSB relocatable, Intel 80386, version 1 (SYSV), not stripped

$ i386-aros-size frontier
text data bss dec hex filename
2580672 2036 1422076 4004784 3d1bb0 frontier

*REMEMBER as68k has to actually run on the host machine, so it needs to be native, you cannot use a cross compiler for that. However you do cross compile it’s output.

Naturally you’ll now want to run your exe!

For testing the binaries you’ll need some kind of Aros system, I recommend WinAROS, it’s a pre-built Qemu package, so the disk will work on all kinds of platforms. You can download it here: WinAros Developer

This is a pretty snazzy setup, I recommend booting into a 32bit depth display option, however you will want to modify the default script to look like this at the last line:

qemu.exe -L . -m 256 -localtime -boot c -hda WinArosHD.img -no-kqemu -net nic -net user

The next thing you’ll want to do is enable the networking. I don’t know why it’s disabled by default, but with a few moments in the CLI, and edit you can have it running:

To get the network running you have to go into Extras:Networking/Stacks/AROSTCP/db and edit static-routes, netbd-myhost, and interfaces.

First edit interfaces and uncomment the line that has device prm-rtl8029 and change the IP to

Second edit netbd-myhost and make it look like this:
HOST arosbox.arosnet arosbox
DOMAIN arosnet 10.0.2.

Third edit static-routes and change the address to

Last add the following line to your user-startup
Execute Extras:Networking/Stacks/AROSTCP/S/startnet.

Now reboot. Open a shell and verify that you have a connection with “ifconfig -a”
You can also try to ping a website, but you might not get any return packets because of QEMU’s built in firewall. You should at least see the ip address for the site you ping. Or ping to make sure you network is communicating with Qemu.

Now for the final moment, put your exe on a web server, and simply use wget to get it! I’d recommend zipping up your work directory, so it includes the ‘bin’ file, and the structure that GLFrontier expects. I like the zip file format as WinAROS includes unzip.

I do the following from AROS


It’s that easy! Now you can either ‘cd’ or click on your frontier, and away it should go!

The video is a bit wonky in that it seems to only work in 8 bit or 24bit depths. So far I’ve only tested this in WinArosDeveloper.

It actually works, the keyboard is buggy as hell, but you can play with the mouse. The first key code seems to work, then it gets stuck, so I recommend the ‘enter’ key so you can thrust…

I’ve published my zip up to The AROS Archives with any luck when it’s there I’ll update it with a link to it. In the mean time, I’ll provide a dump of the screen.c that I fixed to remove the OpenGL support. Naturally blogspot will screw up the formatting, however it should work…

#include “main.h”
#include “../m68000.h”
#include “screen.h”

/* new stuff */
enum RENDERERS use_renderer = R_OLD;
int len_main_palette;
unsigned short MainPalette[256];
unsigned short CtrlPalette[16];
int fe2_bgcol;
int mouse_shown = 0;
unsigned long logscreen, logscreen2, physcreen, physcreen2;
unsigned long VideoBase;
unsigned char *VideoRaster;
unsigned int MainRGBPalette[256];
unsigned int CtrlRGBPalette[16];
int screen_w=320;
int screen_h=200;
BOOL bGrabMouse = FALSE;
BOOL bInFullScreen = FALSE;
SDL_Surface *sdlscrn;

static const unsigned char font_bmp[] = {

static inline void read_m68k_vertex (int st_vptr, int output[3])
output[0] = STMemory_ReadLong (st_vptr);
output[1] = STMemory_ReadLong (st_vptr+4);
output[2] = -STMemory_ReadLong (st_vptr+8);

struct ZNode {
unsigned int z;
struct ZNode *less, *more;
void *data;

#define MAX_OBJ_DATA (2<<17)
static unsigned char obj_data_area[MAX_OBJ_DATA];
static int obj_data_pos;
#define MAX_ZNODES 1000
static struct ZNode znode_buf[MAX_ZNODES];
static int znode_buf_pos;
static struct ZNode *znode_start;
static struct ZNode *znode_cur;

enum NuPrimitive {

struct QueuedString {
int x, y, col;
unsigned char str[64];
} queued_strings[MAX_QUEUED_STRINGS];
int queued_string_pos;
static bool no_znodes_kthx;

static void _BuildRGBPalette (unsigned int *rgb, unsigned short *st, int len);
static void draw_3dview (struct ZNode *node);
static int DrawChar (int col, int xoffset, char *scrline, int chr);
static void Nu_DrawPrimitive (void *data);
static inline int znode_rdlong (void **data);
static void add_node (struct ZNode **node, unsigned int zval);
static void znode_insert (struct ZNode *node, unsigned int zval);
static inline void end_node ();
static inline void znode_databegin ();
static inline void znode_wrlong (int val);

int DrawStr (int xpos, int ypos, int col, unsigned char *str, bool shadowed)
int x, y, chr;
char *screen;

x = xpos;
y = ypos;

if ((y > 192) || (y<0)) return x;
screen = LOGSCREEN2;
screen += SCREENBYTES_LINE * y;

while (*str) {
chr = *(str++);

if (chr < 0x1e) {
if (chr == ‘\r’) {
y += 10;
x = xpos;
goto set_line;
else if (chr == 1) col = *(str++);
} else if (chr == 0x1e) {
/* read new xpos */
x = *(str++);
x *= 2;
} else if (chr < 0x20) {
/* Read new position */
x = *(str++);
x *= 2;
y = *(str++);
goto set_line;

//if (x > 316) continue;

if (shadowed) {
DrawChar (0, x+1, screen+SCREENBYTES_LINE, chr-0x20);
x = DrawChar (col, x, screen, chr-0x20);

return x;
printf (“DrawStr [%s]\n”,str);
return 0;

void Nu_PutColoredPoint()

void Nu_ComplexSNext()
void Nu_DrawComplexSNext()

void Nu_DrawComplexStart()
void Nu_DrawComplexEnd()

void Nu_ComplexStartInner()
void Nu_DrawComplexStartInner()
void Nu_ComplexBezier()
void Nu_DrawComplexBezier()

void draw_control_panel()
unsigned int *pal;
// Lock surface if needed
if (SDL_MUSTLOCK(sdlscrn))
if (SDL_LockSurface(sdlscrn) < 0)

// Declare a couple of variables
int y, x, yofs, ofs;

// Draw to screen
yofs = 0;
for (y = 0; y < screen_h; y++)
if(y==168)pal=CtrlRGBPalette; //bottom has differnet palette
for (x = 0, ofs = yofs; x < screen_w; x++, ofs++)
//((unsigned int*)sdlscrn->pixels)[ofs] = pal[VideoRaster[ofs]];

switch (sdlscrn->format->BytesPerPixel)
case 1: // 8-bpp
Uint8 *bufp;
bufp = (Uint8 *)sdlscrn->pixels + y*sdlscrn->pitch + x;
*bufp =(Uint8*) pal[VideoRaster[ofs]];
case 2: // 15-bpp or 16-bpp
Uint16 *bufp;
bufp = (Uint16 *)sdlscrn->pixels + y*sdlscrn->pitch/2 + x;
*bufp = pal[VideoRaster[ofs]];
case 3: // 24-bpp mode, usually not used
Uint8 *bufp;
bufp = (Uint8 *)sdlscrn->pixels + y*sdlscrn->pitch + x * 3;
bufp[0] = pal[VideoRaster[ofs]];
bufp[1] = pal[VideoRaster[ofs]] >> 8;
bufp[2] = pal[VideoRaster[ofs]] >> 16;
} else {
bufp[2] = pal[VideoRaster[ofs]];
bufp[1] = pal[VideoRaster[ofs]] >> 8;
bufp[0] = pal[VideoRaster[ofs]] >> 16;
case 4: // 32-bpp
Uint32 *bufp;
bufp = (Uint32 *)sdlscrn->pixels + y*sdlscrn->pitch/4 + x;
*bufp = pal[VideoRaster[ofs]];

//yofs += sdlscrn->pitch / 4;
yofs += sdlscrn->pitch / sdlscrn->format->BytesPerPixel;

// Unlock if needed
if (SDL_MUSTLOCK(sdlscrn))

// Tell SDL to update the whole screen
SDL_UpdateRect(sdlscrn, 0, 0, screen_w, screen_h);


void Nu_DrawScreen()
_BuildRGBPalette (MainRGBPalette, MainPalette, len_main_palette);
_BuildRGBPalette (CtrlRGBPalette, CtrlPalette, 16);
//printf (“Frame: %d znodex.\n”,znode_buf_pos);
//draw_3dview (znode_start);
if (mouse_shown) {
SDL_ShowCursor (SDL_ENABLE);
mouse_shown = 0;
} else {



void Nu_PutBezierLine()
void Nu_DrawBezierLine()

void Nu_3DViewInit()
queued_string_pos = 0;
//printf (“3dviewinit()\n”);
znode_buf_pos = 0;
//printf (“%d bytes object data\n”, obj_data_pos);
obj_data_pos = 0;

znode_start = NULL;
znode_cur = NULL;
no_znodes_kthx = FALSE;
void Nu_InsertZNode()
unsigned int zval = GetReg (4);
if (use_renderer == R_OLD) return;
if (no_znodes_kthx) return;
if (znode_start == NULL) {
add_node (&znode_start, zval);
} else {
znode_insert (znode_start, zval);

void Nu_PutCircle()
void Nu_DrawCircle()

void Nu_PutOval()
void Nu_DrawOval()

void Nu_PutCylinder()
void Nu_DrawCylinder()

void Nu_QueueDrawStr()
void Nu_IsGLRenderer()

void Nu_PutPlanet()
void Nu_DrawPlanet()

void Nu_Put2Line()
void Nu_Draw2Line()

void Nu_PutQuad()
void Nu_DrawQuad()

void Nu_GLClearArea()
void Nu_PutBlob()
void Nu_DrawBlob()

void Nu_Put2DLine()
void Nu_Draw2DLine()

void Nu_PutLine()
void Nu_DrawLine()

void Nu_UnInit()

void Nu_PutTeardrop()
void Nu_DrawTeardrop()

void Nu_PutPoint()
void Nu_DrawPoint()

void Nu_PutTwinklyCircle()
void Nu_DrawTwinklyCircle()

void Nu_ComplexStart()

void Nu_PutTriangle()
void Nu_DrawTriangle()

void Nu_ComplexSBegin()

void Nu_ComplexEnd()

void Nu_32ViewInit()

void Screen_ToggleRenderer ()
use_renderer = R_OLD;

void change_vidmode(void);

void Screen_Init(void)
SDL_WM_SetCaption(PROG_NAME, “Frontier”);

void change_vidmode (void)
const SDL_VideoInfo *info = NULL;
int modes;

info = SDL_GetVideoInfo ();

assert (info != NULL);


if ((sdlscrn = SDL_SetVideoMode (screen_w, screen_h,
info->vfmt->BitsPerPixel, modes)) == 0) {
fprintf (stderr, “Video mode set failed: %s\n”, SDL_GetError ());
SDL_Quit ();
exit (-1);
printf(“change_vidmode %d x %d %d deep\n”,screen_w,screen_h,info->vfmt->BitsPerPixel);

void Screen_UnInit(void)
void Screen_ToggleFullScreen()

static void _BuildRGBPalette (unsigned int *rgb, unsigned short *st, int len)
int i;
int st_col, r, g, b;

for (i=0; i>4;
rgb[i] = 0xff000000 | (b<<16) | (g<<8) | (r);

static int DrawChar (int col, int xoffset, char *scrline, int chr)
const char *font_pos;
char *pix;
int i;

font_pos = font_bmp;
font_pos += (chr&0xff)*10;
scrline += xoffset;

if (xoffset < 0) {
font_pos += 9;
return xoffset + *font_pos;

for (i=0; i<8; i++, font_pos++, scrline += SCREENBYTES_LINE) {
pix = scrline;
if (xoffset > 319) continue;
if (*font_pos & 0x80) *pix = col;
if (xoffset+1 > 319) continue;
if (*font_pos & 0x40) *pix = col;
if (xoffset+2 > 319) continue;
if (*font_pos & 0x20) *pix = col;
if (xoffset+3 > 319) continue;
if (*font_pos & 0x10) *pix = col;
if (xoffset+4 > 319) continue;
if (*font_pos & 0x8) *pix = col;
if (xoffset+5 > 319) continue;
if (*font_pos & 0x4) *pix = col;
if (xoffset+6 > 319) continue;
if (*font_pos & 0x2) *pix = col;
if (xoffset+7 > 319) continue;
if (*font_pos & 0x1) *pix = col;
/* width of character */
i = *font_pos;
return xoffset + i;
* znode_start is the head of a btree of znodes, each with a linked list
* of GL display lists to draw (in list order).
* Draw this crap starting from biggest value znodes.
static void draw_3dview (struct ZNode *node)
if (node == NULL) return;
if (node->more) draw_3dview (node->more);

if (use_renderer) {
printf (“Z=%d “, node->z);
Nu_DrawPrimitive (node->data);

if (node->less) draw_3dview (node->less);

typedef void (*NU_DRAWFUNC) (void **);
NU_DRAWFUNC nu_drawfuncs[NU_MAX] = {
&Nu_DrawComplexSNext, // 6
&Nu_DrawComplexStartInner, // 9

static void Nu_DrawPrimitive (void *data)
int fnum;

for (;;) {
fnum = znode_rdlong (&data);
//fprintf (stderr, “%d “, fnum);
if (!fnum) return;
nu_drawfuncs[fnum] (&data);

static inline int znode_rdlong (void **data)
int val = *((int*)(*data));
(*data) += 4;
return val;

static void add_node (struct ZNode **node, unsigned int zval)
assert (znode_buf_pos < MAX_ZNODES);
/* end previous znode display list!!!!!!! */
if (znode_cur) end_node ();

*node = znode_cur = &znode_buf[znode_buf_pos++];
znode_cur->z = zval;
znode_cur->less = NULL;
znode_cur->more = NULL;
znode_databegin ();

static inline void end_node ()
znode_wrlong (0);

static void znode_insert (struct ZNode *node, unsigned int zval)
if (zval > node->z) {
if (node->more) {
znode_insert (node->more, zval);
} else {
add_node (&node->more, zval);
} else {
if (node->less) {
znode_insert (node->less, zval);
} else {
add_node (&node->less, zval);

static inline void znode_databegin ()
znode_cur->data = &obj_data_area[obj_data_pos];

static inline void znode_wrlong (int val)
*((int*)(obj_data_area+obj_data_pos)) = val;

Frontier, Elite II

I was playing with DOSBox on an XP machine, and I came across this exciting link: You can now download Frontier II as shareware! Most cool, so I’ve downloaded it & just run it under DOSBox. No tweaks, answer for the SoundBlaster sound card, and away you go! Here is me attempting to do a flyby of the Saturn system..

This game was super cool back in the day for it’s realistic physics as you could do slingshots, flybys, orbits & even land on various moons & planets. There is nothing more exhilarating then flying through the solar system or the universe at hundreds of thousands of Km/s. Not to mention the hyper drive!

You can give it a shot too, if your browser is Java enabled!  Just click right here, and enjoy!