diff options
Diffstat (limited to 'backends/platform/ds/arm9/source')
-rwxr-xr-x | backends/platform/ds/arm9/source/adpcm_arm.s | 108 | ||||
-rw-r--r-- | backends/platform/ds/arm9/source/cdaudio.cpp | 14 |
2 files changed, 121 insertions, 1 deletions
diff --git a/backends/platform/ds/arm9/source/adpcm_arm.s b/backends/platform/ds/arm9/source/adpcm_arm.s new file mode 100755 index 0000000000..38e8e60c6d --- /dev/null +++ b/backends/platform/ds/arm9/source/adpcm_arm.s @@ -0,0 +1,108 @@ +@ ScummVM Scumm Interpreter +@ Copyright (C) 2007 The ScummVM project +@ +@ 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 2 +@ 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, write to the Free Software +@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +@ +@ $URL: $ +@ $Id: $ +@ +@ @author Robin Watts (robin@wss.co.uk) + + .global ARM_adpcm + .section .itcm,"ax", %progbits + .align 2 + .code 32 + + @ ARM implementation of inner ADPCM decoding loop + @ + @ C prototype would be: + @ + @ extern "C" void ARM_adpcm(int *block, + @ int len, + @ int stepTableIndex, + @ int firstSample, + @ s16 *decompressionBuffer) +ARM_adpcm + @ r0 = block + @ r1 = len + @ r2 = stepTableIndex + @ r3 = firstSample + @ <> = decompressionBuffer + STMFD r13!,{r4-r11,r14} + LDR r4,[r13,#4*9] + + LDR r12,[r0],#4 @ r12 = word = block[r>>3] + MOV r14,#0 + ADR r11,stepTab + ADR r7, indexTab + MOV r2, r2, LSL #1 @ r2 = stepTableIndex*2 - hold it doubled + STR r3, [r4],#2 @ decompBuff[0] = firstSample + MOV r3, r3, LSL #16 @ r3 = firstSample<<16 (for saturated maths) + SUBS r1, r1, #1 + BLE end +loop: + LDRH r10,[r11,r2] @ r10 = stepTab[stepTableIndex] + TST r12,#4 @ if ((offset & 4) == 0) + MOVEQ r9, #0 @ r9 = diff = 0 + MOVNE r9, r10 @ else r9 = diff = stepTab[stepTableIndex] + + TST r12,#2 @ if (offset & 2) + ADDNE r9, r9, r10,ASR #1 @ diff += r10>>1 + + TST r12,#1 @ if (offset & 1) + ADDNE r9, r9, r10,ASR #2 @ diff += r10>>2 + + ADD r9, r9, r10,ASR #3 @ diff += r10>>3 + + TST r12,#8 @ if (offset & 8 + RSBNE r9, r9, r10 + + ADDS r3, r3, r9 @ r3 = newSample = prevSample+diff + RSCVS r3, r3, #1<<31 @ r3 = clip(newSample) + MOV r8, r3, LSR #16 + + AND r6, r12,#4 @ r6 = offset + LDRB r6, [r7,r6] @ r6 = indexTab[offset] + MOV r12,r12,LSR #4 + STRH r8, [r4],#2 + + ADDS r2,r2,r6,LSL #1 @ r2 = stepTableIndex += indexTab[offset] + MOVLT r2,#0 + CMP r2,#88*2 + MOVGT r2,#88*2 + SUBS r1,r1,#1 + BEQ end + SUBS r14,r14,#0x10000000 + LDREQ r12,[r0],#4 + B loop + +end: + LDMFD r13!,{r4-r11,PC} + +stepTab: + DCW 7, 8, 9, 10, 11, 12, 13, 14, + DCW 16, 17, 19, 21, 23, 25, 28, 31, + DCW 34, 37, 41, 45, 50, 55, 60, 66, + DCW 73, 80, 88, 97, 107, 118, 130, 143, + DCW 157, 173, 190, 209, 230, 253, 279, 307, + DCW 337, 371, 408, 449, 494, 544, 598, 658, + DCW 724, 796, 876, 963, 1060, 1166, 1282, 1411, + DCW 1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024, + DCW 3327, 3660, 4026, 4428, 4871, 5358, 5894, 6484, + DCW 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899, + DCW 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, + DCW 32767 +indexTab: + DCB -1, -1, -1, -1, 2, 4, 6, 8, -1, -1, -1, -1, 2, 4, 6, 8 diff --git a/backends/platform/ds/arm9/source/cdaudio.cpp b/backends/platform/ds/arm9/source/cdaudio.cpp index 2b285e782a..9569a820f2 100644 --- a/backends/platform/ds/arm9/source/cdaudio.cpp +++ b/backends/platform/ds/arm9/source/cdaudio.cpp @@ -244,6 +244,11 @@ void update() { playNextBlock(); } +#ifdef ARM_ADPCM +extern "C" void ARM_adcpm(int *block, int len, int stepTableIndex, + int firstSample, s16 *decompressionBuffer); +#endif + void decompressBlock() { int block[2048]; bool loop = false; @@ -294,7 +299,13 @@ void decompressBlock() { return; } } - + +#ifdef ARM_ADPCM + ARM_adpcm(block, waveHeader.fmtExtra, + blockHeader.stepTableIndex, + blockHeader.firstSample, + decompressionBuffer); +#else // First sample is in header decompressionBuffer[0] = blockHeader.firstSample; @@ -387,6 +398,7 @@ void decompressBlock() { } +#endif } void playNextBlock() { |