VOGONS


First post, by onre

User metadata
Rank Newbie
Rank
Newbie

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

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

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:

        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:

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.

Reply 1 of 10, by root42

User metadata
Rank l33t
Rank
l33t

Maybe you can share the resulting binary? 😀 As Nethack is open source, this should be fine, right?

YouTube and Bonus
80486DX@33 MHz, 16 MiB RAM, Tseng ET4000 1 MiB, SnarkBarker & GUSar Lite, PC MIDI Card+X2+SC55+MT32, OSSC

Reply 2 of 10, by onre

User metadata
Rank Newbie
Rank
Newbie
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.

Reply 3 of 10, by akula65

User metadata
Rank Oldbie
Rank
Oldbie

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/

Reply 4 of 10, by onre

User metadata
Rank Newbie
Rank
Newbie
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 😀

Reply 5 of 10, by root42

User metadata
Rank l33t
Rank
l33t
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 😀

Yeah, Nethack is a real resource hog...

YouTube and Bonus
80486DX@33 MHz, 16 MiB RAM, Tseng ET4000 1 MiB, SnarkBarker & GUSar Lite, PC MIDI Card+X2+SC55+MT32, OSSC

Reply 6 of 10, by onre

User metadata
Rank Newbie
Rank
Newbie

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.

Reply 7 of 10, by onre

User metadata
Rank Newbie
Rank
Newbie

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.

Reply 8 of 10, by onre

User metadata
Rank Newbie
Rank
Newbie

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

Reply 9 of 10, by onre

User metadata
Rank Newbie
Rank
Newbie
onre wrote:

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:
illegal_instruction.png
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.

Reply 10 of 10, by onre

User metadata
Rank Newbie
Rank
Newbie

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