;
asize	EQU 10		; number of elements in array
;
array:	db 9		; this is pretty much worst case
	db 8
	db 7
	db 6
	db 5
	db 4
	db 3
	db 2
	db 1
	db 0
;

; ------------------------------------------------
; | cocktail_sort
; |     sort an array of integers
; |
; |  bx holds the base address of the array
; |  si is used for current index in both loops
; |  di is the first element to check
; |  cx is the last element to check
; |
; |  dl is the 'swap' flag - used to stop the sort
; |  ax holds the number of iterations at the end
; |  
; -------------------------------------------------
;
Start:
	call cocktail
;
; After this call, the array 'array' is sorted
; and number of iterations is in AX register
;
	hlt
;
cocktail:
;
; save all registers used
;
		push  bx
		push  cx
		push  si
		push  dx
		push  di
;
		mov   bx, array		; base address of array
		mov   di, 0		; beginning of array
		mov   cx, asize
		dec   cx		; end of array (one less than size)
;
loopi:
		mov   si, di		; set beginning element
		mov   dl, 0		; clear swap flag
		mov   al, [bx+si]	; pick up top element
;
loopj:					; 'down' loop
		mov   ah, [bx+si+1]	; pick up next element
		cmp   al, ah		; compare these two
		jle   noswapj
;
		mov   [bx+si], ah	; swap next into current
		jmp   checkj
;
noswapj:		
		mov   [bx+si], al	; if no swap, element in al is placed
		mov   al, ah		; and next element readied
;
checkj:
		inc   si		; increase i
		cmp   si, cx		; see if done 'down' loop
		jb    loopj
;
; end of loop j
;
		mov   [bx+si], al	; if so, last element in al has to be placed
		dec   cx		; now decrease end position since highest element in place
		mov   si, cx		; counter for 'up' loop
		mov   al, [bx+si]	; pick up bottom element
;
loopk:					; 'up' loop
		mov   ah, [bx+si-1]	; pick up previous element
		cmp   al, ah		; compare these two
		jge   noswapk
;
		mov   dl, 1		; set swap flag (notice only set in this loop)
		mov   [bx+si], ah	; swap previous into current
		jmp   checkk
;
noswapk:
		mov   [bx+si], al	; if no swap, element in al is placed
		mov   al, ah		; and previous element readied
;
checkk:
		dec   si		; decrement i
		cmp   si, di		; see if done 'up' loop
		ja    loopk
;
; end of loop k
;
		mov   [bx+si], al	; place final element in al
		inc   di		; now increase start position since lowest element in place
		cmp   dl, 0		; check swap flag
		jnz   loopi		; not done if swap occured
;
; end of loop i
;
		mov   ax, di		; number of iter's
		pop   di		; restore other registers used
		pop   dx
		pop   si
		pop   cx
		pop   bx
	        ret
;
end Start