0100 ;MACHINE LANGUAGE SORTS, PART 1 0110 ;BY KEVIN PECK 0120 ;(c)1987, ANTIC PUBLISHING 0130 FLAST = $00 ;End, outer loop 0140 FLENKEY = $CB ;Key length 0150 RLEN = $CC ;Record Length 0160 OFFSETKEY = $CF ;Key offset 0170 FIRST = $CD ;1st element ptr 0180 SECOND = $D4 ;2nd element ptr 0190 LAST = $D6 ;End, inner loop 0200 FENDKEY = $D8 ;End, key field 0210 ORDER = $E1 ;Order, sort 0,1 0220 FLENSEC = $D0 ;2nd field lngth 0230 OFFSETSEC = $E0 ;2nd " " offset 0240 FENDSEC = $D1 ;End 2nd field 0250 ; 0260 *= $4000 0270 ; 0280 CLD 0290 PLA 0300 ; Retrieve arguments from BASIC 0310 PLA 0320 STA FIRST+1 0330 PLA 0340 STA FIRST 0350 PLA 0360 STA LAST+1 0370 PLA 0380 STA LAST 0390 PLA 0400 PLA 0410 STA FLENKEY 0420 PLA 0430 PLA 0440 STA OFFSETKEY 0450 CLC ;Find end of 0460 ADC FLENKEY ;First key 0470 STA FENDKEY 0480 PLA 0490 PLA 0500 STA FLENSEC 0510 PLA 0520 PLA 0530 STA OFFSETSEC 0540 CLC 0550 ADC FLENSEC ;Find end of 0560 STA FENDSEC ;second key 0570 PLA 0580 PLA 0590 STA RLEN 0600 PLA 0610 PLA 0620 STA ORDER 0630 ; 0640 ; All parms. now in zero page. 0650 ; Next, set pointer to the end 0660 ; of the outer loop 0670 LDA LAST+1 0680 STA FLAST+1 0690 SEC 0700 LDA LAST 0710 SBC RLEN 0720 STA FLAST 0730 BCS SETSECOND 0740 ; 0750 DEC FLAST+1 0760 ; Start of outer loop. 0770 ; Adjust the second pointer to 0780 ; point to the first pointer 0790 ; plus the record length. 0800 ; 0810 SETSECOND 0820 CLC 0830 LDA FIRST+1 0840 STA SECOND+1 0850 LDA FIRST 0860 ADC RLEN 0870 STA SECOND 0880 BCC SORTKEY 0890 INC SECOND+1 0900 ; Start of the inner loop. 0910 ; 1. Compare the Key field of 0920 ; the two sort elements. 0930 ; 2. If we find a mismatch, 0940 ; do we need to swap them? 0950 SORTKEY 0960 LDY OFFSETKEY 0970 ; 0980 KEYLOOP 0990 ; 1000 LDA (FIRST),Y ;get a byte 1010 CMP (SECOND),Y ;of each. 1020 BEQ CHKMORE ;If = Continue. 1030 ; 1040 BCC NOSWAP ;If F<S no swap. 1050 ; 1060 BCS SWAP ;If F>S swap. 1070 ; 1080 CHKMORE 1090 ; 1100 INY ;Adjust pointer 1110 CPY FENDKEY ;All done? 1120 BNE KEYLOOP ;No. Continue. 1130 ; 1140 ; At this point, all bytes in 1150 ; the key field of both sort 1160 ; elements are equal. Drop to 1170 ; SORTSECOND and check the 1180 ; secondary fields. 1190 ; If their lengths = 0, then 1200 ; we don't have 2ndry fields. 1210 ; We are only doing a one-field 1220 ; sort--goto the Noswap routine. 1230 ; If the key fields are equal, 1240 ; there is no need to swap them. 1250 ; 1260 SORTSEC 1270 LDA FLENSEC ;A second field? 1280 BEQ NOSWAPBD ;No. 1290 ; 1300 LDY OFFSETSEC 1310 SECLOOP 1320 LDA (FIRST),Y ;Compare byte 1330 CMP (SECOND),Y ;by byte... 1340 BEQ CHKMORE2 ;If = do more. 1350 ; 1360 BCC NOSWAP ;If F<S Noswap. 1370 ; 1380 BCS SWAP ;If F>s Swap. 1390 ; 1400 CHKMORE2 1410 INY ;Point to next. 1420 CPY FENDSEC ;End of 2nd? 1430 BNE SECLOOP ;No, do more. 1440 ; 1450 ; Now, both the key and the 1460 ; secondary fields of both sort 1470 ; elemtents are equal. Goto 1480 ; the noswap routine through the 1490 ; "back door." No need to check 1500 ; the order, no need to swap. 1510 BEQ NOSWAPBD 1520 ; 1530 ; This is where the swapping 1540 ; occurs. First, check the 1550 ; swapping order. 1560 ; (Assume swapping in ascending 1570 ; order.) If order<>0, then 1580 ; sort in descending order. 1590 ; 1600 SWAP 1610 ; 1620 LDA ORDER ;Get order 1630 BNE NOSWAPBD ;Not 0, No swap 1640 ; 1650 ; Swap routine's back door. 1660 ; If NOSWAP decides we need to 1670 ; swap by checking the order, 1680 ; we need to come here (instead 1690 ; of SWAP) or we would go into 1700 ; a continuous loop. 1710 ; 1720 SWAPBD 1730 LDY #0 1740 SWAPLOOP 1750 LDA (FIRST),Y ;Key byte 1760 PHA ; to stack. 1770 LDA (SECOND),Y ; 2ndry byte 1780 STA (FIRST),Y ; to key. 1790 PLA ;Key from stack 1800 STA (SECOND),Y ;to 2ndry. 1810 INY ;Next byte. 1820 CPY RLEN ; More? 1830 BNE SWAPLOOP ;Yes. Continue. 1840 ; 1850 ; All bytes have been swapped. 1860 ; Now adjust pointers to the 1870 ; next elements for the sort. 1880 ; Goto the noswap back door. 1890 ; 1900 BEQ NOSWAPBD 1910 ; 1920 NOSWAP 1930 ; 1940 LDA ORDER ;Is ORDER=1? 1950 BNE SWAPBD ;Yes. Swap them 1960 ; 1970 NOSWAPBD 1980 CLC 1990 LDA SECOND 2000 ADC RLEN 2010 STA SECOND 2020 LDA SECOND+1 2030 ADC #0 2040 STA SECOND+1 2050 CMP LAST+1 2060 BNE SORTKEY 2070 ; 2080 LDA SECOND 2090 CMP LAST 2100 BNE SORTKEY 2110 ; 2120 ; We've made one pass through 2130 ; the sort's inner loop. Now, 2140 ; adjust the outer loop and 2150 ; check if we're done with it. 2160 ; If not, readjust the inner 2170 ; loop pointer to the outer loop 2180 ; pointer + the record length. 2190 ; 2200 CLC 2210 LDA FIRST 2220 ADC RLEN 2230 STA FIRST 2240 LDA FIRST+1 2250 ADC #0 2260 STA FIRST+1 2270 CMP FLAST+1 2280 BNE SETSECOND 2290 ; 2300 LDA FIRST 2310 CMP FLAST 2320 BNE SETSECOND 2330 ; 2340 RTS ;Goto BASIC 2350 .END
Back to previous page