80-Bus News


April–June 1982, Volume 1, Issue 2

Page 27 of 55

The last work space is the stack space. This started at 30H bytes long. Having written the program I then loaded it under the debugging tool, filled the stack space with 00’s and ran the game some half a dozen times, trying all combinations of winning and losing. Having done that, I stopped the game and examined the stack space to see how many of my 00’s had been overwritten. Eighteen bytes had been overwritten, indicating a stack depth of 9 (as each stack operation takes two bytes) so I set the stack space to 18 (12H). As I haven’t tried the NAS version I don’t know if it requires more stack space, although it’s unlikely. Anyway I’ve deliberately placed the stack next to CHRTRD, and that will always have some spare space in the end of it, so the stack can probably come down something like 24 bytes without crashing into the used part of CHRTRD.

Next comes the messages. I’ve had to write my own string output routine as I am can’t use the string displaying facilities of either NAS or CP/M because I’ve restricted my output patch to single character by character operation. My string print routine is a simple little subroutine buried somewhere towards the end of the program and labelled SNDTXT. The way this works is to ‘point’ HL at the start of a string of text and call SNDTXT. SNDTXT then marches through the text byte by byte directing it out through the output patch. When SNDTXT encounters a 00 it stops and returns to the next instruction in the main program. The choice of 00 as a text delimiter was deliberate, as it is very easy to test for. Having loaded a character into A, A is ORed with itself, now if this is anything other that 00, the character is unchanged and the Z flag is reset. If it is 00, then the Z flag is set. In fact I’ve used this scheme of using 00 as a delimiter throughout the program, for marking the end of CHRTRD and WBUF. You might like to note that ORing A with itself will also always clear the C flag. Handy thing to remember if the C flag starts getting in the way of some arithmetic operation at any time. Anyway, using 00 as a delimiter makes life very easy.

You might have noticed that the messages do not contain any ‘newlines’ within them, although MSG1 and MSG2 could easily have been run together in this fashion. This is because the NAS version requires only 0DH to be sent, whilst the CP/M version requires 0DH 0AH. By making the ‘newline’ a small message in its own right, it is easily patched. The penalty is that the program ‘grows’ bit, as additional calls have to be made to display the ‘newlines’. To rationalize the additional calls to send newlines I’ve written pair of ‘nested’ subroutines called CRLF1 and CRLF2. CRLF simply points HL to the newline message then calls SNDTXT, hence one newline is sent. CRLF2 calls CRLF1 and then drops through to CRLF1, hence two newlines are sent.

The next bit is obvious, set the stack, then on to initializing the workspaces. XORing A with itself will always result in A being 00 and the Z flag being set, a simple one byte method of clearing A. The 00 thus generated is put in TRYS, to set it to 0 and into the first space in CHRTRD, because it is empty and 00 is the delimiter. Then comes the displaying of the title using SNDTXT bit. I require two newlines after the title, so CRLF2 is called.

Now comes the picking of a word from the table of words. The first thing is to pick a random number. A subroutine is used to do this (even though it’s only used once within the loop) as this is a stand alone module. All it needs to know is where the three byte workspace RING is located, and for A to contain the maximum number (n) on entry to the subroutine. It returns A containing a random number between 0 and n-1. It’s a rather complicated routine and I’m going to gloss over it until some later episode when I’ve worked out what makes it tick. Having chosen a random number, the next thing is to locate the word picked, from the start of the word table. This is done by putting the number in B, pointing HL to the start of the words and testing them byte for byte. If the character picked up is a letter then it is ignored. Where the character is an 00, then the little test mentioned above detects this and the character is counted by the DJNZ instruction. Effectively, this counts the 00 word delimiters downwards from n to 0 in B.

Page 27 of 55