%TITLE          "Memory Sort - CHiPS bv 1995"
;**********************************************************************
;**                                                                  **
;**  Program   : Mem_Sort                                            **
;**  Purpose   : Sort a Memory File                                  **
;**                                                                  **
;**  Author    : B.F. Schreurs - CHiPS bv                            **
;**  Date      : October 22, 1997                                    **
;**                                                                  **
;**  Calls     : [None]                                              **
;**                                                                  **
;**  Model     : Bubble Sort                                         **
;**                                                                  **
;**  Language  : Turbo Assembler                                     **
;**                                                                  **
;**********************************************************************
        IDEAL
        JUMPS

;----------------------------------------------------------------------
;--  Functions which can be called                                   --
;----------------------------------------------------------------------
        PUBLIC  MEMSORT

;----------------------------------------------------------------------
;--  Equates                                                         --
;----------------------------------------------------------------------
include ".\equ\sysdep.equ"
include ".\equ\equipmnt.equ"
include ".\equ\dos.equ"

;**********************************************************************
SEGMENT SSeg Para Stack 'STACK'
;**********************************************************************

        db        64 dup (0)            ; Stack

ENDS    SSeg



;**********************************************************************
SEGMENT DSeg Word Public 'DATA'
;**********************************************************************

;----------------------------------------------------------------------
;--  Structures                                                      --
;----------------------------------------------------------------------
include ".\str\sortkeys.str"

;----------------------------------------------------------------------
;--  Working Storage                                                 --
;----------------------------------------------------------------------
GLOBAL Return_Code:Byte:1

SortKeys_ptr_es         DW    NULL
SortKeys_ptr_di         DW    NULL

Key_1_Position          DW    ?         ; Position within record
Key_1_Size              DW    ?         ; Size to sort on
Key_1_A_D               DB    1 dup (?) ; "A"=ascending "D"=descending

Save_ds                 DW   ?
Save_si                 DW   ?
Temp                    DB   256 dup (?)

;----------------------------------------------------------------------
;--  External Variables                                              --
;----------------------------------------------------------------------

ENDS    DSeg



;**********************************************************************
SEGMENT CSeg Word Public 'CODE'
;**********************************************************************

;**********************************************************************
PROC    MEMSORT
;**********************************************************************
        ASSUME  cs:CSeg
        ASSUME  ds:DSeg
        mov     ax, DSeg                    ; Initialize DS to address
        mov     ds, ax                      ; of data segment

        mov     bx, sp
        mov     ax, [ss:bx+2]                   ; di
        mov     bx, [ss:bx+4]                   ; es

        mov     es, bx
        mov     di, ax

; Assume Sort fails
        mov     al, 1
        mov     [Return_Code], al

;**********************************************************************
;**     Bubble Sort Diagram:                                                     **
;**                                                                  **
;**     For A = ( ENTRY_COUNT - 1 ) To 1                             **
;**         For B = 1 To A                                           **
;**             If   Array[B] > Array[B+1]                           **
;**                  Swap Array[B] and Array[B+1]                    **
;**             End-If                                               **
;**         End-For                                                  **
;**     End-For                                                      **
;**********************************************************************
; For A = ( ENTRY_COUNT - 1 ) To 1
        mov     bx, [(SortKeys ptr di).Key_1_Position]
        mov     [Key_1_Position], bx
        mov     bx, [(SortKeys ptr di).Key_1_Size]
        mov     [Key_1_Size], bx
        mov     bl, [(SortKeys ptr di).Key_1_A_D]
        mov     [Key_1_A_D], bl
        mov     dx, [(SortKeys ptr di).Record_Size]
        mov     bx, [(SortKeys ptr di).Memory_Address_Hi]
        mov     cx, [(SortKeys ptr di).Memory_Address_Lo]
        push    bx cx

        mov     cx, [(SortKeys ptr di).Record_Count]
        dec     cx

@@10:
        pop     di es
        push    es di

        xor     bx, bx                      ; Reset bx

        mov     [Save_ds], es
        mov     [Save_si], di
        add     di, dx

@@20:
; For B = 1 To A
        inc     bx
        push    cx bx

        cmp     bx, cx
        jg      @@60

        push    ds si es di

        push    ax

        mov     ax, [Key_1_Position]
        dec     ax                              ; Adjuster to correct position
        mov     bl, [Key_1_A_D]                 ; Sort Order
        mov     cx, [Key_1_Size]                ; Compare Size
        mov     si, [Save_si]
        mov     ds, [Save_ds]

        add     si, ax                          ; Position to correct position
        add     di, ax                          ; Position to correct position

        pop     ax

@@30:
        cmp     bl, SORT_DESCENDING
        je      @@35

; Sort Ascending
; If Array[B] > Array[B+1]
        rep     cmpsb                           ; Entry first > Entry next?

        pop     di es si ds

        jle     @@50                            ; No
                                                ; Yes, so
        jmp     @@40

@@35:
; Sort Descending
; If Array[B] < Array[B+1]
        rep     cmpsb                           ; Entry first > Entry next?

        pop     di es si ds

        jnle    @@50                            ; No
                                                ; Yes, so

@@40:
;
; Swap Array[B] and Array[B+1]
;

; Array[B] -> Temp
        push    ds si es di

        mov     si, offset Temp

        push    ds si
        pop     di es

        mov     si, [Save_si]
        mov     ds, [Save_ds]

        mov     cx, dx
        rep     movsb                           ; Array[B] copied to Temp

        pop     di es si ds

; Array[B+1] -> Array[B]
        push    ds si es di

        push    es di
        mov     es, [Save_ds]
        mov     di, [Save_si]
        pop     si ds
        mov     cx, dx
        rep     movsb                           ; Array[B+1] copied to Array[B]

        pop     di es si ds

        push    ds si es di

        mov     si, offset Temp                 ; Our Temp field
        mov     cx, dx
        rep     movsb                           ; Temp copied to Array[B+1]

        pop     di es si ds

        jmp     @@50

@@50:
        add     di, dx

        push    ds si es di

        mov     es, [Save_ds]
        mov     di, [Save_si]

        add     di, dx

        mov     [Save_ds], es
        mov     [Save_si], di

        pop     di es si ds

        pop     bx cx

        jmp     @@20

@@60:
        pop     bx cx
        loop    @@10

        pop     bx bx

; Sort succesfull
        mov     al, NULL
        mov     [Return_Code], al

@@99:
        ret

ENDP    MEMSORT



ENDS    CSeg                                ; End of Code segment

END                                         ; End of Memory Sort
