I was looking over an old game in a hex editor recently, and I noticed something interesting with the text data embedded in the program. All of the strings seemed fine until the end character, which was a byte value of 128 or greater.
I realized what the program was doing was using the top bit on ASCII characters to determine the string end. This lets you store strings at their exact size, rather than one byte more to store either a length byte or a null terminator byte. Very clever!
So I thought, how to leverage this on the TI, where I've spent a considerable amount of effort building menus and interfaces that consumed a lot of memory because of having to store strings and their addresses and lengths?
So I write a routine, VTEXT, and it's companion, VTEXTC. It's a subroutine that takes the address on screen into R0, and a pointer to the desired text in R1. No length needed! It writes to the screen until it encounters the eighth bit, and stops.
VTEXTC is the same, except it doesn't alter the VDP address. This will allow you to write concurrent strings to the screen one after the other.
- Your text strings take up exactly their length in space
- Reduced operations for plotting text to screen
- All static text in source files has to end with the top bit set, which can be aggravating to figure out the value of a given ASCII character
- Slower than a straight VMBW due to the need for a COC and copy operation on every character
- If you don't have the top bit set, it could overrun the screen buffer and the rest of VDP
Future expansion may include the idea of "values". Using characters 0-31 can be used as an indicator to, for example, switch to a stored numeric value in text form, so you can introduce string formatting. "%0 takes %1 damage!" for example, so it knows to plug in the 0 and 1 pre-calculated values into the string as it's writing to the screen.
TOPBIT DATA >8000 * Top bit word VDPWA EQU >8C02 * VDP Write address port VDPRD EQU >8800 * VDP Read address port VDPWD EQU >8C00 * VDP access port (input/output) SCRADR EQU >0000 * Screen address TXTLN1 TEXT 'This is sample tex' BYTE 244 TEXT 'More sample tex' BYTE 244 TEXT 'Sample Tex' BYTE 244 TEXT '-Sample Tex' BYTE 244 * Video Text writer, CPU to VDP * Uses only R0 and R1 for location, length is determined by the top bit * Sends R1 value back to calling rouine for continuous stream of text * VTEXTC does not update position in VDP, so you can write multiple strings concurrently VTEXT ORI R0,>4000 * Set address for VDP write SWPB R0 * Swap to low byte MOVB R0,@VDPWA * Move to VDP address SWPB R0 * Swap MOVB R0,@VDPWA * Move to VDP address ANDI R0,>3FFF * remove extra bit so address is preserved for subsequent calls VTEXTC MOVB *R1+,R2 * Copy character to R2 COC @TOPBIT,R2 * Check if top bit is set (end of line indicator) JEQ VTEXT1 * If so, skip to end MOVB R2,@VDPWD * Write character to screen JMP VTEXTC * Loop VTEXT1 ANDI R2,>7F00 * Reset top bit on character MOVB R2,@VDPWD * Write to screen RT * return to calling program * Example LI R0,SCRADR+128 * Set R0 to SCRADR+128 LI R1,TXTLN1 * Set R1 to start of text BL @VTEXT * Write string to screen AI R0,32 * Add 32 to screen position BL @VTEXT * Write a second line of the text LI R0,SCRADR+256 * Change R0 to a different position BL @VTEXT * Write next line to screen BL @VTEXTC * Write the next text segment immediately after the prior * Program continues...