summaryrefslogtreecommitdiffstats
path: root/apps
diff options
context:
space:
mode:
Diffstat (limited to 'apps')
-rw-r--r--apps/plugins/sdl/progs/quake/snd_mix_arm.S109
1 files changed, 46 insertions, 63 deletions
diff --git a/apps/plugins/sdl/progs/quake/snd_mix_arm.S b/apps/plugins/sdl/progs/quake/snd_mix_arm.S
index 15733d8912..0573e85923 100644
--- a/apps/plugins/sdl/progs/quake/snd_mix_arm.S
+++ b/apps/plugins/sdl/progs/quake/snd_mix_arm.S
@@ -19,12 +19,14 @@
*
***************************************************************************/
- /** Sound mixing code for ARM. **/
- /* Takes 8-bit mono audio and outputs stereo 16-bit samples.
- * stereo volumes are passed as arguments.
- *
- * Bear with me. This is my first ARM assembly, ever.
- */
+ /*
+ * Sound mixing code for ARM.
+ *
+ * Takes an array of 8-bit mono audio and outputs stereo 16-bit
+ * samples. Stereo volumes are passed as arguments r0 and r1.
+ *
+ * Bear with me. This is my first ARM assembly, ever.
+ */
.text
.align 2
@@ -33,93 +35,74 @@
#if defined(__ARM_ARCH_5TEJ__)
SND_PaintChannelFrom8:
- // r0: int true_lvol
- // r1: int true_rvol
- // r2: char *sfx
- // r3: int count
+ ;; r0: int true_lvol
+ ;; r1: int true_rvol
+ ;; r2: char *sfx
+ ;; r3: int count
stmfd sp!, {r4, r5, r6, r7, r8, sl}
ldr ip, =paintbuffer
ldr ip, [ip]
- mov r0, r0, asl #16 // pre-scale both volumes by 2^16
+ mov r0, r0, asl #16 ; prescale by 2^16
mov r1, r1, asl #16
- sub r3, r3, #1 // we'll count backwards
- // sl = 0xffff0000
- ldrh sl, =0xffff
+ sub r3, r3, #1 ; count backwards
-.loop:
- ldrsb r4, [r2, r3] // load *sfx[i] -> r4
+ ldrh sl, =0xffff ; halfword mask
- // keep endianness in mind here
- // buffer looks like [left_0, left_1, right_0, right_1] in memory
- // but it is loaded as [right1, right0, left1, left0] to registers
- ldr r8, [ip, r3, lsl #2] // load paintbuffer[0:1] = RIGHTCHANNEL:LEFTCHANNEL
+1:
+ ldrsb r4, [r2, r3] ; load input sample
+ ldr r8, [ip, r3, lsl #2] ; load output sample pair from paintbuffer
+ ; (left:right in memory -> right:left in register)
+ ;; right channel (high half)
+ mul r5, r4, r1 ; scaledright = sfx[i] * (true_rvol << 16) -- bottom half is zero
+ qadd r7, r5, r8 ; right = scaledright + right (in high half of word)
+ bic r7, r7, sl ; zero bottom half of r7
- // handle high half (right channel) first
- mul r5, r4, r1 // SCALEDRIGHT = SFXI * (true_rvol << 16) -- bottom half is zero
+ ;; left channel (low half)
+ mul r5, r4, r0 ; scaledleft = sfx[i] * (true_rvol << 16)
+ mov r8, r8, lsl #16 ; extract original left channel from paintbuffer
+ qadd r8, r5, r8 ; left = scaledleft + left
- // r7 holds right channel in high half (dirty bottom half)
- qadd r7, r5, r8 // RIGHTCHANORIG = SCALEDRIGHT + RIGHTCHANORIG (high half)
-
- bic r7, r7, sl // zero bottom bits of r7
-
- // trash r5, r6 and handle left channel
- mul r5, r4, r0 // SCALEDLEFT = SFXI * (true_rvol << 16)
-
- mov r8, r8, lsl #16 // extract original left channel from paintbuffer
-
- // r8 holds left channel in high half with zero bottom half
- qadd r8, r5, r8
-
- // combine the two 16-bit samples in r7 as 32-bit [left:right]
- // (use lsr to not sign-extend the lower half)
- orr r7, r7, r8, lsr #16
-
- str r7, [ip, r3, lsl #2] // write 32-bit to paintbuffer
+ orr r7, r7, r8, lsr #16 ; combine right:left in r7
+ str r7, [ip, r3, lsl #2] ; write right:left to output buffer
subs r3, r3, #1
- bgt .loop // must use instead of bne because of the corner case count=1
-
+ bgt 1b ; must use bgt instead of bne in case count=1
ldmfd sp!, {r4, r5, r6, r7, r8, sl}
bx lr
-#elif defined(__ARM_ARCH_6__) // ARMv6 with QADD16 (disabled)
+#elif defined(__ARM_ARCH_6__) ; ARMv6 with QADD16 (disabled)
SND_PaintChannelFrom8:
- // r0: int true_lvol
- // r1: int true_rvol
- // r2: char *sfx
- // r3: int count
+ ;; r0: int true_lvol
+ ;; r1: int true_rvol
+ ;; r2: char *sfx
+ ;; r3: int count
stmfd sp!, {r4, r5, r6, r7}
ldr ip, =paintbuffer
- ldr ip, [ip]
- sub r3, r3, #1 // we'll count backwards
-.loop:
- ldrsb r4, [r2, r3] // load *sfx[i] -> r4
-
- // keep endianness in mind here
- // buffer looks like [left_0, left_1, right_0, right_1] in memory
- // but it is loaded as [right1, right0, left1, left0] to registers
- ldr r7, [ip, r3, lsl #2] // load paintbuffer[0:1] = RIGHTCHANNEL:LEFTCHANNEL
+ ldr ip, [ip] ; load paintbuffer address
+ sub r3, r3, #1 ; we'll count backwards
+1:
+ ldrsb r4, [r2, r3] ; load sfx[i] -> r4
+ ldr r7, [ip, r3, lsl #2] ; load old sample pair
- // handle high half (right channel) first
- mul r5, r4, r1 // SCALEDRIGHT = SFXI * true_rvol
- mul r6, r4, r0 // SCALEDLEFT = SFXI * true_rvol
+ mul r5, r4, r1 ; SCALEDRIGHT = SFXI * true_rvol
+ mul r6, r4, r0 ; SCALEDLEFT = SFXI * true_rvol
- orr r6, r6, r5, lsl #16
+ orr r6, r6, r5, lsl #16 ; combine samples as 32-bit
- qadd16 r6, r6, r7
+ qadd16 r6, r6, r7 ; parallel 16-bit add
- str r6, [ip, r3, lsl #2] // write 32-bit to paintbuffer
+ str r6, [ip, r3, lsl #2] ; write 32-bit to paintbuffer
subs r3, r3, #1
- bne .loop
+ bgt 1b
ldmfd sp!, {r4, r5, r6, r7}