;THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
;SOFTWARE CORPORATION ("PARALLAX").  PARALLAX, IN DISTRIBUTING THE CODE TO
;END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
;ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
;IN USING, DISPLAYING,  AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
;SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
;FREE PURPOSES.  IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
;CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES.  THE END-USER UNDERSTANDS
;AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.  
;COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION.  ALL RIGHTS RESERVED.
;
; $Source: f:/miner/source/2d/rcs/vesa.asm $
; $Revision: 1.20 $
; $Author: john $
; $Date: 1994/07/27 15:43:37 $
;
; Routines to access VESA VGA memory
;
; $Log: vesa.asm $
; Revision 1.20  1994/07/27  15:43:37  john
; Fixed bug with allocation dos memory more than once.
; 
; Revision 1.19  1994/06/24  17:27:02  john
; Made rowsizes bigger than actual screen work with SVGA.
; 
; Revision 1.18  1994/05/31  11:10:45  john
; *** empty log message ***
; 
; Revision 1.17  1994/05/06  12:50:21  john
; Added supertransparency; neatend things up; took out warnings.
; 
; Revision 1.16  1994/03/14  16:56:29  john
; Changed grs_bitmap structure to include bm_flags.
; 
; Revision 1.15  1994/02/02  11:27:22  john
; *** empty log message ***
; 
; Revision 1.14  1994/01/25  11:40:46  john
; Added gr_check_mode function.
; 
; Revision 1.13  1994/01/13  14:41:51  unknown
; Fixed bug with Error 7 return Error 8.
; 
; Revision 1.12  1993/12/21  19:58:38  john
; made rep movsb in scanline be rep movsw
; 
; Revision 1.11  1993/12/09  16:05:51  john
; Made no VESA driver detection work correctly
; 
; Revision 1.10  1993/12/09  15:02:41  john
; Changed palette stuff majorly
; 
; Revision 1.9  1993/11/16  11:28:28  john
; *** empty log message ***
; 
; Revision 1.8  1993/10/26  13:18:03  john
; *** empty log message ***
; 
; Revision 1.7  1993/10/15  16:23:28  john
; y
; 
; Revision 1.6  1993/09/29  17:31:10  john
; optimized gr_vesa_pixel
; 
; Revision 1.5  1993/09/26  18:59:34  john
; fade stuff
; 
; Revision 1.4  1993/09/20  14:47:20  john
; *** empty log message ***
; 
; Revision 1.3  1993/09/13  17:54:07  john
; Minor bug fix
; 
; Revision 1.2  1993/09/08  15:56:06  john
; Started adding DPMI support for SVGA paging.
; 
; Revision 1.1  1993/09/08  11:41:25  john
; Initial revision
; 
;
;

.386

OPTION OLDSTRUCTS
INCLUDE VGAREGS.INC
INCLUDE GR.INC

_DATA   SEGMENT BYTE PUBLIC USE32 'DATA'

		PUBLIC      __A0000
		__A0000      dw  ?

		BufferPtr   dd  0
		BufferSeg   dw  0
		GoalMode    dw  ?
		LastPage    db  0FFh

		BPR         dw  ?
		TempReg     dd  ?

		; Information from VESA return SuperVGA Information

		VESAVersion         dw  ?
		OEMStringPtr        dd  ?
		Capabilities        dd  ?
		VideoModePtr        dd  ?
		TotalMemory         dw  ?
		WinGranularity      dw  ?
		WinSize             dw  ?
		WinFuncPtr          dd  ?
		PageSizeShift       db  ?

		VESA_Signature      = 041534556h

REALREGS    STRUCT
		RealEDI     dd      ?
		RealESI     dd      ?
		RealEBP     dd      ?
		Reserved    dd      ?
		RealEBX     dd      ?
		RealEDX     dd      ?
		RealECX     dd      ?
		RealEAX     dd      ?
		RealFlags   dw      ?
		RealES      dw      ?
		RealDS      dw      ?
		RealFS      dw      ?
		RealGS      dw      ?
		RealIP      dw      ?
		RealCS      dw      ?
		RealSP      dw      ?
		RealSS      dw      ?
REALREGS    ENDS

		regs    REALREGS    < >

		vesa_error	dd	?
		SourceInc   dd  ?
		DestInc     dw  ?
		RowWidth    dd  ?

		extern _gr_var_color:dword, _gr_var_bwidth:dword


_DATA   ENDS

DGROUP  GROUP _DATA


_TEXT   SEGMENT BYTE PUBLIC USE32 'CODE'

		ASSUME  DS:_DATA
		ASSUME  CS:_TEXT

MyStosd MACRO Width:REQ
; Assumes:   EDI = Dest Address
;            Width = a 32-bit value, can't be ECX or EDI
; Trashes:   ECX will be zero
;            EDI = Dest Address + Width
;            EDX = ????
;            Width
LOCAL Aligned
			cmp     Width, 16
			jbe     Aligned
			mov     ecx, edi
			and     ecx, 3
			jcxz    Aligned
			neg     ecx
			add     ecx, 4
			sub     Width, ecx
			rep     stosb
Aligned:    		mov     ecx, Width
			shr     ecx, 2
			rep     stosd
			mov     ecx, Width
			and     ecx, 3
			rep     stosb
ENDM


ENTER_PROC  MACRO
			push    esi
			push    edi
			push    ebp
			push    eax
			push    ebx
			push    ecx
			push    edx
ENDM

EXIT_PROC   MACRO

			cmp     [esp-4], edx
			je      @f
			; YOU TRASHED EDX !!!!!!!
			int     3
@@:         pop     edx

			cmp     [esp-4], ecx
			je      @f
			; YOU TRASHED ECX !!!!!!!
			int     3
@@:         pop     ecx

			cmp     [esp-4], ebx
			je      @f
			; YOU TRASHED EBX !!!!!!!
			int     3
@@:         pop     ebx

			cmp     [esp-4], eax
			je      @f
			; YOU TRASHED EAX !!!!!!!
			int     3
@@:         pop     eax

			cmp     [esp-4], ebp
			je      @f
			; YOU TRASHED EBP !!!!!!!
			int     3
@@:         pop     ebp

			cmp     [esp-4], edi
			je      @f
			; YOU TRASHED EDI !!!!!!!
			int     3
@@:         pop     edi

			cmp     [esp-4], esi
			je      @f
			; YOU TRASHED ESI !!!!!!!
			int     3
@@:         pop     esi

ENDM


MyMovsd MACRO Width:REQ
; Assumes:   EDI = Dest Address
;            ESI = Source Address
;            Width = a 32-bit value, can't be ECX or EDI or ESI
;            Assumes that ESI is already aligned
; Trashes:   ECX will be zero
;            EDI = Dest Address + Width
;            ESI = Source Address + Width
;            EDX = ????
LOCAL Aligned
			cmp     Width, 16
			jbe     Aligned
			mov     ecx, edi
			and     ecx, 3
			jcxz    Aligned
			neg     ecx
			add     ecx, 4
			sub     Width, ecx
			rep     movsb
Aligned:    mov     ecx, Width
			shr     ecx, 2
			rep     movsd
			mov     ecx, Width
			and     ecx, 3
			rep     movsb
ENDM


EBXFarTo32:
			push    ecx
			mov     ecx, ebx
			and     ecx, 0FFFF0000h
			shr     ecx, 12
			and     ebx, 0FFFFh
			add     ebx, ecx
			pop     ecx
			ret

PUBLIC  gr_init_A0000_

gr_init_A0000_:

			push    ebx
			mov     ax, 0002h
			mov     bx, 0a000h
			int     31h
			jc      NoGo
			mov     __A0000, ax
			pop     ebx
			xor     eax, eax
			ret
NoGo:       pop     ebx
			mov     eax, 1
			ret

PUBLIC  gr_vesa_checkmode_

gr_vesa_checkmode_:
			pushad

			mov     GoalMode, ax
			cmp 	BufferSeg, 0
			jne	GotDosMemory

			; Allocate a 256 byte block of DOS memory using DPMI
			mov     ax, 0100h
			mov     bx, 16
			int     31h
			jc      NoMemory

			; AX = real mode segment of allocated block
			and     eax, 0FFFFh
			mov     BufferSeg, ax
			shl     eax, 4      ; EAX = 32-bit pointer to DOS memory
			mov     BufferPtr, eax
GotDosMemory:


			; Get SuperVGA information
			mov     ax, BufferSeg
			mov     regs.RealEDI, 0
			mov     regs.RealESI, 0
			mov     regs.RealEBP, 0
			mov     regs.Reserved, 0
			mov     regs.RealEBX, 0
			mov     regs.RealEDX, 0
			mov     regs.RealECX, 0
			mov     regs.RealEAX, 04f00h
			mov     regs.RealFlags, 0
			mov     regs.RealES, ax
			mov     regs.RealDS, 0
			mov     regs.RealFS, 0
			mov     regs.RealGS, 0
			mov     regs.RealIP, 0
			mov     regs.RealCS, 0
			mov     regs.RealSP, 0
			mov     regs.RealSS, 0

			mov     bl, 10h
			xor     bh, bh
			xor     ecx, ecx
			mov     edi, offset regs
			mov     ax, 0300h
			int     31h

			mov     eax, regs.RealEAX
			cmp     ax, 04fh
			jne     NoVESADriver

			; Make sure there is a VESA signature
			mov     eax, BufferPtr
			cmp     dword ptr[eax+0], VESA_Signature
			jne     NoVESADriver

			; We now have a valid VESA driver loaded

			mov     bx, word ptr [eax+4]
			mov     VESAVersion, bx

			mov     ebx, dword ptr [eax+6]
			call    EBXFarTo32
			mov     OEMStringPtr, ebx

			mov     ebx, dword ptr [eax+10]
			mov     Capabilities, ebx

			mov     bx, word ptr [eax+18]
			mov     TotalMemory, bx

			mov     ebx, dword ptr [eax+14]
			call    EBXFarTo32
			mov     VideoModePtr, ebx

TryAnotherMode:
			mov     ax, word ptr [ebx]
			add     ebx, 2
			cmp     ax, GoalMode
			je      ModeSupported
			cmp     ax, -1
			je      ModeNotSupported
			jmp     TryAnotherMode

ModeSupported:

			; Get SuperVGA information
			mov     ax, BufferSeg
			movzx   ecx, GoalMode
			mov     regs.RealEDI, 0
			mov     regs.RealESI, 0
			mov     regs.RealEBP, 0
			mov     regs.Reserved, 0
			mov     regs.RealEBX, 0
			mov     regs.RealEDX, 0
			mov     regs.RealECX, ecx
			mov     regs.RealEAX, 04f01h
			mov     regs.RealFlags, 0
			mov     regs.RealES, ax
			mov     regs.RealDS, 0
			mov     regs.RealFS, 0
			mov     regs.RealGS, 0
			mov     regs.RealIP, 0
			mov     regs.RealCS, 0
			mov     regs.RealSP, 0
			mov     regs.RealSS, 0

			mov     bl, 10h
			xor     bh, bh
			xor     cx, cx
			mov     edi, offset regs
			mov     ax, 0300h
			int     31h

			mov     eax, regs.RealEAX
			cmp     ax, 04fh
			jne     BadStatus

			; Check if this mode supported by hardware.
			mov     eax, BufferPtr
			mov     bx, [eax]
			bt      bx, 0
			jnc     HardwareNotSupported


			mov     bx, [eax+4]
			cmp     bx, 64
			jne     @f
			mov     PageSizeShift, 0
			jmp     GranularityOK
@@:         		cmp     bx, 32
			jne     @f
			mov     PageSizeShift, 1
			jmp     GranularityOK
@@:         		cmp     bx, 16
			jne     @f
			mov     PageSizeShift, 2
			jmp     GranularityOK
@@:         		cmp     bx, 8
			jne     @f
			mov     PageSizeShift, 3
			jmp     GranularityOK
@@:         		cmp     bx, 4
			jne     @f
			mov     PageSizeShift, 4
			jmp     GranularityOK
@@:         		cmp     bx, 2
			jne     @f
			mov     PageSizeShift, 5
			jmp     GranularityOK
@@:         		cmp     bx, 1
			jne     WrongGranularity
			mov     PageSizeShift, 6

GranularityOK:
			shl     bx, 10
			mov     WinGranularity, bx

			mov     bx, [eax+6]
			mov     WinSize, bx

			mov     ebx, [eax+12]
			call    EBXFarTo32
			mov     WinFuncPtr, ebx

			movzx   ebx, word ptr [eax+16]

NoError:
			mov     vesa_error, 0
			jmp     Done

WrongGranularity:
			mov     vesa_error, 2
			jmp     Done

HardwareNotSupported:
			mov     vesa_error, 3
			jmp     Done

ModeNotSupported:
			mov     vesa_error, 4
			jmp     Done

NoVESADriver:
			mov     vesa_error, 5
			jmp     Done

BadStatus:
			mov     vesa_error, 6
			jmp     Done

NoMemory:
			mov     vesa_error, 7
			jmp	Done

DPMIError:
			mov     vesa_error, 8

Done:			popad
			mov	eax, vesa_error

			ret

PUBLIC  gr_get_dos_mem_

gr_get_dos_mem_:
			
		; eax = how many bytes

		push	ebx
		
		mov	ebx, eax
		shr	ebx, 4
		mov	eax, 0100h
		int	31h
		jc	nomem
		and	eax, 0ffffh
		shl	eax, 4
		pop	ebx
		ret

nomem:		pop	ebx
		mov	eax,0
		ret
		



PUBLIC gr_vesa_setmodea_

gr_vesa_setmodea_:

		; eax = mode
		pushad
		mov	ebx, eax				
		mov     eax, 04f02h
		int     10h
		cmp     ax, 04fh
		jne     BadStatus
		jmp	NoError

PUBLIC  gr_vesa_setpage_

gr_vesa_setpage_:

			; EAX = 64K Page number

			cmp     al, LastPage
			jne     @f
			ret
@@:         		mov     LastPage, al
			push    edx
			push    ebx
			push    ecx
			mov     edx, eax
			mov     cl, PageSizeShift
			shl     edx, cl         ; Convert from 64K pages to GranUnit pages.
			xor     ebx, ebx        ; BH=Select window, BL=Window A
			mov     eax, 04f05h     ; AX=Super VGA video memory window control
			int     10h
			pop     ecx
			pop     ebx
			pop     edx
			ret

PUBLIC  gr_vesa_setaddress_

gr_vesa_setaddress_:
			; EAX = Address of video memory to write to
			push    edx
			push    ebx
			push    ecx
			mov     edx, eax
			shl     edx, 12         ; Convert from address pages to 4k GranUnit pages.
			xor     ebx, ebx        ; BH=Select window, BL=Window A
			mov     eax, 04f05h     ; AX=Super VGA video memory window control
			int     10h
			pop     ecx
			pop     ebx
			pop     edx
			ret

PUBLIC  gr_vesa_incpage_

gr_vesa_incpage_:

			push    eax
			push    ebx
			push    ecx
			push    edx
			push    ebp
			inc     LastPage
			mov     dl, LastPage
			mov     cl, PageSizeShift
			shl     edx, cl         ; Convert from 64K pages to GranUnit pages.
			xor     ebx, ebx        ; BH=Select window, BL=Window A
			mov     eax, 04f05h     ; AX=Super VGA video memory window control
			int     10h
			pop     ebp
			pop     edx
			pop     ecx
			pop     ebx
			pop     eax
			ret


PUBLIC  gr_vesa_setstart_

gr_vesa_setstart_:

			; EAX = First column
			; EDX = First row
			push    ebx
			push    ecx
			mov     ecx, eax
			mov     eax, 4f07h
			xor     ebx, ebx
			int     10h
			pop     ecx
			pop     ebx
			ret


PUBLIC  gr_vesa_setlogical_

gr_vesa_setlogical_:

			; EAX = line width
			push    ebx
			push    ecx
			push    edx

			mov     cx, ax
			mov     ax, 04f06h
			mov     bl, 0
			int     10h
			and     ebx, 0FFFFh
			mov     ax, cx

			pop     edx
			pop     ecx
			pop     ebx
			ret



PUBLIC gr_vesa_scanline_

gr_vesa_scanline_:

			; EAX = x1
			; EDX = x2
			; EBX = y
			; ECX = color

			push    edi
			cld
			cmp     edx, eax
			jge     @f
			xchg    edx, eax

@@:         		mov     edi, ebx
			imul    edi, _gr_var_bwidth
			add     edi, eax        ; EDI = y*bpr+x1
			sub     edx, eax        ; ECX = x2-x1
			inc     edx

			mov     eax, edi
			shr     eax, 16

			cmp     al, LastPage
			je      @f
			mov     LastPage, al
			push    edx
			push    ecx
			mov     edx, eax
			mov     cl, PageSizeShift
			shl     edx, cl         ; Convert from 64K pages to GranUnit pages.
			xor     ebx, ebx        ; BH=Select window, BL=Window A
			mov     eax, 04f05h     ; AX=Super VGA video memory window control
			int     10h
			pop     ecx
			pop     edx

@@:         		and     edi, 00FFFFh
			or      edi, 0A0000h

			;mov     eax, _Table8to32[ecx*4]
			mov	ch, cl
			mov	ax, cx
			shl	eax, 16
			mov	ax, cx

			; edx = width in bytes
			; edi = dest
			mov     bx, dx
			add     bx, di
			jnc     scanonepage

			sub     dx, bx
			movzx   ecx, dx
			
			shr	ecx, 1			
			rep     stosw
			adc	ecx, ecx
			rep	stosb

			movzx   edx, bx
			cmp     edx, 0
			je      scandone

			call    gr_vesa_incpage_
			mov     edi, 0A0000h

scanonepage:
			movzx   ecx, dx

			shr	ecx, 1			
			rep     stosw
			adc	ecx, ecx
			rep	stosb

scandone:

			pop     edi
			ret


PUBLIC gr_vesa_set_logical_

gr_vesa_set_logical_:

			; EAX = logical width in pixels

			push    ebx
			push    ecx

			mov     ecx, eax
			mov     eax, 04f06h
			mov     bl, 0
			int     10h
			and     ebx, 0ffffh

			movzx   eax, cx

			pop     ecx
			pop     ebx

			ret


PUBLIC gr_vesa_pixel_

gr_vesa_pixel_:

			; EAX = color (in AL)
			; EDX = offset from 0A0000

			shld    eax, edx, 16
			and     edx, 0ffffh
			cmp     al, LastPage
			jne     @f
			shr     eax, 16
			mov     [edx+0A0000h], al
			ret

@@:         mov     LastPage, al
			pushad
			and     eax, 0fh
			mov     edx, eax
			mov     cl, PageSizeShift
			shl     edx, cl         ; Convert from 64K pages to GranUnit pages.
			xor     ebx, ebx        ; BH=Select window, BL=Window A
			mov     eax, 04f05h     ; AX=Super VGA video memory window control
			int     10h
			popad

			shr     eax, 16
			mov     [edx+0A0000h], al
			ret


PUBLIC gr_vesa_bitblt_

gr_vesa_bitblt_:

			; EAX = source_ptr
			; EDX = vesa_address
			; EBX = height
			; ECX = width

			push    edi
			push    esi

			mov     esi, eax        ; Point ESI to source bitmap

			; Set the initial page
			mov     eax, edx            ; Move offset into SVGA into eax
			shr     eax, 16             ; Page = offset / 64K
			call    gr_vesa_setpage_

			mov     edi, edx            ; EDI = offset into SVGA
			and     edi,  0FFFFh        ; EDI = offset into 64K page
			add     edi, 0A0000h        ; EDI = ptr to dest


			mov     edx, _gr_var_bwidth
			sub     edx, ecx            ; EDX = amount to step each row


			mov     eax, ecx

NextScanLine:
			push    eax
			MyMovsd eax
			pop     eax

			dec     ebx
			jz      DoneBlt

			add     di, dx
			jnc     NextScanLine

			; Need to increment page!
			call    gr_vesa_incpage_
			jmp     NextScanLine

DoneBlt:    pop     esi
			pop     edi

			ret

PUBLIC gr_vesa_bitmap_

gr_vesa_bitmap_:

			; EAX = Source bitmap       (LINEAR)
			; EDX = Destination bitmap  (SVGA)
			; EBX = x
			; ECX = y

			push    esi
			push    edi
			push    ebp
			push    es

			push    eax
			mov     eax, [edx].bm_data
			imul    ecx, _gr_var_bwidth
			add     eax, ecx
			add     eax, ebx
			mov     edi, eax            ; EDI = offset into SVGA
			shr     eax, 16
			call    gr_vesa_setpage_

			mov     ax, __A0000
			mov     es, ax
			pop     eax

			mov     esi, [eax].bm_data
			and     edi, 0ffffh

			movzx   ecx, [eax].bm_h

NextScanLine1:
				push    ecx
				movzx   ecx, [eax].bm_w
				mov     bx, cx
				add     bx, di
				jnc     OnePage

				sub     cx,bx
				mov     ebp, ecx
				MyMovsd ebp
				and     edi, 00ffffh        ; IN CASE IT WENT OVER 64K
				mov     cx,bx
				call    gr_vesa_incpage_
				jcxz    DoneWithLine
OnePage:
				mov     ebp, ecx
				MyMovsd ebp
				and     edi, 00ffffh        ; IN CASE IT WENT OVER 64K

DoneWithLine:   mov     bx, [eax].bm_rowsize
				sub     bx, [eax].bm_w
				and     ebx, 0ffffh
				add     esi, ebx
				mov     bx, [edx].bm_rowsize
				sub     bx, [eax].bm_w
				add     di, bx
				jnc     NoPageInc
				call    gr_vesa_incpage_
NoPageInc:  pop     ecx
			dec     ecx
			jz      @f
			jmp     NextScanLine1

@@:

			pop es
			pop ebp
			pop edi
			pop esi
			ret




PUBLIC gr_vesa_update_

gr_vesa_update_:

			; EAX = Source bitmap       (LINEAR)
			; EDX = Destination bitmap  (SVGA)
			; EBX = Old source bitmap   (LINEAR)

			push    ecx
			push    esi
			push    edi
			push    ebp
			push    fs

			push    eax
			mov     eax, [edx].bm_data
			mov     ebp, eax            ; EDI = offset into SVGA
			shr     eax, 16
			call    gr_vesa_setpage_

			mov     ax, __A0000
			mov     fs, ax
			pop     eax

			mov     esi, [eax].bm_data
			and     ebp, 0ffffh

			movzx   ecx, [eax].bm_h

			mov     edi, [ebx].bm_data

			movzx   ebx, [eax].bm_rowsize
			sub     bx, [eax].bm_w
			mov     SourceInc, ebx

			movzx   ebx, [edx].bm_rowsize
			sub     bx, [eax].bm_w
			mov     DestInc, bx

			movzx   ebx, [eax].bm_w
			mov     RowWidth, ebx

NextScanLine3:
				push    ecx
				mov     ecx, RowWidth
				mov     dx, cx
				add     dx, bp
				jnc     OnePage3

				sub     cx,dx
				mov     ebx, esi

InnerLoop3:     repe    cmpsb
				mov     al, [esi-1]
				sub     esi, ebx
				mov     fs:[ebp+esi-1], al       ; EDX = dest + size - bytes to end
				add     esi, ebx
				cmp     ecx, 0
				jne     InnerLoop3

				sub     esi, ebx
				add     ebp, esi
				add     esi, ebx
				and     ebp, 00ffffh        ; IN CASE IT WENT OVER 64K

				mov     cx,dx
				call    gr_vesa_incpage_
				jcxz    DoneWithLine3
OnePage3:
				mov     ebx, esi
				mov     edx, ecx
				and     edx, 11b
				shr     ecx, 2

InnerLoop4:     repe    cmpsd
				mov     eax, [esi-4]
				sub     esi, ebx
				mov     fs:[ebp+esi-4], eax       ; EDX = dest + size - bytes to end
				add     esi, ebx
				cmp     ecx, 0
				jne     InnerLoop4

				mov     ecx, edx
				jecxz   EvenWidth
InnerLoop5:     repe    cmpsb
				mov     al, [esi-1]
				sub     esi, ebx
				mov     fs:[ebp+esi-1], al       ; EDX = dest + size - bytes to end
				add     esi, ebx
				cmp     ecx, 0
				jne     InnerLoop5

EvenWidth:      sub     esi, ebx
				add     ebp, esi
				add     esi, ebx
				and     ebp, 00ffffh        ; IN CASE IT WENT OVER 64K

DoneWithLine3:
				add     esi, SourceInc
				add     edi, SourceInc
				add     bp, DestInc
				jnc     NoPageInc3
				call    gr_vesa_incpage_
NoPageInc3: pop     ecx
			dec     ecx
			jnz     NextScanLine3

			pop     fs
			pop     ebp
			pop     edi
			pop     esi
			pop     ecx
			ret




_TEXT   ENDS


		END



