
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