SOSCODEC.ASM 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724
  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. ;****************************************************************************
  19. ;*
  20. ;* Copyright (c) 1994, HMI, INC. All Rights Reserved
  21. ;*
  22. ;*---------------------------------------------------------------------------
  23. ;*
  24. ;* FILE
  25. ;* soscodec.asm
  26. ;*
  27. ;* DESCRIPTION
  28. ;* HMI SOS ADPCM compression/decompression.
  29. ;*
  30. ;* PROGRAMMER
  31. ;* Nick Skrepetos
  32. ;* Denzil E. Long, Jr. (Fixed bugs, rewrote for watcom)
  33. ;* Bill Petro (Added stereo support)
  34. ;* Jonathan Lanier
  35. ;*
  36. ;* DATE
  37. ;* Febuary 15, 1995
  38. ;*
  39. ;* LAST MODIFIED
  40. ;* 08/07/95 [jdl] - Rewrote/optimized sosCODECDecompressData
  41. ;*
  42. ;*---------------------------------------------------------------------------
  43. ;*
  44. ;* PUBLIC
  45. ;*
  46. ;****************************************************************************
  47. IDEAL
  48. P386
  49. MODEL USE32 FLAT
  50. LOCALS ??
  51. DPMI_INTR equ 31h
  52. IF_LOCKED_PM_CODE equ 1h ; Locked PM code for DPMI.
  53. IF_LOCKED_PM_DATA equ 2h ; Locked PM code for DPMI.
  54. STRUC sCompInfo
  55. lpSource DD ? ;Compressed data pointer
  56. lpDest DD ? ;Uncompressed data pointer
  57. dwCompSize DD ? ;Compressed size
  58. dwUnCompSize DD ? ;Uncompressed size
  59. dwSampleIndex DD ? ;Index into sample
  60. dwPredicted DD ? ;Next predicted value
  61. dwDifference DD ? ;Difference from last sample
  62. wCodeBuf DW ? ;Holds 2 nibbles for decompression
  63. wCode DW ? ;Current 4 bit code
  64. wStep DW ? ;Step value in table
  65. wIndex DW ? ;Index into step table
  66. dwSampleIndex2 DD ? ;Index into sample
  67. dwPredicted2 DD ? ;Next predicted value
  68. dwDifference2 DD ? ;Difference from last sample
  69. wCodeBuf2 DW ? ;Holds 2 nibbles for decompression
  70. wCode2 DW ? ;Current 4 bit code
  71. wStep2 DW ? ;Step value in table
  72. wIndex2 DW ? ;Index into step table
  73. wBitSize DW ? ;Bit size for decompression
  74. wChannels DW ? ;number of channels
  75. ENDS sCompInfo
  76. DATASEG
  77. InitFlags DD 0 ; Flags to indicate what has been initialized.
  78. LABEL LockedDataStart BYTE
  79. ;* Index table for stepping into step table
  80. INCLUDE "difftb.inc"
  81. INCLUDE "indextb.inc"
  82. INCLUDE "nybbtb.inc"
  83. LABEL LockedDataEnd BYTE
  84. CODESEG
  85. LABEL LockedCodeStart BYTE
  86. ;****************************************************************************
  87. ;*
  88. ;* NAME
  89. ;* sosCODECInitStream - Initialize compression stream.
  90. ;*
  91. ;* SYNOPSIS
  92. ;* sosCODECInitStream(CompInfo)
  93. ;*
  94. ;* void sosCODECInitStream(_SOS_COMPRESS_INFO *);
  95. ;*
  96. ;* FUNCTION
  97. ;* Initialize compression stream for compression and decompression.
  98. ;*
  99. ;* INPUTS
  100. ;* CompInfo - Compression information structure.
  101. ;*
  102. ;* RESULT
  103. ;* NONE
  104. ;*
  105. ;****************************************************************************
  106. GLOBAL sosCODECInitStream:NEAR
  107. PROC sosCODECInitStream C NEAR
  108. ARG sSOSInfo:NEAR PTR
  109. mov eax,[sSOSInfo]
  110. mov [(sCompInfo eax).wIndex],0 ; starting index 0
  111. mov [(sCompInfo eax).dwPredicted],0 ; no predicted value
  112. mov [(sCompInfo eax).wIndex2],0 ; starting index 0
  113. mov [(sCompInfo eax).dwPredicted2],0 ; no predicted value
  114. ret
  115. ENDP sosCODECInitStream
  116. ;****************************************************************************
  117. ;*
  118. ;* NAME
  119. ;* sosCODECDecompressData - Decompress audio data.
  120. ;*
  121. ;* SYNOPSIS
  122. ;* Size = sosCODECDecompressData(CompInfo, NumBytes)
  123. ;*
  124. ;* long sosCODECDecompressData(_SOS_COMPRESS_INFO *, long);
  125. ;*
  126. ;* FUNCTION
  127. ;* Decompress data from a 4:1 ADPCM compressed stream. The number of
  128. ;* bytes decompressed is returned.
  129. ;*
  130. ;* INPUTS
  131. ;* CompInfo - Compress information structure.
  132. ;* NumBytes - Number of bytes to decompress.
  133. ;*
  134. ;* RESULT
  135. ;* Size - Size of decompressed data.
  136. ;*
  137. ;*
  138. ;* NOTES
  139. ;* This routine has been optimized for pipelining on both
  140. ;* 486 and Pentium processors. Changing, inserting, or moving any
  141. ;* instructions will most likely slow down the code, in some cases by
  142. ;* as much as 20%. It can burst-decompress 16384 samples in about
  143. ;* 1940æs on a Pentium 90Mhz, and about 3960æs on a 486 66Mhz.
  144. ;* Instruction reordering could bring this down to below 1870æs on
  145. ;* the Pentium, but this would cause a great degradation in 486
  146. ;* performance. Since slow 486's are the reason this code was
  147. ;* written to be fast, it has been optimized for the Pentium only where
  148. ;* it would not degrade 486 performance. So, be careful when changing
  149. ;* ANY of this code, because it is very carefully balanced...
  150. ;****************************************************************************
  151. GLOBAL C sosCODECDecompressData:NEAR
  152. PROC sosCODECDecompressData C NEAR
  153. ARG sSOSInfo:NEAR PTR
  154. ARG wBytes:DWORD
  155. push esi
  156. push edi
  157. push ebx
  158. push ecx
  159. push edx ;save all the regs
  160. mov ebx,[sSOSInfo] ;get base of sCompInfo struct
  161. mov cx,[(sCompInfo ebx).wBitSize] ;check the bit size
  162. mov dx,[(sCompInfo ebx).wChannels] ;check the number of channels
  163. ;
  164. ;
  165. ; Determine the correct routine to use for decoding
  166. ; (for now only ADPCM 4:1 Mono 16-bit is implemented)
  167. cmp cx,8
  168. jne ??do16Bits
  169. ??do8Bits:
  170. cmp dx,2
  171. jne ??not8Stereo
  172. ; jmp ??decomp8Stereo
  173. jmp ??byeBye
  174. ??not8Stereo:
  175. cmp dx,1
  176. jne ??byeBye
  177. ; jmp decomp8Mono
  178. jmp ??byeBye
  179. ??do16Bits:
  180. cmp cx,16
  181. jne ??byeBye
  182. cmp dx,2
  183. jne ??not16Stereo
  184. ; jmp ??decomp16Stereo
  185. jmp ??byeBye
  186. ??not16Stereo:
  187. cmp dx,1
  188. jne ??byeBye
  189. push ebp
  190. ;
  191. ;
  192. ; 16 bit ADPCM 4:1 Mono pre-loop initialization
  193. ??decomp16Mono:
  194. push ebx ;save struct base
  195. xor edx,edx ;clear index
  196. mov eax,[(sCompInfo ebx).dwPredicted] ;get last sample
  197. mov dx,[(sCompInfo ebx).wIndex] ;get last index value
  198. mov esi,[(sCompInfo ebx).lpSource] ;get source address
  199. mov edi,[(sCompInfo ebx).lpDest] ;get dest address
  200. mov ebp,[wBytes] ;get the number of dest. bytes
  201. cmp ebp,16 ;less than 16? (less than 8 samples)
  202. jl ??fixAlign16Mono0 ;if so, don't bother with alignment
  203. ;
  204. ;
  205. ; Check to see if we need to fix an alignment problem on the source buffer
  206. ; (non-aligned buffers are MUCH slower; if we're given a non-DWORD aligned
  207. ; source address, we do as many samples as needed to get to the nearest
  208. ; DWORD boundary, then finish the bulk as a DWORD-aligned decompress).
  209. mov ebx,esi ;get source address
  210. and ebx,03h ;check LSB
  211. jnz ??fixalign16Mono ;if non-zero, need to align for
  212. ;warp speed
  213. ??fixAlign16Mono0:
  214. push ebp ;save for later
  215. shr ebp,4 ;divide by 16 for 16-bit,
  216. ;because we do 8 nybbles per loop,
  217. ;and there are two samples per
  218. ;byte, so there are n/16 iterations
  219. ;required
  220. xor ebx,ebx ;clear our nybble index
  221. or ebp,ebp ;set flags for EBP
  222. jmp ??start16Mono ;start with test... don't go if
  223. ;we have zero bytes to do
  224. ??fixalign16Mono:
  225. jmp [DWORD PTR dwMono16AlignJmpTable+ebx*4] ;do non-aligned first
  226. align 4
  227. ??fixAlign16Mono1:
  228. sub ebp,12 ;adjust # of dest. bytes
  229. push ebp ;save it
  230. shr ebp,4 ;divide by 16 to get samples/8
  231. xor ebx,ebx ;clear our nybble index
  232. inc ebp ;adjust ebp for loop
  233. jmp ??finish16Mono6 ;borrow exit code to go through a
  234. ;piece of a loop
  235. align 4
  236. ??fixAlign16Mono2:
  237. sub ebp,8 ;adjust # of dest. bytes
  238. push ebp ;save it
  239. shr ebp,4 ;divide by 16 to get samples/8
  240. xor ebx,ebx ;clear our nybble index
  241. inc ebp ;adjust ebp for loop
  242. jmp ??finish16Mono4 ;borrow exit code to go through a
  243. ;piece of a loop
  244. align 4
  245. ??fixAlign16Mono3:
  246. sub ebp,4 ;adjust # of dest. bytes
  247. push ebp ;save it
  248. shr ebp,4 ;divide by 16 to get samples/8
  249. xor ebx,ebx ;clear our nybble index
  250. inc ebp ;adjust ebp for loop
  251. jmp ??finish16Mono2 ;borrow exit code to go through a
  252. ;piece of a loop
  253. ; "The Loop"
  254. ;
  255. ; Process 1st nybble
  256. align 4
  257. ??loop16Mono:
  258. add eax,[dwDiffTable+edx*2] ;add difference to prev. sample
  259. mov dx,[wIndexTable+edx] ;adjust dx to next index base
  260. cmp eax,00007FFFh ;check for overflow
  261. jg ??fix1Smp16MonoO
  262. cmp eax,0FFFF8000h ;check for underflow
  263. jl ??fix1Smp16MonoU
  264. ??fixed1Smp16Mono:
  265. or dl,[BYTE PTR bNybbleTableHigh+ebx] ;adjust index for nybble
  266. mov [edi],ax ;save the sample
  267. ;
  268. ;
  269. ; Process 2nd nybble
  270. ??finish7Smp16Mono:
  271. mov bl,ch ;get next 2 nybbles in ebx
  272. add eax,[dwDiffTable+edx*2] ;add difference to prev. sample
  273. mov dx,[wIndexTable+edx] ;adjust dx to next index base
  274. cmp eax,00007FFFh ;check for overflow
  275. jg ??fix2Smp16MonoO
  276. cmp eax,0FFFF8000h ;check for underflow
  277. jl ??fix2Smp16MonoU
  278. ??fixed2Smp16Mono:
  279. or dl,[BYTE PTR bNybbleTableLow+ebx] ;adjust index for nybble
  280. mov [edi+02h],ax ;save the sample
  281. shr ecx,16 ;move top four nybbles into bottom
  282. ;
  283. ;
  284. ; Process 3rd nybble
  285. ??finish6Smp16Mono:
  286. add eax,[dwDiffTable+edx*2] ;add difference to prev. sample
  287. mov dx,[wIndexTable+edx] ;adjust dx to next index base
  288. cmp eax,00007FFFh ;check for overflow
  289. jg ??fix3Smp16MonoO
  290. cmp eax,0FFFF8000h ;check for underflow
  291. jl ??fix3Smp16MonoU
  292. ??fixed3Smp16Mono:
  293. or dl,[BYTE PTR bNybbleTableHigh+ebx] ;adjust index for nybble
  294. mov [edi+04h],ax ;save the sample
  295. ;
  296. ;
  297. ; Process 4th nybble
  298. ??finish5Smp16Mono:
  299. mov bl,cl
  300. add eax,[dwDiffTable+edx*2] ;add difference to prev. sample
  301. mov dx,[wIndexTable+edx] ;adjust dx to next index base
  302. cmp eax,00007FFFh ;check for overflow
  303. jg ??fix4Smp16MonoO
  304. cmp eax,0FFFF8000h ;check for underflow
  305. jl ??fix4Smp16MonoU
  306. ??fixed4Smp16Mono:
  307. or dl,[BYTE PTR bNybbleTableLow+ebx] ;adjust index for nybble
  308. mov [edi+06h],ax ;save the sample
  309. ;
  310. ;
  311. ; Process 5th nybble
  312. ??finish4Smp16Mono:
  313. add eax,[dwDiffTable+edx*2] ;add difference to prev. sample
  314. mov dx,[wIndexTable+edx] ;adjust dx to next index base
  315. cmp eax,00007FFFh ;check for overflow
  316. jg ??fix5Smp16MonoO
  317. cmp eax,0FFFF8000h ;check for underflow
  318. jl ??fix5Smp16MonoU
  319. ??fixed5Smp16Mono:
  320. or dl,[BYTE PTR bNybbleTableHigh+ebx] ;adjust index for nybble
  321. mov [edi+08h],ax ;save the sample
  322. ;
  323. ;
  324. ; Process 6th nybble
  325. ??finish3Smp16Mono:
  326. mov bl,ch
  327. add eax,[dwDiffTable+edx*2] ;add difference to prev. sample
  328. mov dx,[wIndexTable+edx] ;adjust dx to next index base
  329. cmp eax,00007FFFh ;check for overflow
  330. jg ??fix6Smp16MonoO
  331. cmp eax,0FFFF8000h ;check for underflow
  332. jl ??fix6Smp16MonoU
  333. ??fixed6Smp16Mono:
  334. or dl,[BYTE PTR bNybbleTableLow+ebx] ;adjust index for nybble
  335. mov [edi+0Ah],ax ;save the sample
  336. ;
  337. ;
  338. ; Process 7th nybble
  339. ??finish2Smp16Mono:
  340. add eax,[dwDiffTable+edx*2] ;add difference to prev. sample
  341. mov dx,[wIndexTable+edx] ;adjust dx to next index base
  342. cmp eax,00007FFFh ;check for overflow
  343. jg ??fix7Smp16MonoO
  344. cmp eax,0FFFF8000h ;check for underflow
  345. jl ??fix7Smp16MonoU
  346. ??fixed7Smp16Mono:
  347. or dl,[BYTE PTR bNybbleTableHigh+ebx] ;adjust index for nybble
  348. mov [edi+0Ch],ax ;save the sample
  349. ;
  350. ;
  351. ; Process 8th nybble
  352. ??finish1Smp16Mono:
  353. add eax,[dwDiffTable+edx*2] ;add difference to prev. sample
  354. mov dx,[wIndexTable+edx] ;adjust dx to next index base
  355. cmp eax,00007FFFh ;check for overflow
  356. jg ??fix8Smp16MonoO
  357. cmp eax,0FFFF8000h ;check for underflow
  358. jl ??fix8Smp16MonoU
  359. ;
  360. ;
  361. ; Loop cleanup for next pass
  362. ??fixed8Smp16Mono:
  363. mov [edi+0Eh],ax ;save the sample
  364. add esi,04h ;bump esi to point to next longword
  365. add edi,10h ;incr. the destination buffer ptr
  366. dec ebp ;count down the number of samples/8
  367. ??start16Mono:
  368. jng ??cleanup16Mono ;if done, clean up
  369. mov ecx,[esi] ;get 4 nybbles in one whack (whee!)
  370. mov bl,cl ;get next 2 nybbles in ebx
  371. or dl,[BYTE PTR bNybbleTableLow+ebx] ;adjust index for nybble
  372. jmp ??loop16Mono ;loop until done
  373. ??cleanup16Mono:
  374. jnz ??done16Mono ;if ebp is non-zero, we're DONE
  375. ;if exactly zero, finish the tail-end
  376. ;of the conversion (may be a non-
  377. ;multiple of 8 nybbles)
  378. ;
  379. ;
  380. ; Loop cleanup for last (incomplete) pass
  381. pop ecx ;restore # of words
  382. shr ecx,1 ;divide by two to get samples
  383. and ecx,07h ;get # of samples we missed
  384. jmp [DWORD PTR dwMono16JmpTable+ecx*4] ;go finish the job...
  385. ;
  386. ;
  387. ; Structure cleanup
  388. ??done16Mono:
  389. pop ebx ;restore struct base
  390. pop ebp ;restore stack frame pointer
  391. mov [(sCompInfo ebx).dwPredicted],eax ;save last sample
  392. mov [(sCompInfo ebx).wIndex],dx ;save last index value
  393. mov eax,[wBytes] ;get # of bytes we did
  394. ??byeBye:
  395. pop edx ;restore all the regs
  396. pop ecx
  397. pop ebx
  398. pop edi
  399. pop esi
  400. ret
  401. ;
  402. ;
  403. ; Jumps for -32768/+32767 bounds check go to these vvvv
  404. align 4
  405. ??fix1Smp16MonoO:
  406. mov eax,00007FFFh ;Overflow - truncate to +32767
  407. jmp ??fixed1Smp16Mono ;go back
  408. align 4
  409. ??fix1Smp16MonoU:
  410. mov eax,0FFFF8000h ;Underflow - truncate to -32768
  411. jmp ??fixed1Smp16Mono ;go back
  412. align 4
  413. ??fix2Smp16MonoO:
  414. mov eax,00007FFFh ;Overflow - truncate to +32767
  415. jmp ??fixed2Smp16Mono ;go back
  416. align 4
  417. ??fix2Smp16MonoU:
  418. mov eax,0FFFF8000h ;Underflow - truncate to -32768
  419. jmp ??fixed2Smp16Mono ;go back
  420. align 4
  421. ??fix3Smp16MonoO:
  422. mov eax,00007FFFh ;Overflow - truncate to +32767
  423. jmp ??fixed3Smp16Mono ;go back
  424. align 4
  425. ??fix3Smp16MonoU:
  426. mov eax,0FFFF8000h ;Underflow - truncate to -32768
  427. jmp ??fixed3Smp16Mono ;go back
  428. align 4
  429. ??fix4Smp16MonoO:
  430. mov eax,00007FFFh ;Overflow - truncate to +32767
  431. jmp ??fixed4Smp16Mono ;go back
  432. align 4
  433. ??fix4Smp16MonoU:
  434. mov eax,0FFFF8000h ;Underflow - truncate to -32768
  435. jmp ??fixed4Smp16Mono ;go back
  436. align 4
  437. ??fix5Smp16MonoO:
  438. mov eax,00007FFFh ;Overflow - truncate to +32767
  439. jmp ??fixed5Smp16Mono ;go back
  440. align 4
  441. ??fix5Smp16MonoU:
  442. mov eax,0FFFF8000h ;Underflow - truncate to -32768
  443. jmp ??fixed5Smp16Mono ;go back
  444. align 4
  445. ??fix6Smp16MonoO:
  446. mov eax,00007FFFh ;Overflow - truncate to +32767
  447. jmp ??fixed6Smp16Mono ;go back
  448. align 4
  449. ??fix6Smp16MonoU:
  450. mov eax,0FFFF8000h ;Underflow - truncate to -32768
  451. jmp ??fixed6Smp16Mono ;go back
  452. align 4
  453. ??fix7Smp16MonoO:
  454. mov eax,00007FFFh ;Overflow - truncate to +32767
  455. jmp ??fixed7Smp16Mono ;go back
  456. align 4
  457. ??fix7Smp16MonoU:
  458. mov eax,0FFFF8000h ;Underflow - truncate to -32768
  459. jmp ??fixed7Smp16Mono ;go back
  460. align 4
  461. ??fix8Smp16MonoO:
  462. mov eax,00007FFFh ;Overflow - truncate to +32767
  463. jmp ??fixed8Smp16Mono ;go back
  464. align 4
  465. ??fix8Smp16MonoU:
  466. mov eax,0FFFF8000h ;Underflow - truncate to -32768
  467. jmp ??fixed8Smp16Mono ;go back
  468. ;
  469. ;
  470. ; Jump tables for cleanup after loop unroll point to these vvvv
  471. align 4
  472. ??finish16Mono1:
  473. xor ecx,ecx ;clear nybble bucket
  474. mov ch,[esi] ;get 1 nybble (1 byte)
  475. shl ch,4 ;move it over
  476. mov bl,ch ;get nybble in ebx
  477. sub edi,0Eh ;back edi up
  478. or dl,[BYTE PTR bNybbleTableHigh+ebx] ;adjust index for nybble
  479. jmp ??finish1Smp16Mono ;go finish it
  480. align 4
  481. ??finish16Mono2:
  482. xor ecx,ecx ;clear nybble bucket
  483. mov ch,[esi] ;get 2 nybbles (1 byte)
  484. mov bl,ch ;get nybbles in ebx
  485. sub edi,0Ch ;back edi up
  486. sub esi,3 ;adjust esi (used for dword aligning)
  487. or dl,[BYTE PTR bNybbleTableLow+ebx] ;adjust index for nybble
  488. jmp ??finish2Smp16Mono ;go finish it
  489. align 4
  490. ??finish16Mono3:
  491. xor ecx,ecx ;clear nybble bucket
  492. mov cx,[esi] ;get 3 nybbles (2 bytes)
  493. shl cx,4 ;move it over
  494. mov bl,cl ;get nybbles in ebx
  495. sub edi,0Ah ;back edi up
  496. or dl,[BYTE PTR bNybbleTableHigh+ebx] ;adjust index for nybble
  497. jmp ??finish3Smp16Mono ;go finish it
  498. align 4
  499. ??finish16Mono4:
  500. xor ecx,ecx ;clear nybble bucket
  501. mov cx,[esi] ;get 4 nybbles (2 bytes)
  502. mov bl,cl ;get nybbles in ebx
  503. sub edi,08h ;back edi up
  504. sub esi,2 ;adjust esi (used for dword aligning)
  505. or dl,[BYTE PTR bNybbleTableLow+ebx] ;adjust index for nybble
  506. jmp ??finish4Smp16Mono ;go finish it
  507. align 4
  508. ??finish16Mono5:
  509. xor ecx,ecx ;clear nybble bucket
  510. mov cl,[esi+2] ;get 1 nybble (1 byte)
  511. shl ecx,16 ;shift it over
  512. mov cx,[esi] ;get 4 nybbles (2 bytes)
  513. mov bl,cl ;get nybbles in ebx
  514. shr ecx,4 ;move it over
  515. shl bl,4 ;move it over
  516. sub edi,06h ;back edi up
  517. or dl,[BYTE PTR bNybbleTableHigh+ebx] ;adjust index for nybble
  518. jmp ??finish5Smp16Mono ;go finish it
  519. align 4
  520. ??finish16Mono6:
  521. xor ecx,ecx ;clear nybble bucket
  522. mov cl,[esi+2] ;get 2 nybbles (1 byte)
  523. shl ecx,16 ;move it over
  524. mov cx,[esi] ;get 4 nybbles (2 bytes)
  525. mov bl,cl ;get nybbles in ebx
  526. shr ecx,8 ;move it over
  527. sub esi,1 ;adjust esi (used for dword aligning)
  528. sub edi,04h ;back edi up
  529. or dl,[BYTE PTR bNybbleTableLow+ebx] ;adjust index for nybble
  530. jmp ??finish6Smp16Mono ;go finish it
  531. align 4
  532. ??finish16Mono7:
  533. xor ecx,ecx ;clear nybble bucket
  534. mov ecx,[esi] ;get 7 nybbles (4 bytes)
  535. shl ecx,4 ;move it over
  536. mov bl,cl ;get nybbles in ebx
  537. sub edi,02h ;back edi up
  538. or dl,[BYTE PTR bNybbleTableHigh+ebx] ;adjust index for nybble
  539. jmp ??finish7Smp16Mono ;go finish it
  540. ;
  541. ;
  542. ; Jump Tables
  543. align 4
  544. dwMono16JmpTable DD ??done16Mono
  545. DD ??finish16Mono1
  546. DD ??finish16Mono2
  547. DD ??finish16Mono3
  548. DD ??finish16Mono4
  549. DD ??finish16Mono5
  550. DD ??finish16Mono6
  551. DD ??finish16Mono7
  552. align 4
  553. dwMono16AlignJmpTable DD ??fixAlign16Mono0
  554. DD ??fixAlign16Mono1
  555. DD ??fixAlign16Mono2
  556. DD ??fixAlign16Mono3
  557. ENDP sosCODECDecompressData
  558. LABEL LockedCodeEnd BYTE
  559. ;***************************************************************************
  560. ;* sosCODEC_LOCK -- locks the JLB audio decompression code *
  561. ;* *
  562. ;* INPUT: none *
  563. ;* *
  564. ;* OUTPUT: BOOL true is lock sucessful, false otherwise *
  565. ;* *
  566. ;* PROTO: BOOL sosCODEC_Lock(void); *
  567. ;* *
  568. ;* HISTORY: *
  569. ;* 06/26/1995 PWG : Created. *
  570. ;*=========================================================================*
  571. GLOBAL sosCODEC_Lock:NEAR
  572. PROC sosCODEC_Lock C NEAR USES ebx ecx edx esi edi
  573. ;
  574. ; Lock the code that is used by the sos decompression method.
  575. ;
  576. mov eax,0600h ; function number.
  577. mov ecx,OFFSET LockedCodeStart ; ecx must have start of memory.
  578. mov edi,OFFSET LockedCodeEnd ; edi will have size of region in bytes.
  579. shld ebx,ecx,16
  580. sub edi, ecx
  581. shld esi,edi,16
  582. int DPMI_INTR ; do call.
  583. jc ??error
  584. or [InitFlags], IF_LOCKED_PM_CODE
  585. ;
  586. ; Lock the data used by the sos decompression method.
  587. ;
  588. mov eax,0600h ; function number.
  589. mov ecx,OFFSET LockedDataStart ; ecx must have start of memory.
  590. mov edi,OFFSET LockedDataEnd ; edi will have size of region in bytes.
  591. shld ebx,ecx,16
  592. sub edi, ecx
  593. shld esi,edi,16
  594. int DPMI_INTR ; do call.
  595. jc ??error ; eax = 8 if mem err, eax = 9 if invalid mem region.
  596. or [InitFlags], IF_LOCKED_PM_DATA
  597. mov eax,1
  598. jmp ??exit
  599. ??error:
  600. xor eax,eax
  601. ??exit:
  602. ret
  603. ENDP sosCODEC_Lock
  604. ;***************************************************************************
  605. ;* DECOMPRESS_FRAME_UNLOCK -- Unlocks the JLB audio compression code *
  606. ;* *
  607. ;* INPUT: none *
  608. ;* *
  609. ;* OUTPUT: BOOL true is unlock sucessful, false otherwise *
  610. ;* *
  611. ;* PROTO: BOOL sosCODEC_Unlock(void); *
  612. ;* *
  613. ;* HISTORY: *
  614. ;* 06/26/1995 PWG : Created. *
  615. ;*=========================================================================*
  616. GLOBAL sosCODEC_Unlock:NEAR
  617. PROC sosCODEC_Unlock C NEAR USES ebx ecx edx esi edi
  618. test [InitFlags],IF_LOCKED_PM_CODE
  619. jz ??code_not_locked
  620. mov eax , 0601h
  621. mov ecx,OFFSET LockedCodeStart ; ecx must have start of memory.
  622. mov edi,OFFSET LockedCodeEnd ; edx will have size of region in bytes.
  623. sub edi,ecx ; - figure size.
  624. shld ebx , ecx , 16
  625. shld esi , edi , 16
  626. int DPMI_INTR ; do call.
  627. jc ??error
  628. ??code_not_locked:
  629. test [InitFlags],IF_LOCKED_PM_DATA
  630. jz ??data_not_locked
  631. mov ax,0601h ; set es to descriptor of data.
  632. mov ecx,OFFSET LockedDataStart ; ecx must have start of memory.
  633. mov edi,OFFSET LockedDataEnd ; edx will have size of region in bytes.
  634. sub edi,ecx ; - figure size.
  635. shld ebx , ecx , 16
  636. shld esi , edi , 16
  637. int DPMI_INTR ; do call.
  638. jc ??error ; eax = 8 if mem err, eax = 9 if invalid mem region.
  639. ??data_not_locked:
  640. mov [InitFlags],0
  641. mov eax,1
  642. jmp ??exit
  643. ??error:
  644. xor eax,eax
  645. ??exit:
  646. ret
  647. ENDP sosCODEC_Unlock
  648. END