| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221 |
- ;
- ; 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/>.
- ;
- ; $Header: g:/library/wwlib32/misc/rcs/lcwuncmp.asm 1.1 1994/04/11 15:31:21 jeff_wilson Exp $
- ;***************************************************************************
- ;** 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 routine *
- ;* *
- ;* File Name : UNCOMP.ASM *
- ;* *
- ;* Programmer : Christopher Yates *
- ;* *
- ;* Last Update : 20 August, 1990 [CY] *
- ;* *
- ;*-------------------------------------------------------------------------*
- ;* Functions: *
- ;* *
- ; ULONG LCW_Uncompress(BYTE *source, BYTE *dest, ULONG length); *
- ;* *
- ;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
- IDEAL
- P386
- MODEL USE32 FLAT
- GLOBAL LCW_Uncompress :NEAR
- CODESEG
- ; ----------------------------------------------------------------
- ;
- ; Here are prototypes for the routines defined within this module:
- ;
- ; ULONG LCW_Uncompress(BYTE *source, BYTE *dest, ULONG length);
- ;
- ; ----------------------------------------------------------------
- PROC LCW_Uncompress C near
- USES ebx,ecx,edx,edi,esi
-
- ARG source:DWORD
- ARG dest:DWORD
- ARG length:DWORD
- ;LOCALS
- LOCAL a1stdest:DWORD
- LOCAL maxlen:DWORD
- LOCAL lastbyte:DWORD
- LOCAL lastcom:DWORD
- LOCAL lastcom1:DWORD
- mov edi,[dest]
- mov esi,[source]
- mov edx,[length]
- ;
- ;
- ; uncompress data to the following codes in the format b = byte, w = word
- ; n = byte code pulled from compressed data
- ; Bit field of n command description
- ; n=0xxxyyyy,yyyyyyyy short run back y bytes and run x+3
- ; n=10xxxxxx,n1,n2,...,nx+1 med length copy the next x+1 bytes
- ; n=11xxxxxx,w1 med run run x+3 bytes from offset w1
- ; n=11111111,w1,w2 long copy copy w1 bytes from offset w2
- ; n=11111110,w1,b1 long run run byte b1 for w1 bytes
- ; n=10000000 end end of data reached
- ;
- mov [a1stdest],edi
- add edx,edi
- mov [lastbyte],edx
- cld ; make sure all lod and sto are forward
- mov ebx,esi ; save the source offset
- ??loop:
- mov eax,[lastbyte]
- sub eax,edi ; get the remaining byte to uncomp
- jz short ??out ; were done
-
- mov [maxlen],eax ; save for string commands
- mov esi,ebx ; mov in the source index
- sub eax,eax
- lodsb
- or al,al ; see if its a short run
- js short ??notshort
-
- mov ah,al ; put rel offset high nibble in ah
- and ah,0Fh ; only 4 bits count
-
- sub ecx,ecx
- mov cl,al ; put count nibble in ch
- shr cl,4 ; get run -3
- add ecx,3 ; get actual run length
-
- cmp ecx,[maxlen] ; is it too big to fit?
- jbe short ??rsok ; if not, its ok
-
- mov ecx,[maxlen] ; if so, max it out so it dosen't overrun
- ??rsok:
- lodsb ; get rel offset low byte
- mov ebx,esi ; save the source offset
- mov esi,edi ; get the current dest
- sub esi,eax ; get relative offset
-
- rep movsb
- jmp ??loop
- ??notshort:
- test al,40h ; is it a length?
- jne short ??notlength ; if not it could be med or long run
-
- cmp al,80h ; is it the end?
- je short ??out ; if so its over
-
- mov cl,al ; put the byte in count register
- and ecx,3Fh ; and off the extra bits
-
- cmp ecx,[maxlen] ; is it too big to fit?
- jbe short ??lenok ; if not, its ok
-
- mov ecx,[maxlen] ; if so, max it out so it dosen't overrun
- ??lenok:
- rep movsb
- mov ebx,esi ; save the source offset
- jmp ??loop
- ??out:
- mov eax,edi
- sub eax,[a1stdest]
- jmp short ??exit
- ??notlength:
- mov cl,al ; get the entire code
- and ecx,3Fh ; and off all but the size -3
- add ecx,3 ; add 3 for byte count
-
- cmp al,0FEh
- jne short ??notrunlength
-
- sub eax,eax
- lodsw
-
- mov ecx,eax
-
- sub eax,eax
- lodsb
-
- mov ebx,esi ; save the source offset
- cmp ecx,[maxlen] ; is it too big to fit?
- jbe short ??runlenok ; if not, its ok
-
- mov ecx,[maxlen] ; if so, max it out so it dosen't overrun
- ??runlenok:
- rep stosb
- jmp ??loop
- ??notrunlength:
- cmp al,0FFh ; is it a long run?
- jne short ??notlong ; if not use the code as the size
-
- sub eax,eax
- lodsw ; if so, get the size
- mov ecx,eax ; put int the count byte
- ??notlong:
- lodsw ; get the rel index
- mov ebx,esi ; save the source offset
- add eax,[a1stdest] ; add in the first index
- mov esi,eax ; use this as a source
- cmp ecx,[maxlen] ; is it too big to fit?
- jbe short ??runok ; if not, its ok
-
- mov ecx,[maxlen] ; if so, max it out so it dosen't overrun
- ??runok:
- rep movsb
- jmp ??loop
- ??exit:
- mov eax,edi
- mov ebx,[dest]
- sub eax,ebx
-
- ret
- ENDP LCW_Uncompress
- ;***********************************************************
- END
-
|