GCC 1.27 & MS-DOS

Inspired by Building and using a 29-year-old compiler on a modern system, i thought I too could get this ancient version of GCC working.  At the time I never had bothered with the older version as I had always assumed that there were many fixes and adaptations to GCC  for it to run on MS-DOS via GO32/DJGPP.  However after doing this, its obvious that GO32/DJGPP was rather built around GCC’s stock output, which would sure make a lot more sense.

And it turns out that the target machine being an i386 Sequent running BSD is the best match, both in turns of underscores, and debugging format.  At first I had tried the AT&T SYSV i386 target, however it couldn’t link anything from the standard libraries that DJGPP has as they all have a leading underscore.  After starting to mess with internal macros to turn things on and off, and re-define how various portions of assembly are emittied, I found the Sequent target and went with that and everything was fine, and using the existing build infrastructure for GCC 1.39 I now could actually run hello world!

gcc_v1 -v -E hello.c -o hello.i
gcc version 1.39
cpp_v1 -v -undef -D__GNUC__ -DGNUDOS -Dunix -Di386 -D__unix__ -D__i386__ hello.c -o hello.i
GNU CPP version 1.39
gcc_v1 -v -S hello.i -o hello.s
gcc version 1.39
cc1_v1 hello.i -quiet -version -o hello.s
GNU C version 1.27 (80386, BSD syntax) compiled by GNU C version 5.1.0.
gcc_v1 -v -c hello.s -o hello.o
gcc version 1.39
as -o hello.o hello.s
gcc_v1 -v -o hello hello.o
gcc version 1.39
ld -o hello C:/dos/xdjgpp.v1/lib/crt0.o hello.o -lc

go32 version 1.12.maint3 Copyright (C) 1994 DJ Delorie

hello from DJGPP v1/GCC 1.39!

Wasn’t that great?  Then going through my ‘test’ programs I went to try to build the infocom interpreter, and that is when things went off the rails.

funcs.o: Undefined symbol __udivsi3 referenced from text segment
options.o: Undefined symbol __divsi3 referenced from text segment
options.o: Undefined symbol __divsi3 referenced from text segment
print.o: Undefined symbol __divsi3 referenced from text segment
print.o: Undefined symbol __udivsi3 referenced from text segment
support.o: Undefined symbol __divsi3 referenced from text segment
gcc_v1: Program ld got fatal signal 1.

I’ve had some issues with GCC and these ‘built in’ functions before.  This was an early major stumbling block back in the x68000 GCC days, where after a lot of searching I was able to find 68000 versions of various math routines that were in the native Hudson Soft assembler to link in.  While GCC 1.x does have a libgnu/gnulib to include these functions it warns you over and over to not use GCC to build them, but rather the native CC.  But the problem is that I don’t have a native CC.

But I managed to save myself after googling around by finding srt0.c from 386BSD.  Namely these two:

.globl ___udivsi3
___udivsi3:
  movl 4(%esp),%eax
  xorl %edx,%edx
  divl 8(%esp)
  ret

.globl ___divsi3
___divsi3:
  movl 4(%esp),%eax
  xorl %edx,%edx
  cltd
  idivl 8(%esp)
  ret

I ended up having to removing a single underscore, but now I could link infocom, and even better it runs!

Wanting to try something far more exciting, I went ahead and tried to build DooM.  However GCC 1.27 has an issue with m_fixed.c  I fired up GDB to at least take a look, although I’m not sure where the fault lies.

FixedMul
This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.

Breakpoint 1, 0x752c5ad5 in msvcrt!_exit () from C:\WINDOWS\System32\msvcrt.dll
(gdb) bt
#0 0x752c5ad5 in msvcrt!_exit () from C:\WINDOWS\System32\msvcrt.dll
#1 0x752bb379 in msvcrt!abort () from C:\WINDOWS\System32\msvcrt.dll
#2 0x0045805c in final (first=0xe066a0, file=0x75312688 <msvcrt!_iob+128>, write_symbols=NO_DEBUG, optimize=0)
at final.c:653
#3 0x00403198 in rest_of_compilation (decl=0x722718) at toplev.c:1296
#4 0x0040fbce in finish_function () at c-decl.c:3272
#5 0x004040c0 in yyparse () at c-parse.y:224
#6 0x0040239d in compile_file (name=0xe00def "C:/dos/xdjgpp.v1/tmp/cca02992.cpp") at toplev.c:837
#7 0x00403a33 in main (argc=11, argv=0xe00f90, envp=0xe01598) at toplev.c:1556

With the code being:
#ifdef REGISTER_CONSTRAINTS
      if (! constrain_operands (insn_code_number))
        abort ();
#endif

So I assume some error with constrain_operands? Not that it makes it any better.  However I know this one file compiles fine with 1.39, and since we are on the i386 another alternative is just to used the assembly version that was hiding in the readme..

DooM mostly built by GCC 1.27

And much to my amazement, it works!  Keeping in mind that this is using an a.out tool chain, along with the last DPMI enabled GO32 extender.

Considering the compiler dates back from September 5th, 1988 it’s really great to see it running.

I’ll have to upload source (GCC 1.27/DooM) & binaries later.  But I imagine it should also run on EMX/RSX for a Win32 version.

Started to re-build my MS-DOS machine

DooM!

Good news, it actually works!  I was using the version 1.1 WAD, so honestly weird crashes really aren’t unexpected.  I haven’t looked much at what to do with audio, but I was really impressed compared to the Qauake II wars, it was really surprising to not only see DooM run on the first shot in real metal, but the keyboard works as well.  Well enough for me to pick a level, and get killed.

Naturally it doesn’t work under Windows, however it runs fine with MS-DOS mode.

Porting Catacomb3D to MS-DOS (DJGPP v1/GO32).

Catacomb 3-D for GO32

No really, it’s Catacomb 3-D: The Descent.  First ported to 32-bit SDL by NotStiller.  Me being the person I am, I fixed a slight bug regarding binary files on Windows, and MS-DOS, then cleaned up some of the C++ syntax (yuck!) making it far more C89 friendly.  And of course, hot off the heels of DooM for GO32 DPMI, I was able to get it to build and run using GCC 1.39 and GO32.

I know most people really won’t care, but I found it kind of interesting.  I should try to see if it’ll run on actual hardware, just as a comparison of tightly optimized Borland C++ / Assembly vs 100% pure C on DJGPP.  The best tech of 1991 for sure!

At current I just put the source up, you can git it here.

Uploaded my cross DJGPP v1 environment to sourceforge

project is here.

I also put up the source for my ‘null doom‘, for anyone who ever needs some massaged source to DooM that will compile with a C compiler, instead of needing something that can understand C++ style comments, although I know in cccp.c there is the ability to turn on cplusplus style processing.  However since I did want something that would compile without altering the compiler (too much) I thought it was best to just change all the comments.

And a quick download link to the zip file with the source & binaries.
Download crossdjgppv1
Download crossdjgppv1

Null DooM, GCC 1.39, GO32 and DPMI


phew.

DooM via DJGPP v1 GO32

Around the time of the x68000 port of DooM, I was cutting down the DooM source for a null/portable version.  I never could get it to actually run either using EMX or  DJGPP 1.03, as I couldn’t get it to link to save my life with a constant never ending battle of unresolved symbols. After a while I just used what I had towards the x68000 version and concentrated on getting it up and running, and just shelved the null/portable effort.

Later on I wanted to get it running again as part of messing with another cross compiler, as DooM isn’t a trivial application to port and verify correct operation. And in the process of trying to get the null version to build and run on Windows using TDM GCC, I wanted to make sure it at least kept compiling with GCC v1.x.

Once more again I was able to compile individual files but unable to link.  But this time, I just looked at the diffs for binutils, I thought it should be somewhat easy to get hosted on Windows.  Although versions may point to binutils 1.0, I had to use binutils-1.9.tar.gz even though the diffs are against Mar 24 1991, and the source for 1.9 is dated April 17 1991.

My first effort gave me a linker that would happily link, but go32 would either refuse to run the executable, or just crash.  I was going to give up again, but I found mention in another file that DJGPP actually uses the linker from G++, the C++ compiler which was a separate thing in the late ’80s and early’90’s.  This time it worked, and I could link a trivial hello world style application!

Now that I finally had a cross linker actually working, I didn’t want to compile under emulation, so looking at the other diffs, they didn’t look too extensive. I went ahead ,and took DJGPP v1.06 and patched up the compiler & assembler to get a full cross toolchain.  And in no time, I had a null version of DooM running on MS-DOS well at least tested on DOSBox.

This was fun, and all but I didn’t see any easy way to do fun things like hook interrupts so I could get the keyboard & clock like any good MS-DOS program.  DPMI greatly eased this kind of stuff, so looking at the DJGPP history, DJGPP v1 version 1.10 actually adds preliminary DPMI support!  And in the next version, DPMI was much more better supported, however the binary format had changed from a.out to COFF as part of the move to v1.11. I was able to take the memory, and DPMI portions from the final v1.12 libc, and manually build and run them against the v1.06 library / dev tools.

And much to my surprise, it actually worked!  At least having the wrong format didn’t have any effect on how GO32 worked for me.

So feeling lazy, I snagged some of the support code from Maraakate’s revamp of DooM, just to make sure of the timer code, and the keyboard code, and again verified that I can build with the keyboard & timer ISR and I’m able to play the v1.9 shareware & commercial levels fine.  I haven’t done a thing to clean up or update the DooM source itself against all the dozens of bugs and issues with Ultimate DooM, or other games like Chex Quest etc.

I’m sure 99% of people wouldn’t care but you can download it here:

Win32_DJGPPv1_DooM.7z
Download crossdjgppv1

Although I’m using DPMI to drive realtime events, if I looked further at the GO32 v1.06 environments I could either figure out how it operates it’s timer, or modify the extender directly to drive the PIC timer and keyboard as I need.  But overlooking that, the vintage 1991 software is more than capable of running DooM.

DJGPP memory fouled

free: memory fouled

free: memory fouled

If you ever get this fun error while trying to exit or shell a program with DJGPP:

combinelo: memory fouled

free: memory fouled

You are mixing libraries built with a different version of the DJGPP runtime.  In my case, I built the allegro library with GCC 2.7.2.2 to use the older binutils but I’m cross compiling with GCC 5, so it’s using the newer runtime.

In my case I just needed to replace the contents of the lib directory with djcrx202.zip, and I was good to go.  I guess I could re-compile allegro, but that takes the better part of forever on DOSBox, and once was good enough.

[ANNOUNCE] DJGPP port of gcc-6.1.0

This is announcement of an update of DJGPP port of GCC-6.1.0

GCC used to stand for the GNU C Compiler, but since the
compiler supports several other languages aside from C,
it now stands for the GNU Compiler Collection.

See
https://gcc.gnu.org/ml/gcc/2016-04/msg00244.html
for original announcement of gcc-6.1.0 release


  • WARNING: This GCC port is for DJGPP v2.05 *
  • Build for DJGPP 2.03p2 is not and will not be available. *

Warning: DJGPP port of binutils-2.22 or newer is recommended.
Version 2.19 and 2.20 may work but are not tested
It is however recommended to use binutils-2.22
or newer

Use of DJGPP port of binutils-2.22 or newer is however required for

building gcc-6.1.0 for DJGPP.

Build for current stable version of DJGPP (djdev205) is
available
ftp://ftp.delorie.com/pub/djgpp/current/v2gnu/
and mirror sites (see http://www.delorie.com/djgpp/getting.html)

gcc610b.zip GNU GCC 6.1.0 for DJGPP V2
ftp://ftp.delorie.com/pub/djgpp/current/v2gnu/gcc610b.zip

gcc610d.zip Documentation for GNU C compiler
ftp://ftp.delorie.com/pub/djgpp/current/v2gnu/gcc610d.zip

gpp610b.zip GNU C++ Compiler 6.1.0 for DJGPP V2
ftp://ftp.delorie.com/pub/djgpp/current/v2gnu/gpp610b.zip

gfor610b.zip GNU Fortan 95 compiler 6.1.0 for DJGPP V2
ftp://ftp.delorie.com/pub/djgpp/current/v2gnu/gfor610b.zip

gcc610s.zip GNU GCC 6.1.0 sources for DJGPP
ftp://ftp.delorie.com/pub/djgpp/current/v2gnu/gcc610s.zip

objc610b.zip GNU Objective C and Objective C++ compiler and
runtime libraries v6.1.0
ftp://ftp.delorie.com/pub/djgpp/current/v2gnu/objc610b.zip

gfor610d.zip Documentation for GNU Fortran compiler
ftp://ftp.delorie.com/pub/djgpp/current/v2gnu/gfor610d.zip

ada610b.zip GNU Ada compiler
ftp://ftp.delorie.com/pub/djgpp/current/v2gnu/ada610b.zip

ada610d.zip Documentation for GNU Ada compiler
ftp://ftp.delorie.com/pub/djgpp/current/v2gnu/ada610d.zip

Binaries are built and tested mostly under Windows Vista Business (SP2)

Source RPMS needed for building Linux to DJGPP cross-compiler

Binary RPMs for both i686 and x86_64 are available. I built these binary RPMs
in CentOS 6.7 chroot under Fedora 23. Binaries are statically linked with GMP-6.1.0
MPFR-3.1.4 and MPC-1.0.3 to avoid unnecessary dependencies and increase
compatibility with other Linux distributions. For example they are expected
to work without problems in other reasonably recent Linux distributions
(like Fedora, RHEL-6 and newer, etc)

gcc610s2.zip is no more provided as patching GCC using DJGPP tools
has not been tested and even attempted by me for a long time.
DJGPP source file gcc610s.zip is a side product of building
gcc-6.1.0 Linux to DJGPP cross-compiler RPM packages. See source
RPM for patches applied to original FSF version of GCC-6.1.0.
You can find the same contents in the file

ftp://ftp.delorie.com/pub/djgpp/rpms/djcross-gcc-6.1.0/djcross-gcc-6.1.0.tar.bz2
Cross-compiler SRPM:

ftp://ftp.delorie.com/pub/djgpp/rpms/djcross-gcc-6.1.0/djcross-gcc-6.1.0-2ap.src.rpm

Cross-compiler binary RPMs (built under CentOS 5.11 i386, are expected to work on other recent enough RPM based Linux distributions, I myself have tried Fedora 19 x86_64):

GNU C compiler:
ftp://ftp.delori3.com/pub/djgpp/rpms/djcross-gcc-6.1.0/i686/djcross-gcc-6.1.0-2ap.i686.rpm

GNU C++ compiler:
ftp://ftp.delorie.com/pub/djgpp/rpms/djcross-gcc-6.1.0/i686/djcross-gcc-c++-6.1.0-2ap.i686.rpm

GNU Ada compiler:
ftp://ftp.delorie.com/pub/djgpp/rpms/djcross-gcc-6.1.0/i686/djcross-gcc-gnat-6.1.0-2ap.i686.rpm

GNU Fortran compiler:
ftp://ftp.delorie.com/pub/djgpp/rpms/djcross-gcc-6.1.0/i686/djcross-gcc-gfortran-6.1.0-2ap.i686.rpm

GNU Objective C and Objective C++ compilers:
ftp://ftp.delorie.com/pub/djgpp/rpms/djcross-gcc-6.1.0/i686/djcross-gcc-objc-6.1.0-2ap.i686.rpm

Tools for GCC 6.1.0 (currently only fixincl, most users do not need this):
ftp://ftp.delorie.com/pub/djgpp/rpms/djcross-gcc-6.1.0/i686/djcross-gcc-tools-6.1.0-2ap.i686.rpm

Info files of GCC-6.1.0 (a separate RPM file as these files are expected to
conflict with system compiler info files, but You do not need to install them…):
ftp://ftp.delorie.com/pub/djgpp/rpms/djcross-gcc-6.1.0/i686/djcross-gcc-info-6.1.0-2ap.i686.rpm

Substitute i686 with x86_64 For x86_64 binary RPMs in the URLs above.

You need also cross binutils (choose required binary RPM file or build from SRPM)
ftp://ftp.delorie.com/pub/djgpp/rpms/djcross-binutils-2.24-1ap.src.rpm
ftp://ftp.delorie.com/pub/djgpp/rpms/djcross-binutils-2.24-1ap.i686.rpm
ftp://ftp.delorie.com/pub/djgpp/rpms/djcross-binutils-2.24-1ap.x86_64.rpm

You need also DJGPP development libraries, include files and some tools (eg. stubify)
ftp://ftp.delorie.com/pub/djgpp/rpms/djcrx-2.05-5.i686.rpm
ftp://ftp.delorie.com/pub/djgpp/rpms/djcrx-2.05-5.x86_64.rpm
ftp://ftp.delorie.com/pub/djgpp/rpms/djcrx-2.05-5.src.rpm
Note that one can use
ftp://ftp.delorie.com/pub/djgpp/rpms/djcrx-bootstrap-2.05-1.src.rpm

for bootstrapping

See
http://gcc.gnu.org/gcc-6
for more information about GCC-6.1.0 and about changes in comparison
with earlier versions

Also see file gnu/gcc-6.10/readme.DJGPP (from gcc610b.zip and
gcc610s.zip) for more information about this port.

There is also my web page about DJGPP port of GCC

http://www.iki.fi/andris.pavenis/djgpp/gcc

I cannot promise however, that I’ll update it very often.
However new versions may appear there earlier (including ones not available
from ftp://ftp.delorie.com).

Andris Pavenis <andris DOT pavenis AT iki DOT fi>

System 16

A long long time ago, back when I got a Pentium 100 the wonderful world of emulation was really starting to be possible with such a high powered CPU.  First was the simple Game Boy emulators, then a Commodore 64 emulator, the incredible Amiga Emulator, the beginnings of SIMH (back when it was only a PDP-11 emulator), and then I found the SEGA emulator, System 16.

It was really cool being able to play 16bit arcade games on the desktop, although rather slowly.  From there everyone knows the rise of MAME.  But while looking around for a small 68000 C compiler, I came across the source code to an older version of System 16, 0.53 on archive.org.  Naturally it’s for MS-DOS, as was everything back in the day.  Also slightly interesting is the 68000 emulation, written by Bernd Schmitd of UAE fame.  So for the heck of it, I set about getting Thierry Lescot’s System 16 building again.  I’ve never used allegro before, so it was a bit of a fight to get a version of it to actually build.  It turns out that I should have been building version 2.11 with tools of that era (why on earth was I using GCC 4, and binutils 2.18?) and instead stick with GCC 2.7.2.2 and some much older binutils.  And in no time I had build the library, and it’s examples.  With that done, I was able to re-build System 16 with GCC 4.1.2 and get a binary!

Back in the day, I actually did have an Altered Beast arcade board.  Sadly it died in a move, someone near and dear just saw the PCB as “garbage” and tossed it.  Sigh, but I did have ROM dumps, as I did a refresh of it forever ago.  Anyways I still have the ROM files, so I guess that is nice.

Anyways I fired up the emulator and got what is known as the “jail bar” effect, which is from a bad ROM.

Corrupt tiles

Corrupt tiles

Notice the sprites

Notice the sprites

The System 16 splits it’s memory into a program space, a sprite memory bank, a tile memory bank, and RAM for stack and things like the palette.  As you can see the program is certainly running, and the sprites are good.  I did some poking around a bit later, and noticed that due to a logic bug, the texture ROMs are actually never loaded!

So a quick patch, and now we get Altered Beast up and running!

Altered Beast title screen

Altered Beast title screen

demo play

demo play

Well, now isn’t that great!

Not that I would imagine anyone would really care, I mean MAME is a thing, and even from the readme:

Altered Beast : No sound emulation

So it’s pretty quiet.  Additionally the source is pretty restrictive:

These sources can’t be used for commercial purpose, any new version of the
emulator done with these sources must specify my name somewhere on the screen
et docs and I must be informed about any new release of the emulator.

For anyone interested you can find the source & binaries out on sourceforge.

Porting Quake II to MS-DOS pt5 – 3DFX, GameSpy, Quake 2, and The Universe

The following is a guest post / wrap-up of the Q2DOS adventure by [HCI]Mara’akate.q2dos_3dfx_4
In the last update sezero and I([HCI]Mara’akate) tied up most loose ends with regards to Q2DOS.  Specifically: adding in DXE support for mods and cleaning up some code from the early efforts.  During this time, a forum user by the name of ggorts (strogg spelled backwards!) mentioned the possibility of using an old Mesa version with 3DFX support in DOS. I worked on separating the ref_soft from being statically linked into a DXE form and sezero cleaned up any potential problems there.

I mentioned the possibility of attempting the Mesa port to sezero and he thought it was probably a wasted effort and thought making a ref_glide depending only on glide3x.dxe would be a better way to go with less overhead.  I started some initial work on it but quickly abandoned this side-project as I have no real glide (or even OpenGL) knowledge and didn’t have enough time on my hands to play around with it.

Around this time, we also separated the GameSpy browser code into a separate DXE for potential legal issues.  The GameSpy code was publicly released, but never officially GPL’d.  Using this method, other port authors could link against a gamespy.dll to add in the browser capabilities that connect to my GameSpy master server emulator (see QDOS branch for source code to that particular project).

Ggorts also came up with some code for us to be able to finally use the banked modes and Mode-X 320×240.  Though 320×240 Mode-X seems to have some issues with certain emulator configurations, for the most part it works OK.  This also helped us to get some ASM rendering code in from Q1 and help clean up the original mess that was the SVGA driver; a lot of unused code from Q1 was removed and sezero found a clever way to send the video modes list between the game binary and renderer DXE.

In any event, one night I figured I’d take a stab at trying to get Mesa working in Q2DOS.  Checking out the Mesa3d FTP and researching the various changelogs it appears as if Mesa 5 series was the last true effort with Mesa 6.4.x series being the last maintained version with 3DFX specific code.  I got everything to compile but ran into hard-lock issues no matter what I attempted.  During this time, ggorts found out some various small, but now obvious issues. Including increasing the stack size to 1MB and he hard-coded the ref_gl to only work in 640×480.  It took a lot of pleading but eventually he released his source with a static compile for Voodoo 1 cards only as he was testing this on emulators like DOSBox with glide support and PCem dev branch.

I worked on cleaning up the source and he produced some glide3x libraries for me for Voodoo 2 and Voodoo 5 as these were the only cards I personally owned.  Imagine my surprise as I first loaded it up and it actually worked!  And it was smooth with no rendering issues!

q2dos_3dfx_3

At this point, sezero became involved and worked very hard to clean up the Mesa compile issues, including various scary warnings and helped to update us to the final glide3x commit pushed to the development branch and Mesa v6.4.3 which was an unreleased maintenance update for Mesa v6.4.2.

It was a long journey to get the code all working together just right, and a big thanks goes out to the early Mesa crew including Brian Paul, Daniel Borca, and “KoolSmoky” and the mysterious ggorts fellow who pushed hard for this feature.

To recap, Q2DOS from the last time we talked now has:

  • 3DFX Rendering with Mesa v6.4.3 for all Voodoo cards.
  • Separated renderer so it is no longer statically linked.
  • GameSpy is now a DXE.
  • WAV streaming, which is practically free as opposed to the OGG format.

q2dos_3dfx_1
q2dos_3dfx_8

We are about at the end of our Q2DOS journey.  A few odds and ends with Mesa and Voodoo 5 SLI issues remain (though nothing too show stopping) and there’s a small wishlist of some unnecessary features but it’s come a long way from the initial null driver effort!

q2dos_3dfx_2*Neozeed

I have to say it is simply incredible to see how Q2DOS went from a very primitive ‘wow it works’ port to a full featured port.  Simply amazing!

For those who missed the adventure it starts in Part 1, continued in Part 2, Part 3 and Part 4.