ELKS port of Adventure - help needed :)
I grabbed the src of adventure
wget -r -l 1 -nH --cut-dirs=5 \
http://www.cise.ufl.edu/class/cop4600/minix/src/commands/advent/
make clean to get rid of the binaries.
I've fixed up the make file which compiles. (patch below)
Install the dat files to /usr/lib/advent and use elksemu to run adventure
[paul@bender advent]$ file advent
advent: Linux-8086 executable not stripped
[paul@bender advent]$ ./advent
<Generic Adventure -- Version:7.0, July 1994>
...
The game will accept y/n for the first input for instructions but the word processing is b0rked.
Quoted 1 line
north
I didn't understand the word "north"
I imagine it's something fixable in the src's, I'd like to get it running though as I'm going to a lan party with only an 8086 laptop to take :)
Any adventure hackers got any clue
Paul
Makefile 2002-12-10 12:35:50.000000000 +0000 renamed from Makefile.old 1997-09-22 15:46:59.000000000 +0100 +5 -4
@@ -9,10 +9,11 @@ # # On Minix, use '-m' in CFLAGS and '-i' in LDFLAGS. -CC = mcc -CFLAGS = -D_POSIX_SOURCE +CC = bcc +GCC = gcc +LD = ld86 +CFLAGS = -0 LDFLAGS = -GCC = /usr/local/bin/gcc OBJS = advent.o database.o english.o initial.o itverb.o score.o\ travel.o turn.o utility.o verb.o vocab.o
@@ -22,7 +23,7 @@ all: $(DAT) advent advent: $(OBJS) - $(CC) $(LDFLAGS) -o advent -S 16kw $(OBJS) + $(CC) $(LDFLAGS) -o advent $(OBJS) setup: setup.c advent.h $(GCC) -o setup setup.c
For the heck of it, and for nostalgia's sake,
I edited the Makefile to compile and run on
my Linux PC (changed CC=mcc to CC=gcc, got
rid of -S switch).
It runs fine on my PC - no problems parsing
commands. I'm guessing, without having looked
at the code, that this is not a source code
problem.
Phil
--------------
phil@castle:advent$ diff -u Makefile.old Makefile --- Makefile.old Mon Sep 22 09:46:59 1997 +++ Makefile Wed Dec 11 01:48:14 2002 @@ -2,17 +2,17 @@
# Where to put the adventure text files, and the binary executable. # Need the trailing "/"s.
-TEXTDIR = /usr/lib/advent/
+TEXTDIR = ./
# Flags you may want to add to CFLAGS:
# -DHAS_STDC=0 or 1 We have Standard C. Default=1 iff __STDC__ is
nonzero.
#
# On Minix, use '-m' in CFLAGS and '-i' in LDFLAGS.
-CC = mcc
+CC = /usr/bin/gcc
CFLAGS = -D_POSIX_SOURCE
LDFLAGS =
-GCC = /usr/local/bin/gcc
+GCC = /usr/bin/gcc
OBJS = advent.o database.o english.o initial.o itverb.o score.o\
travel.o turn.o utility.o verb.o vocab.o
@@ -22,7 +22,8 @@
all: $(DAT) advent
advent: $(OBJS)
- $(CC) $(LDFLAGS) -o advent -S 16kw $(OBJS)
+# $(CC) $(LDFLAGS) -o advent -S 16kw $(OBJS)
+ $(CC) $(LDFLAGS) -o advent $(OBJS)
setup: setup.c advent.h
$(GCC) -o setup setup.c
phil@castle:advent$ make /usr/bin/gcc -o setup setup.c ./setup Processing file advent1.txt completed Processing file advent2.txt completed Processing file advent3.txt completed Processing file advent4.txt completed /usr/bin/gcc -c -D_POSIX_SOURCE -DTEXTDIR='"./"' advent.c /usr/bin/gcc -D_POSIX_SOURCE -c -o database.o database.c ...
phil@castle:advent$ ./advent <Generic Adventure -- Version:7.0, July 1994>
Welcome to ADVENTURE!
...
Would you like instructions?
Quoted 1 line
no
You are standing at the end of a road before a small brick building. Around you is a forest. A small stream flows out of the building and down a gully.
Quoted 1 line
north
You are in open forest, with a deep valley to one side. Not far is a large billboard.
Quoted 1 line
read
The billboard reads:
"Visit Beautiful Colossal Cave. Open Year Around. Fun for the entire family, or at least for those who survive." Below the headline is an impossibly complicated map showing how to find Colossal Cave. Not that it matters, because all the directions are written in Elvish.
Quoted 1 line
...
Quoted 2 lines · Phil Goembel
I'm guessing, without having looked at the code, that this is not a source code problem.
Possible a source code or bcc problem - the area to look at is the function 'binary' in the 'vocab.c' file.
Put:
printf("binary.vocab: mid=%d lo=%d hi=%d\n",mid,lo,hi);
before and after the line:
mid = (lo + hi) / 2;
(about line 596 - I've been messing with my file)
You'll see in the Linux compilation it follows a very nice textbook binary tree traversal.
In the ELKS version, it starts out badly and just gets worse.
I haven't found the cause yet - it's been a long day, and my brain isn't working properly :)~
I thought it might be something to do with overflow, but changing the int defs to long doesn't help.
Still, there should be enough pointers here for someone to figure it out... (I'm still working on it as well)
P.S. Phil - I think my mailer used your address rather than the list on my last post. Forward it if you like, but I think this supersedes it.
Signature · 2 lines
Richard Wallman http://www.murkygoth.uklinux.net/elks
Quoted 1 line · Richard Wallman
Possible a source code or bcc problem
It's a bcc problem: strcmp doesn't return the right values.
I think on line 142 of libc/string/string.c:
sbb ax,ax ; Collect correct val (-1,1).
I'm not too hot on x86 assembly, but surely this command is subtracting the ax register from itself, using the status flags to show sign? Does the processor support a negative and positive zero value?
The next line (orb al,#1) then turns on bit 1. It is assuming that the scasb command has correctly set the right flag to indicate whether the comparison was negative or positive, and so give the sign.
I think this is what's wrong - every time, I'm getting a -1 result from strcmp.
Paul: short answer = rewrite strcmp. Only "vocab.c" and "english.c" use that function, so just replace all references. sed is your friend. :)
Signature · 2 lines
Richard Wallman http://www.murkygoth.uklinux.net/elks
On 11 Dec, I wrote:
{SNIP: a load of rubbish}
Scratch all that, I did a quick test and bcc is fine.
I blame tiredness. >:)
Still getting -1 each time for the comparison in vocab.c though. I even tried "check=1" before the "check = strcmp(w, wc[mid].aword);" line, and it still comes up -1 each time.
Just tried pasting the bit of C from the end of the libc code:
--------------------------------------------------------------
int newcmp(d, s)
const char *d;
const char * s;
{
register char *s1=(char *)d, *s2=(char *)s, c1,c2; while((c1= *s1++) == (c2= *s2++) && c1 );
return c1 - c2;
};
--------------------------------------------------------------
Put that in vocab.c, replace the reference in the "binary" function, and it all works smoothly (for that function at least).
Looks like the only useful part of my last post was the suggestion to replace strcmp.
There's a problem here somewhere, but I'm damned if I can find it right now.
Yawn...time for bed...
Signature · 2 lines
Richard Wallman http://www.murkygoth.uklinux.net/elks
Quoted 5 lines · Richard Wallman
Quoted 1 line · Richard Wallman
Possible a source code or bcc problem
It's a bcc problem: strcmp doesn't return the right values.
Cheers that's a great pointer, oh well time to get my hands dirty...
Quoted 2 lines
Paul: short answer = rewrite strcmp. Only "
vocab.c" and "english.c" use that function, so just replace all references. sed is your friend. :)
Indeed - I'll hopefully have some time to do this tomorrow. I have the bcc archives to hand so can look at previous versions to brush up my asm.
Just got nice shiny 8086 laptop - but without floppy/serial. It's an Olivetti Quaderno, I may be able to use a flash pcmcia disk on it to get elks onto it, but we'll see. Else it's going to be pinouts from usenet and some soldering (eep)...
Paul
Quoted 6 lines · Richard Wallman
Quoted 1 line · Richard Wallman
Possible a source code or bcc problem
It's a bcc problem: strcmp doesn't return the right values.
Yes, I was thinking either a compiler problem or a runtime library problem.
I think on line 142 of libc/string/string.c:
Quoted 3 lines
sbb ax,ax ; Collect correct val (-1,1).
This is suspicious, as I would expect the result to be either -1 or 0 (I'm not an 8086 assembly guru, though), depending on the borrow bit.
The borrow bit should be unchanged (I'm assuming the 8086 arithmetic instructions work like all other 2's complement processors I've worked with).
I don't, think after the sbb, that the status bits resulting from a compare would be preserved, i.e. you would not be able to distinguish between a value being less than, equal, or greater than another value. The sbb would clobber the status, and just give greater than or not greater than (borrow or not borrow).
It's hard to say without seeing the code. If you want to email me the assembly code, that would help.
Quoted 8 lines
I'm not too hot on x86 assembly, but surely this command is subtracting the ax register from itself, using the status flags to show sign? Does the processor support a negative and positive zero value?
The next line (orb al,#1) then turns on bit 1. It is assuming that the scasb command has correctly set the right flag to indicate whether the comparison was negative or positive, and so give the sign.
Sigh. Guess I'm going to have to set up the ELKS development environment to help here. If the orb is the very next instruction, after the sbb, it would change 0 to 1, but leave -1 unchanged.
Where does the scasb fit in?
Quoted 7 lines
I think this is what's wrong - every time, I'm getting a -1 result from strcmp.
Paul: short answer = rewrite strcmp. Only "
vocab.c" and "english.c" use that function, so just replace all references. sed is your friend. :)
This is a good idea. I'm surprised nobody's run into problems with strcmp before this, though.
Is strcmp written in assembly, or are you looking at the code generated by the compiler?
Sorry about asking such basic questions, but it's been a long time since I've actually tried to set up the ELKS development environment (and failed). So I don't have the source code on hand. I've been lurking ever since, but I thought here was a simple problem I could help with. Heh!
Phil
Quoted 9 lines · Phil Goembel
Quoted 6 lines · Richard Wallman
Quoted 1 line · Richard Wallman
Possible a source code or bcc problem
It's a bcc problem: strcmp doesn't return the right values.
Yes, I was thinking either a compiler problem or a runtime library problem.
Two possible fixes - there is a new dev86 out which string.c has changed in (0.16.10). I'm going to test this out later when I get into work. Thanks Robert :)
Or you can use the C version from uclibc:
Paul
Quoted 3 lines · Paul Nasrat
Two possible fixes - there is a new dev86 out which
string.chas changed in (0.16.10). I'm going to test this out later when I get into work. Thanks Robert :)
I can confirm adventure *works* with bcc 0.16.10 which was released on the 5th of December.
This is a bleeding edge bcc with pre-processor, etc. But other than a complaint about:
advent.h:265: warning: Unexpected text following preprocessor command
But it compiles and runs :)
At least I get to play a game at the lan party now...
Paul
Adventure - the answer to what went wrong?
In reply to Phil GoembelGave it a bit of thought today, and I think I know what happened.
Looking at the libc sources, it looks like the strcmp and strncmp functions assume that both strings are in the same 64Kb segment. (There may be other functions that make this assumption as well, but I haven't really looked).
Looking at the file sizes, the "advent" program is 84Kb when compiled using bcc.
I put forward the theory that it fails because the two strings are not in the same 64Kb segment. The reason no-one has found this problem before is that so far all of the binaries have been <64Kb in size.
Still, looks like it's been fixed now, but if anyone was wondering why their port of their favourite app failed, that may be the reason.
Signature · 2 lines
Richard Wallman http://www.murkygoth.uklinux.net/elks
Re: Adventure - the answer to what went wrong?
Quoted 6 lines
Gave it a bit of thought today, and I think I know what happened.
Looking at the libc sources, it looks like the strcmp and strncmp functions assume that both strings are in the same 64Kb segment. (There may be other functions that make this assumption as well, but I haven't really looked).
They assume right! In ELKS DS=SS=ES.
By the way, the CVS ELKS tree solves many memory problems but requires a patch to the linker that I posted here some time ago and never got in the linker tree... :(
Harry
Re: Adventure - the answer to what went wrong?
In reply to Richard WallmanQuoted 3 lines · Richard Wallman
I put forward the theory that it fails because the two strings are not in the same 64Kb segment. The reason no-one has found this problem before is that so far all of the binaries have been <64Kb in size.
ELKS only supports a max of 64K code / 64K data per app...
Alan
Re: Adventure - the answer to what went wrong?
Also, the file size is 84k, but that doesn't mean that the code segment is going to be more than 64k, does it? Does the whole file get loaded into memory and executed, or can there be other "stuff" in that file besides executable code that may not get loaded into the code segment? I haven't messed with this stuff in a while, so I don't remember :)
Dan
Quoted 16 lines · Alan Cox
Quoted 3 lines · Richard Wallman
I put forward the theory that it fails because the two strings are not in the same 64Kb segment. The reason no-one has found this problem before is that so far all of the binaries have been <64Kb in size.
ELKS only supports a max of 64K code / 64K data per app...
Alan
-
To unsubscribe from this list: send the line "unsubscribe linux-8086" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: Adventure - the answer to what went wrong?
Quoted 8 lines
Also, the file size is 84k, but that doesn't mean that the code segment is going to be more than 64k, does it? Does the whole file get loaded into memory and executed, or can there be other "stuff" in that file besides executable code that may not get loaded into the code segment? I haven't messed with this stuff in a while, so I don't remember :)
Dan
It is ok for a file to be bigger than 64K since initialized data exist in the file along with the code.
Harry
Re: Adventure - the answer to what went wrong?
Quoted 6 lines
Quoted 6 lines
Also, the file size is 84k, but that doesn't mean that the code segment is going to be more than 64k, does it? Does the whole file get loaded into memory and executed, or can there be other "stuff" in that file besides executable code that may not get loaded into the code segment? I haven't messed with this stuff in a while, so I don't remember :)
Quoted 6 lines
Quoted 1 line
Dan
It is ok for a file to be bigger than 64K since initialized data exist in the file along with the code.
Harry
That's what I was thinking, just haven't done any x86 asm for a while.
Dan
Re: Adventure - the answer to what went wrong?
In reply to Dan OlsonQuoted 5 lines · Dan Olson
Also, the file size is 84k, but that doesn't mean that the code segment is going to be more than 64k, does it? Does the whole file get loaded into memory and executed, or can there be other "stuff" in that file besides executable code that may not get loaded into the code segment? I haven't messed with this stuff in a while, so I don't remember :)
"size" should tell you.
Basically you have code at CS:0 for upto 64K (and possibly shared). Then you have data at DS:0->n and stack at DS:[topsize] going down and the dynamic memory space settable using chmem.