
 1000  *SAVE S.SUPER STRING ADDER
 1010  *--------------------------------
 1020  *      STRING ADDITION:  & +$,A$,B$,C$
 1030  *--------------------------------
 1040  BUFFER              .EQ $200 - $2FF
 1050  AMPERSAND.VECTOR    .EQ $3F5 - $3F7
 1060  AS.CHRGET           .EQ $00B1
 1070  AS.SYNERR           .EQ $DEC9
 1080  AS.PTRGET           .EQ $DFE3
 1090  AS.CHKCOM           .EQ $DEBE
 1100  AS.GETSPA           .EQ $E452
 1110  AS.MOVSTR           .EQ $E5E2
 1120  *--------------------------------
 1130         .OR $9000
 1140         .TF B.STRING ADDER
 1150  *--------------------------------
 1160  SETUP  LDA #$4C     JMP OPCODE
 1170         STA AMPERSAND.VECTOR
 1180         LDA #STRADD
 1190         STA AMPERSAND.VECTOR+1
 1200         LDA /STRADD
 1210         STA AMPERSAND.VECTOR+2
 1220         RTS
 1230  *--------------------------------
 1240  FRESPC              .EQ $71,72
 1250  VARPNT              .EQ $83,84
 1260  *--------------------------------
 1270  *      TWO SIMILAR BLOCKS, FOR A$ AND B$
 1280  *      REFERENCED WITH X=0 OR X=4
 1290  *--------------------------------
 1300  A.LENGTH            .BS 1
 1310  A.ADDR              .BS 2
 1320  A.DIGITS.AFTER      .BS 1
 1330  *
 1340  B.LENGTH            .BS 1
 1350  B.ADDR              .BS 2
 1360  B.DIGITS.AFTER      .BS 1
 1370  *--------------------------------
 1380  *      A THIRD BLOCK, NEARLY THE SAME AS ABOVE,
 1390  *      FOR C$:  REFERENCED WITH X=8
 1400  *--------------------------------
 1410  C.LENGTH            .BS 1
 1420  C.STRING            .BS 2
 1430  *--------------------------------
 1440  CARRY               .BS 1
 1450  TENS.FLAG           .BS 1
 1460  C.ADDR              .BS 2
 1470  MAX.DIGITS.BEFORE   .BS 1
 1480  MAX.DIGITS.AFTER    .BS 1
 1490  *--------------------------------
 1500  *      & BRANCHES HERE
 1510  *--------------------------------
 1520  STRADD CMP #$C8     CHECK FOR "+$,"
 1530         BNE .1
 1540         JSR AS.CHRGET
 1550         CMP #'$
 1560         BNE .1
 1570         JSR AS.CHRGET
 1580         CMP #',
 1590         BEQ .2
 1600  .1     JMP AS.SYNERR
 1610  *--------------------------------
 1620  .2     LDX #0       POINT AT A$ DATA
 1630         JSR PARSE.STRING.NAME   FIRST OPERAND
 1640         LDX #4       POINT AT B$ DATA
 1650         JSR PARSE.STRING.NAME   SECOND OPERAND
 1660         JSR AS.CHKCOM           RESULT STRING
 1670         JSR AS.PTRGET
 1680         STY C.STRING+1          ADDRESS OF VARIABLE
 1690         STA C.STRING
 1700  *--------------------------------
 1710  *      SCAN BOTH STRINGS TO DETERMINE BUFFER PARAMETERS
 1720  *--------------------------------
 1730         LDX #0       POINT AT A$ DATA
 1740         JSR SCAN     GET Y=LEFT LENGTH, X=RIGHT LENGTH
 1750         STX A.DIGITS.AFTER
 1760         STX MAX.DIGITS.AFTER
 1770         STY MAX.DIGITS.BEFORE
 1780         LDX #4       POINT AT B$ DATA
 1790         JSR SCAN     GET Y=LEFT LENGTH, X=RIGHT LENGTH
 1800         STX B.DIGITS.AFTER
 1810         CPX MAX.DIGITS.AFTER
 1820         BCC .3
 1830         STX MAX.DIGITS.AFTER
 1840  .3     CPY MAX.DIGITS.BEFORE
 1850         BCC .4
 1860         STY MAX.DIGITS.BEFORE
 1870  *--------------------------------
 1880  *      CLEAR THAT MUCH OF THE BUFFER
 1890  *--------------------------------
 1900  .4     INC MAX.DIGITS.BEFORE  TWO MORE CHARS FOR
 1910         INC MAX.DIGITS.BEFORE    SIGN AND CARRY
 1920         CLC
 1930         LDA MAX.DIGITS.BEFORE  TOTAL LENGTH OF RESULT
 1940         ADC MAX.DIGITS.AFTER
 1950         STA C.LENGTH
 1960         TAY
 1970         LDA #0       ZERO THE BUFFER FOR USE AS AN
 1980  .5     STA BUFFER-1,Y    ACCUMULATOR
 1990         DEY
 2000         BNE .5
 2010  *--------------------------------
 2020  *      ADD A$ TO BUFFER
 2030  *--------------------------------
 2040         LDX #0       POINT AT A$ DATA
 2050         JSR ADD.TO.BUFFER
 2060  *--------------------------------
 2070  *      ADD B$ TO BUFFER
 2080  *--------------------------------
 2090         LDX #4       POINT AT B$ DATA
 2100         JSR ADD.TO.BUFFER
 2110  *--------------------------------
 2120  *      CONVERT BUFFER TO ASCII AGAIN
 2130  *--------------------------------
 2140         LDA BUFFER   SEE IF NUMBER IS NEGATIVE
 2150         CMP #5       SET CARRY IF NEGATIVE, ELSE CLEAR
 2160         ROR          MAKE A=0XXXXXXX OR 1XXXXXXX
 2170         STA CARRY        TO SET OR CLEAR THESE FLAGS
 2180         STA TENS.FLAG    APPROPRIATELY
 2190         LDX C.LENGTH
 2200         BEQ .10      FINISHED
 2210  .6     LDA BUFFER-1,X
 2220         CMP #'.
 2230         BEQ .9
 2240         BIT TENS.FLAG
 2250         BPL .8
 2260         ASL CARRY
 2270         LDA #10
 2280         SBC BUFFER-1,X
 2290         CMP #10
 2300         BCC .7 
 2310         SBC #10
 2320  .7     ROR CARRY
 2330  .8     ORA #'0
 2340  .9     STA BUFFER-1,X
 2350         DEX
 2360         BNE .6
 2370  .10    BIT TENS.FLAG   SEE ABOUT FINAL SIGN
 2380         BPL .11         VALUE IS POSITIVE
 2390         LDA #'-         NEGATIVE, SO STUFF "-"
 2400         STA BUFFER        IN FRONT OF BUFFER
 2410  .11    JSR CHOP.OFF.LEADING.ZEROES
 2420  *--------------------------------
 2430  *      PUT (BUFFER) IN OUTPUT STRING
 2440  *--------------------------------
 2450         LDX #8       POINT AT C$ DATA
 2460         JSR SETUP.OPERAND
 2470         JSR AS.GETSPA
 2480         LDY #0
 2490         STA (VARPNT),Y
 2500         INY
 2510         LDA FRESPC
 2520         STA (VARPNT),Y
 2530         INY
 2540         LDA FRESPC+1
 2550         STA (VARPNT),Y
 2560         LDY C.ADDR+1
 2570         LDX C.ADDR
 2580         LDA C.LENGTH
 2590         JMP AS.MOVSTR
 2600  *--------------------------------
 2610  *      ADD STRING TO BUFFER
 2620  *      ENTER WITH X=0 FOR A$, X=4 FOR B$
 2630  *--------------------------------
 2640  ADD.TO.BUFFER
 2650         JSR SETUP.OPERAND
 2660         TAY          STRING LENGTH
 2670         LDA A.DIGITS.AFTER,X
 2680         PHA
 2690         LDX #0
 2700         LDA (VARPNT,X)  CHECK FOR MINUS SIGN
 2710         CMP #'-
 2720         BEQ .1       YES, CARRY SET
 2730         CLC          ELSE CLEAR CARRY
 2740  .1     ROR          MAKE A=0XXXXXXX OR 1XXXXXXX
 2750         STA TENS.FLAG  MAKE FLAGS<0 IF MINUS
 2760         STA CARRY
 2770  *--------------------------------
 2780         CLC          POINT INTO BUFFER WHERE OPERAND
 2790         PLA               ALIGNS
 2800         ADC MAX.DIGITS.BEFORE
 2810         TAX
 2820  *--------------------------------
 2830  .2     TXA          TEST X FOR BEGINNING OF BUFFER
 2840         BEQ .8       YES, FINISHED!
 2850         DEX          NO, BACK ANOTHER ONE
 2860         TYA          CHECK OPERAND POINTER
 2870         BEQ .3       END OF OPERAND, BUT WE
 2880  *                          STILL NEED TO FINISH CARRIES
 2890         DEY          BACK UP IN OPERAND
 2900         LDA (VARPNT),Y  NEXT CHAR FROM OPERAND
 2910         CMP #'.      DECIMAL POINT?
 2920         BEQ .7       YES, SKIP OVER IT
 2930         CMP #'-      MINUS SIGN?
 2940         BNE .4       NO, MUST BE DIGIT
 2950  .3     LDA #'0      ASCII ZERO THEN
 2960  .4     AND #$0F     CONVERT ASCII TO BINARY
 2970         BIT TENS.FLAG
 2980         BPL .5       NOT 9'S COMPLEMENTING
 2990         EOR #$FF
 3000         CLC
 3010         ADC #10      FORM 9'S COMPLEMENT
 3020  .5     ASL CARRY    GET PREVIOUS CARRY INTO C-BIT
 3030         ADC BUFFER,X
 3040         CMP #10      SEE IF CARRY
 3050         BCC .6       NO
 3060         SBC #10      YES, BACK THIS DIGIT DOWN
 3070  .6     ROR CARRY    SAVE CARRY FOR NEXT LOOP
 3080  .7     STA BUFFER,X
 3090         JMP .2
 3100  .8     RTS
 3110  *--------------------------------
 3120  *      SCAN STRING
 3130  *      ENTER WITH X=0 FOR A$, X=4 FOR B$
 3140  *      RETURN WITH X = # DIGITS AFTER DECIMAL POINT
 3150  *                        (COUNTING THE DECIMAL POINT)
 3160  *                  Y = # DIGITS BEFORE DECIMAL POINT
 3170  *                        (COUNTING SIGN IF ANY)
 3180  *--------------------------------
 3190  SCAN
 3200         JSR SETUP.OPERAND
 3210         LDY #0
 3220         TAX
 3230         BEQ .2       NULL STRING
 3240  .1     LDA (VARPNT),Y
 3250         CMP #'.      LOOKING FOR DECIMAL POINT
 3260         BEQ .2 
 3270         INY
 3280         DEX
 3290         BNE .1
 3300  .2     RTS
 3310  *--------------------------------
 3320  *      CHOP OFF LEADING ZEROES
 3330  *--------------------------------
 3340  CHOP.OFF.LEADING.ZEROES
 3350         LDY #1       FIND FIRST NON-ZERO POSITION
 3360  .1     LDA BUFFER,Y
 3370         CMP #'0
 3380         BNE .2 
 3390         INY
 3400         CPY MAX.DIGITS.BEFORE
 3410         BCC .1 
 3420         DEY
 3430  .2     LDA BUFFER   SIGN, MAYBE
 3440         CMP #'-
 3450         BNE .3 
 3460         DEY
 3470         STA BUFFER,Y
 3480  .3     CLC
 3490         TYA
 3500         ADC #BUFFER
 3510         STA C.ADDR
 3520         LDA #0
 3530         ADC /BUFFER
 3540         STA C.ADDR+1
 3550         SEC
 3560         TYA
 3570         EOR #$FF
 3580         ADC C.LENGTH
 3590         STA C.LENGTH
 3600         RTS
 3610  *--------------------------------
 3620  *      PARSE STRING NAME, SET UP POINTER
 3630  *--------------------------------
 3640  PARSE.STRING.NAME
 3650         TXA
 3660         PHA
 3670         JSR AS.CHKCOM
 3680         JSR AS.PTRGET     GET SECOND STRING PNTR
 3690         PLA
 3700         TAX
 3710         LDY #0
 3720         LDA (VARPNT),Y    GET LENGTH
 3730         STA A.LENGTH,X
 3740         INY
 3750         LDA (VARPNT),Y    GET ADDRESS OF DATA
 3760         STA A.ADDR,X
 3770         INY
 3780         LDA (VARPNT),Y
 3790         STA A.ADDR+1,X
 3800         RTS
 3810  *--------------------------------
 3820  *      LOAD ADDRESS INTO VARPNT
 3830  *      X=0 FOR A$, X=4 FOR B$
 3840  *--------------------------------
 3850  SETUP.OPERAND
 3860         LDA A.ADDR,X
 3870         STA VARPNT
 3880         LDA A.ADDR+1,X
 3890         STA VARPNT+1
 3900         LDA A.LENGTH,X
 3910         RTS
 3920  *--------------------------------

