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