I created routine for printing strings that terminate with EOS in the post “6502, Printing, Pointers and Subroutines“. I also created one for printing strings that terminate with EOL. The routine to print EOS terminated strings (PRTCH) loops through the string printing one character at a time via CIO until it reaches EOS. Because there is no EOL the cursor retains its position on screen at the end of the text so a subsequent print will start at that position. Useful for printing variables in sentence form such as :
Hello variable, Welcome!
The routine to print EOL terminated strings (PRTLN) prints the entire string with one CIO call. The result is a slightly faster print but at the cost of EOL being printed as well, which causes the cursor to position on the next line. Using the previous example, output of a variable in a sentence would result in:
Hello variable , Welcome!
Not very desirable, which is why I created two routines. The one to print an EOS terminated string (PRTCH) is working as designed but not as desired. I found that it would overrun the end of the string if it was passed a string terminated with EOL instead. Sounds like programmer error, but there are instances where it becomes useful to pass and EOL terminated string to the looped printing call. One example is allowing string manipulation routines to always terminate with EOL which can make life easier for the programmer.
Print EOS (or EOL) Terminated String (PRTCH)
I updated the PRTCH routine so that it will also stop printing if EOL is encountered. It has been incorporated into a library since it was originally written. Here is the new code:
0100 ; Storage & Pointers 0110 PRINDX *= *+1 0120 PRSPTR = $CC 5000 ; ------------------------------ 5001 ; Desc: Print String (EOS Term) 5002 ; Parm: A=H byte of string addr 5003 ; X=L byte of string addr 5004 ; ------------------------------ 5009 PRTCH 5010 ; Store Starting String Address 5015 STX PRSPTR 5020 STA PRSPTR+1 5025 LDA #$00 5030 STA PRINDX 5035 ; Set IOCB Command 5040 LDX #$00 5045 LDA #$0B 5050 STA ICCOM,X 5055 ; Set Max Buffer Length 5060 LDA #$00 5065 STA ICBLL,X 5070 STA ICBLH,X 5080 ; Call CIO to Print 5085 PRCHLP LDY PRINDX 5090 LDA (PRSPTR),Y 5095 BEQ PRCHDN 5096 CMP #EOL 5097 BEQ PRCHDN 5100 JSR CIOV 5105 INC PRINDX 5110 BNE PRCHLP 5115 PRCHDN RTS
Breakdown
I’ll only document the changed lines of this routine:
- Line 110: Reserve space for the print index of the string. This was previously declared in the test program but now resides in the library code.
- Line 120: Page 0 storage space for the string to be printed address. This was previously declared in the test program but now resides in the library code.
- Line 5096: Compare the current string character (in the accumulator) with the value EOL
- Line 5097: If the comparison was equal (current character = EOL) branch to PRCHDN (end of the routine).
Print EOL Terminated String (PRTLN)
It occurred to me that I have not posted about this library function. As mentioned this routine prints the entire string in one CIO call. That includes the EOL.
5200 ; ------------------------------ 5201 ; Desc: Print Line (EOL Term) 5202 ; Parm: A=H byte of string addr 5203 ; Y=L byte of string addr 5204 ; ------------------------------ 5209 PRTLN 5210 ; Store Starting String Address 5215 LDX #$00 5220 STA ICBAH,X 5225 TYA 5230 STA ICBAL,X 5235 ; Set IOCB Command 5240 LDA #$09 5245 STA ICCOM,X 5250 ; Set Max Buffer Length 5255 LDA #$00 5260 STA ICBLH,X 5262 LDA #$FF 5265 STA ICBLL,X 5270 ; Call CIO to Print 5275 JSR CIOV 5280 RTS
Breakdown of PRTLN
This is also now part of my library. It does not need the PRSPTR or PRINDX variables like PRTCH does.
- Line 5215: Load the X register with value 0.
- Line 5220: Store the accumulator at the X offset of ICBAH (the high byte of the string address to be printed).
- Line 5225: Transfer the Y register to the accumulator (Y is holding the low byte of the string address to be printed).
- Line 5230: Store the accumulator at the X offset of ICBAL (the low byte of the string address to be printed).
- Line 5240: Load the accumulator with value 9 (IOCB print text record).
- Line 5245: Store the accumulator in ICCOM (IOCB command).
- Line 5255: Load the accumulator with value 0.
- Line 5260: Store the accumulator at the X offset of ICBLH (high byte of the max buffer length). For my purposes the string will always be less then 256 characters so this byte should always be 0.
- Line 5262: Load the accumulator with value 255 ($FF).
- Line 5265: Store the accumulator at the X offset of ICBLL (low byte of the max buffer length). For my purposes the string will always be 255 characters or less.
- Line 5275: Call CIO to do the print.
- Line 5280: Exit function.
Results
I tested the routines in a program I’m writing and they work as designed, and now, as desired. I don’t have any output to show, and they are working right. I will reveal it later as I progress.
In this screenshot you can see two strings input (both terminated with EOL) and then output, one with the print routine PRTCH (EOS) and one with the print routine PRTLN (EOL). Both work as they should.
I’ve also squashed my last bug in the string to integer routine. I’ll discuss that in the post.