| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437 |
- ;
- ; 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 S T U D I O S **
- ;***************************************************************************
- ;* *
- ;* Project Name : Westwood 32 bit Audio Library *
- ;* *
- ;* File Name : AUDUNCMP.ASM *
- ;* *
- ;* Programmer : Phil W. Gorrow *
- ;* *
- ;* Start Date : March 14, 1995 *
- ;* *
- ;* Last Update : June 26, 1995 [PWG] *
- ;* *
- ;*-------------------------------------------------------------------------*
- ;* Functions: *
- ;* Decompress_Frame_Lock -- locks the JLB audio decompression code *
- ;* Decompress_Frame_Unlock -- Unlocks the JLB audio compression code *
- ;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
- IDEAL
- P386
- MODEL USE32 FLAT
- LOCALS ??
- CODESEG
- DPMI_INTR equ 31h
- LABEL LockedCodeStart BYTE
- CODE_2BIT EQU 0
- CODE_4BIT EQU 1
- CODE_RAW EQU 2
- CODE_SILENCE EQU 3
- MAGICNUMBER EQU 00000DEAFh
- MAGICNUMBER2 EQU 0BABEBABEh
- _2bitdecode DB -2,-1,0,1
- _4bitdecode DB -9,-8,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,8
- ;***************************************************************************
- ;* DECOMPRESS_FRAME -- Uncompresses a WW compressed audio frame *
- ;* *
- ;* INPUT: void * source - pointer to encoded audio data *
- ;* void * dest - pointer to decompression area *
- ;* long size - the maximum size of destination buffer *
- ;* *
- ;* OUTPUT: long - the number of bytes we uncompressed *
- ;* *
- ;* PROTO: long Decompress_Frame(void *, void *, long); *
- ;* *
- ;* HISTORY: *
- ;* 03/14/1995 PWG : Created. *
- ;*=========================================================================*
- GLOBAL Decompress_Frame:NEAR
- PROC Decompress_Frame C NEAR USES ebx ecx edx esi edi
- ARG source:DWORD
- ARG dest:DWORD
- ARG count:DWORD
- LOCAL previous:BYTE
- LOCAL incount:DWORD
- pushf
- cld
- mov [incount],0 ;Bytes read from source
- ; Source, Dest and count must be valid.
- cmp [source],0
- je ??fini
- cmp [dest],0
- je ??fini
- cmp [count],0
- je ??fini
- mov esi,[source] ;Pointer to source data.
- mov edi,[dest] ;Pointer to destination data.
- mov ecx,[count] ;Number of bytes to fill dest buffer.
- mov dl,080h ;Previous sample (starting value).
- ??mainloop:
- cmp ecx,0 ;If dest full then exit
- jle ??fini
- xor eax,eax
- mov al,[esi] ;Get code byte
- inc [incount]
- inc esi
- shl eax,2 ;AH contains code.
- shr al,2 ;AL contains sub-code data.
- cmp ah,CODE_RAW ;Raw sequence?
- jne short ??try4bit
- ; The code contains either a 5 bit delta or a count of
- ; raw samples to dump out.
- test al,00100000b
- je short ??justraw
- ; The lower 5 bits are actually a signed delta.
- ; Sign extend the delta and add it to the stream.
- shl al,3
- sar al,3
- add dl,al
- mov [edi],dl
- dec ecx
- inc edi
- jmp ??mainloop
- ; The lower 5 bits hold a count of the number of raw
- ; samples that follow this code. Dump these samples to
- ; the output buffer.
- ??justraw:
- mov ebx,ecx
- xor ah,ah
- inc al
- mov ecx,eax
- shr ecx,1
- rep movsw
- adc ecx,ecx
- rep movsb
- mov ecx,ebx
- add [incount],eax
- sub ecx,eax
- dec edi
- mov dl,[edi] ;Set "previous" value.
- inc edi
- jmp ??mainloop
- ; Check to see if this is a 4 bit delta code sequence.
- ??try4bit:
- inc al ;Following codes use AL+1
- cmp ah,CODE_4BIT
- jne short ??try2bit
- ; A sequence of 4bit deltas follow. AL equals the
- ; number of nibble packed delta bytes to process.
- ??bit4loop:
- mov ah,[esi] ;Fetch nibble packed delta codes
- mov bl,ah
- inc [incount]
- inc esi
- ; Add first delta to 'previous' sample already in DL.
- and ebx,00001111b
- add dl,[_4bitdecode+ebx]
- pushf
- cmp [_4bitdecode+ebx],0
- jl short ??neg1
- popf
- jnc short ??ok1
- mov dl,0FFh
- jmp short ??ok1
- ??neg1:
- popf
- jc short ??ok1
- xor dl,dl
- ??ok1:
- mov dh,dl ;DH now holds new 'previous' sample.
- mov bl,ah
- shr bl,4
- add dh,[_4bitdecode+ebx]
- pushf
- cmp [_4bitdecode+ebx],0
- jl short ??neg2
- popf
- jnc short ??ok2
- mov dh,0FFh
- jmp short ??ok2
- ??neg2:
- popf
- jc short ??ok2
- xor dh,dh
- ??ok2:
- mov [edi],dx ;Output the two sample bytes
- sub ecx,2
- add edi,2
- ; Put the correct 'previous' sample in DL where it belongs.
- mov dl,dh
- ; If there are more deltas to process then loop back.
- dec al
- jnz short ??bit4loop
- jmp ??mainloop
- ; Check to see if 2 bit deltas need to be processed.
- ??try2bit:
- cmp ah,CODE_2BIT
- jne ??zerodelta
- ; A sequence of 2bit deltas follow. AL equals the number of
- ; packed delta bytes to process.
- ??bit2loop:
- mov ah,[esi] ;Fetch packed delat codes
- inc [incount]
- inc esi
- ; Add first delta to 'previous' sample already in DL.
- mov bl,ah
- and ebx,000011b
- add dl,[_2bitdecode+ebx]
- pushf
- cmp [_2bitdecode+ebx],0
- jl short ??neg3
- popf
- jnc short ??ok3
- mov dl,0FFh
- jmp short ??ok3
- ??neg3:
- popf
- jc short ??ok3
- xor dl,dl
- ??ok3:
- mov dh,dl
- ror edx,8
- mov bl,ah
- shr ebx,2
- and bl,00000011b
- add dl,[_2bitdecode+ebx]
- pushf
- cmp [_2bitdecode+ebx],0
- jl short ??neg4
- popf
- jnc short ??ok4
- mov dl,0FFh
- jmp short ??ok4
- ??neg4:
- popf
- jc short ??ok4
- xor dl,dl
- ??ok4:
- mov dh,dl
- ror edx,8
- mov bl,ah
- shr ebx,4
- and bl,00000011b
- add dl,[_2bitdecode+ebx]
- pushf
- cmp [_2bitdecode+ebx],0
- jl short ??neg5
- popf
- jnc short ??ok5
- mov dl,0FFh
- jmp short ??ok5
- ??neg5:
- popf
- jc short ??ok5
- xor dl,dl
- ??ok5:
- mov dh,dl
- ror edx,8
- mov bl,ah
- shr ebx,6
- and bl,00000011b
- add dl,[_2bitdecode+ebx]
- pushf
- cmp [_2bitdecode+ebx],0
- jl short ??neg6
- popf
- jnc short ??ok6
- mov dl,0FFh
- jmp short ??ok6
- ??neg6:
- popf
- jc short ??ok6
- xor dl,dl
- ??ok6:
- ror edx,8
- mov [edi],edx ;Output two sample bytes
- sub ecx,4
- add edi,4
- ; Put the correct 'previous' sample in DL where it belongs.
- rol edx,8
- ; If there are more deltas to process then loop back.
- dec al
- jnz ??bit2loop
- jmp ??mainloop
- ; There is a run of zero deltas. Zero deltas merely duplicate
- ; the 'previous' sample the requested number of times.
- ??zerodelta:
- xor ebx,ebx
- mov bl,al
- mov al,dl
- sub ecx,ebx
- xchg ecx,ebx
- rep stosb
- mov ecx,ebx
- jmp ??mainloop
- ??fini:
- popf
- mov eax,[incount]
- ret
- ENDP Decompress_Frame
- LABEL LockedCodeEnd BYTE
- ;***************************************************************************
- ;* DECOMPRESS_FRAME_LOCK -- locks the JLB audio decompression code *
- ;* *
- ;* INPUT: none *
- ;* *
- ;* OUTPUT: BOOL true is lock sucessful, false otherwise *
- ;* *
- ;* PROTO: BOOL Decompress_Frame_Lock(void); *
- ;* *
- ;* HISTORY: *
- ;* 06/26/1995 PWG : Created. *
- ;*=========================================================================*
- GLOBAL Decompress_Frame_Lock:NEAR
- PROC Decompress_Frame_Lock C NEAR USES ebx ecx edx esi edi
- mov eax,0600h ; function number.
- mov ecx,OFFSET LockedCodeStart ; ecx must have start of memory.
- mov edi,OFFSET LockedCodeEnd ; edi will have size of region in bytes.
- shld ebx,ecx,16
- sub edi, ecx
- shld esi,edi,16
- int DPMI_INTR ; do call.
- jc ??error
- mov eax,1
- jmp ??exit
- ??error:
- xor eax,eax
- ??exit:
- ret
- ENDP Decompress_Frame_Lock
- ;***************************************************************************
- ;* DECOMPRESS_FRAME_UNLOCK -- Unlocks the JLB audio compression code *
- ;* *
- ;* INPUT: none *
- ;* *
- ;* OUTPUT: BOOL true is unlock sucessful, false otherwise *
- ;* *
- ;* PROTO: BOOL Decompress_Frame_Unlock(void); *
- ;* *
- ;* HISTORY: *
- ;* 06/26/1995 PWG : Created. *
- ;*=========================================================================*
- GLOBAL Decompress_Frame_Unlock:NEAR
- PROC Decompress_Frame_Unlock C NEAR USES ebx ecx edx esi edi
- mov eax , 0601h
- mov ecx,OFFSET LockedCodeStart ; ecx must have start of memory.
- mov edi,OFFSET LockedCodeEnd ; edx will have size of region in bytes.
- sub edi,ecx ; - figure size.
- shld ebx , ecx , 16
- shld esi , edi , 16
- int DPMI_INTR ; do call.
- jc ??error
- mov eax,1
- jmp ??exit
- ??error:
- xor eax,eax
- ??exit:
- ret
- ENDP Decompress_Frame_Unlock
- END
|