N64 cross GCC / Binutils for Win32

Building GCC & Binutils for the Nintendo 64

I had a request to help get a GCC+Binutils running as native win32 exe’s something comperable to the ancient ‘ultra’ N64 toolchain done by Kyoto Microcomputer (resume pdf).  One interesting thing about their toolchain is that they used a common object format for MS-DOS, DOS/V and MS-DOS on the PC-98 format, along with Win32.  However the Win32 runtime doesn’t like Win64 environments.  On Win64 the exew32 driver just complains:

Can’t allocate memory (Error Code=487)

However the stubs in all the exe’s reference exegcc98 exegccv DOS extender’s along with a exegcc.  However googling around yields nothing.

Running on a x86 version of Windows, however the tools run and report gcc 2.7.2 release 1.2 and the binutils version is simply 2.6 with BFD version 2.6.  So going with this, and the request to keep it 1997 vintage I went ahead with Gcc and Binutils 2.8.1 as they are the end of the line in both trains of code.

To configure is really a snap, as both support the Windows NT platform directly

sh configure --host=i386-winnt3.5 --target=mips-elf

I guess I should add that I build with TDM GCC 5.1, and I use the incredibly ancient MSYS-1.0.11-rc-1.  But it’s enough to bootstrap and build with!  Since my GCC is much newer, I did have to finagle some things.  Here is a quick list of my notes on what I had changed, and some justification.

Binutils 2.8.1 notes:


make sure this uses MS-DOS rb wb type constraints!


There is no sbrk on my MinGW32 … so comment out all the sbrk stuff.


My sed LOVES UNIX style text files, so this one shouldn’t be in MS-DOS CRLF format.


mkdir only accepts the path on Win32.  Also there is now chown.

Gcc notes:


‘__inline’ for is_reserved_word needs to be commented out.


Set like the following for both ASM_FINAL_SPEC to prevent the t-mips from trying to be run.

#define ASM_FINAL_SPEC “\



Just because we are on Windows NT, doesn’t mean we want an .obj object suffix.


__spawnv : __spawnvp work better as _spawnv : _spawnvp


*((void **)__o->next_free)++ = ((void *)datum);

confuses newer compilers, with this error message:

obstack.h:341:32: error: lvalue required as increment operand

replace it with with:

*(__o->next_free)++ = ((void *)datum);

So at the end I have a cross compiler, and I can generate object files, and link files that the final tool MILD can then use and produce N64 ROM images.  It’s not a 100% solution, as I don’t see any mention of MILD being GNU, however the compiler and binutils is running on Windows 10 x64!

GCC cross compiling to the N64 target

GCC cross compiling to the N64 target

I built a few demos and tested with the 1964 emulator.

And there you have it.  For anyone who cares, you can download the toolchain + source here: winnt3.5_i386-mips_elf-gcc-

Torbjörn Granlund’s Excellent resource on running free OS’s on Qemu

Ever get tired of x86 on x86?  yeah me too.

How to solve that problem?

Simple, grab QEMU, and jump off into all those cool RISC processors of the 1990’s that were going to save us all from the WINTEL hegemony!

Lots of instructions, samples, images, and hints here:


It’s really more comprehensive than I’ve sat down to do, so yeah it’s awesome!

Supported platforms include:



So I stumbled onto LiteBSD while I was trying to see if I can cross compile 386BSD 0.0 from Windows (it compiles, but triple faults on boot.)

LiteBSD is a 4.4 BSD derived OS for PIC32MZ microcontrollers.

And to make things more fun, Serge Vakulenko has a Qemu fork that includes these simulators so you can run them on Linux and OS X.

So what about us poor Windows users?

Well a few tweeks, and only one annoying bug remains, but it’s easy enough to sidestep and it runs!



Even better, I got the console to kind of work, although you can still control+c it to kill Qemu.  I guess I could capture the signal being kind of UNIXy.

For some reason when opening the SD card image, it’s already open by the time pic32_sdcard_init is called.  Or so I suspect.  It gets the file handle of 3 which tells me that it shouldn’t be open.  So my fix is lame but it works.  Since something is holding the file that I can’t see, I launch Qemu like this:

qemu-system-mipsel.exe -machine pic32mz-wifire -nographic -serial vc -serial vc -serial vc -serial mon:stdio  -bios boot-wifire.hex -kernel vmunix.hex -hda litebsd.img

with the SD/HDA being litebsd.img but in pic32_sdcard_init I do this:


So you need a dummy file named litebsd.img (it’s just junk but it needs to exist), so whatever is blocking it will block it, then let pic32_sdcard_init open the file litebsd.img.SD which is the real file.

C:\litebsd>qemu-system-mipsel.exe -machine pic32mz-wifire -nographic -serial vc -serial vc -serial vc -serial mon:stdio -bios boot-wifire.hex -kernel vmunix.hex -hda litebsd.img
WARNING: Image format was not specified for ‘litebsd.img’ and probing guessed raw.
Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted.
Specify the ‘raw’ format explicitly to remove the restrictions.
Board: chipKIT WiFire
Processor: microAptivP
RAM size: 512 kbytes
Load file: ‘boot-wifire.hex’, 6916 bytes
Load file: ‘vmunix.hex’, 522408 bytes
sdcard: opened d->fd 3
Card0 image ‘litebsd.img’, 339969 kbytes
Copyright (c) 1982, 1986, 1989, 1991, 1993
The Regents of the University of California. All rights reserved.

4.4BSD-Lite build 13 compiled 2015-01-20
cpu: PIC32MZ2048ECG100 rev A4, 200 MHz
oscillator: system PLL div 1:6 mult x50
real mem = 512 kbytes
avail mem = 344 kbytes
using 18 buffers containing 73728 bytes of memory
spi1 at pins sdi=D14/sdo=C1/sck=D1
spi2 at pins sdi=F0/sdo=D11/sck=G6
spi3 at pins sdi=B10/sdo=C4/sck=B14
spi4 at pins sdi=F5/sdo=G0/sck=D10
uart1 at pins rx=F1/tx=D15, interrupts 112/113/114
uart4 at pins rx=F2/tx=F8, interrupts 170/171/172, console
sd0 at port spi3, pin cs=C3
sd0: type I, size 339968 kbytes, speed 12 Mbit/sec
sd0a: partition type b7, sector 2, size 204800 kbytes
sd0b: partition type b8, sector 409602, size 32768 kbytes
sd0c: partition type b7, sector 475138, size 102400 kbytes
bpf: sl0 attached
bpf: lo0 attached
WARNING: preposterous clock chip time — CHECK AND RESET THE DATE!

starting file system checks.
/dev/rsd0a: file system is clean; not checking
starting network
clearing /tmp
standard daemons: update.
Wed Dec 10 21:06:39 PST 2014

4.4BSD-Lite (bsd.net) (tty4)


So there it is!  As always, you can do the whole telnet console, on port 2023 like the SPARC with:

qemu-system-mipsel.exe -machine pic32mz-wifire -nographic -serial vc -serial vc -serial vc -serial mon:telnet:,server,wait  -bios boot-wifire.hex -kernel vmunix.hex

In this case, I prefer to use the ‘wait’ portion of the server, so I can watch it boot.  Maybe I’m just weird.  But this way you can control+c to your hearts content.

As always, you can download my image here.

Also for those who like graphical serial connections (???) you can launch it like this:

qemu-system-mipsel.exe -machine pic32mz-wifire  -serial vc -serial vc -serial vc -serial vc  -bios boot-wifire.hex -kernel vmunix.hex -sd litebsd.img

And use control+alt and hunt around for s3, and you’ll have your console….. That you can’t paste into.

**EDIT I found out I forgot to link this with static libgcc so there were missing DLL’s.  sorry, I’ve re-linked and now it’ll just work out of the box (tested with clearing my path on Windows 10).  Next I need to add curses support.

Restoring the MIPS Magnum in Qemu 1.6.0

As many of you Windows NT MIPS fans may know (apparently there are more than 3 of us now!) the MIPS Magnum target is broken in the current build of Qemu.  The problem lies in the firmware as it accesses unassigned memory.  Luckily I just received an email from Hervé that details how to fix this!

The good news is that the fix is VERY easy, all you need to do is comment out a single line in target-mips/op_helper.c

In the function mips_cpu_unassigned_access:

void mips_cpu_unassigned_access(CPUState *cs, hwaddr addr,
bool is_write, bool is_exec, int unused,
unsigned size)
MIPSCPU *cpu = MIPS_CPU(cs);
CPUMIPSState *env = &cpu->env;

if (is_exec) {
helper_raise_exception(env, EXCP_IBE);
} else {
helper_raise_exception(env, EXCP_DBE);

Simply comment out the line

helper_raise_exception(env, EXCP_DBE);

And you’ll be able to boot up the NT PROM.

MIPS Firmware

MIPS Firmware

Remember you’ll want to run it something like this:

qemu-system-mips64el -L /tmp -M magnum -m 64 -cdrom WindowsNT4.0-MIPS.iso -hda MIPS.disk -net nic -net user -global ds1225y.filename=nvram  -global ds1225y.size=8200

Where I’m keeping my NT PROM is /tmp (although that is probably a bad idea…)  But you’ll need the NVRam stuff to add extra space for the ethernet MAC address.  The clock is always trashed but at least it is doing something this time!

For the uninitiated, some installation notes can be found here.

GoldenEye’s hidden ZX Spectrum 48x emulator

Unbeknownst to the world, retail versions of GoldenEye contain a ZX Spectrum 48x emulator, merely lacking a program monitor and user access. This video displays the results of a nifty little patch to re-enable the content. In total, nine games are embedded. Each is mapped to keypresses on controller 3. The original access point couldn’t be determined, so now you load the games while on the folder select menu (menu 5).
c left Sabre Wulf
c right Atic Atac
c up Jetpac
c down Lunar Jetman
+ left Alien 8
+ right Gun Fright
+ up Underwurlde
+ down Knight Lore
A button Pssst
(default) Cookie

The video displays short sections from each of the games. (Forgot to map the A button, so Pssst won’t appear in this video.) The emulator is fully-compartmentilzed so you can leave, load another game, or play GoldenEye normally.

The emulator was a side-project of one of the programmers, experimentally inserted in the current game under production to see if Spectrum emulation on the N64 was possible. Access to it was removed before release, but the emulation code itself remained embedded, much like debug and devtool support, within a large chunk of assembly code. The patch, exclusively for the North American release (NGEE), is available here:

Don’t pirate ROMs! In most countries you can legally make your own backup copies and apply the patch to those. No direct links to ROMs of any kind, patched or otherwise. Respect the Fuzz!


Steve Ellis, who originally created the emulator, sent an email to clarify how the original Spectrum ROM was set up. Since it wasn’t included and the copyright has been lifted by Amstrad I’ve included the complete one with the patch. If there is any further issue I’ll reduce it to a copyright-unrestricted version.
Here’s the letter though, and be certain to check out Crash Lab. Really!

I see various posts about this on the web now. I thought I’d clarify the point about spec_rom.seg.rz – the contents of this file fill the bottom 16kb of the Spectrum’s memory. On the original Spectrum, the bottom 16kb would have included the whole operating system (the BASIC programming language, functions for loading from and saving to cassettes, etc.). Since the ROM is copyrighted we weren’t able to use it. However, some of the games that we were emulating wanted to call one or two Spectrum ROM functions. The solution to this was to create an empty ROM (99.9% filled with NOP’s), but with newly-created (copyright-free) replacements for the few short functions that the games needed to call. The games should run with this minimal replacement ROM.

BTW, if you’d like to send any people in the direction of @CrashLab or facebook.com/CrashLab, I’d be grateful. We’re going to release something later this year that hopefully should appeal to fans of “old-school” games.


Steve Ellis
Crash Lab



Check the thread at:
For Steve Ellis’s letter and a snippet debunking DK64 Spectrum emulation.

Also, check out Steve’s latest venture at Crash Lab. Expect some great stuff out of there!

So I thought I’d have some fun with jsmips

Hello World!

Hello World!

The Javascript MIPS emulator.. So after snagging the source, and all went well building the binutils, gcc, then gcc again, the libc. All seemed well except I couldn’t work out exactly what goes where…

So after a bunch of messing around I managed to get it run..  kind of.  I think the php file that proxies the filesystem is broken as I get something like this from the now broken main js page..

function genroot(p){var dir=new Directory(p);function genbin(p){var dir=new Directory(p);dir.children["=listusers"]=remoteFile("./bin/listusers","http://codu.org/jsmips/server/dir.php?f=.%2Fbin%2Flistusers");dir.children["=apropos"]=remoteFile("./bin/apropos","http://codu.org/jsmips/server/dir.php?f=.%2Fbin%2Fapropos");dir.children["=banner"]=remoteFile("./bin/banner","http://codu.org/jsmips/server/dir.php?f=.%2Fbin%2Fbanner");

And yet I get this kind of output:

{error: false, type: ‘d’, cont: [“dtextc.dat+”,”hi+”,”var/”,”hi.c+”,”source/”,”bin/”,”dungn27s.zip+”,”dungeon+”,”./”, “../”]}

Which.. isn’t right enough.  I’m not sure what is up with dir.php ..

Oh well, I was able to build a simple hello world type program, but anything that hopes to pull data off the drive won’t work.  If anyone thinks they can do better my archive of all the bits is here (48MB), and the ‘runnable’ version is here .. hi is about as much fun as it’ll get.

Windows NT 4.0 MIPS on Qemu 1.1.1 (OS X)

I’ve got to find a way to build Qemu for Win64, it looks like the only way for it to produce anything other than trivial hello world applications is to cross compile on linux.. which no doubt will need a billion dependancies…

But in the interim the MIPS emulator in Qemu 1.1.1 has made a bunch of progress, and can install & run NT 4.0 without any issues!

There is a few things to look out for, the first is that you have to specify a NVRAM image file to keep it persistant across instances.  And you need to ‘expand’ it beyond the definition size to get things like the MAC address to be stored.

./qemu-system-mips64el  -L . -M magnum -hda MIPS.disk -net nic -net user  -global ds1225y.filename=nvram  -global ds1225y.size=8200

And by default the Qemu MAC address to configure within the Magnum BIOS is 525400123456 ..

Windows NT 4.0 MIPS on Qemu 1.1.1 on OS X

I’ve been able to download & install Internet Explorer 3, and Quake World.. And even connect up to quake.xs4all.nl and it worked!

One thing I’d advise is to copy the directory OS\WINNT40 on the system partition to OS\NT to make it that much easier to re-add the boot statement, if you have to go down that road.

ARC boot statement


As always, special thanks to Hervé Poussineau for making all of this possible.


2.11 BSD Unix for PIC32, build #826:
     Compiled 2011-08-07 by vak@Cobra.local:
phys mem  = 128 kbytes
user mem  = 96 kbytes
root dev  = (0,0)
root size = 16384 kbytes
swap size = 2048 kbytes
standard daemons: update.
Sun Aug  7 16:47:45 PST 2011

2.11 BSD UNIX (pic32) (console)

login: root
Welcome to RetroBSD!
# _

Wow isn’t that cool? Who needs a ‘basic stamp’ if you can have UNIX!  Not to mention it’s from Serge Vakulenko, of DEMOS fame!

From the main site:

RetroBSD is a port of 2.11BSD Unix intended for embedded systems with fixed memory mapping. The current target is Microchip PIC32microcontroller with 128 kbytes of RAM and 512 kbytes of Flash. PIC32 processor has MIPS M4K architecture, executable data memory and flexible RAM partitioning between user and kernel modes.

Main features:

  • Small resource requirements. RetroBSD requires only 128 kbytes of RAM to be up and running user applications.
  • Memory protection. Kernel memory is fully protected from user application using hardware mechanisms.
  • Open functionality. Usually, user application is fixed in Flash memory – but in case of RetroBSD, any number of applications could be placed into SD card, and run as required.
  • Real multitasking. Standard POSIX API is implemented (fork, exec, wait4 etc).
  • Development system on-board. It is possible to have C compiler in the system, and to recompile the user application (or the whole operating system) when needed.

Internet Explorer 3.0 for the MIPS.

I got a tip that there actually was a version of Internet Explorer 3.0 for the MIPS. I was thinking there was no way, as there was no mention of this thing as IE 3.0 came out after the MIPS had been dropped from the roster.

Well luckily it turns out to be true.

The original download link is here, and I’ve mirrored it here.

Who knows what other things are out there for the MIPS?


Javascript MIPS

Hot on the heels of the javascript 80386 emulator, I found this javascript MIPS syscall emulator, jsmips.

What is cool about this one, is that commands are downloaded on demand.  And it supports more browsers, like Internet Explorer (well modern ones, IE 5.5sp2 didn’t work).

Vi works, but you’ll need to reset the terminal afterwards.  At least with this on demand filesystem it’d make it easier to add new binaries…

It’s amazing how far the world of javascript has come, but at the same time, it’s scary how precarious it is perched on browsers where stuff only seems to work at the moment and on select browsers.  But then that’s the way things seem to go.