Initial commit: README, Woods1977, Knuth2002, ODwyer2012.

My C version has no known bugs yet, although it is unplayable on
the Z-machine due to unknown bugs somewhere (presumably in vbccz).

I'll commit the vbccz sources later. Yes, I know my Makefile has
a hard-coded path to /tmp/vbcc-0.7.orig/bin/vc, which is a pretty
dumb place to keep a compiler anyway... I'll be fixing that.
Initial commit of unmodified vbcc.

This is the UNMODIFIED source distribution of Volker Barthelmann's
vbcc compiler. This includes a Z-machine backend originally by
David Given (2001) and updated by Volker Barthelmann (2006).

For now, I'll follow Given's lead in distributing my modifications
to vbcc as a big patch, even though you could certainly argue that
any modifications made via git are already a series of patches.
I have contacted Dr. Barthelmann to ask for clarification and/or
permission to distribute a modified version in this case.
Get vbccz to build, and update my Makefile to use the new path.

No more "/tmp/vbcc-0.7.orig" paths in my checkout!

The script ./build-vbcc.sh will apply a patch to vbcc and then
build it. In this first checkin, the changes are:

    - Make dtgen treat EOF as "non-interactive mode", instead
      of going into an infinite loop. This lets us build vbcc
      without user interaction.

    - Change how the vc front-end finds its config file.
      Instead of searching in a lot of odd places, just look
      at getenv("VBCC").

    - Don't require the config file to contain full pathnames
      to all the utilities; special-case the prefix "../" as
      meaning "prepend the value of VBCC to this path".
      In other words, paths beginning "../" are treated as
      relative to the config file itself; all other paths are
      fed to the shell as-is (relative to the CWD).

    - Add a config file for the "z" backend. Is it just me,
      or are *all* the config files missing from Barthelmann's
      current source distribution?

    - Add -Wno-format to the Makefile in order to suppress
      spammy (albeit totally correct) warnings from gcc.
Fix two ierrors introduced in vbcc 0.8.

Now vbccz not only builds, but actually accepts "advent.c" without
crashing, and produces Inform6 output which is accepted by the Inform6
assembler. While "advent.c" does now compile, it does not yet
successfully assemble: the combined size of its Z-code and static data
is too large.

New changes to vbcc-patch.diff in this revision are:

    - Between 0.7 and 0.8, Barthelmann got rid of the "vpointer"
      field in "union atyps". He replaced two uses of it in the
      Z-machine backend with ierror(0) [i.e., a crash]. I've
      reverted to the old code, just using "vulong" instead of
      "vpointer".
Optimize puts("foo") into the Z-machine's @print opcode.

Now we begin hacking vbcc in earnest. I'm inserting this optimization
right into the indep "ic.c", just because there doesn't seem to be
any elegant place to put it. (I don't think HAS_LIBCALLS is quite
what I'm looking for, unfortunately.)

After this change, "advent.c" will successfully compile AND assemble,
producing "advent.z8". You can even run it in an interpreter (I'm
using fizmo as my interpreter for now), and see it produce a sort of
lopsided version of Adventure --- a lot of things work, but there are
a LOT of bugs and glitches that don't appear in the gcc-compiled
version. My next task will be to track down and eradicate the
compiler bugs that I presume are responsible.

New changes to vbcc-patch.diff in this revision are:

    - In "ic.c", look for CALL-expressions like puts("hello")
      and replace them with calls to made-up inline_asm functions
      that will expand into the right thing, namely, a single
      @print opcode. This drastically cuts down on static data
      size, which means we can assemble larger C programs.
Fix a bunch of long/int format-string mismatches.

These mismatches showed up only on 32-bit systems, where they caused the
compiler to produce completely bogus Inform code: usually in the form of
variable names showing up as "(null)" because there was unexpectedly an
extra zero word on the stack from the previous "zlong" or "zmax" value.

On a 32-bit Ubuntu system:
  zmax is zllong is long long
  zlong is int(!)
  zint is short(!)
  zshort is short
  zchar is signed char

On a 64-bit Ubuntu system:
  zmax is zllong is long(!)
  zlong is int(!)
  zint is short(!)
  zchar is signed char

So basically vbcc likes to pretend that it's running on a 16-bit system
with 32-bit longs, but it will avoid using "long long" if "long" is
a 64-bit type already. What a mess.

In general, I am fixing this by using the plain old C types "short" and
"int". Since the Z-machine itself is only a 16-bit machine, there's no
reason ever to use "long" or "long long" in the backend.
Fix a bug in the generation of the __init_vars function.

The routine cleanup_cg() emits the __init_vars_<modulename>() function to
initialize all the static data containing pointers, since that can't be
done statically. It's using @storew instructions to store the data, but
it forgot to use word-offsets instead of byte-offsets: i.e., there was
a missing ">> 1".

After this change, the initial "Welcome to Colossal Cave!!" help-text
displays correctly. The turn-counter still displays as garbage when
you quit, though, and "xyzzy" from the Well House will take you to Y2
instead of to the debris room. That's a weird bug.
Squash stack usage to solve the biggest remaining Advent glitches.

vbcc may be an embedded compiler, but even at -O=3 it generates HUGE
stack frames! The first instruction of build_travel_table() was
    @sub xp 0+17610 -> xp;
That's right, vbcc thought build_travel_table() needed 17,610 bytes
of temporary storage, just for the scratch variables used in its
arithmetic expressions!

This revision adds a new backend routine, squash_stack_frame(),
which walks the IC, collects all the references to variables that
are actually accessed on the stack frame (which most are not, since
vbcc tries to allocate them to registers), and then squashes them
all down into a contiguous range. After this change, the first
instruction of build_travel_table() is
    @sub xp 0+992 -> xp;
In other words, vbcc's scratch-allocation algorithm is still abjectly
failing to merge all 248 scratch variables into the same stack slot,
but at least we're not wasting 16K on variables that never hit the
stack at all.

The absurd stack sizes were causing the stack pointer (xp) to
wander into the middle of the data section and overwrite random
things; hence all the glitches. Now that the stack sizes are more
under control, the glitches have vanished. Admittedly I don't know
how much stack the program uses in the worst case; I will have to
instrument it to find out, I guess.

After this revision, "advent.z8" is completely playable, although
there are still at least two bugs I need to flush out:
    * The SCORE command prints "out of a possible 1" instead
      of "out of a possible 350". This is a compiler bug.
    * At the bottom of the clean pit, GET STREAM causes a crash.
      This is a bug in my "advent.c".
Fix my off-by-one error in dealing with MAX_SPEC.

Knuth apparently leaves remarks[0] empty, and begins the remarks
table at remarks[1]. I had missed that, and started my remarks at 0,
which meant that the logic for when to print a remark was wrong,
because I had MAX_SPEC+0 meaning "print remark 0" at the same time
that it meant "go to R_TROLL".

This bug was exposed whenever the game should have printed remark 0,
which is the "you can't fit through a two-inch slit" message.
Cosmetic improvements to the source.

I probably should have done these three things in separate commits, but...

    - Remove trailing whitespace and convert tabs to spaces.

    - Add copious /* sections X--Y in Knuth */ comments, and
      fix the ones that were already there but incomplete.

    - Replace all instances of default_msg[] with the corresponding
      string literals. The default_msg[] array can now be removed.

Also factor out attempt_off() to make the main routine a little
smaller, just for cosmetic purposes.

This revision shouldn't change the game's behavior at all.
Remove the default_msg[] array, now that it's no longer needed.

Again, no change in game behavior.
Remove the hack for Inform bug C62105.

Actually it's still there, but under a switch (-patch-not) which is off
by default. This means we can compile C expressions containing "~" without
needing to provide a library function __not().

This code was working around a bug in Inform <6.30:
http://www.inform-fiction.org/patches/C62105.html
The bug is fixed in Inform 6.31 and 6.32, which are the versions of
Inform 6 that are currently available for Ubuntu Linux.
Fix two bugs related to "POUR BOTTLE".

The first bug appears in Knuth2002 but is fixed in Knuth2010: the
get_object message "%s what?" was not capitalizing its first letter.

The second bug was a typo on my part: POUR BOTTLE while carrying a
full bottle would yield "You aren't carrying it!" instead of
"Your bottle is empty and the ground is wet." This is now fixed.

Interestingly, POUR BOTTLE while carrying an empty bottle yields
"Bottle what?" instead of the slightly more proper "Pour what?".
This matches Knuth's version; I don't know what Woods' version
would print.
Add a copy of Parchment to the repository.

Typing "make parchment" will now copy advent.z8 into the parchment/
directory, so that you can run it by pointing your Web browser to
parchment/index.html (even in offline mode).

I acquired this copy of Parchment by packaging a dummy Inform 7
project for "release", and then switching out the project-specific
bits. Notice that index.html doesn't mention the Treaty of Babel
IFID for advent.z8; that's partly because it's a work in progress,
and partly because I'm not sure how to choose one. (I suspect that
it's just the md5sum of advent.z8, but maybe the Inform assembler
is inserting an IFID for me already.)

I've also added the commands SAVE and RESTO[re], which will eventually
do what it says on the tin, but for now are slightly broken. I need
to understand what the Z-machine means by "save" and "restore" first.
SAVE and RESTORE are not available in the gcc-compilable version,
because that's not a very interesting problem to me.
Fix a major backend bug with "stackparamadjust".

To compile a call to a variadic function, the middle-end generates
a series of PUSHes followed by a CALL. It doesn't generate any POPs;
it leaves that up to the backend.

We do need to generate POPs to get the stack pointer (that's "xp",
not "sp") back to its old value. If we left "xp" unbalanced, we'd
have problems with diamond-shaped control flow:

    if (foo)
        printf("%d", 42);  /* decrements xp by 2 */
    localvar = 1;  /* we need to know localvar's offset relative
                      to xp, but now that depends on foo! */

Before this revision, David Given's algorithm was to assume that
every CALL should reset xp's offset to zero. But this isn't true!
Consider:

    printf("You scored %d out of a possible %d.\n", score(), 350);

This corresponds to an IC of

    PUSH 350
    CALL _score -> r0
    PUSH r0
    ASSIGN "%d %d" -> r0
    CALL _printf

Given's algorithm caused printf to "forget" any parameters that
followed a parameter containing a function call!

Fortunately, Barthelmann's IC foresaw this problem and included
a field "arg_list" which lets us see exactly which PUSHes correspond
to function arguments of the present CALL. In the above example,
the "arg_cnt" of CALL _score would be 0 and that of CALL _printf
would be 3 (only two of which would point to PUSH instructions).
So after CALL _score, we'd do no fixup at all, because its arg_list
didn't point to any PUSHes. Problem solved!

This new algorithm for adjusting the stack seems to work in all
cases; certainly it solves the problem in say_score() to which I
alluded earlier.
Switch to C99. Update the README.

vbcc 0.7 (the version used by David Given's "Silicon Castles") didn't
support C99; vbcc 0.8 does. The only C99 feature I'm using is
for-loop initial declarations, but it's so worth it. (Oh, and C99
allows string literals to be really long, so I can remove
-Wno-overlength-strings from the GCC warning-suppression options.)

Also, update the README to be less self-deprecating now that the
program actually works. Mission pretty much Accomplished!

I think vbcc is still DOA on a 32-bit OS, though. I need to
investigate that... tomorrow.
Shorten the patch for the "stackparamadjust" bug (8e9d2cce).

Volker Barthelmann points out that the middle-end actually keeps track
of the total PUSHed bytes for us, in pushedargsize(ic_of_the_CALL).
So we don't need to recompute it ourselves.

No change in behavior.
Fix dwarves' initial locations.

I just totally skipped over the array initializer in Knuth's code!
No wonder the dwarves hadn't been showing up; they all started out
in R_LIMBO and never left it. With this change, it is finally possible
to die by sharp nasty knife. I haven't seen whether the pirate shows
up now or not.

New bug report: the Persian rug's initial description isn't showing
up (it "magically" appears only when you kill the dragon). I suspect
this one is also my fault, although it *could* be a compiler bug.
Oops! I'd gotten the Ming vase's behavior backwards.

Amusingly, both the comments and code were backwards (thus cancelling
 out the bug), except that the wrong object was immobilized. Once the
vase was safely dropped, you couldn't pick it back up; and if you broke
it, you could reconstitute it simply by entering the command "GET VASE".

This is now fixed.
Another typo. Dwarves aren't *that* good at knife-throwing!

I'd missed a zero in Knuth's version; ran(100) should have been ran(1000).
This makes the dwarves about one-tenth as likely to hit you with their
knives (9.5% instead of 95%, 19% instead of 100%). Whoops.