32016 stand alone planetfall!

InfoTaskForce’87 running on a simple NS32016 emulator

What is it?

It sure may not look like much but it was an adventure getting here.

First, what is it? Well it’s the very simple NS32016 from here, with a few minor changes. I expanded the RAM from 256kb to a whopping 8MB. Then I added simple character I/O allowing me to print messages to the screen. Next looking at the toolchain page, I used my old Linux to Windows GCC 4 cross compiler to build the appropriate Canadian cross compiler to the NS3216.

Building the tools

A while back, I had built a cross compiler from Linux to Windows using GCC 4.1 as the basis as it was the last version that didn’t have massive external dependencies. NS32016 support was dropped some time in the late 3.x or early 4.x GCC so it means we need to go old anyways. I arbitrary picked GCC 2.8.1 for this build, while using the recommended Binutils 2.27

I cheated and just downloaded my existing linux-minw32.7z cross compiler as I didn’t feel like rebuilding everything again, although it is all in the Building a MIPS Compiler for Windows on a Linux VM! article. I also used an old Linux to Linux i586 32bit compiler (back from the OSKit build!) although you can use your hosts as well.

configuring Binutils is pretty simple like this:

./configure --prefix=/cross --target=ns32k-pc532-netbsd --host=i686-mingw32 --build=i586-linux

You can try omitting the –build portion, Debian GNU Linux 10 seemed okay with Gcc 8 as the default system compiler.

configuring GCC 2.8.1 was pretty similar:

./configure --target=ns32k-pc532-netbsd --prefix=/cross --disable-libssp --build=i586-linux --host=i686-mingw32

GCC 2.8.1 doesn’t quite know what we are doing so there is some flags we need to run off in auto-config.h namely

  • #define HAVE_BCMP 1
  • #define HAVE_BCOPY 1
  • #define HAVE_BZERO 1
  • #define HAVE_INDEX 1
  • #define HAVE_KILL 1
  • #define HAVE_RINDEX 1
  • #define HAVE_SYS_RESOURCE_H 1
  • #define HAVE_SYS_TIMES_H 1

You can just comment them out, or remove those lines all together.

When it came to building GCC, I did run into issues with GCC 7/8 trying to build GCC 2.8.1. I found it much easier to either have that Linux 4.1 compiler, or if you have access to Wine or WSL you can just run the Win32 binaries for the gen phases.

./configure --prefix=/cross --target=ns32k-pc532-netbsd --host=i686-mingw32
make CC=i686-mingw32-gcc xgcc cccp cc1 cc1obj

If you can run your own Win32 exe’s on Linux it’ll run just fine using the Linux to Windows GCC 4 cross. Otherwise you will need to either patch GCC or make your own GCC 4 hosted Linux to Linux cross compiler like this:

make CC=i686-mingw32-gcc HOST_CC=i586-linux-gcc xgcc cccp cc1 cc1obj

Hopefully that worked enough, and now you have your cross compiler. Now it’s time to build libgcc1.a

cp cccp cpp.exe
cp cc1 cc1.exe
cp xgcc xgcc.exe
cp ../binutils-2.27/gas/.libs/as-new.exe as.exe
cp ../binutils-2.27/binutils/.libs/ar.exe ar
cp ../binutils-2.27/binutils/.libs/ranlib.exe ranlib
make libgcc1.a TARGET_TOOLPREFIX="./" OLDCC=./xgcc.exe

Again you really want to be able to run the resulting programs on Linux but I guess you could script it out. Naturally if you wanted to just use Linux, it’d be easier to make that cross compiler directly, although I’m not sure how much of GCC 2.8.1 I want to fight, or just get GCC 4 running on Linux and use that to port.

crt0, somewhere for C to start

As mentioned a crt0.s is missing but there was enough inspiration to come up with this:

#NO_APP
gcc_compiled.:
.text
        .align 1
.globl _start
_start:
        enter [],0
#APP
#       setting the stack 256k under 8MB
        lprd sp,0x7c0000
        jsr _main
#NO_APP
L1:
        exit []
#       setting the stack 256k under 8MB
        lprd sp,0x7c0000
        bpt
        .align 1

#does nothing
.globl ___main
___main:
        ret 0

.globl _exit
_exit:
        bpt
        ret 0

I used a bit of the C example, and added some hooks that GCC was expecting namely a __main call that is made from main before it does anything (a place to init memory perhaps?), a place to catch an explicit exit call, along with setting the stack of course.

Patching InfoTaskForce without malloc / disk access

It’s not going to win any awards, but it was really great to get it to run a simple program written in GCC. Looking for something more fun, I took the old InfoTaskForce interpreter from ’87, and dug up my modification to run on cisco routers, and cooked up this version, that adds enough of printf from Linux, a bogus malloc that just allocates from a fixed memory array (otherwise you have to actually know about your platform), and a fun trick with later binutils where you can import a binary file directly as an object!

Neat!

Since I don’t have any file I/O being able to have the game data in RAM is crucial. I tried to tweak it so you could build the same working thing on Windows (maybe others?).

So for anyone who wants to look at the standalone adventure Win32 hosted tools are here, although the emulator should be somewhat portable.

Definicon DSI-32 co-processor emulation

Definicon DSI-32 coprocessor card

Well this is a little interesting thing.  Back in the 1980’s people were increasingly frustrated with the limitations of the 8086 processor in their IBM PC/XT computers, and wanted a way to get the latest & greatest 16 bit, and 32bit processors.  One such hot processor was the  National Semiconductor NS32032.

Enter the Definicon DSI-32 co-processor card.  It’s a simple 8bit ISA card containing the NS32032 processor, some memory an sockets for both a math co-processor, and a MMU.  The NS32032 is also somewhat infamous as being rather ‘VAX like’, and being difficult for compilers of the era to properly optimize for.  As mentioned in Michael Tiemann’s interview in the O’Riley book Open Sources .

The real bombshell came in June of 1987, when Stallman released the GNU C Compiler (GCC) Version 1.0. I downloaded it immediately, and I used all the tricks I’d read about in the Emacs and GDB manuals to quickly learn its 110,000 lines of code. Stallman’s compiler supported two platforms in its first release: the venerable VAX and the new Sun3 workstation. It handily generated better code on these platforms than the respective vendors’ compilers could muster. In two weeks, I had ported GCC to a new microprocessor (the 32032 from National Semiconductor), and the resulting port was 20% faster than the proprietary compiler supplied by National. With another two weeks of hacking, I had raised the delta to 40%. (It was often said that the reason the National chip faded from existence was because it was supposed to be a 1 MIPS chip, to compete with Motorola’s 68020, but when it was released, it only clocked .75 MIPS on application benchmarks. Note that 140% * 0.75 MIPS = 1.05 MIPS. How much did poor compiler technology cost National?) 

Such was the fate of the NS32032.  Getting back to the Definicon card, it has no real IO of it’s own, instead it relies on being able to copy memory in and out of a window to program the CPU, much like how LIM EMS stores more than 64kb onto a card.  MS-DOS provides all the I/O operations though a simple software interrupt driven system, allowing the host to open and read files, tell the time, and even simple EGA graphics.

Unfortunately, the window of interest in these types of boards waned pretty quick, so the only development tools available are the original Green Hills Software packages, along with a simple PD (no sources) LISP & FORTH interpreter.  The board has support for C, Assembly, Fortran and Pascal.  Naturally the user is expected to invoke each component of the tool chain manually, as was the case for many micro hosted tools of the day.  What is kind of interesting is that the environment isn’t a strict 8086 MS-DOS based cross compiler, rather the tools run on the NS32032 co-processor allowing seemingly large programs to run on machines from the early 1980s.

In addition to PC ISA boards, the NS32032 was popular as a secondary processor for various machines, including the 6502 based Acorn.

BBC Second Processor NS32032

This module could plug into the back of the Acorn, and then much like the Definicon DSI-32, let Acorn users run full 32bit program on their 8bit machines.  There has been an ongoing effort to emulate the Second Processor in a FPGA.  Flipping that on it’s head, a NS32032 emulator was found, and using a FPGA Acorn, the second processor was then emulated on a raspberry pi, using a C based emulator for the NS32032.

FPGA Acorn with raspberry pi second processor

Taking that CPU core, and finding the source code to the load program allowed for a 32bit Linux or Windows based load program to feed the C CPU core emulator.  I made some minor tweeks regarding it’s handling of files, and have a version that runs on Windows.

Series 32000 Emulator 4Mb Version 1.0b(MinGW32) of 8 Sep 2017
C-32000 1.6.12 Copyright(c)1985 Green Hills Software, Inc.
Series 32000 Emulator 4Mb Version 1.0b(MinGW32) of 8 Sep 2017
CSD-32000 Assembler V1.00a, Computer Systems Design
Pass 1 in progress
Pass 2 in progress
Pass 3 in progress
0 Assembly error(s) detected.
Series 32000 Emulator 4Mb Version 1.0b(MinGW32) of 8 Sep 2017
DSI-32000 Linker V1.03c, Definicon Systems Inc
@ FILE=LIB\CMAIN
@ LIBRARY=LIB\CLIB
@ NOCOMM
@ MOD=80
@ MODULE=CLIB/CODE_START=3600,NOCOPY
@ MODULE=CLIB/LINK_START=35E0,NOCOPY
@ MODULE=CRTLIB.C/CODE_START=4000,NOCOPY
@ MODULE=CRTLIB.C/LINK_START=7500,NOCOPY
@ MODULE=CRTLIB.C/SB_START=7000,NOCOPY
@ STACK=+40
@ CODE=A000
@ RAM=0..FFFFF
Series 32000 Emulator 4Mb Version 1.0b(MinGW32) of 8 Sep 2017
Dhrystone(1.1) time for 50000 passes = 1
This machine benchmarks at 50000 dhrystones/second

I was unable to get either the Pascal  or Fortran compilers to generate output that the assembler liked, however the C compiler works.  Other ISA NS32032 cards include the Opus, which could be configured to run SYSV unix!

For a while, these types of second processor cards were quite common, even being used as upgrade cards, like the Microsoft Mach-20, or giving access to a completly different CPU/OS combination like the CP/M z80 card for the Commodore 64, to the incredible Amiga BridgeBoard.

One thing to keep in mind is that the DSI-32 board came out in 1985.  The GNU project wouldn’t launch in earnest until 1988, which may not seem like that big of a window but in reality it really is.  3 years is a substantial time in the industry.  And like many things GNU in the 1980’s it was focused on bigger minicomputers like the SUN-2/SUN-3, VAX etc, not common machines like the Apple Macintosh, Commodore Amiga, Atari ST, although it’s 68000 was common subset of the 68010 in the SUN-2 and 68020 of the SUN-3.  Even the 32-bit giant of them all, the 80386 didn’t begin to get support until GCC 1.23 (the summer of 1988.  Early GCC had incredibly rapid progress).  But by the late 1980’s people with NS32032’s were using them in full systems, they weren’t the typical ‘brain in a jar’ type users that had these fancy CPU co-processor cards.

I did built a copy of GCC 1.39 & GAS 1.38 for the NS32K, although since it’s unable to link in any format the DSI-32 would understand it did seem kind of pointless.  The assembler syntax is quite different.  Perhaps if it were the 1980’s something like the x68000 port of GCC which modified GCC to use a syntax that the platform’s native assembler & linker were comfortable with.

Using the 1987 Infocom Interpreter source code, I was able to cross compile it to the NS32k.

Series 32000 Emulator 4Mb Version 1.0b(MinGW32) of 8 Sep 2017
DSI-32000 Linker V1.03c, Definicon Systems Inc
@ FILE=LIB\CMAIN
@ LIBRARY=LIB\CLIB
@ NOCOMM
@ MOD=80
@ MODULE=CLIB/CODE_START=3600,NOCOPY
@ MODULE=CLIB/LINK_START=35E0,NOCOPY
@ MODULE=CRTLIB.C/CODE_START=4000,NOCOPY
@ MODULE=CRTLIB.C/LINK_START=7500,NOCOPY
@ MODULE=CRTLIB.C/SB_START=7000,NOCOPY
@ STACK=+40
@ CODE=A000
@ RAM=0..FFFFF

C:\dsi\set021387>emu.exe infocom -a planetfa-37.z3
Series 32000 Emulator 4Mb Version 1.0b(MinGW32) of 8 Sep 2017
PLANETFALL
Infocom interactive fiction – a science fiction story
Copyright (c) 1983 by Infocom, Inc. All rights reserved.
PLANETFALL is a trademark of Infocom, Inc.
Release 37 / Serial number 851003

Another routine day of drudgery aboard the Stellar Patrol Ship Feinstein. This
morning’s assignment for a certain lowly Ensign Seventh Class: scrubbing the
filthy metal deck at the port end of Level Nine. With your Patrol-issue
self-contained multi-purpose all-weather scrub brush you shine the floor with a
diligence born of the knowledge that at any moment dreaded Ensign First Class
Blather, the bane of your shipboard existence, could appear.

Deck Nine
This is a featureless corridor similar to every other corridor on the ship. It
curves away to starboard, and a gangway leads up. To port is the entrance to
one of the ship’s primary escape pods. The pod bulkhead is closed.

Deck Nine Score: 0/4451
>

Although the The DSI-32 was followd up by 68020 based DSI-780, which was nearly three times faster.  As with the Amiga Bridge board, and cards like the SunPCi, these types of cards became more and more of an addon to run IBM PC software, and less about trying out new and exciting processors.  But now thanks to emulation you can try them all out without any additional messy hardware.

Anyone who cares, my dump of what I found and messed around with is here:

ns32032_dsi-32.7z

Great resources can be found:

Thanks to Alexander Voropay for giving me some heads up & materials for this interesting side trek!