I saw this many years ago, but for some reason never finished writing about this. Moxie was a virtual CPU designed to be as simple as possible for the GNU toolchain to target.
So yes, it’s a virtual CPU, OS & Game, running in java-script and on the page.
I’ve been able to save, restore and go up, down and even die without it crashing so it seems OK to me.
It’s kind of cool to build it with GCC 1.40 on Windows 10, and get a native executable. Maybe pointless in the golden age of emulation / virtualization as you could just as easily build stock 1.3d on a 4.2 BSD VAX, or even 386BSD 0.1 system.
Maybe I’ll finish the work to see if I can get it running on OS/2 or MS-DOS via EMX, but for now the project stuff is on sourceforge.net
I know with all the talk of GCC 6.1.0 for MS-DOS, and other platforms, you must be thinking that all this talk of progress, and high versions numbers just isn’t right! I’ve just started to migrate code to GCC 5.1, and now you are telling me there is a GCC 6!
Where can I turn away from all this so called progress! I don’t like my C compilers to be C++ programs that require massive HOURS to compile. Can’t we just go back to the good old days?
And the answer is YES, you can!
While looking for some libraries on another project, I came across this old defunct project called RSXNT. And it’s a port of EMX to Win32 platforms! Well isn’t that fantastic!
So, considering I was able to build GCC 1.40 and cross compile to Linux 0.11 from Windows, can we do something with this?
Well ancient versions of EMX are very difficult to track down. Somehow I did mange to find this hybrid of 0.8B & 0.8C. The EMX runtime & binaries are from 0.8C, but the source code is from 0.8B. And the best thing is that the 0.8B is based around GCC 1.40! So with a little bit of tweaking the files, and messing around I got the assembler, linker, and C compiler to build with MinGW! Sadly the source code to EMXBIND, wasn’t included in the zips that I have, but the aformentioned RSXNT packages included a version of EMXBIND that will run on Windows! So I managed to mash them together, and for the fun of it, I’m using the old InfoTaskForce interpreter from 1987 to complete the vintage feel.
Now with my executable, I can run it on MS-DOS & OS/2!
and OS/2 2.0!
Well isn’t that fantastic!
However when running RSXNT’s bind, NTBIND I got this error:
No relocations in file:
you have not linked the NT library
Great. Some more digging around, and if you want to make Windows programs, you need to use the RSXNT includes & libraries. So I shifted the libraries around, and patched gcc to call the linker the same way RSXNT’s gcc driver calls it, and first go this error:
io.o: Undefined symbol __streams referenced from text segment
And looking at the stdio.h there is this:
extern struct _stdio _streams;
No doubt, the headers & libraries are tied together. So now making both of the RSXNT versions, I can link the executable. (YES I did try declaring the structure anyways, and I get stdout, but stdin doesn’t work).
Just like EMX before it, RSXNT, requires you to have the RSXNT.DLL file in your path, or in the same directory. I suppose it’s a fair trade off. Not that I expect there to be a surge of people cross compiling from Windows to OS/2, or even MS-DOS these days. GCC 1.40 is ancient, 1991 vintage, but even Linus Torvalds loved it!
For comparison, GCC 5.10 produces a 55,906 byte interpreter, while GCC 1.40 produces a 88,576 byte interpreter.
For an attempt at porting some code, I choose Nethack 1.3d, and used the MS-DOS based makefiles. It didn’t work so well, but I was able to patch in enough of the unix based termios logic, and thanks to EMX/RSXNT’s built in termios capabilities I was able to get a working version!
I don’t know if there really was any advantage to compiling with GCC 1.40, but it was great to see that this 1991 compiler could handily compile the 1987 based code.
How about some speed comparisons? I dug out the ancient dhrystone.c, and gave it a shot. I had to define 500,000,000 passes, as my computer is fast. GCC 1.40 only offers -O for optimization, while GCC 5.1 offers many more levels, but for this quick experiment they really aren’t needed.
Dhrystone(1.1) time for 500000000 passes = 57
This machine benchmarks at 8771929 dhrystones/second
Dhrystone(1.1) time for 500000000 passes = 40
This machine benchmarks at 12500000 dhrystones/second
Dhrystone(1.1) time for 500000000 passes = 43
This machine benchmarks at 11627906 dhrystones/second
Dhrystone(1.1) time for 500000000 passes = 16
This machine benchmarks at 31250000 dhrystones/second
Dhrystone(1.1) time for 500000000 passes = 14
This machine benchmarks at 35714285 dhrystones/second
Dhrystone(1.1) time for 500000000 passes = 11
This machine benchmarks at 45454545 dhrystones/second
As you can see, GCC 1.40 produces the slowest code. While it’s optimized code did beat out GCC 5.10 with no optimizations, turning on optimizations did blow it away. And again GCC 5.1 beat out the older 1.40 for executable sizes.
And this time by over a 2x lead! It is fair to say that the new versions of GCC, despite being significantly larger do indeed produce smaller and faster code.
For anyone who’s read this far, I guess you want to take it out for a test drive? Remember it is still EMX based, which means is wants to live on the ROOT of your hard disk. I’m using the ‘D’ drive for myself, so if you are using C or whatever you’ll need to alter the environment vars.
So I figured since I’ve had major issues trying to get DOOM to run, I’d try something bigger, like NetHack. I figured its a good fit, it’s all ASCII based anyways, so how complicated can it be?
Actually it turned out to not be that complicated. Thankfully having both run68’s source and NetHack source I was able to adapt enough of the system stuff to get it running. I decided to use this build of NetHack 1.3d that has been updated to compile with modern compilers, since the cross tools use GCC 4.6.2. NetHack 1.3d synchronized PC hack, and UNIX based NetHack enough that I could start to build under MS-DOS, and then re-target it, as Human68k and MS-DOS share a lot of features (although Human68k has support for tasks, and shared memory. It’s more like OS/2 although no memory protection… ).
I’ve gotten it to the point where you can save, load and quit. Oddly enough the ANSI support in Human68k isn’t as good as ansicon so it actually runs better on run68.
So my next step will be to figure out more of the console controls on Human68k, and remove the ANSI support.
Ideally I’d love to figure out how to talk to the sound drivers on the x68000. Add some music. Maybe sound effects, and graphics?
I came across this PDP-11 version. I saved it to the side while I was looking for my main target.
Now I’ve tried to compile it on contemporary UNIX of the time, namely Unix v7, 2.9 BSD and 2.10 BSD and they fail at the same point:
hack.monst.c:99: Too many initializers: mon
*** Error code 1
What is more weird is I didn’t see anyone having any reports of it working, just requests for the code. Although I have been able to compile and run it on 4.2BSD/VAX. So it must be a cc/pcc thing, or some other C compiler they are using on the PDP-11 in Amsterdam circa 1985. And then I found this interesting bit:
Date-Received: Mon, 22-Apr-85 06:57:56 EST
Reply-To: aeb@mcvax.UUCP (Andries Brouwer)
Organization: CWI, Amsterdam
In article <556@intelca.UUCP> cem@intelca.UUCP (Chuck McManis) writes:
>… about the PDP-11 version of hack …
>All in all it doesn’t seem to do 90% of the things that make it different
The PDP-11 version of hack is a slightly improved (by people at the VU,
Amsterdam) version of some code that was stolen from my directory
some three years ago; it was being worked on, and certainly not in a
shape fit for distribution. Thus, as you noted, it doesnt have half
of the features present in hack, and, what is worse, it is very buggy.
I am sorry it was distributed.
The NetHack Development Team feels it is necessary to publicly address an issue that has surfaced in the last week.
Recently a NetHack source distribution has appeared, claiming to be NetHack 3.5 or 3.5.0 or 3.4.4.
This claim is partially correct. This is our code. However it was not released by us or with our authorization. This code is not ready for release: it is unfinished, unpolished, and almost certainly very buggy. It has not been play-tested for balance or functionality. It is best considered a partial and unfinished rough draft. We will not be supporting this code, nor will we be releasing binaries or bugfixes for it. It will not be available through our website.
Due to this incident and to prevent confusion, we will not now nor in the future release anything with a version number of 3.4.4, 3.5, or 3.5.0.
We thank those of you who play and develop both NetHack and its many variants for your support and encouragement at this time and over the many years NetHack and its progeny have and continue to evolve.
So yeah it seems there is a long history of hacking hack, why even the Fortran port of Zork was born that way:
Zork (was) only as encrypted files that were runnable in an MDL environment but were not readable (and modifiable) as source code. They even went so far as to patch their famously insecure ITS development system, adding security to just the directory that stored the source. Hackers, however, won’t be denied, and soon one from DEC itself had penetrated the veil. From Infocom’s own official “History of Zork“:
[The security] was finally beaten by a system hacker from Digital: using some archaic ITS documentation (there’s never been any other kind), he was able to figure out how to modify the running operating system. Being clever, he was also able to figure out how our patch to protect the source directory worked. Then it was just a matter of decrypting the sources, but that was soon reduced to figuring out the key we’d used. Ted had no trouble getting machine time; he just found a new TOPS-20 machine that was undergoing final testing, and started a program that tried every key until it got something that looked like text. After less than a day of crunching, he had a readable copy of the source. We had to concede that anyone who’d go to that much trouble deserved it. This led to some other things later on.
The source code to Hack was posted onto usenet back in December of 1984:
From: play@mcvax.UUCP (funhouse)
Subject: Hack sources posted
Date: Mon, 17-Dec-84 09:11:48 EST
Posted: Mon Dec 17 09:11:48 1984
Date-Received: Tue, 18-Dec-84 07:04:44 EST
Organization: CWI, Amsterdam
Xref: watmath net.games:1303 net.sources:2185
I will post the sources for Hack to net.sources.
They come in 10 parts; the total source is slightly over 400kbyte.
Hack is a game resembling rogue (but much richer than the versions
of rogue I have had access to).
The game runs on all machines with sufficient address space:
$ ls -l /usr/games/HACK
-rws--x--x 1 play 159744 Nov 10 19:09 /usr/games/HACK
$ size /usr/games/HACK
text data bss dec hex
106496 34816 29264 170576 29a50
but if you are unfortunate enough to have a backward C compiler
(without structure assignments or bitfields or functions returning
structures or with only 6 significant chars to an identifier)
then you'll have to work to get this running.
I am happy with mail, but will be abroad the next four weeks.
Good Luck & Happy Hacking !
Oddly enough the full source code to Hack had been lost. Even the Nethack Wiki didn’t have the full source code, although thanks to the UTZOO archives by Henry Spencer, I was able to look through enough of the tapes since I had the date and subject in hand, and I was able to pull out the entire thing.
So after struggling like CRAZY on trying to build nethack for Windows CE, it came down to two posts out there….
Thanks to some people in Russia, and Google translate, I found some explicit instructions on building Nethack…
Which spelt out that you need Visual C++ 6.0 to create the dependancies, then use embedded Visual C++ 3.0 to build, which the snag there, is that I was foolishly using 4.0 service packed to level 4, which stripped out support for the SH4 cpu…!
Thankfully, the site hpcfactor, maintains a download for embedded VC 3.0, and I was able to churn out an exe for the emulator. Then tearing it appart, I was able to replicate the build using Platform Builder 2.11 to create a native x86 executable.