aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobin Watts2007-12-24 18:32:18 +0000
committerRobin Watts2007-12-24 18:32:18 +0000
commit22dca84d30fdbb6b9c2bcd8accdbb6595f89e12d (patch)
tree4da9464839309d67aa36a1569f517193d27b26dc
parentbe737e074dfd82a00e8cdcbc69f53fe4614e63c2 (diff)
downloadscummvm-rg350-22dca84d30fdbb6b9c2bcd8accdbb6595f89e12d.tar.gz
scummvm-rg350-22dca84d30fdbb6b9c2bcd8accdbb6595f89e12d.tar.bz2
scummvm-rg350-22dca84d30fdbb6b9c2bcd8accdbb6595f89e12d.zip
ARM version of central ADPCM decoding block for NDS. Define ARM_ADPCM to
enable. Apparently may not be required as this isn't speed critical - but I've written it now, so seems a shame to lose it. svn-id: r29980
-rwxr-xr-xbackends/platform/ds/arm9/source/adpcm_arm.s108
-rw-r--r--backends/platform/ds/arm9/source/cdaudio.cpp14
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() {