Fixes to build and play on OpenVMS x86#9
Open
jhamby wants to merge 7 commits intotesneddon:masterfrom
Open
Conversation
Add a MACRO-32 version of the variable-argument-list wrapper that was originally written in MACRO-32 and then converted to BLISS, presumably for portability. Unfortunately, the x86 version of the BLISS compiler isn't ready yet, and it's just as efficient to have MACRO-32 generate the argument list from the register params, especially since there can be so many of them (up to 9 for ifc$message or 7 for ifc$message_indent). Besides this change, there was a bug in reading objects, like the sign in the first room, or the ASCII table in the second room, because the call to ifc$message() had some extra "0, 0" parameters for some reason. This caused it to print "The sign reads:" but then nothing after that. With these diffs, the game should now build and play on OpenVMS V9.2-1.
My workaround to get messages printing by removing pairs of 0, 0 params wasn't correct. The code is supposed to print a blank line when it sees those. The reason it's failing on x86 is due to a VSI Pascal compiler bug with default parameters causing bad behavior at the default optimization level. I'm going to try to work around the bug by modifying function put_scroll_dx to not use "[truncate]".
The VSI Pascal compiler on x86 is generating bad code when default params are used. This was causing some game messages not to print because of embedded blank lines (a pair of 0 params in the ifc$message call) causing put_scroll_dx to be called with no arguments, which was stopping the rest of the message from being printed. I reproduced the bad behavior with a standalone Pascal test program that checks the presence of its parameters and prints them if present. It behaves correctly when compiled with "/NoOpt" but crashes with the default optimization level. I've reported this issue on the VSI Forum. As a workaround, commented out the "[truncate]" modifier on all three parameters, and passed default params in the one location where it was being called with no arguments (the case that was failing). This fixes the game text.
For the arg pointer wrappers now in ifc/ifcrtl_macro.mar, we need to copy up to 9 args for ifc$message (read_start_record in zk/zkinit.pas), and up to 7 args for ifc$message_indent (zk$print_ast in zk/zkast.pas). Save a few clock cycles and memory copies by reducing MAX_ARG from 10.
Initialize the card_ptr field in the context record so that the game can save its state without getting an ACCVIO in write_context_record.
The no-longer-documented MTH$RANDOM returns its result in VAX FP format. The game gives array index exceptions because it's expecting IEEE values (on non-VAX). Changed to use Pascal's RANDOM function, which returns the same range.
Use Pascal RANDOM and not MTH$RANDOM.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
I ran into a few tricky issues getting this code to compile and run correctly on x86. I've resolved them in this PR.
Lacking a BLISS compiler, I rewrote the wrapper code that converts the $message and $message_indent calls to pass the arguments as a list to the Pascal implementations. On non-VAX, the compiler has to make a fake argument block to pass to the callee since the first 6 arguments are passed in registers. I figured out what the original MACRO-32 code must've looked like and wrote my own version to use in place of the BLISS version, which was itself rewritten from MACRO-32. It looks like the game code uses up to 9 params for $message calls and up to 7 params for $message_indent calls, but I set MAX_ARGS to 10 for both wrappers to be on the safe side.
Hacked zk/zklink_time.pas to never print a negative number for version, which caused a build failure for me. I haven't looked yet to see why it calculated -48 for the version.
The bug that caused me the most grief was messages like the sign in the first room not printing. I saw "The sign reads:" and then nothing. My first commit was to remove pairs of "0, 0" params in the $message lines that had those, which caused the sign to start printing, but I realized those "0, 0" pairs were supposed to print a blank line. It turns out the VSI Pascal compiler is generated bad code when you use the optional parameters feature ("truncate"). The shortest fix was to modify the one call to put_scroll_dx with no parameters (the one to print a blank line that was failing) to pass all three parameters, with an empty descriptor.
With these changes, now I can play ZK.