; SHELL-METZNER SORT ; Call with the following information: ; ; BC = Number of records to be sorted ; DE = Record length ; HL = Buffer address ; ; Comment out the following line if subroutine is ; to be yanked into a file instead of using RMAC/LINK ; PUBLIC SORT ; TRUE EQU 255 FALSE EQU 0 ; ASCEND EQU TRUE ;set FALSE for descending sort STRIPHI EQU FALSE ;true, if high bits not significant ; SORT: SHLD SSTADR PUSH H XCHG SHLD SRECLEN PUSH H MOV H,B MOV L,C SHLD SNUMRT SHLD SNUMRW ; ; NOW DIVIDE # OF FIELDS BY 2 ; DIVIDE: LHLD SNUMRW ;GET VALUE ORA A ;CLEAR CARRY MOV A,H RAR MOV H,A MOV A,L RAR MOV L,A SHLD SNUMRW ;SAVE RESULT MOV A,L ;IF SNUMRW<>0 ORA H ; THEN JNZ NOTDONE ; NOT DONE ; ; ALL FIELDS SORTED ; POP B ;CLEAN UP STACK POP D RET ; NOTDONE:XCHG LHLD SNUMRT MOV A,L SUB E MOV L,A MOV A,H SBB D MOV H,A SHLD SRECLEN LXI H,1 SHLD SORTV1 SHLD SSTADR DCR L POP B PUSH B NDONE1: DAD D DCX B MOV A,B ORA C JNZ NDONE1 SHLD SORTV2 XCHG POP B POP H PUSH H PUSH B NDONE2: SHLD SORTV4 SHLD SORTV3 XCHG DAD D XCHG COMPRE: POP B PUSH B COMPR1: LDAX D IF STRIPHI ANI 7FH PUSH B PUSH PSW MOV A,M ANI 7FH MOV B,A POP PSW SUB B POP B ELSE SUB M ENDIF JNZ NOTEQU INX H INX D DCX B MOV A,B ORA C JNZ COMPR1 JMP NOSWITCH ; NOTEQU: IF ASCEND JNC NOSWITCH ELSE JC NOSWITCH ENDIF SWITCH: PUSH B MOV B,M LDAX D MOV M,A MOV A,B STAX D INX H INX D POP B DCX B MOV A,B ORA C JNZ SWITCH LHLD SNUMRW MOV A,H CMA MOV D,A MOV A,L CMA MOV E,A LHLD SORTV1 DAD D JNC NOSWITCH INX H SHLD SORTV1 LHLD SORTV3 XCHG LHLD SORTV2 MOV A,E SUB L MOV L,A MOV A,D SBB H MOV H,A SHLD SORTV3 JMP COMPRE ; NOSWITCH: LHLD SSTADR INX H SHLD SSTADR SHLD SORTV1 XCHG LHLD SRECLEN MOV A,L SUB E MOV A,H SBB D JC DIVIDE LHLD SORTV4 POP D PUSH D DAD D XCHG LHLD SORTV2 XCHG JMP NDONE2 ;..... ; ; ; UTILITY SUBTRACTION SUBROUTINE... ; HL=HL-DE ; SUBDE: MOV A,L SUB E MOV L,A MOV A,H SBB D MOV H,A RET ; SRECLEN:DW 0 SSTADR: DW 0 SORTV1:DW 0 SORTV2:DW 0 SORTV3:DW 0 SORTV4:DW 0 SNUMRT:DW 0 SNUMRW:DW 0