SOSCODEC.ASM 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871
  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. ;* DATE
  35. ;* Febuary 15, 1995
  36. ;*
  37. ;*---------------------------------------------------------------------------
  38. ;*
  39. ;* PUBLIC
  40. ;*
  41. ;****************************************************************************
  42. IDEAL
  43. P386
  44. MODEL USE32 FLAT
  45. LOCALS ??
  46. DPMI_INTR equ 31h
  47. IF_LOCKED_PM_CODE equ 1h ; Locked PM code for DPMI.
  48. IF_LOCKED_PM_DATA equ 2h ; Locked PM code for DPMI.
  49. STRUC sCompInfo
  50. lpSource DD ? ;Compressed data pointer
  51. lpDest DD ? ;Uncompressed data pointer
  52. dwCompSize DD ? ;Compressed size
  53. dwUnCompSize DD ? ;Uncompressed size
  54. dwSampleIndex DD ? ;Index into sample
  55. dwPredicted DD ? ;Next predicted value
  56. dwDifference DD ? ;Difference from last sample
  57. wCodeBuf DW ? ;Holds 2 nibbles for decompression
  58. wCode DW ? ;Current 4 bit code
  59. wStep DW ? ;Step value in table
  60. wIndex DW ? ;Index into step table
  61. dwSampleIndex2 DD ? ;Index into sample
  62. dwPredicted2 DD ? ;Next predicted value
  63. dwDifference2 DD ? ;Difference from last sample
  64. wCodeBuf2 DW ? ;Holds 2 nibbles for decompression
  65. wCode2 DW ? ;Current 4 bit code
  66. wStep2 DW ? ;Step value in table
  67. wIndex2 DW ? ;Index into step table
  68. wBitSize DW ? ;Bit size for decompression
  69. wChannels DW ? ;number of channels
  70. ENDS sCompInfo
  71. DATASEG
  72. InitFlags DD 0 ; Flags to indicate what has been initialized.
  73. LABEL LockedDataStart BYTE
  74. ;* Index table for stepping into step table
  75. wCODECIndexTab DD -1,-1,-1,-1,2,4,6,8
  76. DD -1,-1,-1,-1,2,4,6,8
  77. ;Lookup table of replacement values
  78. ;The actual sound value is replaced with an index to lookup in this table
  79. ;The index only takes up a nibble(4bits) and represents an int(16bits)
  80. ;Essentially:
  81. ;Get a value
  82. ;compare it with the value before it
  83. ;find closest value in table and store the index into the table
  84. ;if i'm going down then negitize it
  85. ;go to next byte.
  86. ;Theory for stereo:
  87. ;1)handle stereo and mono in two seperate loops. cleaner...
  88. ;start at byte 0 and skip every other byte(or word) both write and read
  89. ;when we get done
  90. ; set start byte to 1 and do it again
  91. ;This table essentialy round off to closes values in 3 distinct bands
  92. ; precalculated and optimized(i guess) for human hearing.
  93. wCODECStepTab DD 7, 8, 9, 10, 11, 12, 13,14
  94. DD 16, 17, 19, 21, 23, 25, 28, 31
  95. DD 34, 37, 41, 45, 50, 55, 60, 66
  96. DD 73, 80, 88, 97, 107, 118, 130, 143
  97. DD 157, 173, 190, 209, 230, 253, 279, 307
  98. DD 337, 371, 408, 449, 494, 544, 598, 658
  99. DD 724, 796, 876, 963, 1060, 1166, 1282, 1411
  100. DD 1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024
  101. DD 3327, 3660, 4026, 4428, 4871, 5358, 5894, 6484
  102. DD 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899
  103. DD 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794
  104. DD 32767
  105. wCode DD 0 ; this is to hold index into wCodeStep
  106. dwCODECByteIndex DD 0 ; this is when to stop compressing
  107. dwCODECBytesProcessed DD 0 ; this is how many so far compressed
  108. dwCODECTempStep DD 0 ; tempory storage for step value
  109. wCODECMask DW 0 ; Current mask
  110. LABEL LockedDataEnd BYTE
  111. CODESEG
  112. LABEL LockedCodeStart BYTE
  113. ;****************************************************************************
  114. ;*
  115. ;* NAME
  116. ;* sosCODECInitStream - Initialize compression stream.
  117. ;*
  118. ;* SYNOPSIS
  119. ;* sosCODECInitStream(CompInfo)
  120. ;*
  121. ;* void sosCODECInitStream(_SOS_COMPRESS_INFO *);
  122. ;*
  123. ;* FUNCTION
  124. ;* Initialize compression stream for compression and decompression.
  125. ;*
  126. ;* INPUTS
  127. ;* CompInfo - Compression information structure.
  128. ;*
  129. ;* RESULT
  130. ;* NONE
  131. ;*
  132. ;****************************************************************************
  133. GLOBAL sosCODECInitStream:NEAR
  134. PROC sosCODECInitStream C NEAR
  135. ARG sSOSInfo:NEAR PTR
  136. mov eax,[sSOSInfo]
  137. mov [(sCompInfo eax).wIndex],0 ; starting index 0
  138. mov [(sCompInfo eax).wStep],7 ; start with a step of 7
  139. mov [(sCompInfo eax).dwPredicted],0 ; no predicted value
  140. mov [(sCompInfo eax).dwSampleIndex],0 ;start at head of index
  141. mov [(sCompInfo eax).wIndex2],0 ; starting index 0
  142. mov [(sCompInfo eax).wStep2],7 ; start with a step of 7
  143. mov [(sCompInfo eax).dwPredicted2],0 ; no predicted value
  144. mov [(sCompInfo eax).dwSampleIndex2],0 ;start at head of index
  145. ret
  146. ENDP sosCODECInitStream
  147. ;****************************************************************************
  148. ;*
  149. ;* NAME
  150. ;* sosCODECDecompressData - Decompress audio data.
  151. ;*
  152. ;* SYNOPSIS
  153. ;* Size = sosCODECDecompressData(CompInfo, NumBytes)
  154. ;*
  155. ;* long sosCODECDecompressData(_SOS_COMPRESS_INFO *, long);
  156. ;*
  157. ;* FUNCTION
  158. ;* Decompress data from a 4:1 ADPCM compressed stream. The number of
  159. ;* bytes decompressed is returned.
  160. ;*
  161. ;* INPUTS
  162. ;* CompInfo - Compress information structure.
  163. ;* NumBytes - Number of bytes to compress.
  164. ;*
  165. ;* RESULT
  166. ;* Size - Size of decompressed data.
  167. ;*
  168. ;****************************************************************************
  169. GLOBAL sosCODECDecompressData:NEAR
  170. PROC sosCODECDecompressData C NEAR
  171. ARG sSOSInfo:NEAR PTR
  172. ARG wBytes:DWORD
  173. push esi
  174. push edi
  175. push ebx
  176. push ecx
  177. push edx
  178. ;*---------------------------------------------------------------------------
  179. ;* Initialize
  180. ;*---------------------------------------------------------------------------
  181. mov ebx,[sSOSInfo]
  182. mov eax,[wBytes]
  183. mov [dwCODECBytesProcessed],eax
  184. mov [(sCompInfo ebx).dwSampleIndex],0 ;start at head of index
  185. mov [(sCompInfo ebx).dwSampleIndex2],0 ;start at head of index
  186. cmp [(sCompInfo ebx).wBitSize],16
  187. jne short ??skipByteDivide
  188. shr eax,1 ;Divide size by two
  189. ??skipByteDivide:
  190. mov [dwCODECByteIndex],eax
  191. mov esi,[(sCompInfo ebx).lpSource]
  192. mov edi,[(sCompInfo ebx).lpDest]
  193. cmp [(sCompInfo ebx).wChannels],2 ;stereo check
  194. je ??mainloopl ;do left side first
  195. ; Determine if sample index is even or odd. This will determine
  196. ; if we need to get a new token or not.
  197. ;---------------------------------------------------------------------------
  198. ;Main Mono Loop
  199. ;---------------------------------------------------------------------------
  200. push ebp
  201. movzx edx,[(sCompInfo ebx).wIndex] ;preload index
  202. mov ebp, [dwCODECByteIndex]
  203. mov ecx,[(sCompInfo ebx).dwSampleIndex] ;preload SampleIndex
  204. ??mainloop:
  205. xor eax,eax ;get a new token
  206. test ecx,1 ;odd Sample??
  207. je short ??fetchToken ; if so get new token
  208. mov ax,[(sCompInfo ebx).wCodeBuf] ;ored with Code
  209. shr eax,4
  210. jmp short ??calcDifference
  211. align 4
  212. ??fetchToken:
  213. mov al,[esi] ;put in codebuf
  214. inc esi
  215. mov [(sCompInfo ebx).wCodeBuf],ax
  216. ??calcDifference:
  217. xor ecx,ecx
  218. and eax,000Fh
  219. mov cx,[(sCompInfo ebx).wStep] ;cx is step value
  220. mov [wCode],eax
  221. jmp [DWORD PTR JumpTable + eax*4]
  222. align 4
  223. ; note: it is important for speed reasons to keep the order the
  224. ; following jumps entries as well as the "align 4" after some of
  225. ; the jmp statements
  226. ??7:
  227. ; eax = x + x/2 + x/4 + x/8 = (8*x + 4*x +2*x + x)>>3 =
  228. ; = ( x * ( 8 + 4 + 2 + 1 )) >> 3 = ( x * 15 ) >> 3
  229. lea ecx,[ecx+ecx*2]
  230. lea eax,[ecx+ecx*4]
  231. sar eax,3 ; now we divide x>>3
  232. jmp ??save_dif
  233. align 4
  234. ??6:
  235. ; eax = x + x / 2 + x / 8 = (8*x + 4*x + x) >> 3 =
  236. ; = ( x * 8 + x * 5 ) >> 8
  237. lea eax,[ecx+ecx*4]
  238. lea eax,[eax+ecx*8]
  239. sar eax,3 ; now we divide x>>3
  240. jmp ??save_dif
  241. align 4
  242. ??5:
  243. ; eax = x + x / 4 + x / 8 = (8*x + 2*x + x) >> 3 =
  244. ; = ( 8 * x + 3 * x) >> 3
  245. lea eax,[ecx+ecx*2]
  246. lea eax,[eax+ecx*8]
  247. sar eax,3 ; now we divide x>>3
  248. jmp ??save_dif
  249. align 4
  250. ??4:
  251. ; eax = x + x / 8 = (8*x + x) >> 3 = (x * 9)>> 3
  252. lea eax,[ecx+ecx*8]
  253. sar eax,3 ; now we divide x>>3
  254. jmp ??save_dif
  255. align 4
  256. ??3:
  257. ; eax = x/2 + x/4 + x/8 = (4*x + 2*x + x) >> 3
  258. ; = ( 4x + 3x ) >> 3
  259. lea eax,[ecx+ecx*2]
  260. lea eax,[eax+ecx*4]
  261. sar eax,3 ; now we divide x>>3
  262. jmp ??save_dif
  263. align 4
  264. ??2:
  265. ; eax = x/2 + x/8 = (4*x + x) >> 3
  266. lea eax,[ecx+ecx*4]
  267. sar eax,3 ; now we divide x>>3
  268. jmp ??save_dif
  269. align 4
  270. ??1:
  271. ; eax = x/4 + x/8 = (2x + x )>>8
  272. lea eax,[ecx+ecx*2]
  273. sar eax,3 ; now we divide x>>3
  274. jmp ??save_dif
  275. align 4
  276. ??0:
  277. ; eax = x/8 = x >> 3
  278. mov eax,ecx
  279. sar eax,3 ; now we divide x>>3
  280. jmp ??save_dif
  281. align 4
  282. ??15:
  283. ; eax = x + x/2 + x/4 + x/8 = (8*x + 4*x +2*x + x)>>3 =
  284. ; = ( x * ( 8 + 4 + 2 + 1 )) >> 3 = ( x * 15 ) >> 3
  285. lea ecx,[ecx+ecx*2]
  286. lea eax,[ecx+ecx*4]
  287. jmp ??neg_save_dif
  288. align 4
  289. ??14:
  290. ; eax = x + x / 2 + x / 8 = (8*x + 4*x + x) >> 3 =
  291. ; = ( x * 8 + x * 5 ) >> 8
  292. lea eax,[ecx+ecx*4]
  293. lea eax,[eax+ecx*8]
  294. jmp ??neg_save_dif
  295. align 4
  296. ??13:
  297. ; eax = x + x / 4 + x / 8 = (8*x + 2*x + x) >> 3 =
  298. ; = ( 8 * x + 3 * x) >> 3
  299. lea eax,[ecx+ecx*2]
  300. lea eax,[eax+ecx*8]
  301. jmp ??neg_save_dif
  302. align 4
  303. ??12:
  304. ; eax = x + x / 8 = (8*x + x) >> 3 = (x * 9)>> 3
  305. lea eax,[ecx+ecx*8]
  306. jmp ??neg_save_dif
  307. align 4
  308. ??11:
  309. ; eax = x/2 + x/4 + x/8 = (4*x + 2*x + x) >> 3
  310. ; = ( 4*x - 3*x ) >> 3
  311. lea eax,[ecx+ecx*2]
  312. lea eax,[eax+ecx*4]
  313. jmp ??neg_save_dif
  314. align 4
  315. ??10:
  316. ; eax = x/2 + x/8 = (4*x + x) >> 3
  317. lea eax,[ecx+ecx*4]
  318. jmp ??neg_save_dif
  319. align 4
  320. ??9:
  321. ; eax = x/4 + x/8 = (2x + x )>>8
  322. lea eax,[ecx+ecx*2]
  323. jmp ??neg_save_dif
  324. align 4
  325. ??8:
  326. ; eax = x/8 = x >> 3
  327. mov eax,ecx ; !!important!! no need for align here
  328. ??neg_save_dif:
  329. sar eax,3 ; now we divide x>>3
  330. neg eax
  331. ??save_dif:
  332. mov ecx,[wCode] ; load offset into CODETab table
  333. mov [(sCompInfo ebx).dwDifference],eax ;Store wStep
  334. ; add difference to predicted value.
  335. add eax,[(sCompInfo ebx).dwPredicted]
  336. ; make sure there is no under or overflow.
  337. cmp eax,7FFFh
  338. jl short ??noOverflow
  339. mov eax,7FFFh
  340. ??noOverflow:
  341. cmp eax,0FFFF8000h
  342. jg short ??noUnderflow
  343. mov eax,0FFFF8000h
  344. ??noUnderflow:
  345. add edx,[wCODECIndexTab + ecx*4] ; won't hurt 486
  346. cmp [(sCompInfo ebx).wBitSize],16
  347. mov [(sCompInfo ebx).dwPredicted],eax
  348. mov ecx,[(sCompInfo ebx).dwSampleIndex] ;load dwSampleindex
  349. je short ??output16Bit
  350. ; output 8 bit sample
  351. xor ah,80h
  352. mov [edi],ah
  353. inc edi
  354. jmp short ??adjustIndex
  355. align 4
  356. ??output16Bit:
  357. mov [edi],ax ;Output 16bit sample
  358. add edi,2
  359. ??adjustIndex:
  360. cmp edx,8000h
  361. jb short ??checkOverflow
  362. mov edx,0 ;reset index to zero
  363. ??checkOverflow:
  364. inc ecx ; advance index and store step value
  365. cmp edx,88 ;check if wIndex > 88
  366. jbe short ??adjustStep
  367. mov edx,88 ;reset index to 88
  368. ??adjustStep:
  369. ; advance index and store step value
  370. mov [(sCompInfo ebx).dwSampleIndex],ecx
  371. ; fetch wIndex so we can fetch new step value
  372. mov eax,[wCODECStepTab + edx*4]
  373. ; decrement bytes processed and loop back.
  374. dec ebp
  375. mov [(sCompInfo ebx).wStep],ax
  376. jne ??mainloop
  377. pop ebp
  378. mov eax,[wCode] ; these three lines do not
  379. mov [(sCompInfo ebx).wCode],ax ; seem to have any relevance
  380. mov [(sCompInfo ebx).wIndex],dx ; save index
  381. jmp ??exitout
  382. ;--------------------------------------------------------------------------
  383. ;Left Channel Start
  384. ;--------------------------------------------------------------------------
  385. ??mainloopl:
  386. test [(sCompInfo ebx).dwSampleIndex],1
  387. je short ??fetchTokenl
  388. xor eax,eax
  389. mov ax,[(sCompInfo ebx).wCodeBuf]
  390. shr eax,4
  391. and eax,000Fh
  392. mov [(sCompInfo ebx).wCode],ax
  393. jmp short ??calcDifferencel
  394. ??fetchTokenl:
  395. xor eax,eax
  396. mov al,[esi]
  397. mov [(sCompInfo ebx).wCodeBuf],ax
  398. add esi,2 ;2 for stereo
  399. and eax,000Fh
  400. mov [(sCompInfo ebx).wCode],ax
  401. ??calcDifferencel:
  402. ; reset difference
  403. mov [(sCompInfo ebx).dwDifference],0
  404. xor ecx,ecx
  405. mov cx,[(sCompInfo ebx).wStep]
  406. test eax,4 ;Check for wCode & 4
  407. je short ??no4l
  408. add [(sCompInfo ebx).dwDifference],ecx ;Add wStep
  409. ??no4l:
  410. test eax,2 ;Check for wCode & 2
  411. je short ??no2l
  412. mov edx,ecx ;Add wStep >> 1
  413. shr edx,1
  414. add [(sCompInfo ebx).dwDifference],edx
  415. ??no2l:
  416. test eax,1 ;Check for wCode & 1
  417. je short ??no1l
  418. mov edx,ecx ;Add wStep >> 2
  419. shr edx,2
  420. add [(sCompInfo ebx).dwDifference],edx
  421. ??no1l:
  422. mov edx,ecx ;Add in wStep >> 3
  423. shr edx,3
  424. add [(sCompInfo ebx).dwDifference],edx
  425. test eax,8 ;Check for wCode & 8
  426. je short ??no8l
  427. neg [(sCompInfo ebx).dwDifference] ;Negate diff
  428. ??no8l:
  429. ; add difference to predicted value.
  430. mov eax,[(sCompInfo ebx).dwPredicted]
  431. add eax,[(sCompInfo ebx).dwDifference]
  432. ; make sure there is no under or overflow.
  433. cmp eax,7FFFh
  434. jl short ??noOverflowl
  435. mov eax,7FFFh
  436. ??noOverflowl:
  437. cmp eax,0FFFF8000h
  438. jg short ??noUnderflowl
  439. mov eax,0FFFF8000h
  440. ??noUnderflowl:
  441. mov [(sCompInfo ebx).dwPredicted],eax
  442. cmp [(sCompInfo ebx).wBitSize],16
  443. jne short ??output8Bitl
  444. mov [edi],ax ;Output 16bit sample
  445. add edi,4 ;4 for stereo
  446. jmp short ??adjustIndexl
  447. ??output8Bitl:
  448. ; output 8 bit sample
  449. xor ah,80h
  450. mov [edi],ah
  451. add edi,2 ;2 for stereo
  452. ??adjustIndexl:
  453. xor ecx,ecx
  454. mov cx,[(sCompInfo ebx).wCode]
  455. xor eax,eax
  456. shl ecx,2
  457. mov eax,[wCODECIndexTab + ecx]
  458. add [(sCompInfo ebx).wIndex],ax
  459. ; check if wIndex < 0
  460. cmp [(sCompInfo ebx).wIndex],8000h
  461. jb short ??checkOverflowl
  462. mov [(sCompInfo ebx).wIndex],0
  463. jmp short ??adjustStepl ;reset index to zero
  464. ??checkOverflowl:
  465. cmp [(sCompInfo ebx).wIndex],88 ; check if wIndex > 88
  466. jbe short ??adjustStepl
  467. mov [(sCompInfo ebx).wIndex],88 ; reset index to 88
  468. ??adjustStepl:
  469. ; fetch wIndex so we can fetch new step value
  470. xor ecx,ecx
  471. mov cx,[(sCompInfo ebx).wIndex]
  472. xor eax,eax
  473. shl ecx,2
  474. mov eax,[wCODECStepTab + ecx]
  475. ; advance index and store step value
  476. add [(sCompInfo ebx).dwSampleIndex],1
  477. mov [(sCompInfo ebx).wStep],ax
  478. ; decrement bytes processed and loop back.
  479. sub [dwCODECByteIndex],2
  480. jne ??mainloopl
  481. ;----------------------------------------------------------------------------
  482. ; Right Side Setup
  483. ;----------------------------------------------------------------------------
  484. mov eax,[wBytes]
  485. mov [dwCODECBytesProcessed],eax
  486. mov esi,[(sCompInfo ebx).lpSource]
  487. mov edi,[(sCompInfo ebx).lpDest]
  488. inc esi ; skip left channel
  489. inc edi ; skip left channel
  490. cmp [(sCompInfo ebx).wBitSize],16 ;16 bit ??
  491. je short ??doByteDivide
  492. mov [dwCODECByteIndex],eax
  493. jmp short ??mainloopr
  494. ??doByteDivide:
  495. shr eax,1 ;Divide size by two
  496. inc edi ; 16 bit so skip 1 more
  497. mov [dwCODECByteIndex],eax
  498. ;--------------------------------------------------------------------------
  499. ;Right Channel Start
  500. ;--------------------------------------------------------------------------
  501. ??mainloopr:
  502. test [(sCompInfo ebx).dwSampleIndex2],1
  503. je short ??fetchTokenr
  504. xor eax,eax
  505. mov ax,[(sCompInfo ebx).wCodeBuf2]
  506. shr eax,4
  507. and eax,000Fh
  508. mov [(sCompInfo ebx).wCode2],ax
  509. jmp short ??calcDifferencer
  510. ??fetchTokenr:
  511. xor eax,eax
  512. mov al,[esi]
  513. mov [(sCompInfo ebx).wCodeBuf2],ax
  514. add esi,2 ;2 for stereo
  515. and eax,000Fh
  516. mov [(sCompInfo ebx).wCode2],ax
  517. ??calcDifferencer:
  518. ; reset difference
  519. mov [(sCompInfo ebx).dwDifference2],0
  520. xor ecx,ecx
  521. mov cx,[(sCompInfo ebx).wStep2]
  522. test eax,4 ;Check for wCode & 4
  523. je short ??no4r
  524. add [(sCompInfo ebx).dwDifference2],ecx ;Add wStep
  525. ??no4r:
  526. test eax,2 ;Check for wCode & 2
  527. je short ??no2r
  528. mov edx,ecx ;Add wStep >> 1
  529. shr edx,1
  530. add [(sCompInfo ebx).dwDifference2],edx
  531. ??no2r:
  532. test eax,1 ;Check for wCode & 1
  533. je short ??no1r
  534. mov edx,ecx ;Add wStep >> 2
  535. shr edx,2
  536. add [(sCompInfo ebx).dwDifference2],edx
  537. ??no1r:
  538. mov edx,ecx ;Add in wStep >> 3
  539. shr edx,3
  540. add [(sCompInfo ebx).dwDifference2],edx
  541. test eax,8 ;Check for wCode & 8
  542. je short ??no8r
  543. neg [(sCompInfo ebx).dwDifference2] ;Negate diff
  544. ??no8r:
  545. ; add difference to predicted value.
  546. mov eax,[(sCompInfo ebx).dwPredicted2]
  547. add eax,[(sCompInfo ebx).dwDifference2]
  548. cmp eax,7FFFh
  549. jl short ??noOverflowr
  550. mov eax,7FFFh
  551. ??noOverflowr:
  552. cmp eax,0FFFF8000h
  553. jg short ??noUnderflowr
  554. mov eax,0FFFF8000h
  555. ??noUnderflowr:
  556. mov [(sCompInfo ebx).dwPredicted2],eax
  557. cmp [(sCompInfo ebx).wBitSize],16
  558. jne short ??output8Bitr
  559. mov [edi],ax ;Output 16bit sample
  560. add edi,4 ;4 for stereo ***
  561. jmp short ??adjustIndexr
  562. ??output8Bitr:
  563. ; output 8 bit sample
  564. xor ah,80h
  565. mov [edi],ah
  566. add edi,2 ;2 for stereo
  567. ??adjustIndexr:
  568. xor ecx,ecx
  569. mov cx,[(sCompInfo ebx).wCode2]
  570. xor eax,eax
  571. shl ecx,2
  572. mov eax,[wCODECIndexTab + ecx]
  573. add [(sCompInfo ebx).wIndex2],ax
  574. ; check if wIndex < 0
  575. cmp [(sCompInfo ebx).wIndex2],8000h
  576. jb short ??checkOverflowr
  577. ; reset index to zero
  578. mov [(sCompInfo ebx).wIndex2],0
  579. jmp short ??adjustStepr
  580. ??checkOverflowr:
  581. ; check if wIndex > 88
  582. cmp [(sCompInfo ebx).wIndex2],88
  583. jbe short ??adjustStepr
  584. mov [(sCompInfo ebx).wIndex2],88 ; reset index to 88
  585. ??adjustStepr:
  586. ; fetch wIndex so we can fetch new step value
  587. xor ecx,ecx
  588. mov cx,[(sCompInfo ebx).wIndex2]
  589. xor eax,eax
  590. shl ecx,2
  591. mov eax,[wCODECStepTab + ecx]
  592. ; advance index and store step value
  593. add [(sCompInfo ebx).dwSampleIndex2],1
  594. mov [(sCompInfo ebx).wStep2],ax
  595. ; decrement bytes processed and loop back.
  596. sub [dwCODECByteIndex],2
  597. jne ??mainloopr
  598. ??exitout:
  599. ; don't think we need this but just in case i'll leave it here!!
  600. ; mov [(sCompInfo ebx).lpSource],esi
  601. ; mov [(sCompInfo ebx).lpDest],edi
  602. ; set up return value for number of bytes processed.
  603. mov eax,[dwCODECBytesProcessed]
  604. pop edx
  605. pop ecx
  606. pop ebx
  607. pop edi
  608. pop esi
  609. ret
  610. JumpTable DD ??0
  611. DD ??1
  612. DD ??2
  613. DD ??3
  614. DD ??4
  615. DD ??5
  616. DD ??6
  617. DD ??7
  618. DD ??8
  619. DD ??9
  620. DD ??10
  621. DD ??11
  622. DD ??12
  623. DD ??13
  624. DD ??14
  625. DD ??15
  626. ENDP sosCODECDecompressData
  627. LABEL LockedCodeEnd BYTE
  628. ;***************************************************************************
  629. ;* sosCODEC_LOCK -- locks the JLB audio decompression code *
  630. ;* *
  631. ;* INPUT: none *
  632. ;* *
  633. ;* OUTPUT: BOOL true is lock sucessful, false otherwise *
  634. ;* *
  635. ;* PROTO: BOOL sosCODEC_Lock(void); *
  636. ;* *
  637. ;* HISTORY: *
  638. ;* 06/26/1995 PWG : Created. *
  639. ;*=========================================================================*
  640. GLOBAL sosCODEC_Lock:NEAR
  641. PROC sosCODEC_Lock C NEAR USES ebx ecx edx esi edi
  642. ;
  643. ; Lock the code that is used by the sos decompression method.
  644. ;
  645. mov eax,0600h ; function number.
  646. mov ecx,OFFSET LockedCodeStart ; ecx must have start of memory.
  647. mov edi,OFFSET LockedCodeEnd ; edi will have size of region in bytes.
  648. shld ebx,ecx,16
  649. sub edi, ecx
  650. shld esi,edi,16
  651. int DPMI_INTR ; do call.
  652. jc ??error
  653. or [InitFlags], IF_LOCKED_PM_CODE
  654. ;
  655. ; Lock the data used by the sos decompression method.
  656. ;
  657. mov eax,0600h ; function number.
  658. mov ecx,OFFSET LockedDataStart ; ecx must have start of memory.
  659. mov edi,OFFSET LockedDataEnd ; edi will have size of region in bytes.
  660. shld ebx,ecx,16
  661. sub edi, ecx
  662. shld esi,edi,16
  663. int DPMI_INTR ; do call.
  664. jc ??error ; eax = 8 if mem err, eax = 9 if invalid mem region.
  665. or [InitFlags], IF_LOCKED_PM_DATA
  666. mov eax,1
  667. jmp ??exit
  668. ??error:
  669. xor eax,eax
  670. ??exit:
  671. ret
  672. ENDP sosCODEC_Lock
  673. ;***************************************************************************
  674. ;* DECOMPRESS_FRAME_UNLOCK -- Unlocks the JLB audio compression code *
  675. ;* *
  676. ;* INPUT: none *
  677. ;* *
  678. ;* OUTPUT: BOOL true is unlock sucessful, false otherwise *
  679. ;* *
  680. ;* PROTO: BOOL sosCODEC_Unlock(void); *
  681. ;* *
  682. ;* HISTORY: *
  683. ;* 06/26/1995 PWG : Created. *
  684. ;*=========================================================================*
  685. GLOBAL sosCODEC_Unlock:NEAR
  686. PROC sosCODEC_Unlock C NEAR USES ebx ecx edx esi edi
  687. test [InitFlags],IF_LOCKED_PM_CODE
  688. jz ??code_not_locked
  689. mov eax , 0601h
  690. mov ecx,OFFSET LockedCodeStart ; ecx must have start of memory.
  691. mov edi,OFFSET LockedCodeEnd ; edx will have size of region in bytes.
  692. sub edi,ecx ; - figure size.
  693. shld ebx , ecx , 16
  694. shld esi , edi , 16
  695. int DPMI_INTR ; do call.
  696. jc ??error
  697. ??code_not_locked:
  698. test [InitFlags],IF_LOCKED_PM_DATA
  699. jz ??data_not_locked
  700. mov ax,0601h ; set es to descriptor of data.
  701. mov ecx,OFFSET LockedDataStart ; ecx must have start of memory.
  702. mov edi,OFFSET LockedDataEnd ; edx will have size of region in bytes.
  703. sub edi,ecx ; - figure size.
  704. shld ebx , ecx , 16
  705. shld esi , edi , 16
  706. int DPMI_INTR ; do call.
  707. jc ??error ; eax = 8 if mem err, eax = 9 if invalid mem region.
  708. ??data_not_locked:
  709. mov [InitFlags],0
  710. mov eax,1
  711. jmp ??exit
  712. ??error:
  713. xor eax,eax
  714. ??exit:
  715. ret
  716. ENDP sosCODEC_Unlock
  717. END