I found the problem that is causing the string to integer routine to fail. It’s actually two-fold. I’m addressing the first part here.
Problem
The conversion routine was overrunning the input string. It was looking for EOL while the input string routine was terminating the string with EOS.
Earlier I wrote a string input routine, (6502, String Input), but at the time I wanted it terminated with EOS to prevent a carriage return from being output if the string is printed. Fair enough. For the same routine to be compatible with the string to integer routine a modification was needed.
New Code
I revised the string input routine. It now accepts three parameters, the 3rd being which termination character to append. This gets stored in the Y register before calling the string input routine. The string input routine saves the Y register in the 2nd IOCB auxiliary byte (ICAX2, location $0351) since the Y register will be disturbed through the CIO call it executes. At the end of the routine, it pulls the value from the auxiliary byte and tacks it onto the string.
Here is the new INPSTR function assembly code:
7000 ; ------------------------------ 7001 ; Desc: Input String 7002 ; Parm: A=H byte of string addr 7003 ; X=L byte of string addr 7004 ; Y=String Term Char 7005 ; ------------------------------ 7009 INPSTR 7010 ; Store Starting String Address 7012 STX ICBAL 7014 STA ICBAH 7016 STY ICAX2 7025 ; Store Str Address in P0 Ptr 7030 STX INSPTR 7035 STA INSPTR+1 7040 ; Set IOCB Command 7045 LDX #$00 7050 LDA #$05 ; Get Record 7055 STA ICCOM,X 7060 ; Set Max Buffer Length 7065 LDA #30 7070 STA ICBLL,X 7075 LDA #0 7080 STA ICBLH,X 7085 ; Call CIO to Print 7090 JSR CIOV 7095 ; Get # chars input 7100 LDY ICBLL 7105 ; Reduce char count by 1 7110 DEY 7115 ; Store EOS at EOL position 7118 LDX #0 7120 LDA ICAX2,X 7125 STA (INSPTR),Y 7130 RTS
The following lines are noteworthy, and are the extent of the changes to the original routine:
- 7016: Stores the Y register in location ICAX2.
- 7118: Loads the X register with 0. The offset from ICAX2 that the Y register was stored in.
- 7120: Load the accumulator from the X byte offset of address ICAX2. Since x is 0, it will load from address ICAX2.
Since I wrote the original code I started using include files to manage definitions, functions, and macros. If you look at the previous string input post, the code above replaces lines 7000 through 7160. For the new input string test code, it is included from “A8FUNCS.LIB”.
Here is the new string input test code. I apologize for the lack of inline comments but I break it down afterward:
10 *= $3600 20 .INCLUDE #D2:A8DEFS.LIB 0300 ; TEST PRINTING 0302 TEST 0310 LDA #SCLR/256 0312 LDX #SCLR&255 0314 JSR PRTCH 0320 LDX #0 0322 LDY #0 0324 JSR CURXY 0326 LDA #SRULE/256 0328 LDX #SRULE&255 0330 JSR PRTCH 0340 LDX #0 0342 LDY #2 0344 JSR CURXY 0350 LDA #SP1/256 0352 LDX #SP1&255 0354 JSR PRTCH 0360 LDA #VSNAME/256 0362 LDX #VSNAME&255 0364 LDY #EOS 0366 JSR INPSTR 0370 LDX #0 0372 LDY #3 0374 JSR CURXY 0380 LDA #SP2/256 0382 LDX #SP2&255 0384 JSR PRTCH 0390 LDA #VSNAM2/256 0392 LDX #VSNAM2&255 0394 LDY #EOL 0396 JSR INPSTR 0460 LDX #0 0470 LDY #5 0480 JSR CURXY 0490 LDA #SP3/256 0500 LDX #SP3&255 0510 JSR PRTCH 0520 LDA #VSNAME/256 0530 LDX #VSNAME&255 0540 JSR PRTCH 0550 LDA #SWELC/256 0560 LDX #SWELC&255 0570 JSR PRTCH 0700 LDX #0 0710 LDY #7 0720 JSR CURXY 0730 LDA #SP3/256 0732 LDX #SP3&255 0734 JSR PRTCH 0736 LDA #VSNAM2/256 0738 LDX #VSNAM2&255 0740 JSR PRTCH 0750 LDA #SWELC/256 0752 LDX #SWELC&255 0754 JSR PRTCH 0990 RTS 010000 ; STRING DATA 010001 SCLR .BYTE CLS 010002 SRULE .BYTE "-|Input|--------------------------------",EOS 010005 SP1 .BYTE "Name (EOS)?",EOS 010007 SP2 .BYTE "Name (EOL)?",EOS 010010 SP3 .BYTE "Hello ",EOS 010020 SWELC .BYTE ", Welcome!",EOS 010050 VSNAME *= *+30 010060 VSNAM2 *= *+30 063500 .INCLUDE #D2:A8FUNCS.LIB 064000 .END
Breakdown
The highlighted lines the important differences between the new input test code and the original input test code.
- Line 10: Set the program loading address to $3600.
- Line 20: Include file to pull in standard definitions from the library “A8DEFS.LIB”.
- Lines 310 to 316: Clears the screen
- Lines 320 to 324: Moves the cursor to position 0,0 (upper left corner) of the screen.
- Lines 326 to 330: Prints the screen header.
- Lines 340 to 344: Moves the cursor to position 2,0 (column 0, row 2) of the screen.
- Lines 350 to 354: Prints the “Name (EOS)?” prompt.
- Lines 360 to 366: Gets the first string from the user. Note in line 364 the Y register is loaded with EOS. #EOS is specified so the value EOS is stored instead of the value of memory location designated by EOS (0).
- Lines 370 to 374: Moves the cursor to position 3,0 (column 0, row 2) of the screen.
- Lines 380 to 384: Prints the “Name (EOL)?” prompt.
- Lines 390 to 396: Gets the second string from the user. Note in line 394 the Y register is loaded with EOS.
- Lines 460 to 480: Moves the cursor to position 5,0 (column 0, row 5) of the screen.
- Lines 490 to 510: Prints the “Hello ” portion of the output message.
- Lines 520 to 540: Prints the first input string. Notice there is no positioning done as we want the string printed at the last position the cursor was at.
- Lines 550 to 570: Prints the “, Welcome!” portion of the output message. Again, there was no positioning done so the message would be printed at the last cursor position.
- Lines 700 to 720: Moves the cursor to position 7,0 (column 0, row 7) of the screen.
- Lines 730 to 734: Prints the “Hello ” portion of the output message.
- Lines 736 to 740: Prints the second input string. Notice there is no positioning.
- Lines 750 to 754: Prints the “, Welcome!” portion of the output message. Again, no positioning.
- Line 990: Exit
- Lines 10001 to 10020: Definitions for the output messages.
- Lines 10050 to 10060: Buffer space reservation for the input strings.
- Lines 63500: Include file to pull in the INPSTR routine from the library “A8FUNCS.LIB”.
Output
The test code above asks for two names. The first is terminated with EOS, the second is terminated with EOL. It then prints both out in single line message form. As you can see the first name is printed inline with the complete message, where the second is printed inline with part of the message after the name broken onto a second line.
Success! Now off to squash the other part of the string to integer conversion.