185 lines
6.5 KiB
NASM
185 lines
6.5 KiB
NASM
![]() |
;
|
|||
|
; Command & Conquer Red Alert(tm)
|
|||
|
; Copyright 2025 Electronic Arts Inc.
|
|||
|
;
|
|||
|
; This program is free software: you can redistribute it and/or modify
|
|||
|
; it under the terms of the GNU General Public License as published by
|
|||
|
; the Free Software Foundation, either version 3 of the License, or
|
|||
|
; (at your option) any later version.
|
|||
|
;
|
|||
|
; This program is distributed in the hope that it will be useful,
|
|||
|
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|||
|
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|||
|
; GNU General Public License for more details.
|
|||
|
;
|
|||
|
; You should have received a copy of the GNU General Public License
|
|||
|
; along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
|
;
|
|||
|
|
|||
|
;***************************************************************************
|
|||
|
;** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S **
|
|||
|
;***************************************************************************
|
|||
|
;* *
|
|||
|
;* Project Name : LIBRARY *
|
|||
|
;* *
|
|||
|
;* File Name : MEM_COPY.ASM *
|
|||
|
;* *
|
|||
|
;* Programmer : Scott Bowen *
|
|||
|
;* *
|
|||
|
;* Last Update : September 8, 1994 [IML] *
|
|||
|
;* Ported to watcom c32 : 01/03/96 [JRJ] *
|
|||
|
;*-------------------------------------------------------------------------*
|
|||
|
;* Functions: *
|
|||
|
;* Mem_Copy -- Copies from one pointer to another. *
|
|||
|
;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
|
|||
|
|
|||
|
IDEAL
|
|||
|
P386
|
|||
|
MODEL USE32 FLAT
|
|||
|
|
|||
|
|
|||
|
LOCALS ??
|
|||
|
|
|||
|
|
|||
|
;******************************************************************************
|
|||
|
; Much testing was done to determine that only when there are 14 or more bytes
|
|||
|
; being copied does it speed the time it takes to do copies in this algorithm.
|
|||
|
; For this reason and because 1 and 2 byte copies crash, is the special case
|
|||
|
; used. SKB 4/21/94. Tested on 486 66mhz.
|
|||
|
OPTIMAL_BYTE_COPY equ 14
|
|||
|
|
|||
|
|
|||
|
;******************************************************************************
|
|||
|
; External declares so these functions can be called
|
|||
|
;
|
|||
|
GLOBAL C Mem_Copy : NEAR
|
|||
|
GLOBAL C Largest_Mem_Block : near
|
|||
|
|
|||
|
CODESEG
|
|||
|
|
|||
|
|
|||
|
;***************************************************************************
|
|||
|
;* MEM_COPY -- Copies from one pointer to another. *
|
|||
|
;* This routine copies bytes from source to dest. It takes care of *
|
|||
|
;* overlapped memory, and unsigned long copies. *
|
|||
|
;* *
|
|||
|
;* *
|
|||
|
;* *
|
|||
|
;* *
|
|||
|
;* INPUT: *
|
|||
|
;* *
|
|||
|
;* OUTPUT: *
|
|||
|
;* *
|
|||
|
;* WARNINGS: *
|
|||
|
;* *
|
|||
|
;* HISTORY: *
|
|||
|
;* 04/18/1994 SKB : Created. *
|
|||
|
;*=========================================================================*
|
|||
|
; void Mem_Copy(void *source, void *dest, unsigned long bytes_to_copy);
|
|||
|
|
|||
|
|
|||
|
PROC Mem_Copy C near
|
|||
|
USES ecx , esi , edi , ebx
|
|||
|
ARG source:DWORD
|
|||
|
ARG dest:DWORD
|
|||
|
ARG bytes:DWORD
|
|||
|
|
|||
|
;********************************* Setup ******************************************
|
|||
|
cld
|
|||
|
mov esi,[source]
|
|||
|
mov edi,[dest]
|
|||
|
mov ecx,[bytes] ; get number of bytes to copy.
|
|||
|
|
|||
|
; check pointers for singularities
|
|||
|
cmp esi,edi ; Compare source with dest.
|
|||
|
je ??done ; No sence in copying the same pointer.
|
|||
|
or esi,0
|
|||
|
jz ??done
|
|||
|
or edi,0
|
|||
|
jz ??done
|
|||
|
|
|||
|
cmp ecx,OPTIMAL_BYTE_COPY ; see notes above about equate.
|
|||
|
jge ??normal ; If >= MAX(2,OPTIMAL_BYTE_COPY), do normal dword copy.
|
|||
|
|
|||
|
;******************************** Special case <= 2 *******************************
|
|||
|
;
|
|||
|
; This section must be called for bytes <= 2 since the other case will crash. It
|
|||
|
; optionally uses OPTIMAL_BYTE_COPY for the cut off point. This is because after
|
|||
|
; extensive testing, it was proved that only at that point (14 or more bytes) does
|
|||
|
; it become quicker to use the dword copy method.
|
|||
|
|
|||
|
cmp esi,edi ; Compare source with dest.
|
|||
|
jge ??do_move ; if source greater do forward copy.
|
|||
|
lea esi,[esi+ecx-1]
|
|||
|
std ; Opps, wrong, force the pointers to decrement.
|
|||
|
lea edi,[edi+ecx-1]
|
|||
|
??do_move:
|
|||
|
rep movsb ; move the one or two bytes.
|
|||
|
cld
|
|||
|
??done:
|
|||
|
ret
|
|||
|
|
|||
|
;************************** back or forth, that is the question *******************
|
|||
|
|
|||
|
??normal:
|
|||
|
mov ebx,ecx
|
|||
|
cmp esi,edi ; Compare source with dest.
|
|||
|
jge ??forward ; if source greater do forward copy.
|
|||
|
|
|||
|
;********************************* Backward ***************************************
|
|||
|
??backward:
|
|||
|
lea ecx,[edi+ebx]
|
|||
|
std
|
|||
|
lea edi,[edi+ebx-1]
|
|||
|
and ecx,3 ; Get non aligned bytes.
|
|||
|
lea esi,[esi+ebx-1]
|
|||
|
sub ebx,ecx ; remove that from the total size to be copied later.
|
|||
|
rep movsb ; do the copy.
|
|||
|
sub esi,3
|
|||
|
mov ecx,ebx ; Get number of bytes left.
|
|||
|
sub edi,3
|
|||
|
shr ecx,2 ; Do 4 bytes at a time.
|
|||
|
rep movsd ; do the dword copy.
|
|||
|
mov ecx,ebx
|
|||
|
add esi,3
|
|||
|
add edi,3
|
|||
|
and ecx,03h
|
|||
|
rep movsb ; finnish the remaining bytes.
|
|||
|
cld
|
|||
|
ret
|
|||
|
|
|||
|
;********************************* Forward ***************************************
|
|||
|
??forward:
|
|||
|
cld
|
|||
|
mov ecx,edi ; get destination pointer.
|
|||
|
neg ecx
|
|||
|
and ecx,3 ; Get non aligned bytes.
|
|||
|
sub ebx,ecx ; remove that from the total size to be copied later.
|
|||
|
rep movsb ; do the copy.
|
|||
|
mov ecx,ebx ; Get number of bytes left.
|
|||
|
shr ecx,2 ; Do 4 bytes at a time.
|
|||
|
rep movsd ; do the dword copy.
|
|||
|
mov ecx, ebx
|
|||
|
and ecx,03h
|
|||
|
rep movsb ; finnish the remaining bytes.
|
|||
|
ret
|
|||
|
|
|||
|
ENDP Mem_Copy
|
|||
|
IF 0
|
|||
|
PROC Largest_Mem_Block C near
|
|||
|
uses esi , edi , ebx , ecx , edx
|
|||
|
local mem_struct : dword : 16
|
|||
|
|
|||
|
mov eax , 0500h
|
|||
|
lea edi , [ mem_struct ]
|
|||
|
int 31h
|
|||
|
mov eax , [ mem_struct ]
|
|||
|
|
|||
|
ret
|
|||
|
ENDP Largest_Mem_Block
|
|||
|
ENDIF
|
|||
|
END
|
|||
|
|
|||
|
|
|||
|
|