LCWUNCMP.ASM 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292
  1. ;
  2. ; Command & Conquer Red Alert(tm)
  3. ; Copyright 2025 Electronic Arts Inc.
  4. ;
  5. ; This program is free software: you can redistribute it and/or modify
  6. ; it under the terms of the GNU General Public License as published by
  7. ; the Free Software Foundation, either version 3 of the License, or
  8. ; (at your option) any later version.
  9. ;
  10. ; This program is distributed in the hope that it will be useful,
  11. ; but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ; GNU General Public License for more details.
  14. ;
  15. ; You should have received a copy of the GNU General Public License
  16. ; along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. ;
  18. ; $Header: g:/library/wwlib32/misc/rcs/lcwuncmp.asm 1.1 1994/04/11 15:31:21 jeff_wilson Exp $
  19. ;***************************************************************************
  20. ;** 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 **
  21. ;***************************************************************************
  22. ;* *
  23. ;* Project Name : Library routine *
  24. ;* *
  25. ;* File Name : UNCOMP.ASM *
  26. ;* *
  27. ;* Programmer : Christopher Yates *
  28. ;* *
  29. ;* Last Update : 20 August, 1990 [CY] *
  30. ;* *
  31. ;*-------------------------------------------------------------------------*
  32. ;* Functions: *
  33. ;* *
  34. ; ULONG LCW_Uncompress(BYTE *source, BYTE *dest, ULONG length); *
  35. ;* *
  36. ;* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
  37. IDEAL
  38. P386
  39. MODEL USE32 FLAT
  40. GLOBAL C LCW_Uncompress :NEAR
  41. CODESEG
  42. ; ----------------------------------------------------------------
  43. ;
  44. ; Here are prototypes for the routines defined within this module:
  45. ;
  46. ; ULONG LCW_Uncompress(BYTE *source, BYTE *dest, ULONG length);
  47. ;
  48. ; ----------------------------------------------------------------
  49. PROC LCW_Uncompress C near
  50. USES ebx,ecx,edx,edi,esi
  51. ARG source:DWORD
  52. ARG dest:DWORD
  53. ARG length:DWORD
  54. ;LOCALS
  55. LOCAL a1stdest:DWORD
  56. LOCAL maxlen:DWORD
  57. LOCAL lastbyte:DWORD
  58. LOCAL lastcom:DWORD
  59. LOCAL lastcom1:DWORD
  60. mov edi,[dest]
  61. mov esi,[source]
  62. mov edx,[length]
  63. ;
  64. ;
  65. ; uncompress data to the following codes in the format b = byte, w = word
  66. ; n = byte code pulled from compressed data
  67. ; Bit field of n command description
  68. ; n=0xxxyyyy,yyyyyyyy short run back y bytes and run x+3
  69. ; n=10xxxxxx,n1,n2,...,nx+1 med length copy the next x+1 bytes
  70. ; n=11xxxxxx,w1 med run run x+3 bytes from offset w1
  71. ; n=11111111,w1,w2 long copy copy w1 bytes from offset w2
  72. ; n=11111110,w1,b1 long run run byte b1 for w1 bytes
  73. ; n=10000000 end end of data reached
  74. ;
  75. mov [a1stdest],edi
  76. add edx,edi
  77. mov [lastbyte],edx
  78. cld ; make sure all lod and sto are forward
  79. mov ebx,esi ; save the source offset
  80. ??loop:
  81. mov eax,[lastbyte]
  82. sub eax,edi ; get the remaining byte to uncomp
  83. jz short ??out ; were done
  84. mov [maxlen],eax ; save for string commands
  85. mov esi,ebx ; mov in the source index
  86. xor eax,eax
  87. mov al,[esi]
  88. inc esi
  89. test al,al ; see if its a short run
  90. js short ??notshort
  91. mov ecx,eax ;put count nibble in cl
  92. mov ah,al ; put rel offset high nibble in ah
  93. and ah,0Fh ; only 4 bits count
  94. shr cl,4 ; get run -3
  95. add ecx,3 ; get actual run length
  96. cmp ecx,[maxlen] ; is it too big to fit?
  97. jbe short ??rsok ; if not, its ok
  98. mov ecx,[maxlen] ; if so, max it out so it dosen't overrun
  99. ??rsok:
  100. mov al,[esi] ; get rel offset low byte
  101. lea ebx,[esi+1] ; save the source offset
  102. mov esi,edi ; get the current dest
  103. sub esi,eax ; get relative offset
  104. rep movsb
  105. jmp ??loop
  106. ??notshort:
  107. test al,40h ; is it a length?
  108. jne short ??notlength ; if not it could be med or long run
  109. cmp al,80h ; is it the end?
  110. je short ??out ; if so its over
  111. mov cl,al ; put the byte in count register
  112. and ecx,3Fh ; and off the extra bits
  113. cmp ecx,[maxlen] ; is it too big to fit?
  114. jbe short ??lenok ; if not, its ok
  115. mov ecx,[maxlen] ; if so, max it out so it dosen't overrun
  116. ??lenok:
  117. rep movsb
  118. mov ebx,esi ; save the source offset
  119. jmp ??loop
  120. ??out:
  121. mov eax,edi
  122. sub eax,[a1stdest]
  123. jmp ??exit
  124. ??notlength:
  125. mov cl,al ; get the entire code
  126. and ecx,3Fh ; and off all but the size -3
  127. add ecx,3 ; add 3 for byte count
  128. cmp al,0FEh
  129. jne short ??notrunlength
  130. xor ecx,ecx
  131. mov cx,[esi]
  132. xor eax,eax
  133. mov al,[esi+2]
  134. lea ebx,[esi+3] ;save the source offset
  135. cmp ecx,[maxlen] ; is it too big to fit?
  136. jbe short ??runlenok ; if not, its ok
  137. mov ecx,[maxlen] ; if so, max it out so it dosen't overrun
  138. ??runlenok:
  139. test ecx,0ffe0h
  140. jnz ??dont_use_stosb
  141. rep stosb
  142. jmp ??loop
  143. ??dont_use_stosb:
  144. mov ah,al
  145. mov edx,eax
  146. shl eax,16
  147. or eax,edx
  148. test edi,3
  149. jz ??aligned
  150. mov [edi],eax
  151. mov edx,edi
  152. and edi,0fffffffch
  153. lea edi,[edi+4]
  154. and edx,3
  155. dec dl
  156. xor dl,3
  157. sub ecx,edx
  158. ??aligned:
  159. mov edx,ecx
  160. shr ecx,2
  161. rep stosd
  162. and edx,3
  163. jz ??loop
  164. mov ecx,edx
  165. rep stosb
  166. jmp ??loop
  167. ??notrunlength:
  168. cmp al,0FFh ; is it a long run?
  169. jne short ??notlong ; if not use the code as the size
  170. xor ecx,ecx
  171. xor eax,eax
  172. mov cx,[esi] ; if so, get the size
  173. lea esi,[esi+2]
  174. ??notlong:
  175. mov ax,[esi] ;get the real index
  176. add eax,[a1stdest] ;add in the 1st index
  177. lea ebx,[esi+2] ;save the source offset
  178. cmp ecx,[maxlen] ;compare for overrun
  179. mov esi,eax ;use eax as new source
  180. jbe short ??runok ; if not, its ok
  181. mov ecx,[maxlen] ; if so, max it out so it dosen't overrun
  182. ??runok:
  183. test ecx,0ffe0h
  184. jnz ??dont_use_movsb
  185. rep movsb
  186. jmp ??loop
  187. ??dont_use_movsb:
  188. lea edx,[edi+0fffffffch]
  189. cmp esi,edx
  190. ja ??use_movsb
  191. test edi,3
  192. jz ??aligned2
  193. mov eax,[esi]
  194. mov [edi],eax
  195. mov edx,edi
  196. and edi,0fffffffch
  197. lea edi,[edi+4]
  198. and edx,3
  199. dec dl
  200. xor dl,3
  201. sub ecx,edx
  202. add esi,edx
  203. ??aligned2:
  204. mov edx,ecx
  205. shr ecx,2
  206. and edx,3
  207. rep movsd
  208. mov ecx,edx
  209. ??use_movsb:
  210. rep movsb
  211. jmp ??loop
  212. ??exit:
  213. mov eax,edi
  214. mov ebx,[dest]
  215. sub eax,ebx
  216. ret
  217. ENDP LCW_Uncompress
  218. ;***********************************************************
  219. END