0100 ;UTILITY SORT - CALLED FROM BASIC
0105 ;
0110 ;ENTRY PARAMETERS:
0115 ;
0120 ; 1. FILE ADDRESS
0125 ; 2. RECORD LENGTH <=256 BYTES
0130 ; 3. NUMBER OF RECORDS TO SORT
0135 ; 4. ANY NUMBER OF FIELDS TO SORT IN
0140 ; MAJOR TO MINOR ORDER
0145 ; 4.1 FIELD POSITION
0150 ; 4.2 FIELD LENGTH
0155 ; 4.3 0=ASCENDING 1=DESCENDING
0160 ;
0165 ORG $0600
0170 FILE = 203 ;FILE START ADDRESS
0175 PNTR1 = 205 ;POINTERS TO TWO
0180 PNTR2 = 207 ;ADJACENT RECORDS.
0185 RECNBR = 209 ;NUMBER OF RECORDS
0190 SCOUNT = 211 ;RECORD COUNTER
0195 BUBLE = 213 ;OUT OF SEQUENCE
0200 RECSIZ = 214 ;SIZE OF RECORD
0205 FLDNDX = 216 ;SORT FIELD COUNTER
0210 FLDCNT = 217 ;NUMBER OF SORT FIELDS
0215 SORTAD = 218 ;ASCENDING/DESCENDING
0220 STACK = 256 ;SAVE SORT FIELDS HERE
0225 ;
0230 ;DETERMINE HOW MANY FIELDS TO SORT
0235 CLD
0240 PLA ;ALL BUT THE FIRST
0245 SEC ;THREE PARAMETERS
0250 SBC #3 ;ARE FIELDS TO
0255 STA FLDCNT ;SORT
0260 ;
0265 ;PICK UP SORT PARAMETERS
0270 PLA ;FILE START
0275 STA FILE+1 ;ADDRESS
0280 PLA ;
0285 STA FILE ;
0290 PLA ;RECORD LENGTH
0295 STA RECSIZ+1 ;
0300 PLA ;
0305 STA RECSIZ ;
0310 PLA ;NUMBER OF RECORDS
0315 STA RECNBR+1 ;
0320 PLA ;
0325 STA RECNBR ;
0330 ;
0335 ;PICK UP FIELDS TO SORT
0340 LDX #0
0345 PICKFIELDS
0350 PLA ;GET ALL THE SORT
0355 PLA ;FIELD PARAMETERS FOR
0360 STA STACK,X ;POSITION, LENGTH
0365 INX ;AND DIRECTION.
0370 CPX FLDCNT ;ANY MORE
0375 BNE PICKFIELDS ;GO GET THEM
0380 ;
0385 ;SET UP NUMBER OF RECORDS TO SORT
0390 SEC
0395 LDA RECNBR ;MUST BE AT LEAST
0400 SBC #2 ;TWO RECORDS TO
0405 STA RECNBR ;SORT
0410 LDA RECNBR+1 ;
0415 SBC #0 ;
0420 STA RECNBR+1 ;
0425 BMI ENDSORT ;ELSE GET OUT
0430 ;
0435 ;MAIN LINE SORT LOOP
0440 ;
0445 SORT LDA RECNBR ;RESET NUMBER OF
0450 STA SCOUNT ;RECORDS TO SORT
0455 LDA RECNBR+1 ;
0460 STA SCOUNT+1 ;
0465 LDA FILE+1 ;SET UP POINTERS
0470 STA PNTR1+1 ;FOR THE FIRST
0475 STA PNTR2+1 ;AND
0480 LDA FILE ;SECOND RECORDS.
0485 BUMPRECORD
0490 STA PNTR1 ;PUT PNTR2
0495 CLC ;AHEAD
0500 ADC RECSIZ ;OF
0505 STA PNTR2 ;PNTR1
0510 LDA PNTR2+1 ;BY
0515 ADC RECSIZ+1 ;ONE
0520 STA PNTR2+1 ;RECORD.
0525 ;
0530 ;SEQUENCE CHECK RECORDS
0535 ;
0540 LDY #0 ;RESET STACK INDEX
0545 NEXTFIELD
0550 LDA STACK,Y ;FIELD POSITION.
0555 LDX STACK+2,Y ;SORT DIRECTION
0560 STX SORTAD ;SAVE IT.
0565 LDX STACK+1,Y ;FIELD LENGTH.
0570 INY ;BUMP
0575 INY ;STACK
0580 INY ;INDEX
0585 STY FLDNDX ;AND SAVE IT.
0590 TAY ;FIELD POSITION TO Y
0595 DEY ;MAKE RELATIVE TO ZERO
0600 SEQCHECK
0605 LDA (PNTR1),Y ;COMPARE ADJACENT
0610 CMP (PNTR2),Y ;RECORDS
0615 BEQ SEQNDX ;= KEEP ON LOOKING
0620 LDA SORTAD ;GET SORT DIRECTION
0625 BNE DSNDG ;GO TO DESCENDING
0630 ;
0635 ; SORT IN ASCENDING SEQUENCE
0640 ;
0645 BCC BUMPINDEX ;< BUMP NEXT RECORD
0650 BCS SWAP ;> SWAP POSITIONS
0655 ;
0660 ; SORT IN DESCENDING SEQUENCE
0665 ;
0670 DSNDG BCC SWAP ;< SWAP POSITIONS
0675 BCS BUMPINDEX ;> BUMP NEXT RECORD
0680 ;
0685 SEQNDX INY ;CHECK THE LENGTH OF
0690 DEX ;THE SORT FIELD AND
0695 BNE SEQCHECK ;KEEP SEQUENCE CHECKING.
0700 LDY FLDNDX ;ANY MORE FIELDS
0705 CPY FLDCNT ;TO SORT
0710 BNE NEXTFIELD ;YES, GO TO IT
0715 ;
0720 ;INDEX THROUGH THE SORT FILE
0725 ;
0730 BUMPINDEX
0735 DEC SCOUNT ;COUNT DOWN RECORDS
0740 LDA #255 ;AND CHECK FOR
0745 CMP SCOUNT ;END OF FILE.
0750 BNE NOTEOF ;
0755 LDX SCOUNT+1 ;
0760 BEQ CKSWAP ;
0765 DEC SCOUNT+1 ;
0770 NOTEOF LDA PNTR2+1 ;BUMP PNTR2 AND
0775 STA PNTR1+1 ;PNTR1 TO THE
0780 LDA PNTR2 ;NEXT RECORDS.
0785 CLC
0790 BCC BUMPRECORD
0795 ;
0800 ;AT END OF FILE SEE IF A SWAP WAS MADE
0805 ;
0810 CKSWAP LDA BUBLE ;IF NO RECORDS SWAPPED
0815 BEQ ENDSORT ;THEN IS END OF SORT,
0820 STX BUBLE ;ELSE SEQUENCE CHECK
0825 BNE SORT ;THE FILE AGAIN.
0830 ENDSORT
0835 RTS ;BACK TO BASIC
0840 ;
0845 ;SWAP RECORDS IF OUT OF SEQUENCE
0850 ;
0855 SWAP STX BUBLE ;STILL OUT OF SEQUENCE
0860 LDY #0
0865 SWAPLOP
0870 LDA (PNTR1),Y ;THIS ROUTINE
0875 TAX ;EXCHANGES THE
0880 LDA (PNTR2),Y ;POSITIONS OF TWO
0885 STA (PNTR1),Y ;OUT OF SEQUENCE
0890 TXA ;ADJACENT RECORDS
0895 STA (PNTR2),Y ;
0900 INY
0905 CPY RECSIZ ;KEEP LOOPING FOR
0910 BNE SWAPLOP ;THE LENGTH OF RECORD.
0915 BEQ BUMPINDEX ;GO GET NEXT RECORD
0920 .END