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 2.7.2.3 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:

include/fopen-same.h

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

libiberty/xmalloc.c

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

bfd/targmatch.sed

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

binutils/objcopy.c

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

Gcc 2.7.2.3 notes:

c-gperf.h

‘__inline’ for is_reserved_word needs to be commented out.

config/mips/mips.h

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

#define ASM_FINAL_SPEC “\
+%{pipe:-}”

config/winnt/xm-winnt.h

OBJECT_SUFFIX “.o”

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

gcc.c

__spawnv : __spawnvp work better as _spawnv : _spawnvp

obstack.h

*((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-2.7.2.3_binutils-2.8.1.7z

12 thoughts on “N64 cross GCC / Binutils for Win32

        • I’ve extracted the new GCC build with 2.0L SDK. When attempting to make any of the demo src it will crash with the error: This application has requested the Runtime to terminate it in an unusual way.
          Please contact the application’s support team for more information.
          make: *** [main.o] Error 3

          My ultra directory is in the same location as your console window. I am using Windows 7 SP1 64 bit. I’m not sure what else to try, maybe I missed setting a env path. Would you know why GCC would crash?

          Thanks!

          • I just put a simple ” void main(void){} ” style program in the bin directory, and ran it and I got an object files…

            I’m using Windows 10 though, maybe 7 has drifted too far back? The source is there, if you have a working MinGW you may be able to re-build it from source, it should be configured and ready to go.


            Microsoft Windows [Version 10.0.16299.371]

            C:\temp\mips\bin>gcc -v -c x.c
            gcc version 2.7.2.3
            cpp -lang-c -v -undef -D__GNUC__=2 -D__GNUC_MINOR__=7 -Dmips -DMIPSEB -DR3000 -D_mips -D_MIPSEB -D_R3000 -D__mips__ -D__MIPSEB__ -D__R3000__ -D___mips__ -D_MIPSEB -D_R3000 -D__mips -D__MIPSEB -D__R3000 -D___mips -D__LANGUAGE_C -D_LANGUAGE_C -DLANGUAGE_C -D__SIZE_TYPE__="unsigned int" -D__PTRDIFF_TYPE__=int -D_ULTRA64 -D__EXTENSIONS__ -D_ULTRA64 -D__EXTENSIONS__ x.c C:\Temp\cca13112.i
            GNU CPP version 2.7.2.3 [AL 1.1, MM 40] BSD Mips
            #include "..." search starts here:
            #include <...> search starts here:
            D:/pcem/building/MinGW/msys/1.0/local/lib/gcc-lib/mips-elf/2.7.2.3/include
            D:/pcem/building/MinGW/msys/1.0/local/lib/gcc-lib/mips-elf/2.7.2.3/sys-include
            D:/pcem/building/MinGW/msys/1.0/local/mips-elf/include
            End of search list.
            cc1 C:\Temp\cca13112.i -quiet -dumpbase x.c -version -o C:\Users\Temp\cca13112.s
            GNU C version 2.7.2.3 [AL 1.1, MM 40] BSD Mips compiled by GNU C version 5.1.0.
            as -nocpp -v -o x.o C:\Temp\cca13112.s
            GNU assembler version 2.8.1 (mips-elf), using BFD version 2.8.1

          • My output matches yours, and it successfully compiled the file.

            Just for clarification, I’ve put the new GCC files
            GCC: C:\ultra\GCC\MIPSE\bin\
            2.0L: C:\ultra\

            Running from the same directory as GCC fixes the crash, but now it is looking for spec.

            C:\ultra\GCC\MIPSE\bin>make -f C:\ultra\usr\src\PR\demos\ginv\makefile
            make: *** No rule to make target `spec’, needed by `ginv.n64′. Stop.

            Is there something I’m doing wrong? Thanks for the help so far.

          • Sounds like a missing linker spec file….

            I’ll have to try it on a virgin machine when I get time

  1. Hi. I tried to copy the bin folder from your link into my ultra\gcc\mipse folder and rename the old bin folder to bin.old before copying. I get most of the way thru compiling but get an error when attempting to compile the nu5 demo:

    C:\nintendo\n64kit\nusys\sample\nu5>make
    gcc -DNU_DEBUG -DF3DEX_GBI_2 -I. -Ic:\nintendo\n64kit/nusys/include -Ic:\ultra/usr/include/PR -G 0 -c -Ic:\ultra/usr/include -D_MIPS_SZLONG=32 -D_MIPS_SZINT=32 -g main.c
    gcc -DNU_DEBUG -DF3DEX_GBI_2 -I. -Ic:\nintendo\n64kit/nusys/include -Ic:\ultra/usr/include/PR -G 0 -c -Ic:\ultra/usr/include -D_MIPS_SZLONG=32 -D_MIPS_SZINT=32 -g stage00.c
    gcc -DNU_DEBUG -DF3DEX_GBI_2 -I. -Ic:\nintendo\n64kit/nusys/include -Ic:\ultra/usr/include/PR -G 0 -c -Ic:\ultra/usr/include -D_MIPS_SZLONG=32 -D_MIPS_SZINT=32 -g stage01.c
    gcc -DNU_DEBUG -DF3DEX_GBI_2 -I. -Ic:\nintendo\n64kit/nusys/include -Ic:\ultra/usr/include/PR -G 0 -c -Ic:\ultra/usr/include -D_MIPS_SZLONG=32 -D_MIPS_SZINT=32 -g graphic.c
    gcc -DNU_DEBUG -DF3DEX_GBI_2 -I. -Ic:\nintendo\n64kit/nusys/include -Ic:\ultra/usr/include/PR -G 0 -c -Ic:\ultra/usr/include -D_MIPS_SZLONG=32 -D_MIPS_SZINT=32 -g gfxinit.c
    ld -o codesegment.o -r main.o stage00.o stage01.o graphic.o gfxinit.o c:\nintendo\n64kit/nusys/lib/nusys.o -Lc:\ultra/usr/lib -Lc:\nintendo\n64kit/nusys/lib -lnualsgi_n_d -lgn_audio_d -lnusys_d -lgultra_d -L/mipse/lib -lkmc
    ld: cannot open -lkmc: No such file or directory
    make: *** [codesegment.o] Error 1

    And this error when trying to compile the topgun demo:

    C:\ultra\usr\src\pr\demos\topgun>make
    elftbl
    process_begin: CreateProcess(NULL, elftbl, …) failed.
    make (e=2): The system cannot find the file specified.
    make: *** [__elfcom.tbl] Error 2

    Can you please help me figure out why I get these errors? I am running windows 10 64 bit and ran the setup batch file to set all the environment variables before attempting to compile

    • Where did you get the ‘ultra\gcc’ and demo from?

      the missing lib ought to still be in there, although my chain didn’t have a working linker to output something any N64 emulator would need, so you still have to have a 32bit OS with MS-DOS support to run the ancient linker.

    • It’s been a few years, but having a 32bit os with working ntvdm was important as the Nintendo tools are all msdos based.

      I think I had to tweak the one demo I did get to run, but it’s been a long time, and I don’t have pc access for a while..

  2. Hi neozeed, I know it’s been a long time but I need some help on this project.

    I try to build gcc and binutils (by your folders you uploaded here) with tdm-gcc and msys, all of them are the same versions with those from this project, also I’m using your configure command. However not the gcc, neither the binutils are compiled successfully as it returns errors which makes me believe that you didn’t wrote all the steps at this post.

    Is there any chance to help me build it so this project will remain alive?

Leave a Reply