;///////////////////////////////////////////////////////////////////////////////
;/// @file memccpy.asm
;///
;/// @brief Destiny3D Memory Manager memccpy replacement
;///
;/// @author Lightning
;///
;/// This file is the intellectual property of Novus Delta, LLC.. Usage of the
;/// contents of this file is subject to the Destiny3D Member License which
;/// can be found at http://www.destiny3d.com.  Any other usage is prohibited.
;///
;/// This file is distributed "AS IS" without warranty of any kind.  Novus
;/// Delta, LLC. does not guarantee the fitness of the contents of this file
;/// for any particular purpose.
;///
;/// Copyright (C) 2001-2003 Novus Delta, LLC. All Rights Reserved.
;///
;/// <hr>
;///                                 Change History
;/// <hr>
;///
;/// @date May 2001
;/// @author Lightning
;/// @remarks Creation
;///
;///////////////////////////////////////////////////////////////////////////////

.586p					;pentium commands allowed
.mmx					;MMX allowed
.k3d					;3DNow allowed
.model flat, C

.CODE

;i take care of pushing and popping edi, esi, ebp, and ebx if I need to use them
;as it makes it easier to cut down on the code that the function goes thru

Internal_ASM_memccpy proc
	;the Paramaters are void *Ptr1, const void *Ptr2, char c, long Len

	push ebx
	mov ebx, esp
	align 4

	;divide by 16, edx = remainder
	mov edi, [ebx + 0Ch]	;Ptr2
	mov eax, [ebx + 14h]	;Len
	mov edx, [ebx + 08h]	;Ptr1
	mov ebx, [ebx + 10h]	;c

	push eax

	;bl = character to compare against
	mov bh, bl
	ror ebx, 8
	mov bh, bl
	ror ebx, 8
	mov bh, bl

	and eax, 0FFFFFFFCh
	jz Check3Bytes

	MemccpyLoop:
		mov ecx, [edx]
		xor ecx, ebx
		
		test ecx, 0000000FFh
		jz short Found_1

		test ecx, 00000FF00h
		jz short Found_2

		test ecx, 000FF0000h
		jz short Found_3

		test ecx, 0FF000000h
		jz short Found_4

		xor ecx, ebx
		mov [edi], ecx

		add edx, 4
		add edi, 4
		sub eax, 4
		jnz short MemccpyLoop

	Check3Bytes:
		pop eax
		push 0h			;push so that the Found's will work
		mov ecx, [edx]
		xor ecx, ebx
		and eax, 3
		jmp dword ptr CheckArray[eax * 4]

	Found_4:
		pop eax
		xor ecx, ebx
		mov [edi], ecx
		pop ebx
		mov eax, edx
		add eax, 4
		ret

	Found_1:
		pop eax
		xor ecx, ebx
		mov ebx, [edi]
		and ecx, 0000000FFh
		and ebx, 0FFFFFF00h
		or ecx, ebx
		mov [edi], ecx
		pop ebx
		mov eax, edx
		inc eax
		ret

	Found_2:
		pop eax
		xor ecx, ebx
		mov ebx, [edi]
		and ecx, 00000FFFFh
		and ebx, 0FFFF0000h
		or ecx, ebx
		mov [edi], ecx
		pop ebx
		mov eax, edx
		add eax, 2
		ret

	Found_3:
		pop eax
		xor ecx, ebx
		mov ebx, [edi]
		and ecx, 000FFFFFFh
		and ebx, 0FF000000h
		or ecx, ebx
		mov [edi], ecx
		pop ebx
		mov eax, edx
		add eax, 3
		ret

	Check1:
		test ecx, 0000000FFh
		jz short Found_1

		pop eax
		pop ebx
		ret

	Check2:
		test ecx, 0000000FFh
		jz short Found_1

		test ecx, 00000FF00h
		jz short Found_2

		pop eax
		pop ebx
		ret

	Check3:
		test ecx, 0000000FFh
		jz short Found_1

		test ecx, 00000FF00h
		jz short Found_2

		test ecx, 000FF0000h
		jz short Found_3

		pop eax
		pop ebx
		ret

	CheckDone:
		pop eax
		pop ebx
		ret

	CheckArray dd CheckDone, Check1, Check2, Check3

Internal_ASM_memccpy endp

END