Compiling old Nethack versions

Getting old DOS games working on modern hardware. (DOSBox topics belong in DOSBox areas below, not here).

Compiling old Nethack versions

Postby onre » 2018-9-28 @ 06:32

Greetings all.

I couldn't find old Nethack binaries anywhere so I decided to roll my own. Here's how to produce a working binary for Nethack 2.3e as the process isn't completely trivial. I couldn't find a similar walkthru anywhere so I decided to write it here.

1. Install MS C 4.0, available at least on WinWorldPC
- as I did not know the preferred installation layout, I just copied contents of disk 1 and 2 into one dir (BIN) and 3, 4, and 5 into another (03)
- one could of course make a neat installation where binaries are in BIN, includes in INCLUDE and libraries in LIB, but I was lazy
- after this, edit autoexec.bat and include following:
PATH=C:\BIN;%PATH% (or wherever you put the binaries)
set LIB=C:\LIB (or wherever you put the libraries)
set INCLUDE=C:\INCLUDE (or wherever you put the includes)
- reboot to have the vars set
2. Install NDMAKE 4.5 somewhere in path
- this includes MAKE45.EXE and MAKE45L.EXE, whose difference is the memory model used, which affects the complexity of makefiles they can process
- I just renamed MAKE45L.EXE to NDMAKE.EXE
3. Unpack Nethack 2.3e source somewhere
4. Use an uudecode tool (I did this on a separate Unix machine) to extract termcap.uu to get termcap.arc
5. Unpack termcap.arc someplace else
6. Use this makefile to compile the termcap lib
Code: Select all
#       SCCS Id: @(#)Makefile.lib       3.0     90/02/17
#       Nethack makefile for Fred fish termlib -- Norman Meluch
#
CC      = cl /c
MODEL   = L
CFLAGS  = /A$(MODEL) /Os /Oa /Gs /Zp1 /W0
#
# Termcap routines.
TERMLIB = termlib.lib
#
TL_LOBJECTS =   tgetent.o       tgetflag.o      tgetnum.o       \
                tgetstr.o       tgoto.o         tputs.o         \
                isdigit.o       fgetlr.o
#
.SUFFIXES: .exe .o .c .obj .asm
#
.c.o:
        $(CC) $(CFLAGS) /Fo$*.o $*.c
#
$(TERMLIB):     $(TL_LOBJECTS)
        lib $(TERMLIB) -+ $(TL_LOBJECTS);

- to actually compile, run ndmake
- ignore whatever the library tool says, just copy the resulting *.O files to the Nethack 2.3e source dir
7. go back to nethack 2.3e source dir and copy makefile.pc to makefile
8. edit makefile as follows
- we want to avoid creating too large segments because otherwise linking will fail, thus we adjust the -Gt parameter of the compiler
- change line 8 (CFLAGS) to:
Code: Select all
CFLAGS = -A$(MODEL) -DREGBUG -DLINT_ARGS -DVER=$V $(WIZARD) -Ot -Gs -Gt16

- I could not figure out for life of mine how to make the MS C 4.0 linker to actually accept both libs and objects when linking the final executable, so I took a shortcut by just including the object files for termlib instead of actually using the lib (apparently there are no online copies of MS C 4.0 documentation?)
- also, the maximum number of segments should be increased because whatever the default value is, it is too small
- change line 46 (commented out by default) to:
Code: Select all
        link fgetlr.o isdigit.o tgetent.o tgetflag.o tgetnum.o tgetstr.o tgoto.o tputs.o $(OBJS), $(GAME) /NOIG /STACK:0xa00 /CP:1 /
SEG:256;

9. edit config.h
- #define MSDOS because the compiler does not seem to do it despite contrary claims in the makefile
- comment out everything that looks like unix
- here's a diff so you can figure out what to change and where:
Code: Select all
21c21
< # define MSDOS        /* define for MS-DOS (actually defined by compiler) */
---
> /* # define MSDOS     /* define for MS-DOS (actually defined by compiler) */
23c23
< /* #define    UNIX            /* delete if no fork(), exec() available */
---
> #define       UNIX            /* delete if no fork(), exec() available */
25c25
< /* #define BSD                /* defind for 4.n BSD  */
---
> #define BSD           /* defind for 4.n BSD  */
32c32
< /* #define PYRAMID_BUG        /* avoid a bug on the Pyramid */
---
> #define PYRAMID_BUG   /* avoid a bug on the Pyramid */
48c48
< /* #define    LOGFILE "logfile" /* larger file for debugging purposes */
---
> #define       LOGFILE "logfile" /* larger file for debugging purposes */
75c75
< /* #define    MAIL
---
> #define       MAIL
78d77
< */
80c79,80
< /* #define SHELL              /* do not delete the '!' command */
---
>
> #define SHELL         /* do not delete the '!' command */
103c103
< /* #define HACKDIR    "/usr/games/lib/nethackdir" */
---
> #define HACKDIR       "/usr/games/lib/nethackdir"
112c112
< /* #define SECURE                     /* do setuid(getuid()) after chdir() */
---
> #define SECURE                        /* do setuid(getuid()) after chdir() */

9. run ndmake
10. wait (took about three hours on Toshiba T1200)
11. make directory C:\ETC
12. copy TERMCAP.CNF to C:\ETC\TERMCAP - no extension
- the termlib could be compiled so that it looks for termcap.cnf in current dir instead but I didn't bother
13. if you don't have ANSI.SYS or equivalent, uudecode nansi_sy.uu, copy it somewhere and put device=C:\somewher\nansi.sys into config.sys, reboot to load it
14. set TERM=ibmpc (or ibmpc-mono if you have a monochrome monitor)
15. make a directory for nethack, say, C:\nethack
16. copy hack.exe and nethack.cnf to the dir created, edit nethack.cnf to point to the dir you just created
17. make directory save under the dir created, also create an empty file record
18. run HACK.EXE
19. (countless hours of frustration trying to ascend)

These should be complete instructions. Took me better part of a day to figure this out. Next I'll try 3.1 or 3.2.
User avatar
onre
Newbie
 
Posts: 12
Joined: 2018-9-28 @ 05:37
Location: finland

Re: Compiling old Nethack versions

Postby root42 » 2018-9-28 @ 07:54

Maybe you can share the resulting binary? :) As Nethack is open source, this should be fine, right?
Soldering, retro game reviews and more on YouTube and Bonus videos
80386DX@25 MHz, 8 MiB RAM, Tseng ET4000 1 MiB, Jazz16, PC MIDI Card + SC55MkII + MT32, XT CF Lite, OSSC 1.6
User avatar
root42
Oldbie
 
Posts: 1250
Joined: 2018-1-27 @ 13:23

Re: Compiling old Nethack versions

Postby onre » 2018-9-28 @ 08:05

root42 wrote:Maybe you can share the resulting binary? :) As Nethack is open source, this should be fine, right?

Yeah, it can be distributed freely. I have to kermit the binary out from the Toshiba first, though, and it's building stuff right now. I'll get to it once I get that done.

I have tried the binary also on FreeDOS inside VirtualBox, where the screen handling did not work correctly with FreeDOS supplied NANSI.SYS. This behavior does not happen with MS-DOS 3.3 and NANSI.SYS included in source package.
User avatar
onre
Newbie
 
Posts: 12
Joined: 2018-9-28 @ 05:37
Location: finland

Re: Compiling old Nethack versions

Postby akula65 » 2018-9-28 @ 11:18

Here is one of many sites with Version 3.43 binaries (nh343dos.zip) for DOS/Win3.1:

https://www.nethack.org/v343/ports/download-msdos.html

Note this site is using the following archive of source and binaries, so if you prowl around, you can find a lot more binaries for various OSes:

https://www.nethack.org/download/
User avatar
akula65
Oldbie
 
Posts: 537
Joined: 2004-9-28 @ 01:29
Location: North Carolina

Re: Compiling old Nethack versions

Postby onre » 2018-9-28 @ 11:22

akula65 wrote:Here is one of many sites with Version 3.43 binaries (nh343dos.zip) for DOS/Win3.1:

https://www.nethack.org/v343/ports/download-msdos.html

Note: there is no real-mode overlaid binary distribution of NetHack 3.4.3

I run this stuff on a Toshiba T1200, which has 80C86 CPU. Only real mode is possible. 3.3.1 was last version to support that, but it is unplayably slow on this hardware. What I'm after here could be defined as follows: the newest Nethack that can be comfortably played on a 10 MHz 80C86 machine :happy:
User avatar
onre
Newbie
 
Posts: 12
Joined: 2018-9-28 @ 05:37
Location: finland

Re: Compiling old Nethack versions

Postby root42 » 2018-9-28 @ 11:32

onre wrote: What I'm after here could be defined as follows: the newest Nethack that can be comfortably played on a 10 MHz 80C86 machine :happy:


Yeah, Nethack is a real resource hog...
Soldering, retro game reviews and more on YouTube and Bonus videos
80386DX@25 MHz, 8 MiB RAM, Tseng ET4000 1 MiB, Jazz16, PC MIDI Card + SC55MkII + MT32, XT CF Lite, OSSC 1.6
User avatar
root42
Oldbie
 
Posts: 1250
Joined: 2018-1-27 @ 13:23

Re: Compiling old Nethack versions

Postby onre » 2018-9-28 @ 12:25

http://anteek.fi/~esp/nh23bin.zip

Here is the binary and a couple of support files for it. Unpack somewhere, adjust nethack.cnf, copy termcap to C:\ETC, install ANSI.SYS or equivalent and start playing.

edit; oh damn, forgot one important thing: set TERM=ibmpc or set TERM=ibmpc-mono before playing.
User avatar
onre
Newbie
 
Posts: 12
Joined: 2018-9-28 @ 05:37
Location: finland

Re: Compiling old Nethack versions

Postby onre » 2018-9-28 @ 16:42

http://anteek.fi/~esp/nh313bin.zip

Here's real-mode 3.1.3 with all gameplay affecting options compiled in. I set the Toshiba expanded memory (384 kB) as disk cache and it is, well, slow, but playable. This one has native screen routines, so it does not need ANSI.SYS - just unpack, adjust nethack.cnf and start playing.

3.0.10 seemed to have a Makefile bug affecting the link stages when assembling the overlays. I may return to that later.
User avatar
onre
Newbie
 
Posts: 12
Joined: 2018-9-28 @ 05:37
Location: finland

Re: Compiling old Nethack versions

Postby onre » 2018-9-29 @ 12:03

The makefile bug of 3.0.10 was of my own doing as I was trying to avoid too long command lines that DOS could not execute. Using CL environment variable for compiler flags solved this. This one was also really picky about compiler version - 5.1 produced an executable with weird bugs in the overlay system, 7.0 executable just claimed "run-time error R6806 - cannot read file" but 6.0 worked. I feel almost like an expert at building antique DOS applications now.

This one requires ANSI.SYS to run correctly. It is a lot bigger game than 2.3e - alignments, character attributes, special levels, separate endgame. It also runs enjoyably on my Toshiba, which the 3.1.3 doesn't quite do. The latter is playable, too, but sluggish.

http://anteek.fi/~esp/nh3010b.zip
User avatar
onre
Newbie
 
Posts: 12
Joined: 2018-9-28 @ 05:37
Location: finland

Re: Compiling old Nethack versions

Postby onre » 2018-9-30 @ 08:13

onre wrote:http://anteek.fi/~esp/nh3010b.zip

This build has a bug that I just discovered. On newer than MS-DOS 3.3, saving causes a stack overflow. I've identified the reason to be an illegal instruction generated by the compiler. Here we can see MS Codeview disassembly of the situation:
Image
I could try patching MS C 6.0a to 6.0ax, if I could only find the patch file somewhere.

Another way of working around this would involve figuring out what exactly triggers the behaviour, and hacking at the C source writing something different accomplishing the same functionality and seeing whether that would compile to a different, working code.
User avatar
onre
Newbie
 
Posts: 12
Joined: 2018-9-28 @ 05:37
Location: finland

Re: Compiling old Nethack versions

Postby onre » 2018-9-30 @ 08:26

Figured it out. I had left COMPRESS defined and the DOS binary was trying to exec /usr/local/compress to make the save file smaller, which - strangely enough - didn't cause an error on DOS 3.3 but did so on later versions.

Here's a fixed version of the whole thing.

http://anteek.fi/~esp/nh3010b2.zip
User avatar
onre
Newbie
 
Posts: 12
Joined: 2018-9-28 @ 05:37
Location: finland


Return to DOS

Who is online

Users browsing this forum: No registered users and 7 guests