z80
comment !
       shell-metzner sort routine in z80 code.
       April 1982, Claude Almer
                   Software Source Pty. Ltd.
       no end statement in file
       ========================
       sort-routine to be called as follows:
       call    sort    ;hl, de, bc set up as below:
       on entry:       HL contains the number of elements
       ---------       DE points to location of first element
                       BC contains the length of the strings
       on exit:        AF register destroyed.
       --------        BC register destroyed.
                       DE register destroyed.
                       HL register destroyed.
       reserved labels:        sort,sort1 through sort26
       ----------------
       sort1  through sort10   sorting  routine
       sort11 through sort12   compare  routine
       sort13 through sort14   swap     routine
       sort15 through sort18   indexing routine
       sort19 through sort26            data area !

;       >>>>>>>>>>>>>>          sort-routine
;                               ============

sort::  ld      (sort19),de     ;area to sort
       ld      (sort20),bc     ;length to compare and swap
sort1:  ld      (sort25),hl     ;set arrays
       ld      (sort26),hl     ;initialise
sort2:  ld      bc,(sort25)     ;sort25/2
       srl     b               ;divide by 2
       rr      c               ;bc / 2
       ld      (sort25),bc     ;now sort25=sort25/2
       ld      a,b             ;if sort25=0 then return
       or      c

;       >>>>>>>>>>>>>>>>>       ;exit if through

       ret     z               ;yes, RETURN
                               ;===========

sort3:  ld      hl,(sort26)     ;calculate sort23
       ld      de,(sort25)     ;sort23 = sort26-sort25
       or      a               ;clear carry
       sbc     hl,de           ;sort23 now in hl
       ld      (sort23),hl     ;sort23 now stored
       ld      hl,0            ;clear sort22
       ld      (sort22),hl     ;sort22=1
sort4:  ld      hl,(sort22)     ;sort21=sort22
       ld      (sort21),hl     ;store
sort5:  ld      hl,(sort21)     ;sort24=sort21+sort25
       ld      de,(sort25)     ;get sort25
       add     hl,de           ;add it together
       ld      (sort24),hl     ;and store it
sort6:  ld      hl,(sort21)     ;for comparisons now
       ld      de,(sort24)     ;as well
       call    sort11          ;compare the two
       jr      nc,sort10       ;if sort21>=sort22 then sort10
sort7:  call    sort13          ;swap the two arrays
sort8:  ld      hl,(sort21)     ;sort21=sort21-sort25
       ld      de,(sort25)     ;get sort25
       or      a               ;clear carry
       sbc     hl,de           ;subtract sort25
       ld      (sort21),hl     ;and store it in sort21
sort9:  ld      a,h             ;if sort21 >=0 then sort5
       or      a               ;is sort21 greter ?
       jp      p,sort5         ;if positive it's greater
sort10: ld      hl,(sort22)     ;sort22=sort22+1
       inc     hl              ;+1
       ld      (sort22),hl     ;store back there
       inc     hl              ;adjust for flag below
       ld      de,(sort23)     ;if sort22>sort23 then sort2
       or      a               ;clear carry
       sbc     hl,de           ;sort22 greater then sort23 ?
       jr      c,sort4         ;not greater, goto sort4
       jr      sort2           ;if sort22>sort23 then sort2

;       >>>>>>>>>>>>>>>>        compare routine
;                               ===============

sort11: call    sort15          ;set up hl,de
       ld      bc,(sort20)     ;number of chars to compare
sort12: ld      a,(de)          ;get char in de
       cp      (hl)            ;compare it with (hl)
       ret     nz              ;return if not equal
       inc     de              ;point to next
       cpi                     ;dec bc, inc hl
       jp      pe,sort12       ;pe if not zero
       xor     a               ;clear flags and exit
       ret                     ;all the same

;       >>>>>>>>>>>>>>>>        swap routine
;                               ============

sort13: call    sort15          ;set up hl and de
       ld      bc,(sort20)     ;get the length
sort14: ld      a,(de)          ;get byter
       push    bc              ;keep counter
       ld      c,a             ;keep char
       ld      a,(hl)          ;get second char
       ld      (de),a          ;swap it
       ld      (hl),c          ;and the other one
       pop     bc              ;restore counter
       inc     de              ;point to next
       cpi                     ;inc hl + dec bc
       jp      pe,sort14       ;pe if bc not 0
       ret                     ;all done

;       >>>>>>>>>>>>>>>>        indexing routine
;                               ================

sort15: ld      hl,(sort24)     ;get sort24
       call    sort16          ;point hl to sort24'th position
       push    hl              ;keep it
       ld      hl,(sort21)     ;sort21
       call    sort16          ;hl to sort21'th. position
       pop     de              ;de now restored (sort24)
       ret                     ;all indexing done
sort16: ld      c,h             ;mpr high
       ld      a,l             ;mpr low
       ld      b,16            ;count bits
       ld      hl,0            ;for result
       ld      de,(sort20)     ;length to multiply with
sort17: srl     c               ;right shift mpr h
       rra                     ;r rotate mpr l
       jr      nc,sort18       ;carry ??
       add     hl,de           ;add mpd to result
sort18: ex      de,hl           ;for double shift
       add     hl,hl           ;doublebit-shift mpd left
       ex      de,hl           ;back to normal
       djnz    sort17          ;until all bits
       ld      de,(sort19)     ;add offset
       add     hl,de           ;add it to result
       ret                     ;all done


       >>>>>>>>>>>>>>>>        ;data area
                               ;=========

sort19: dw      0               ;string start position
sort20: dw      0               ;string length
sort21: dw      0               ;data area for sort
sort22: dw      0               ;data area for sort
sort23: dw      0               ;data area for sort
sort24: dw      0               ;data area for sort
sort25: dw      0               ;data area for sort
sort26: dw      0               ;data area for sort

;       end of sort routine     <<<<<<<<<<<<<<<<<<<<<<<<