This is the eighth part in a series of posts on digging into the code of the Acornsoft side-scrolling arcade game, Rocket Raid.
Text Input and Output
In this post we'll look at routines used for displaying standard text on screen using OSWRCH (the standard operating system routine for writing a character) and for gathering text input from the user by making a call to OSWORD. In Rocket Raid these are used mainly for displaying screens relating to the Hall of Fame.
String Representation
Rocket Raid stores text strings in memory in two different formats: the first, which the author refers to as an "ATOM" string in his book, is a string of characters followed by a RETURN character (&0D); the second, which the author calls a Microsoft string, is where the length of the string is placed in the first byte, followed by the characters of the string.
Accordingly, the game contains two separate routines to handle printing each type of string. These are identical to the routines published in Creative Assembler.
"Microsoft" string print routine
A Microsoft string consists of the length of the string as the first byte, followed by the characters of the string. The game uses this format for storing the text of the congratulatory screen displayed to the user if their score has qualified for the Top Eight.
Before calling this routine the address of the string to print should be stored in X and Y.
BeebDis labels:
stringPtr $0000
stringPtr+1 $0001
stringLen $0002
printMicrosoftString $069B
printNextChar $06A6
Disassembly:
.printMicrosoftString
STX stringPtr ;
STY stringPtr+1 ; Store addr of string to print
LDY #$00 ;
LDA (stringPtr),Y ; Fetch length (first byte)
STA stringLen ; Store length of string
INY ; Move to first character
.printNextChar
LDA (stringPtr),Y ; Fetch character to print
JSR OSWRCH ; Print character
INY ; Move to next character
CPY stringLen ;
BNE printNextChar ; Loop until length reached
RTS
"ATOM" string print routine
An ATOM string is a string of characters followed by a RETURN character (&0D). The game uses this format for storing and printing short strings, such as when displaying the names in the Top Eight high score table.
The routine is very similar to the Microsoft string printing routine and, similarly, before calling this routine the address of the string to print should be stored in X and Y.
BeebDis labels:
printAtomString $06B1
printNextAtomChar $06B7
Disassembly:
.printAtomString
STX stringPtr ;
STY stringPtr+1 ; Store addr of string to print
LDY #$00 ; Start from first char
.printNextAtomChar
LDA (stringPtr),Y ; Fetch character to print
JSR OSWRCH ; Print character
INY ; Move to next character
CMP #$0D ; Check for a RETURN character
BNE printNextAtomChar; If not found, loop back
RTS
Printing a BCD (Binary-Coded Decimal) Number
One other routine we will cover here is for printing numbers that have been stored as binary-coded decimals. This will be used for printing the scores in the high-score table. Each score is stored as a three-byte BCD number, where each byte encodes two digits of 4 bits each. This means that the maximum score achievable in the game is 999999.
This number printing routine is also contained in the author's book. Before calling the routine, A should be set to the BCD number to be printed, and Y is a "leading character suppression" flag to indicate whether the padding character (".") should be output if a leading zero is found.
The routine reuses the same logic for printing both "halves" of the BCD number by manipulating to ensure that the lower four bits of the A register are set to the single number to be printed.
BeebDis labels:
printBCDNumber $1D41
printDigit $1D4C
validChar $1D51
padLeading $1D58
Disassembly:
.printBCDNumber
PHA ; Save number to stack
LSR A ;
LSR A ;
LSR A ;
LSR A ; Shift 4 bits right to get first BCD digit
JSR printDigit ; Print first digit
PLA ; Retrieve number from stack
AND #$0F ; Keep only second digit
.printDigit
BNE validChar ; If digit is non-zero, jump to print
TYA ; Otherwise, is zero-padding enabled?
BNE padLeading ; If so, then jump ahead to pad
.validChar
LDY #$00 ; Clear padding flag
ORA #$30 ; Add 48 to get ASCII value of number,
JMP OSWRCH ; print it and return.
.padLeading
LDA #$2E ; Get ASCII value of "."
JMP OSWRCH ; Print it and return.
Text Input
A line of text can be read from the keyboard by making a call to OSWORD with register A set to zero to select the "read from input" routine. Registers X and Y should be set to an address of a five-byte "parameter block" in memory which holds the following information:
- (two bytes) The address of a buffer to hold the input
- (one byte) Maximum input length accepted, in characters
- (one byte) Minimum valid ASCII character value
- (one byte) Maximum valid ASCII character value
The OSWORD routine can now be called:
JSR OSWORD
On returning from this routine, the zero-carry flag (C) will be set if the input was terminated by the user pressing RETURN; if instead they hit the Escape key to terminate input, it will be cleared.