mirror of
				https://github.com/RaySollium99/picodrive.git
				synced 2025-10-27 00:29:39 -04:00 
			
		
		
		
	 cff531af94
			
		
	
	
		cff531af94
		
	
	
	
	
		
			
			- PicoDrive was originally released by fDave with simple
  "free for non-commercial use / For commercial use, separate licencing
  terms must be obtained" license and I kept it in my releases.
- in 2011, fDave re-released his code (same that I used as base
  many years ago) dual licensed with GPLv2 and MAME licenses:
    https://code.google.com/p/cyclone68000/
Based on the above I now proclaim that the whole source code is licensed
under the MAME license as more elaborate form of "for non-commercial use".
If that raises any doubt, I announce that all my modifications (which
is the vast majority of code by now) is licensed under the MAME license,
as it reads in COPYING file in this commit.
This does not affect ym2612.c/sn76496.c that were MAME licensed already
from the beginning.
		
	
			
		
			
				
	
	
		
			369 lines
		
	
	
	
		
			8 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
			
		
		
	
	
			369 lines
		
	
	
	
		
			8 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
| /*
 | |
|  * Generic routines for mixing audio samples
 | |
|  * (C) notaz, 2007,2008
 | |
|  *
 | |
|  * This work is licensed under the terms of MAME license.
 | |
|  * See COPYING file in the top-level directory.
 | |
|  */
 | |
| 
 | |
| .text
 | |
| .align 4
 | |
| 
 | |
| @ this assumes src is word aligned
 | |
| .global mix_16h_to_32 @ int *dest, short *src, int count
 | |
| 
 | |
| mix_16h_to_32:
 | |
|     stmfd   sp!, {r4-r6,lr}
 | |
| /*
 | |
|     tst     r1, #2
 | |
|     beq     m16_32_mo_unalw
 | |
|     ldrsh   r4, [r1], #2
 | |
|     ldr     r3, [r0]
 | |
|     sub     r2, r2, #1
 | |
|     add     r3, r3, r4, asr #1
 | |
|     str     r3, [r0], #4
 | |
| */
 | |
| m16_32_mo_unalw:
 | |
|     subs    r2, r2, #4
 | |
|     bmi     m16_32_end
 | |
| 
 | |
| m16_32_loop:
 | |
|     ldmia   r0, {r3-r6}
 | |
|     ldmia   r1!,{r12,lr}
 | |
|     subs    r2, r2, #4
 | |
|     add     r4, r4, r12,asr #17 @ we use half volume
 | |
|     mov     r12,r12,lsl #16
 | |
|     add     r3, r3, r12,asr #17
 | |
|     add     r6, r6, lr, asr #17
 | |
|     mov     lr, lr, lsl #16
 | |
|     add     r5, r5, lr, asr #17
 | |
|     stmia   r0!,{r3-r6}
 | |
|     bpl     m16_32_loop
 | |
| 
 | |
| m16_32_end:
 | |
|     tst     r2, #2
 | |
|     beq     m16_32_no_unal2
 | |
|     ldr     r5, [r1], #4
 | |
|     ldmia   r0, {r3,r4}
 | |
|     mov     r12,r5, lsl #16
 | |
|     add     r3, r3, r12,asr #17
 | |
|     add     r4, r4, r5, asr #17
 | |
|     stmia   r0!,{r3,r4}
 | |
| 
 | |
| m16_32_no_unal2:
 | |
|     tst     r2, #1
 | |
|     ldmeqfd sp!, {r4-r6,pc}
 | |
|     ldrsh   r4, [r1], #2
 | |
|     ldr     r3, [r0]
 | |
|     add     r3, r3, r4, asr #1
 | |
|     str     r3, [r0], #4
 | |
| 
 | |
|     ldmfd   sp!, {r4-r6,lr}
 | |
|     bx      lr
 | |
| 
 | |
| 
 | |
| 
 | |
| .global mix_16h_to_32_s1 @ int *dest, short *src, int count
 | |
| 
 | |
| mix_16h_to_32_s1:
 | |
|     stmfd   sp!, {r4-r6,lr}
 | |
| 
 | |
|     subs    r2, r2, #4
 | |
|     bmi     m16_32_s1_end
 | |
| 
 | |
| m16_32_s1_loop:
 | |
|     ldmia   r0, {r3-r6}
 | |
|     ldr     r12,[r1], #8
 | |
|     ldr     lr, [r1], #8
 | |
|     subs    r2, r2, #4
 | |
|     add     r4, r4, r12,asr #17
 | |
|     mov     r12,r12,lsl #16
 | |
|     add     r3, r3, r12,asr #17 @ we use half volume
 | |
|     add     r6, r6, lr, asr #17
 | |
|     mov     lr, lr, lsl #16
 | |
|     add     r5, r5, lr, asr #17
 | |
|     stmia   r0!,{r3-r6}
 | |
|     bpl     m16_32_s1_loop
 | |
| 
 | |
| m16_32_s1_end:
 | |
|     tst     r2, #2
 | |
|     beq     m16_32_s1_no_unal2
 | |
|     ldr     r5, [r1], #8
 | |
|     ldmia   r0, {r3,r4}
 | |
|     mov     r12,r5, lsl #16
 | |
|     add     r3, r3, r12,asr #17
 | |
|     add     r4, r4, r5, asr #17
 | |
|     stmia   r0!,{r3,r4}
 | |
| 
 | |
| m16_32_s1_no_unal2:
 | |
|     tst     r2, #1
 | |
|     ldmeqfd sp!, {r4-r6,pc}
 | |
|     ldrsh   r4, [r1], #2
 | |
|     ldr     r3, [r0]
 | |
|     add     r3, r3, r4, asr #1
 | |
|     str     r3, [r0], #4
 | |
| 
 | |
|     ldmfd   sp!, {r4-r6,lr}
 | |
|     bx      lr
 | |
| 
 | |
| 
 | |
| 
 | |
| .global mix_16h_to_32_s2 @ int *dest, short *src, int count
 | |
| 
 | |
| mix_16h_to_32_s2:
 | |
|     stmfd   sp!, {r4-r6,lr}
 | |
| 
 | |
|     subs    r2, r2, #4
 | |
|     bmi     m16_32_s2_end
 | |
| 
 | |
| m16_32_s2_loop:
 | |
|     ldmia   r0, {r3-r6}
 | |
|     ldr     r12,[r1], #16
 | |
|     ldr     lr, [r1], #16
 | |
|     subs    r2, r2, #4
 | |
|     add     r4, r4, r12,asr #17
 | |
|     mov     r12,r12,lsl #16
 | |
|     add     r3, r3, r12,asr #17 @ we use half volume
 | |
|     add     r6, r6, lr, asr #17
 | |
|     mov     lr, lr, lsl #16
 | |
|     add     r5, r5, lr, asr #17
 | |
|     stmia   r0!,{r3-r6}
 | |
|     bpl     m16_32_s2_loop
 | |
| 
 | |
| m16_32_s2_end:
 | |
|     tst     r2, #2
 | |
|     beq     m16_32_s2_no_unal2
 | |
|     ldr     r5, [r1], #16
 | |
|     ldmia   r0, {r3,r4}
 | |
|     mov     r12,r5, lsl #16
 | |
|     add     r3, r3, r12,asr #17
 | |
|     add     r4, r4, r5, asr #17
 | |
|     stmia   r0!,{r3,r4}
 | |
| 
 | |
| m16_32_s2_no_unal2:
 | |
|     tst     r2, #1
 | |
|     ldmeqfd sp!, {r4-r6,pc}
 | |
|     ldrsh   r4, [r1], #2
 | |
|     ldr     r3, [r0]
 | |
|     add     r3, r3, r4, asr #1
 | |
|     str     r3, [r0], #4
 | |
| 
 | |
|     ldmfd   sp!, {r4-r6,lr}
 | |
|     bx      lr
 | |
| 
 | |
| 
 | |
| 
 | |
| @ limit
 | |
| @ reg=int_sample, lr=1, r3=tmp, kills flags
 | |
| .macro Limit reg
 | |
|     add     r3, lr, \reg, asr #15
 | |
|     bics    r3, r3, #1			@ in non-overflow conditions r3 is 0 or 1
 | |
|     movne   \reg, #0x8000
 | |
|     subpl   \reg, \reg, #1
 | |
| .endm
 | |
| 
 | |
| 
 | |
| @ limit and shift up by 16
 | |
| @ reg=int_sample, lr=1, r3=tmp, kills flags
 | |
| .macro Limitsh reg
 | |
| @    movs    r4, r3, asr #16
 | |
| @    cmnne   r4, #1
 | |
| @    beq     c32_16_no_overflow
 | |
| @    tst     r4, r4
 | |
| @    mov     r3, #0x8000
 | |
| @    subpl   r3, r3, #1
 | |
| 
 | |
|     add     r3, lr, \reg, asr #15
 | |
|     bics    r3, r3, #1			@ in non-overflow conditions r3 is 0 or 1
 | |
|     moveq   \reg, \reg, lsl #16
 | |
|     movne   \reg, #0x80000000
 | |
|     subpl   \reg, \reg, #0x00010000
 | |
| .endm
 | |
| 
 | |
| 
 | |
| @ mix 32bit audio (with 16bits really used, upper bits indicate overflow) with normal 16 bit audio with left channel only
 | |
| @ warning: this function assumes dest is word aligned
 | |
| .global mix_32_to_16l_stereo @ short *dest, int *src, int count
 | |
| 
 | |
| mix_32_to_16l_stereo:
 | |
|     stmfd   sp!, {r4-r8,lr}
 | |
| 
 | |
|     mov     lr, #1
 | |
| 
 | |
|     mov     r2, r2, lsl #1
 | |
|     subs    r2, r2, #4
 | |
|     bmi     m32_16l_st_end
 | |
| 
 | |
| m32_16l_st_loop:
 | |
|     ldmia   r0,  {r8,r12}
 | |
|     ldmia   r1!, {r4-r7}
 | |
|     mov     r8, r8, lsl #16
 | |
|     mov     r12,r12,lsl #16
 | |
|     add     r4, r4, r8, asr #16
 | |
|     add     r5, r5, r8, asr #16
 | |
|     add     r6, r6, r12,asr #16
 | |
|     add     r7, r7, r12,asr #16
 | |
|     Limitsh r4
 | |
|     Limitsh r5
 | |
|     Limitsh r6
 | |
|     Limitsh r7
 | |
|     subs    r2, r2, #4
 | |
|     orr     r4, r5, r4, lsr #16
 | |
|     orr     r5, r7, r6, lsr #16
 | |
|     stmia   r0!, {r4,r5}
 | |
|     bpl     m32_16l_st_loop
 | |
| 
 | |
| m32_16l_st_end:
 | |
|     @ check for remaining bytes to convert
 | |
|     tst     r2, #2
 | |
|     beq     m32_16l_st_no_unal2
 | |
|     ldrsh   r6, [r0]
 | |
|     ldmia   r1!,{r4,r5}
 | |
|     add     r4, r4, r6
 | |
|     add     r5, r5, r6
 | |
|     Limitsh r4
 | |
|     Limitsh r5
 | |
|     orr     r4, r5, r4, lsr #16
 | |
|     str     r4, [r0], #4
 | |
| 
 | |
| m32_16l_st_no_unal2:
 | |
|     ldmfd   sp!, {r4-r8,lr}
 | |
|     bx      lr
 | |
| 
 | |
| 
 | |
| @ mix 32bit audio (with 16bits really used, upper bits indicate overflow) with normal 16 bit audio (for mono sound)
 | |
| .global mix_32_to_16_mono @ short *dest, int *src, int count
 | |
| 
 | |
| mix_32_to_16_mono:
 | |
|     stmfd   sp!, {r4-r8,lr}
 | |
| 
 | |
|     mov     lr, #1
 | |
| 
 | |
|     @ check if dest is word aligned
 | |
|     tst     r0, #2
 | |
|     beq     m32_16_mo_no_unalw
 | |
|     ldrsh   r5, [r0]
 | |
|     ldr     r4, [r1], #4
 | |
|     sub     r2, r2, #1
 | |
|     add     r4, r4, r5
 | |
|     Limit   r4
 | |
|     strh    r4, [r0], #2
 | |
| 
 | |
| m32_16_mo_no_unalw:
 | |
|     subs    r2, r2, #4
 | |
|     bmi     m32_16_mo_end
 | |
| 
 | |
| m32_16_mo_loop:
 | |
|     ldmia   r0,  {r8,r12}
 | |
|     ldmia   r1!, {r4-r7}
 | |
|     add     r5, r5, r8, asr #16
 | |
|     mov     r8, r8, lsl #16
 | |
|     add     r4, r4, r8, asr #16
 | |
|     add     r7, r7, r12,asr #16
 | |
|     mov     r12,r12,lsl #16
 | |
|     add     r6, r6, r12,asr #16
 | |
|     Limitsh r4
 | |
|     Limitsh r5
 | |
|     Limitsh r6
 | |
|     Limitsh r7
 | |
|     subs    r2, r2, #4
 | |
|     orr     r4, r5, r4, lsr #16
 | |
|     orr     r5, r7, r6, lsr #16
 | |
|     stmia   r0!, {r4,r5}
 | |
|     bpl     m32_16_mo_loop
 | |
| 
 | |
| m32_16_mo_end:
 | |
|     @ check for remaining bytes to convert
 | |
|     tst     r2, #2
 | |
|     beq     m32_16_mo_no_unal2
 | |
|     ldr     r6, [r0]
 | |
|     ldmia   r1!,{r4,r5}
 | |
|     add     r5, r5, r6, asr #16
 | |
|     mov     r6, r6, lsl #16
 | |
|     add     r4, r4, r6, asr #16
 | |
|     Limitsh r4
 | |
|     Limitsh r5
 | |
|     orr     r4, r5, r4, lsr #16
 | |
|     str     r4, [r0], #4
 | |
| 
 | |
| m32_16_mo_no_unal2:
 | |
|     tst     r2, #1
 | |
|     ldmeqfd sp!, {r4-r8,pc}
 | |
|     ldrsh   r5, [r0]
 | |
|     ldr     r4, [r1], #4
 | |
|     add     r4, r4, r5
 | |
|     Limit   r4
 | |
|     strh    r4, [r0], #2
 | |
| 
 | |
|     ldmfd   sp!, {r4-r8,lr}
 | |
|     bx      lr
 | |
| 
 | |
| 
 | |
| 
 | |
| .data
 | |
| .align 4
 | |
| 
 | |
| .global mix_32_to_16l_level
 | |
| mix_32_to_16l_level:
 | |
|     .word   0
 | |
| 
 | |
| .text
 | |
| .align 4
 | |
| 
 | |
| @ same as mix_32_to_16l_stereo, but with additional shift
 | |
| .global mix_32_to_16l_stereo_lvl @ short *dest, int *src, int count
 | |
| 
 | |
| mix_32_to_16l_stereo_lvl:
 | |
|     stmfd   sp!, {r4-r9,lr}
 | |
| 
 | |
|     ldr     r9, =mix_32_to_16l_level
 | |
|     mov     lr, #1
 | |
|     ldr     r9, [r9]
 | |
| 
 | |
|     mov     r2, r2, lsl #1
 | |
|     subs    r2, r2, #4
 | |
|     bmi     m32_16l_st_l_end
 | |
| 
 | |
| m32_16l_st_l_loop:
 | |
|     ldmia   r0,  {r8,r12}
 | |
|     ldmia   r1!, {r4-r7}
 | |
|     mov     r8, r8, lsl #16
 | |
|     mov     r12,r12,lsl #16
 | |
|     add     r4, r4, r8, asr #16
 | |
|     add     r5, r5, r8, asr #16
 | |
|     add     r6, r6, r12,asr #16
 | |
|     add     r7, r7, r12,asr #16
 | |
|     mov     r4, r4, asr r9
 | |
|     mov     r5, r5, asr r9
 | |
|     mov     r6, r6, asr r9
 | |
|     mov     r7, r7, asr r9
 | |
|     Limitsh r4
 | |
|     Limitsh r5
 | |
|     Limitsh r6
 | |
|     Limitsh r7
 | |
|     subs    r2, r2, #4
 | |
|     orr     r4, r5, r4, lsr #16
 | |
|     orr     r5, r7, r6, lsr #16
 | |
|     stmia   r0!, {r4,r5}
 | |
|     bpl     m32_16l_st_l_loop
 | |
| 
 | |
| m32_16l_st_l_end:
 | |
|     @ check for remaining bytes to convert
 | |
|     tst     r2, #2
 | |
|     beq     m32_16l_st_l_no_unal2
 | |
|     ldrsh   r6, [r0]
 | |
|     ldmia   r1!,{r4,r5}
 | |
|     add     r4, r4, r6
 | |
|     add     r5, r5, r6
 | |
|     mov     r4, r4, asr r9
 | |
|     mov     r5, r5, asr r9
 | |
|     Limitsh r4
 | |
|     Limitsh r5
 | |
|     orr     r4, r5, r4, lsr #16
 | |
|     str     r4, [r0], #4
 | |
| 
 | |
| m32_16l_st_l_no_unal2:
 | |
|     ldmfd   sp!, {r4-r9,lr}
 | |
|     bx      lr
 | |
| 
 | |
| @ vim:filetype=armasm
 |