Classic Computer Magazine Archive PROGRAM LISTING: 88-05a/NUMSORT.M65


0100 ;NUMSORT.M65
0110 ;BY KEVIN PECK
0120 ;(c)1988, ANTIC PUBLISHING
0130     .OPT NO LIST
0140 ;
0150 ; Define zero page pointers
0160 FLAST = $00     ;End, loop 1
0170 FLEN =  $CB     ;Field length
0180 RLEN =  $CC     ;Record length
0190 FIRST = $CD     ;Pointer to 1st
0200 ;                sort element.
0210 OFFSET = $CF    ;Offset into
0220 ;                DATA string.
0230 LENF =  $D0     ;Length of first
0240 ;                sort element.
0250 LENS =  $D1     ;Length of 2nd
0260 ;                sort element.
0270 SECOND = $D4    ;Pointer to
0280 ;                second element.
0290 LAST =  $D6     ;End of DATA
0300 ;                string pointer.
0310 FEND =  $D8     ;End, Field ptr.
0320 TEMP =  $E0     ;Temp storage
0330 ;                for ORDER.
0340 ORDER = $E1     ;Order of sort:
0350 ;       0-ascending 1-descending
0360 SIGN =  $E2     ;Sign of second
0370 ;            element 0-POS 1-NEG
0380     *=  $4000
0390 ;
0400     CLD 
0410     PLA 
0420     PLA 
0430     STA FIRST+1 ;Start of sort.
0440     PLA 
0450     STA FIRST
0460     PLA 
0470     STA LAST+1  ;End of sort.
0480     PLA 
0490     STA LAST
0500     PLA 
0510     PLA 
0520     STA FLEN    ;Field length
0530     PLA 
0540     PLA 
0550     STA OFFSET  ;Field offset
0560     CLC 
0570     ADC FLEN
0580     STA FEND
0590     PLA 
0600     PLA 
0610     STA RLEN    ;Record length.
0620     PLA 
0630     PLA 
0640     STA ORDER   ;Sort order:
0650 ;                0-ASC 1-DEC
0660 ; Find the last position of
0670 ; sort string for outer loop.
0680 ;
0690     LDA LAST+1
0700     STA FLAST+1
0710     SEC 
0720     LDA LAST
0730     SBC RLEN
0740     STA FLAST
0750     BCS INITFIRST
0760 ;
0770     DEC FLAST+1
0780 ;
0790 ; INITFIRST begins outer loop.
0800 ; INITSECOND is the inner loop.
0810 ;
0820 INITFIRST
0830     LDY OFFSET
0840     LDX #0
0850     LDA (FIRST),Y
0860     CMP #'-
0870     BNE FINDFLEN
0880 ;
0890     INX 
0900 FINDFLEN ;      Find length of
0910 ;              1st sort element.
0920     LDA (FIRST),Y
0930     CMP #'.
0940     BEQ SAVELENF
0950 ;
0960     CMP #32
0970     BEQ SAVELENF
0980 ;
0990     INY 
1000     CPY FEND
1010     BNE FINDFLEN
1020 ;
1030 SAVELENF ;      Save the length.
1040     STY LENF
1050 ; Set SECOND element to FIRST
1060 ; plus record length.
1070 ;
1080 SETSECOND
1090     CLC 
1100     LDA FIRST+1
1110     STA SECOND+1
1120     LDA FIRST
1130     ADC RLEN
1140     STA SECOND
1150     BCC INITSECOND
1160 ;
1170     INC SECOND+1
1180 ; Inner loop's 1st routine,
1190 ; Finds sign of 2nd element.
1200 ;
1210 INITSECOND
1220     LDY OFFSET
1230     LDA #0
1240     STA SIGN
1250     LDA (SECOND),Y
1260     CMP #'-
1270     BNE SETSECLEN
1280 ;
1290     INC SIGN
1300 SETSECLEN
1310     LDA (SECOND),Y
1320     CMP #'.
1330     BEQ SAVELENS
1340 ;
1350     CMP #32
1360     BEQ SAVELENS
1370 ;
1380     INY 
1390     CPY FEND
1400     BNE SETSECLEN
1410 ;
1420 SAVELENS
1430 ;
1440     STY LENS    ;Save length of
1450 ;                second element.
1460 ;
1470 ; Examine & test sort elements.
1480 ; Test signs, then lengths,
1490 ; then test byte-by-byte.
1500 ;
1510 TESTSIGN
1520 ;
1530     LDA ORDER
1540     STA TEMP
1550     CPX SIGN
1560     BEQ TESTLEN ;If = test sign
1570 ;
1580     BCC CHKORDER ;If < swap chk
1590 ;
1600     BCS CHKTEMP ;If > noswap chk
1610 ;
1620 X2INITFIRST
1630 ;
1640     BNE INITFIRST
1650 ;
1660 TESTLEN
1670     LDA LENS    ;Compare lengths
1680     CMP LENF
1690     BEQ XBYTETEST
1700 ;
1710     BCC SWAP
1720 ;
1730     BCS ADJPOINT
1740 ;
1750 XINITSECOND
1760     BNE INITSECOND
1770 ; Routines are only set for
1780 ; positive numbers in
1790 ; ascending order. If both
1800 ; numbers are negative then
1810 ; reverse the order.
1820 SWAP
1830     LDA ORDER
1840     STA TEMP
1850     CLC 
1860     TXA 
1870     ADC SIGN
1880     CMP #2
1890     BNE CHKORDER
1900 ;
1910 ; Both numbers are negative.
1920 ; temporarily reverse order.
1930 ;  Subtract current order
1940 ; from one to flip the order.
1950     LDA #1
1960     SBC ORDER
1970     STA TEMP
1980 ;
1990 ; If order is 1 goto "Back Door"
2000 ; of the adjust pointer routine.
2010 CHKORDER
2020     LDA TEMP
2030     BNE ADJPOINTBD
2040 ;
2050 SWAPBD ;        Swap's backdoor
2060     LDY #0
2070 SWAPLOOP
2080     LDA (FIRST),Y
2090     PHA 
2100     LDA (SECOND),Y
2110     STA (FIRST),Y
2120     PLA 
2130     STA (SECOND),Y
2140     INY 
2150     CPY RLEN
2160     BNE SWAPLOOP
2170 ;
2180     LDA LENS
2190     STA LENF
2200     LDX SIGN
2210     CLC 
2220     BCC ADJPOINTBD
2230 ;
2240 XINITFIRST
2250     BNE X2INITFIRST
2260 ;
2270 XSWAP
2280     BCS SWAP
2290 ;
2300 XBYTETEST
2310 ;
2320     BEQ BYTETEST
2330 ;
2340 ; Due to postive-ascending
2350 ; nature of program we check
2360 ; if both are negative or if
2370 ; the order is descending.
2380 ;
2390 ADJPOINT
2400     LDA ORDER
2410     STA TEMP
2420     CLC 
2430     TXA 
2440     ADC SIGN
2450     CMP #2
2460     BNE CHKTEMP
2470 ;
2480     LDA #1
2490     SBC ORDER
2500     STA TEMP
2510 CHKTEMP
2520     LDA TEMP
2530     BNE SWAPBD
2540 ;
2550 ADJPOINTBD ;    The back door.
2560     CLC 
2570     LDA SECOND
2580     ADC RLEN
2590     STA SECOND
2600     LDA SECOND+1
2610     ADC #0
2620     STA SECOND+1
2630 ;
2640 ; We have adjusted the 2nd
2650 ; Decide if inner loop is done
2660 ; by comparing 2nd to last to
2670 ; see if it is pointing to end
2680 ; of data string. If not then
2690 ; branch to the inner loop.
2700 ;
2710     CMP LAST+1
2720     BNE XINITSECOND
2730 ;
2740     LDA SECOND
2750     CMP LAST
2760     BNE XINITSECOND
2770 ;
2780 ; Adjust outer loop pointer,
2790 ; check if done.  If not,
2800 ; then go to SETSECOND
2810 ; to reset the 2nd element to
2820 ; point one record away from the
2830 ; new 1st element.
2840 ;
2850     CLC 
2860     LDA FIRST
2870     ADC RLEN    ;Compare 1st &
2880 ; 2nd on a byte-by-byte basis.
2890 ; When we find non-equal bytes,
2900 ; check for swap.
2910 ;
2920     STA FIRST
2930     LDA FIRST+1
2940     ADC #0
2950     STA FIRST+1
2960     CMP FLAST+1
2970     BNE XINITFIRST
2980 ;
2990     LDA FIRST
3000     CMP FLAST
3010     BNE XINITFIRST
3020 ;
3030     RTS         ;Return to BASIC
3040 ;
3050 ; We make it to here if the
3060 ; signs and the lengths are
3070 ; both equal. Now compare 1st
3080 ; to 2nd (byte-by-byte).
3090 ;
3100 BYTETEST
3110 ;
3120     LDY OFFSET
3130 ;
3140 TESTLOOP
3150     LDA (FIRST),Y
3160     CMP (SECOND),Y
3170     BEQ TESTMORE
3180 ;
3190     BCS XSWAP
3200 ;
3210     BCC ADJPOINT
3220 ;
3230 TESTMORE
3240     INY 
3250     CPY FEND
3260     BEQ ADJPOINTBD
3270 ;
3280     BNE TESTLOOP
3290 ;
3300     .END 


Back to previous page