Skip to navigation

Revs on the BBC Micro

Text: PrintCharacter

Name: PrintCharacter [Show more] Type: Subroutine Category: Text Summary: Print a character on-screen
Context: See this subroutine in context in the source code References: This subroutine is called as follows: * Print2DigitBCD calls PrintCharacter * PrintDriverName calls PrintCharacter * PrintSpaces calls PrintCharacter * PrintTimer calls PrintCharacter * PrintToken calls PrintCharacter * PrintGearNumber calls via PrintCharacter-6

Arguments: A Character number (ASCII code, 0 to 159) printMode Bit 7 determines how the character is printed on-screen: * 0 = poke the character directly into screen memory (for the custom screen mode) * 1 = print the character with OSWRCH (for mode 7) (xCursor, yCursor) For the custom screen only, this is the coordinate where we should print the character, where xCursor is the character column and yCursor is the pixel row of the bottom of the character
Returns: A A is unchanged
Other entry points: PrintCharacter-6 Print double-width character (this is used to print the double-width number on the gear stick) The routine must be called twice to print double-width characters, which are drawn as follows: * Bit 7 of W is set = draw the right half * Bit 7 of W is clear = draw the left half W must be non-zero when the routine is called on this entry point, otherwise the routine will print characters at the normal width
STA characterDef \ Store the character number in characterDef JMP char1 \ Jump to char1 to skip the printMode check and use the \ current value of W .PrintCharacter BIT printMode \ If bit 7 of printMode is set, jump to char8 to print BMI char8 \ the character in A with OSWRCH STA characterDef \ Store the character number in characterDef LDA #0 \ Set W = 0 to indicate we should print a single-width STA W \ character .char1 TXA \ Store X and Y on the stack so we can retrieve them PHA \ after we have printed the character TYA PHA LDY #HI(characterDef) \ Call OSWORD with A = 10 and (Y X) = characterDef, LDX #LO(characterDef) \ which puts the character definition for the specified LDA #10 \ character into characterDef+1 to characterDef+8 JSR OSWORD LDA W \ If W = 0, jump to char5 to skip the following BEQ char5 \ If we get here, then W is non-zero, so we now update \ the character definition to contain just one half of \ the character in the left half of the character \ definition, as follows: \ \ * If bit 7 of W is set, put the right half of the \ character into left half of the character \ definition \ \ * If bit 7 of W is clear, put the left half of the \ character into left half of the character \ definition LDX #8 \ We are now going to work our way through each pixel \ row of the character definition, so set X as a loop \ counter for each byte in the character definition .char2 LDA characterDef,X \ Set A to the bitmap for the X-th row of the character \ definition BIT W \ If bit 7 of W is set, jump to char3 to skip the next BMI char3 \ two instructions AND #%11110000 \ Clear the four pixels in the right half of the pixel JMP char4 \ row .char3 ASL A \ Shift A to the left so the right half of the pixel ASL A \ row moves to the left half ASL A ASL A .char4 STA characterDef,X \ Store the updated pixel row byte in the X-th row of \ the character definition DEX \ Decrement the row counter BNE char2 \ Loop back until we have processed all eight rows in \ the character definition .char5 LDY yCursor \ Set (Q P) to the screen address of the character block LDA xCursor \ containing character column xCursor and pixel row JSR GetScreenAddress-2 \ yCursor, and set Y to the pixel row number within that \ block \ \ As yCursor is the pixel row of the bottom of where we \ should print the character, (Q P) now points to the \ address where the bottom pixel row of the character \ should go LDX #8 \ We are now going to work our way through each pixel \ row of the character definition, poking each row to \ screen memory, from the bottom row of the character \ to the top, so set a counter in X for eight rows .char6 LDA characterDef,X \ Store the X-th row of the character definition in the STA (P),Y \ Y-th byte of (Q P) DEY \ Decrement the pixel row number to point to the row \ above BPL char7 \ If Y is positive then we are still within the \ character block, so jump to char7 LDA P \ Otherwise we need to move to the bottom pixel row of SEC \ the character row above, so set: SBC #&40 \ STA P \ (Q P) = (Q P) - &140 \ \ starting with the low bytes LDA Q \ And then the high bytes, so (Q P) contains the screen SBC #1 \ address of the character block above (as each STA Q \ character row contains &140 bytes) LDY #7 \ Set Y = 7 to point to the bottom pixel row in the new \ character block .char7 DEX \ Decrement the character pixel row counter BNE char6 \ Loop back to poke the next row into screen memory \ until we have poked all eight rows INC xCursor \ Move the cursor to the right by one character, as we \ have just printed a full character PLA \ Retrieve X and Y from the stack TAY PLA TAX LDA characterDef \ Set A to the character number, so A is unchanged by \ the routine RTS \ Return from the subroutine .char8 JSR OSWRCH \ Print the character in A RTS \ Return from the subroutine