Saturday 6 December 2014

Rocket Raid Under the Hood 8: Text Input and Output

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.



No comments:

Post a Comment