diff options
Diffstat (limited to 'backends/platform')
| -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() {  | 
