All posts for the month August, 2014

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:

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.

Like this:

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.

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:

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.

Like this:

I was a guest at the Atlanta Historical. Computing Society’s (http://atlhcs.org) most recent meeting and met some great people. One of which was Jeff from Commodore Hacker. We discussed my sticking point with the integer to string in assembly and he had a good idea that would give me insight to how it should be done, and thus be able to see where my routine is failing. I have some new motivation now, and I should have some free time this week so I will poke around. Hopefully I will have a worthy update to this blog soon.