PETASCII To ASCII Conversion

Started by Blacklord, August 08, 2009, 08:39 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Blacklord

This very useful machine language routine is well worth its weight in gold when it comes to using your PET/CBM wth ASCII devices such as MODEMS and printers. It's short length (56 bytes) and ease of use make it very easy to add to any existing programs. The assembler listing included is for BASIC 3.0 ROM's. The changes needed for BASIC 2.0 ROM's and BASIC 4.0 ROM's are listed below.

For BASIC 2.0, change COMMA to $CE11 from $CDF8, change EVAL to $CCB8 from $CC9F, and change PTR to $96 from $44. For BASIC 4.0, change COMMA to $BEF5 from $CDF8 and change EVAL to $BD98 from $CC9F. The PTR location is the same for BASIC 4.0 as it is for BASIC 3.0, as Commodore promised it would be.

The machine language program works as follows. It is invoked with a SYS(NNN),A$ statement. The (NNN) is the first location of the ML routine and the string variable A$ is the string to be converted. The ML program then jumps to the routine COMMA, which checks for â€" you guessed it â€" the comma which seperates the SYS(NNN) and the A$. The next jump is to a subroutine called EVAL which looks at the variable A$ and puts its location in PTR and PTR + 1.

CBM/PET identifies characters somewhat differently than the industry standard, the ASCII code. In ASCII, the number 65 means uppercase "A," as it does to PET BASIC. However, if you POKE 32768,65, the screen will either display a spade or lowercase "a," depending on whether you are in "text" or "graphics" mode at the time. Everything is kept straight for you by BASIC, but when you try to communicate with a device outside the computer (a MODEM or a printer), some adjustments may need to be made. This is why wordprocessors like WordPro always first ask you to indicate whether you are using a Commodore printer, an ASCII printer, etc. Mr. Niessen's machine language program does the translating. It takes the CBM/PET character codes and modifies them to conform to ASCII. Within the article, he provides the necessary changes to make the program work on all CBM models: Original (2.0), Upgrade (3.0), and BASIC (4.0).

By using an indirect indexed addressing mode, you can get the length of the string by loading the Y register with zero and executing a LDA(PTR), Y. The length of the string is then transferred into the accumulator and saved into location STRLEN. Next, the Y register is incremented so it has a value of one, and another LDA(PTR), Y is executed. This time the LO byte of the beginning of the actual string in memory is returned. This is saved in the location STRLO. Again the Y register is incremented and the LDA(PTR),Y instruction is executed again, returning the HI byte of the location of the string, which is saved in STRHI.

Now knowing the location and length of the string to be converted, the routine can convert it from PETASCII to ASCII on a character by character basis, beginning with the last one and working forward. It uses the following algorithm:

IF(A) > = 65 AND (A) < = 90 THEN (A) = (A) OR 32
ELSE I (A) > = 193 AND (A) < = 219 THEN (A) = (A) AND 127

Characters above $7B have no ASCII equivalent and are left as is.

The subroutine then returns to BASIC, with the contents of the string A$ converted to ASCII. The string can now be printed normally.

One thing to remember is that the original contents of the string are changed. If the string were dynamically declared, as in the following example, it will be changed within the program:

10 A$ = "STRING" : SYS(NNN), A$

because the PET, to save memory space, sets the pointers to the actual string in the program. Instead use:

10 A$ = "STRING" + " " : SYS(NNN), A$

which will cause the string to be stored away in high memory.

I hope this will prove as useful to others as it has been to me. It was tested on the EPSON MX-80 printer.

References:

Commodore User's Reference Manualâ€"PN 321604
Page E-1, Paragraph I

The PET Revealed
Nick Hampshire, Computabits Ltd, P.O. Box 13, Yeovil, Somerset, England
PET/CBM Personal Computer Guide
Adam Osborne-Carroll S. Donahue
Osborne/McGraw-Hill

LINE#    LOC    CODE           LINE
0001     0000                   ; ***************************************  0002    0000                   ; * PETASCII TO ASCII SUBROUTINE        *
0003    0000                   ; * BY: BRIAN NIESSEN.                  *
0004     0000                   ; *                                     *
0005     0000                   ; * BOX 571                             *
0006     0000                   ; * CHEMAINUS, B.C. VOR 1KO             *
0007     0000                   ; * (604) 246-4556                      *
0008     0000                   ; ***************************************
0009     0000                   ; *TO USE: SYS(NNN), A$                 *
0010     0000                   ; *WHERE (NNN) IS START LOCATION        *
0011     0000                   ; *A$ IS STRING TO BE CONVERTED         *
0012     0000                   ; ***************************************
0013     0000                   ; LOCATIONS FOR 2001 (BASIC 3.0)
0014     0000                   COMMA  =  $CDF8
0015     0000                   EVAL   =  $CC9F
0016     0000                   STRLO  =  $DA
0017    0000                   STRHI  =  $DB
0018    0000                   STRLEN =  $F9
0019    0000                   PTR    =  $44           ;POINTER USED IN EVAL ROUTINE
0020    0000                          *  =634          ;STARTING LOCATION FOR ROUTINE
0021    027A   20  F8   CD             JSR COMMH        ;CHECK FOR COMMA
0022    027D   20  9F   CC             JSR EVAL         ;EVALUATE EXPRESSION
0023    0280   A0  00                 LDY #0           ;SAVE STRING LOCATION
0024    0282   B1  44                 LDA (PTR), Y
0025    0284   85  F9                 STA STRLEN
0026    0286   C8                     INY
0027    0287   B1  44                 LDA (PTR), Y
0028    0289   85  DA                 STA STRLO
0029    028B   C8                     INY
0030    028C   B1  44                 LDA (PTR), Y
0031    028E   85  DB                 STA STRHI
0032    0290                   ;PROCESS STRING ONE CHARACTER AT A TIME.
0033    0290   A4  F9                 LDY STRLEN       ;GET STRING LENGTH
0034    0292   B1  DA          LOOP   LDA (STRLO), Y
0035    0294   C9  41                 CMP #$41         ;IF $41<=A<$5A THEN A=A OR $20
0036    0296   90  12                 BCC DONE         ;IF 'A <=A<= 'Z THEN A=A OR 32
0037    0298   C9  5B                 CMP #$5B
0038    029A   B0  04                 BCS SECOND
0039    029C   09  20                 ORA #$20
0040    029E   D0  0A                 BNE DONE         ;JUMP ALWAYS
0041    02A0                   SECOND                  ;FIRST FAILED-TRY SECOND
0042    02A0   C9  C1                 CMP #$C1         ;IF $C1<=A<=$DA THEN A=A AND $7F
0043    02A2   90  06                 BCC DONE
0044    02A4   C9  DB                 CMP #$DB
0045    02A6   B0  02                 BCS DONE
0046    02A8   29  7F                 AND #$7F
0047    02AA   91  DA          DONE   STA (STRLO), Y
0048    02AC   88                     DEY
0049    02AD   C0  FF                 CPY #$FF
0050    02AF   D0  E1                 BNE LOOP
0051    02B1
0052    02B1   60                     RTS              ;RETURN TO BASIC
0053    02B2                          .END