TEXT FORMATTER This is a simple machine code program that will format text on the screen. The program should be loaded below 32768 (&8000). I normally load it at 16384 (&4000), although MasterBasic users may need to shorten the text area to prevent stack errors. Throughout, I have used syntax for the Comet assembler, but users of other assemblers should have no problem converting the source. To start with, we define the ROM routines that are going to be used by this program. JSETSTRM: EQU &0112 ; This routine sets up the current stream. JCLSLOWER: EQU &0151 ; This routine clears the input area. JREADKEY: EQU &0169 ; This routine reads a key from the keyboard buffer. We then set up the system variables that will be used by the program. UWRHS: EQU &5A38 ; The right-hand side of the upper window. UWLHS: EQU &5A39 ; The left-hand side of the upper window. UWTOP: EQU &5A3A ; The top of the upper window. UWBOT: EQU &5A3B ; The bottom of the upper window. SPOSNU: EQU &5A6C ; The current position in the upper window. Next come the variables that will be used by the program. TEXT: DEFS 512 ; The text storage area. WORKSPACE: DEFS 32 ; Workspace used by the program to store the current word. MORETEXT: DEFM "More..." ; Text printed when the print area is filled. LINE: DEFB 0 ; Line count. OLD_Y: DEFB 0 ; Y position after the previous word was printed. NEW_LINE: DEFB 0 ; Flag whether new line is needed. TEXTFLAG: DEFB 0 ; Flag whether some text has been printed. Now we start on the program. Firstly, we deal with the main loop. SPLSTR: LD A,&FE CALL JSETSTRM LD DE,WORKSPACE LD HL,TEXT The above section sets up the current stream, and sets DE and HL to point to the work area and text area respectively. GETLOOP: LD A,(HL) CP 130 CALL Z,RETURN CP 32 JR Z,PRTTEXT2 CP 0 JR Z,ENDIT LD (DE),A NEXTCHAR: INC HL INC DE JR GETLOOP This section reads a word from the text area, one character at a time. If character 130 (E Acute) is read in, a routine is called to print a return character. If character 32 (SPACE) is read in, the program jumps to print the word. If character 0 is read in, the program jumps to the end of the string. Otherwise, the character is placed in the work area, HL and DE are incremented, and the program jumps back to read in the next character. RETURN: PUSH HL CALL PRTTEXT LD A,(NEW_LINE) CP 0 JR NZ,NO_RETURN CALL CHKLINE LD A,13 RST 16 NO_RETURN: XOR A LD (NEW_LINE),A LD (TEXTFLAG),A POP HL LD DE,WORKSPACE INC HL LD A,(HL) CP 130 JR Z,RETURN RET This routine prints the current word, followed by a return character. If the new line flag is set, a return character is not printed as it is not needed. The new line flag is then reset, along with the text printed flag. HL and DE are then restored to the correct values, and the next character in the text area is checked. If this character is 130, the program jumps back to the start of this routine. Otherwise, it returns to the main loop to process the character accordingly. PRTTEXT2: CALL PRTTEXT JR NEXTCHAR This is a simple dummy routine to print the current word and return to continue processing the text area. ENDIT: CALL PRTTEXT LD A,(TEXTFLAG) CP 0 RET Z LD A,(SPOSNU) LD B,A LD A,(UWRHS) CP B RET NC LD A,13 RST 16 XOR A INC A LD (NEW_LINE),A RET This routine processes the last word in the text area, and then checks the current position. If it is beyond the right-hand side of the print area, then a return character is printed, and the new line flag is set to 1. The routine then exits out of the machine code and back to Basic. PRTTEXT: PUSH HL LD A,(SPOSNU+1) LD (OLD_Y),A EX DE,HL LD DE,WORKSPACE SCF CCF SBC HL,DE JR Z,NOTEXT XOR A INC A LD (TEXTFLAG),A CALL CHKLENGTH PUSH HL POP BC LD DE,WORKSPACE CALL &0013 LD A,(SPOSNU) LD B,A LD A,(UWRHS) CP B JR C,NOTEXT LD A,32 RST 16 NOTEXT: POP HL LD DE,WORKSPACE-1 RET This routine prints the current word on the screen. It first stores the current y position, and then works out the length of the current word. The text printed flag is set, and a routine is called which checks whether the word will fit on the current line, then the word is printed using the ROM routine at &0013. The current position is then checked against the right-hand side of the print area. If they are not equal, a space character is printed. HL and DE are then restored to the correct values, and the program returns to the calling routine. CHKLENGTH: LD A,(SPOSNU) ADD L LD B,A LD A,(UWRHS) INC A CP B JR NC,LENGTHOK PUSH HL CALL CHKLINE LD A,13 RST 16 POP HL LENGTHOK: RET This routine checks whether the current word will fit on the current line. If not, a routine is called that will check whether we have filled the print area with text. A return character is then printed, and the program returns to the calling routine. CHKLINE: LD A,(LINE) INC A LD B,A LD A,(UWBOT) CP B JR NC,LINEOK LD A,&FD CALL JSETSTRM LD DE,MORETEXT LD BC,7 CALL &0013 CALL GET_KEY CALL JCLSLOWER LD A,&FE CALL JSETSTRM LD A,(UWTOP) INC A LD B,A LINEOK: LD A,B LD (LINE),A RET This routine checks whether the line count is equal to the bottom of the print area. If it is, the current stream is changed to the lower screen, the "More..." prompt is displayed, and the program waits for you to press a key. The lower screen is then cleared, and the current stream changed back to the upper screen. The line count is then set to the top of the print area, and the program returns to the calling routine. GET_KEY: CALL JREADKEY JR NZ,GET_KEY GET_KEY_2: CALL JREADKEY JR Z,GET_KEY_2 RET This short routine waits for you to press a key. It first waits until no key is being pressed. This is to ensure that it doesn't pick up any stray key presses. The routine SPLSTR should be called with the string to be printed in TEXT. The string should be terminated with character 0. Character 130 should be used as a return code. LINE should be initially set to the top line of the print area (UWTOP or PEEK &5A3A).