;
; x86 surface clear routines for HERMES
; Copyright (c) 1998 Christian Nentwich (brn@eleet.mcb.at)
; This source code is licensed under the GNU LGPL
; 
; Please refer to the file COPYING.LIB contained in the distribution for
; licensing conditions
;

BITS 32
	

GLOBAL _ClearX86_32
GLOBAL _ClearX86_24
GLOBAL _ClearX86_16
GLOBAL _ClearX86_8

SECTION .text

;;   
;; --------------------------------------------------------------------------
;; HermesClearInterface (ebp+..)
;;   0: char8 *dest
;;   4: int32 value
;;   8: unsigned int width (already checked to be >0!)
;;  12: unsigned int height (already checked to be >0!)
;;  16: int add


_ClearX86_32:
	push ebp
	mov ebp,esp

	mov ebp,[ebp+8]
	
	mov eax,[ebp+4]		; pixel value	
	mov edi,[ebp]		; destination
	
	mov edx,[ebp+12]	; height
	
.L_y
	mov ecx,[ebp+8]
	rep stosd

	add edi,[ebp+16]
	
	dec edx
	jnz .L_y

	pop ebp
	ret

	
		
_ClearX86_24:
	ret

	

_ClearX86_16:
	push ebp
	mov ebp,esp

	mov ebp,[ebp+8]
	
	mov eax,[ebp+4]		; pixel value	
	mov edi,[ebp]		; destination
	
	mov edx,[ebp+12]	; height
	mov ebx,eax

	shl eax,16		; Duplicate pixel value
	and ebx,0ffffh
	
	or eax,ebx
.L_y
	mov ecx,[ebp+8]

	test edi,3		; Check if destination is aligned mod 4
	jz .L_aligned

	mov [edi],ax		; otherwise write one pixel
        add edi,BYTE 2
	
	dec ecx
	jz .L_endline

.L_aligned
	mov ebx,ecx
	shr ecx,1
	
	jz .L_last
		
	rep stosd

.L_last
	test bl,1
	jz .L_endline

	mov [edi],ax
        add edi,BYTE 2

.L_endline
	add edi,[ebp+16]
	
	dec edx
	jnz .L_y

	pop ebp
	ret
	

	
;; Clear8_x86 isn't optimised fully yet as it seems to be a tiny bit slower
;; than the C routine
_ClearX86_8:			
	push ebp
	mov ebp,esp

	mov ebp,[ebp+8]

	mov eax,[ebp+4]		; pixel value		
	mov edx,[ebp+12]	; height
	
	mov ebx,eax

	shl eax,8		; Put the byte pixel value in all four bytes
	and ebx,0ffh		; of eax

	mov al,bl
	mov edi,[ebp]		; destination
	
	shl eax,16		
	mov bh,bl
	
	mov ah,bh
	mov al,bl

.L_y
	mov ecx,[ebp+8]

	test edi,3
	jz .L_aligned

	mov ebx,edi

        and ebx,BYTE 3

	mov [edi],al
	inc edi	
	dec ecx
	jz .L_endline
	dec ebx	
	jz .L_aligned

	mov [edi],al
	inc edi	
	dec ecx
	jz .L_endline
	dec ebx	
	jz .L_aligned

	mov [edi],al
	inc edi	
	dec ecx
	jz .L_endline
	dec ebx	
	jz .L_aligned
	
.L_aligned	
	mov ebx,ecx

	shr ecx,2
	jz .L_last
	
	rep stosd

.L_last
	mov ecx,ebx

        and ecx,BYTE 3
	jz .L_endline

.L_cleanup
	mov [edi],al		; Write remaining (1,2 or 3) pixels
	inc edi

	dec ecx
	jnz .L_cleanup

.L_endline
	add edi,[ebp+16]
	
	dec edx
	jnz .L_y

	pop ebp
	ret


