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.
		
	
			
		
			
				
	
	
		
			927 lines
		
	
	
	
		
			20 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
			
		
		
	
	
			927 lines
		
	
	
	
		
			20 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
| /*
 | |
|  * PicoDrive
 | |
|  * (C) notaz, 2006
 | |
|  *
 | |
|  * This work is licensed under the terms of MAME license.
 | |
|  * See COPYING file in the top-level directory.
 | |
|  */
 | |
| 
 | |
| @ this is a rewrite of MAME's ym2612 code, in particular this is only the main sample-generatin loop.
 | |
| @ it does not seem to give much performance increase (if any at all), so don't use it if it causes trouble.
 | |
| @ - notaz, 2006
 | |
| 
 | |
| @ vim:filetype=armasm
 | |
| 
 | |
| .equiv SLOT1, 0
 | |
| .equiv SLOT2, 2
 | |
| .equiv SLOT3, 1
 | |
| .equiv SLOT4, 3
 | |
| .equiv SLOT_STRUCT_SIZE, 0x30
 | |
| 
 | |
| .equiv TL_TAB_LEN, 0x1A00
 | |
| 
 | |
| .equiv EG_ATT, 4
 | |
| .equiv EG_DEC, 3
 | |
| .equiv EG_SUS, 2
 | |
| .equiv EG_REL, 1
 | |
| .equiv EG_OFF, 0
 | |
| 
 | |
| .equiv EG_SH,			  16             @ 16.16 fixed point (envelope generator timing)
 | |
| .equiv EG_TIMER_OVERFLOW, (3*(1<<EG_SH)) @ envelope generator timer overflows every 3 samples (on real chip)
 | |
| .equiv LFO_SH,            25  /*  7.25 fixed point (LFO calculations)       */
 | |
| 
 | |
| .equiv ENV_QUIET,		  (2*13*256/8)/2
 | |
| 
 | |
| 
 | |
| @ r5=slot, r1=eg_cnt, trashes: r0,r2,r3
 | |
| @ writes output to routp, but only if vol_out changes
 | |
| .macro update_eg_phase_slot slot
 | |
|     ldrb    r2, [r5,#0x17]	     @ state
 | |
|     mov     r3, #1               @ 1ci
 | |
|     cmp     r2, #1
 | |
|     blt     5f                   @ EG_OFF
 | |
|     beq     3f                   @ EG_REL
 | |
|     cmp     r2, #3
 | |
|     blt     2f                   @ EG_SUS
 | |
|     beq     1f                   @ EG_DEC
 | |
| 
 | |
| 0:  @ EG_ATT
 | |
|     ldr     r2, [r5,#0x20]       @ eg_pack_ar (1ci)
 | |
|     mov     r0, r2, lsr #24
 | |
|     mov     r3, r3, lsl r0
 | |
|     sub     r3, r3, #1
 | |
|     tst     r1, r3
 | |
|     bne     5f                   @ do smth for tl problem (set on init?)
 | |
|     mov     r3, r1, lsr r0
 | |
|     ldrh    r0, [r5,#0x1a]	     @ volume, unsigned (0-1023)
 | |
|     and     r3, r3, #7
 | |
|     add     r3, r3, r3, lsl #1
 | |
|     mov     r3, r2, lsr r3
 | |
|     and     r3, r3, #7           @ shift for eg_inc calculation
 | |
|     mvn     r2, r0
 | |
|     mov     r2, r2, lsl r3
 | |
|     add     r0, r0, r2, asr #5
 | |
|     cmp     r0, #0               @ if (volume <= MIN_ATT_INDEX)
 | |
|     movle   r3, #EG_DEC
 | |
|     strleb  r3, [r5,#0x17]       @ state
 | |
|     movle   r0, #0
 | |
|     b       4f
 | |
| 
 | |
| 1:  @ EG_DEC
 | |
|     ldr     r2, [r5,#0x24]       @ eg_pack_d1r (1ci)
 | |
|     mov     r0, r2, lsr #24
 | |
|     mov     r3, r3, lsl r0
 | |
|     sub     r3, r3, #1
 | |
|     tst     r1, r3
 | |
|     bne     5f                   @ do smth for tl problem (set on init?)
 | |
|     mov     r3, r1, lsr r0
 | |
|     ldrh    r0, [r5,#0x1a]       @ volume
 | |
|     and     r3, r3, #7
 | |
|     add     r3, r3, r3, lsl #1
 | |
|     mov     r3, r2, lsr r3
 | |
|     and     r3, r3, #7           @ shift for eg_inc calculation
 | |
|     mov     r2, #1
 | |
|     mov     r3, r2, lsl r3
 | |
|     ldr     r2, [r5,#0x1c]       @ sl (can be 16bit?)
 | |
|     add     r0, r0, r3, asr #1
 | |
|     cmp     r0, r2               @ if ( volume >= (INT32) SLOT->sl )
 | |
|     movge   r3, #EG_SUS
 | |
|     strgeb  r3, [r5,#0x17]       @ state
 | |
|     b       4f
 | |
| 
 | |
| 2:  @ EG_SUS
 | |
|     ldr     r2, [r5,#0x28]       @ eg_pack_d2r (1ci)
 | |
|     mov     r0, r2, lsr #24
 | |
|     mov     r3, r3, lsl r0
 | |
|     sub     r3, r3, #1
 | |
|     tst     r1, r3
 | |
|     bne     5f                   @ do smth for tl problem (set on init?)
 | |
|     mov     r3, r1, lsr r0
 | |
|     ldrh    r0, [r5,#0x1a]       @ volume
 | |
|     and     r3, r3, #7
 | |
|     add     r3, r3, r3, lsl #1
 | |
|     mov     r3, r2, lsr r3
 | |
|     and     r3, r3, #7           @ shift for eg_inc calculation
 | |
|     mov     r2, #1
 | |
|     mov     r3, r2, lsl r3
 | |
|     add     r0, r0, r3, asr #1
 | |
|     mov     r2, #1024
 | |
|     sub     r2, r2, #1           @ r2 = MAX_ATT_INDEX
 | |
|     cmp     r0, r2               @ if ( volume >= MAX_ATT_INDEX )
 | |
|     movge   r0, r2
 | |
|     b       4f
 | |
| 
 | |
| 3:  @ EG_REL
 | |
|     ldr     r2, [r5,#0x2c]       @ eg_pack_rr (1ci)
 | |
|     mov     r0, r2, lsr #24
 | |
|     mov     r3, r3, lsl r0
 | |
|     sub     r3, r3, #1
 | |
|     tst     r1, r3
 | |
|     bne     5f                   @ do smth for tl problem (set on init?)
 | |
|     mov     r3, r1, lsr r0
 | |
|     ldrh    r0, [r5,#0x1a]       @ volume
 | |
|     and     r3, r3, #7
 | |
|     add     r3, r3, r3, lsl #1
 | |
|     mov     r3, r2, lsr r3
 | |
|     and     r3, r3, #7           @ shift for eg_inc calculation
 | |
|     mov     r2, #1
 | |
|     mov     r3, r2, lsl r3
 | |
|     add     r0, r0, r3, asr #1
 | |
|     mov     r2, #1024
 | |
|     sub     r2, r2, #1           @ r2 = MAX_ATT_INDEX
 | |
|     cmp     r0, r2               @ if ( volume >= MAX_ATT_INDEX )
 | |
|     movge   r0, r2
 | |
|     movge   r3, #EG_OFF
 | |
|     strgeb  r3, [r5,#0x17]       @ state
 | |
| 
 | |
| 4:
 | |
|     ldrh    r3, [r5,#0x18]       @ tl
 | |
|     strh    r0, [r5,#0x1a]       @ volume
 | |
| .if     \slot == SLOT1
 | |
|     mov     r6, r6, lsr #16
 | |
|     add     r0, r0, r3
 | |
|     orr     r6, r0, r6, lsl #16
 | |
| .elseif \slot == SLOT2
 | |
|     mov     r6, r6, lsl #16
 | |
|     add     r0, r0, r3
 | |
|     mov     r0, r0, lsl #16
 | |
|     orr     r6, r0, r6, lsr #16
 | |
| .elseif \slot == SLOT3
 | |
|     mov     r7, r7, lsr #16
 | |
|     add     r0, r0, r3
 | |
|     orr     r7, r0, r7, lsl #16
 | |
| .elseif \slot == SLOT4
 | |
|     mov     r7, r7, lsl #16
 | |
|     add     r0, r0, r3
 | |
|     mov     r0, r0, lsl #16
 | |
|     orr     r7, r0, r7, lsr #16
 | |
| .endif
 | |
| 
 | |
| 5:
 | |
| .endm
 | |
| 
 | |
| 
 | |
| @ r12=lfo_ampm[31:16], r1=lfo_cnt_old, r2=lfo_cnt, r3=scratch
 | |
| .macro advance_lfo_m
 | |
|     mov     r2, r2, lsr #LFO_SH
 | |
|     cmp     r2, r1, lsr #LFO_SH
 | |
|     beq     0f
 | |
|     and     r3, r2, #0x3f
 | |
|     cmp     r2, #0x40
 | |
|     rsbge   r3, r3, #0x3f
 | |
|     bic     r12,r12, #0xff000000          @ lfo_ampm &= 0xff
 | |
|     orr     r12,r12, r3, lsl #1+24
 | |
| 
 | |
|     mov     r2, r2, lsr #2
 | |
|     cmp     r2, r1, lsr #LFO_SH+2
 | |
|     bicne   r12,r12, #0xff0000
 | |
|     orrne   r12,r12, r2, lsl #16
 | |
| 
 | |
| 0:
 | |
| .endm
 | |
| 
 | |
| 
 | |
| @ result goes to r1, trashes r2
 | |
| .macro make_eg_out slot
 | |
|     tst     r12, #8
 | |
|     tstne   r12, #(1<<(\slot+8))
 | |
| .if     \slot == SLOT1
 | |
|     mov     r1, r6, lsl #16
 | |
|     mov     r1, r1, lsr #17
 | |
| .elseif \slot == SLOT2
 | |
|     mov     r1, r6, lsr #17
 | |
| .elseif \slot == SLOT3
 | |
|     mov     r1, r7, lsl #16
 | |
|     mov     r1, r1, lsr #17
 | |
| .elseif \slot == SLOT4
 | |
|     mov     r1, r7, lsr #17
 | |
| .endif
 | |
|     andne   r2, r12, #0xc0
 | |
|     movne   r2, r2,  lsr #6
 | |
|     addne   r2, r2,  #24
 | |
|     addne   r1, r1,  r12, lsr r2
 | |
| .endm
 | |
| 
 | |
| 
 | |
| .macro lookup_tl r
 | |
|     tst     \r, #0x100
 | |
|     eorne   \r, \r, #0xff   @ if (sin & 0x100) sin = 0xff - (sin&0xff);
 | |
|     tst     \r, #0x200
 | |
|     and     \r, \r, #0xff
 | |
|     orr     \r, \r, r1, lsl #8
 | |
|     mov     \r, \r, lsl #1
 | |
|     ldrh    \r, [r3, \r]    @ 2ci if ne
 | |
|     rsbne   \r, \r, #0
 | |
| .endm
 | |
| 
 | |
| 
 | |
| @ lr=context, r12=pack (stereo, lastchan, disabled, lfo_enabled | pan_r, pan_l, ams[2] | AMmasks[4] | FB[4] | lfo_ampm[16])
 | |
| @ r0-r2=scratch, r3=sin_tab, r5=scratch, r6-r7=vol_out[4], r10=op1_out
 | |
| .macro upd_algo0_m
 | |
| 
 | |
|     @ SLOT3
 | |
|     make_eg_out SLOT3
 | |
|     cmp     r1, #ENV_QUIET
 | |
|     movcs   r0, #0
 | |
|     bcs     0f
 | |
|     ldr     r2, [lr, #0x18]
 | |
|     ldr     r0, [lr, #0x38] @ mem (signed)
 | |
|     mov     r2, r2, lsr #16
 | |
|     add     r0, r2, r0, lsr #1
 | |
|     lookup_tl r0                  @ r0=c2
 | |
| 
 | |
| 0:
 | |
| 
 | |
|     @ SLOT4
 | |
|     make_eg_out SLOT4
 | |
|     cmp     r1, #ENV_QUIET
 | |
|     movcs   r0, #0
 | |
|     bcs     1f
 | |
|     ldr     r2, [lr, #0x1c]
 | |
|     mov     r0, r0, lsr #1
 | |
|     add     r0, r0, r2, lsr #16
 | |
|     lookup_tl r0                  @ r0=output smp
 | |
| 
 | |
| 1:
 | |
|     @ SLOT2
 | |
|     make_eg_out SLOT2
 | |
|     cmp     r1, #ENV_QUIET
 | |
|     movcs   r2, #0
 | |
|     bcs     2f
 | |
|     ldr     r2, [lr, #0x14]       @ 1ci
 | |
|     mov     r5, r10, lsr #17
 | |
|     add     r2, r5, r2, lsr #16
 | |
|     lookup_tl r2                  @ r2=mem
 | |
| 
 | |
| 2:
 | |
|     str     r2, [lr, #0x38] @ mem
 | |
| .endm
 | |
| 
 | |
| 
 | |
| .macro upd_algo1_m
 | |
| 
 | |
|     @ SLOT3
 | |
|     make_eg_out SLOT3
 | |
|     cmp     r1, #ENV_QUIET
 | |
|     movcs   r0, #0
 | |
|     bcs     0f
 | |
|     ldr     r2, [lr, #0x18]
 | |
|     ldr     r0, [lr, #0x38] @ mem (signed)
 | |
|     mov     r2, r2, lsr #16
 | |
|     add     r0, r2, r0, lsr #1
 | |
|     lookup_tl r0                 @ r0=c2
 | |
| 
 | |
| 0:
 | |
|     @ SLOT4
 | |
|     make_eg_out SLOT4
 | |
|     cmp     r1, #ENV_QUIET
 | |
|     movcs   r0, #0
 | |
|     bcs     1f
 | |
|     ldr     r2, [lr, #0x1c]
 | |
|     mov     r0, r0, lsr #1
 | |
|     add     r0, r0, r2, lsr #16
 | |
|     lookup_tl r0                 @ r0=output smp
 | |
| 
 | |
| 1:
 | |
|     @ SLOT2
 | |
|     make_eg_out SLOT2
 | |
|     cmp     r1, #ENV_QUIET
 | |
|     movcs   r2, #0
 | |
|     bcs     2f
 | |
|     ldr     r2, [lr, #0x14]      @ 1ci
 | |
|     mov     r2, r2, lsr #16
 | |
|     lookup_tl r2                 @ r2=mem
 | |
| 
 | |
| 2:
 | |
|     add     r2, r2, r10, asr #16
 | |
|     str     r2, [lr, #0x38]
 | |
| .endm
 | |
| 
 | |
| 
 | |
| .macro upd_algo2_m
 | |
| 
 | |
|     @ SLOT3
 | |
|     make_eg_out SLOT3
 | |
|     cmp     r1, #ENV_QUIET
 | |
|     movcs   r0, #0
 | |
|     bcs     0f
 | |
|     ldr     r2, [lr, #0x18]
 | |
|     ldr     r0, [lr, #0x38] @ mem (signed)
 | |
|     mov     r2, r2, lsr #16
 | |
|     add     r0, r2, r0, lsr #1
 | |
|     lookup_tl r0                 @ r0=c2
 | |
| 
 | |
| 0:
 | |
|     add     r0, r0, r10, asr #16
 | |
| 
 | |
|     @ SLOT4
 | |
|     make_eg_out SLOT4
 | |
|     cmp     r1, #ENV_QUIET
 | |
|     movcs   r0, #0
 | |
|     bcs     1f
 | |
|     ldr     r2, [lr, #0x1c]
 | |
|     mov     r0, r0, lsr #1
 | |
|     add     r0, r0, r2, lsr #16
 | |
|     lookup_tl r0                 @ r0=output smp
 | |
| 
 | |
| 1:
 | |
|     @ SLOT2
 | |
|     make_eg_out SLOT2
 | |
|     cmp     r1, #ENV_QUIET
 | |
|     movcs   r2, #0
 | |
|     bcs     2f
 | |
|     ldr     r2, [lr, #0x14]
 | |
|     mov     r2, r2, lsr #16      @ 1ci
 | |
|     lookup_tl r2                 @ r2=mem
 | |
| 
 | |
| 2:
 | |
|     str     r2, [lr, #0x38] @ mem
 | |
| .endm
 | |
| 
 | |
| 
 | |
| .macro upd_algo3_m
 | |
| 
 | |
|     @ SLOT3
 | |
|     make_eg_out SLOT3
 | |
|     cmp     r1, #ENV_QUIET
 | |
|     ldr     r2, [lr, #0x38] @ mem (for future)
 | |
|     movcs   r0, r2
 | |
|     bcs     0f
 | |
|     ldr     r0, [lr, #0x18]      @ 1ci
 | |
|     mov     r0, r0, lsr #16
 | |
|     lookup_tl r0                 @ r0=c2
 | |
| 
 | |
| 0:
 | |
|     add     r0, r0, r2
 | |
| 
 | |
|     @ SLOT4
 | |
|     make_eg_out SLOT4
 | |
|     cmp     r1, #ENV_QUIET
 | |
|     movcs   r0, #0
 | |
|     bcs     1f
 | |
|     ldr     r2, [lr, #0x1c]
 | |
|     mov     r0, r0, lsr #1
 | |
|     add     r0, r0, r2, lsr #16
 | |
|     lookup_tl r0                 @ r0=output smp
 | |
| 
 | |
| 1:
 | |
|     @ SLOT2
 | |
|     make_eg_out SLOT2
 | |
|     cmp     r1, #ENV_QUIET
 | |
|     movcs   r2, #0
 | |
|     bcs     2f
 | |
|     ldr     r2, [lr, #0x14]
 | |
|     mov     r5, r10, lsr #17
 | |
|     add     r2, r5, r2, lsr #16
 | |
|     lookup_tl r2                 @ r2=mem
 | |
| 
 | |
| 2:
 | |
|     str     r2, [lr, #0x38] @ mem
 | |
| .endm
 | |
| 
 | |
| 
 | |
| .macro upd_algo4_m
 | |
| 
 | |
|     @ SLOT3
 | |
|     make_eg_out SLOT3
 | |
|     cmp     r1, #ENV_QUIET
 | |
|     movcs   r0, #0
 | |
|     bcs     0f
 | |
|     ldr     r0, [lr, #0x18]
 | |
|     mov     r0, r0, lsr #16      @ 1ci
 | |
|     lookup_tl r0                 @ r0=c2
 | |
| 
 | |
| 0:
 | |
|     @ SLOT4
 | |
|     make_eg_out SLOT4
 | |
|     cmp     r1, #ENV_QUIET
 | |
|     movcs   r0, #0
 | |
|     bcs     1f
 | |
|     ldr     r2, [lr, #0x1c]
 | |
|     mov     r0, r0, lsr #1
 | |
|     add     r0, r0, r2, lsr #16
 | |
|     lookup_tl r0                 @ r0=output smp
 | |
| 
 | |
| 1:
 | |
|     @ SLOT2
 | |
|     make_eg_out SLOT2
 | |
|     cmp     r1, #ENV_QUIET
 | |
|     bcs     2f
 | |
|     ldr     r2, [lr, #0x14]
 | |
|     mov     r5, r10, lsr #17
 | |
|     add     r2, r5, r2, lsr #16
 | |
|     lookup_tl r2
 | |
|     add     r0, r0, r2            @ add to smp
 | |
| 
 | |
| 2:
 | |
| .endm
 | |
| 
 | |
| 
 | |
| .macro upd_algo5_m
 | |
| 
 | |
|     @ SLOT3
 | |
|     make_eg_out SLOT3
 | |
|     cmp     r1, #ENV_QUIET
 | |
|     movcs   r0, #0
 | |
|     bcs     0f
 | |
|     ldr     r2, [lr, #0x18]
 | |
|     ldr     r0, [lr, #0x38] @ mem (signed)
 | |
|     mov     r2, r2, lsr #16
 | |
|     add     r0, r2, r0, lsr #1
 | |
|     lookup_tl r0                 @ r0=output smp
 | |
| 
 | |
| 0:
 | |
|     @ SLOT4
 | |
|     make_eg_out SLOT4
 | |
|     cmp     r1, #ENV_QUIET
 | |
|     bcs     1f
 | |
|     ldr     r2, [lr, #0x1c]
 | |
|     mov     r5, r10, lsr #17
 | |
|     add     r2, r5, r2, lsr #16
 | |
|     lookup_tl r2
 | |
|     add     r0, r0, r2           @ add to smp
 | |
| 
 | |
| 1:  @ SLOT2
 | |
|     make_eg_out SLOT2
 | |
|     cmp     r1, #ENV_QUIET
 | |
|     bcs     2f
 | |
|     ldr     r2, [lr, #0x14]
 | |
|     mov     r5, r10, lsr #17
 | |
|     add     r2, r5, r2, lsr #16
 | |
|     lookup_tl r2
 | |
|     add     r0, r0, r2           @ add to smp
 | |
| 
 | |
| 2:
 | |
|     mov     r1, r10, asr #16
 | |
|     str     r1, [lr, #0x38] @ mem
 | |
| .endm
 | |
| 
 | |
| 
 | |
| .macro upd_algo6_m
 | |
| 
 | |
|     @ SLOT3
 | |
|     make_eg_out SLOT3
 | |
|     cmp     r1, #ENV_QUIET
 | |
|     movcs   r0, #0
 | |
|     bcs     0f
 | |
|     ldr     r0, [lr, #0x18]
 | |
|     mov     r0, r0, lsr #16      @ 1ci
 | |
|     lookup_tl r0                 @ r0=output smp
 | |
| 
 | |
| 0:
 | |
|     @ SLOT4
 | |
|     make_eg_out SLOT4
 | |
|     cmp     r1, #ENV_QUIET
 | |
|     bcs     1f
 | |
|     ldr     r2, [lr, #0x1c]
 | |
|     mov     r2, r2, lsr #16      @ 1ci
 | |
|     lookup_tl r2
 | |
|     add     r0, r0, r2           @ add to smp
 | |
| 
 | |
| 1:  @ SLOT2
 | |
|     make_eg_out SLOT2
 | |
|     cmp     r1, #ENV_QUIET
 | |
|     bcs     2f
 | |
|     ldr     r2, [lr, #0x14]
 | |
|     mov     r5, r10, lsr #17
 | |
|     add     r2, r5, r2, lsr #16
 | |
|     lookup_tl r2
 | |
|     add     r0, r0, r2           @ add to smp
 | |
| 
 | |
| 2:
 | |
| .endm
 | |
| 
 | |
| 
 | |
| .macro upd_algo7_m
 | |
| 
 | |
|     @ SLOT3
 | |
|     make_eg_out SLOT3
 | |
|     cmp     r1, #ENV_QUIET
 | |
|     movcs   r0, #0
 | |
|     bcs     0f
 | |
|     ldr     r0, [lr, #0x18]
 | |
|     mov     r0, r0, lsr #16      @ 1ci
 | |
|     lookup_tl r0                 @ r0=output smp
 | |
| 
 | |
| 0:
 | |
|     add     r0, r0, r10, asr #16
 | |
| 
 | |
|     @ SLOT4
 | |
|     make_eg_out SLOT4
 | |
|     cmp     r1, #ENV_QUIET
 | |
|     bcs     1f
 | |
|     ldr     r2, [lr, #0x1c]
 | |
|     mov     r2, r2, lsr #16      @ 1ci
 | |
|     lookup_tl r2
 | |
|     add     r0, r0, r2           @ add to smp
 | |
| 
 | |
| 1:  @ SLOT2
 | |
|     make_eg_out SLOT2
 | |
|     cmp     r1, #ENV_QUIET
 | |
|     bcs     2f
 | |
|     ldr     r2, [lr, #0x14]
 | |
|     mov     r2, r2, lsr #16      @ 1ci
 | |
|     lookup_tl r2
 | |
|     add     r0, r0, r2           @ add to smp
 | |
| 
 | |
| 2:
 | |
| .endm
 | |
| 
 | |
| 
 | |
| .macro upd_slot1_m
 | |
| 
 | |
|     make_eg_out SLOT1
 | |
|     cmp     r1, #ENV_QUIET
 | |
|     movcs   r10, r10, lsl #16     @ ct->op1_out <<= 16; // op1_out0 = op1_out1; op1_out1 = 0;
 | |
|     bcs     0f
 | |
|     ands    r2, r12, #0xf000
 | |
|     moveq   r0, #0
 | |
|     movne   r2, r2, lsr #12
 | |
|     addne   r0, r10, r10, lsl #16
 | |
|     movne   r0, r0, asr #16
 | |
|     movne   r0, r0, lsl r2
 | |
| 
 | |
|     ldr     r2, [lr, #0x10]
 | |
|     mov     r0, r0, lsr #16
 | |
|     add     r0, r0, r2, lsr #16
 | |
|     lookup_tl r0
 | |
|     mov     r10,r10,lsl #16     @ ct->op1_out <<= 16;
 | |
|     mov     r0, r0, lsl #16
 | |
|     orr     r10,r10, r0, lsr #16
 | |
| 
 | |
| 0:
 | |
| .endm
 | |
| 
 | |
| 
 | |
| /*
 | |
| .global update_eg_phase @ FM_SLOT *SLOT, UINT32 eg_cnt
 | |
| 
 | |
| update_eg_phase:
 | |
|     stmfd   sp!, {r5,r6}
 | |
|     mov     r5, r0             @ slot
 | |
|     ldrh    r3, [r5,#0x18]       @ tl
 | |
|     ldrh    r6, [r5,#0x1a]       @ volume
 | |
|     add     r6, r6, r3
 | |
|     update_eg_phase_slot SLOT1
 | |
|     mov     r0, r6
 | |
|     ldmfd   sp!, {r5,r6}
 | |
|     bx      lr
 | |
| .pool
 | |
| 
 | |
| 
 | |
| .global advance_lfo @ int lfo_ampm, UINT32 lfo_cnt_old, UINT32 lfo_cnt
 | |
| 
 | |
| advance_lfo:
 | |
|     mov     r12, r0, lsl #16
 | |
|     advance_lfo_m
 | |
|     mov     r0, r12, lsr #16
 | |
|     bx      lr
 | |
| .pool
 | |
| 
 | |
| 
 | |
| .global upd_algo0 @ chan_rend_context *c
 | |
| upd_algo0:
 | |
|     stmfd   sp!, {r4-r10,lr}
 | |
|     mov     lr, r0
 | |
| 
 | |
|     ldr     r3, =ym_sin_tab
 | |
|     ldr     r5, =ym_tl_tab
 | |
|     ldmia   lr, {r6-r7}
 | |
|     ldr     r10, [lr, #0x54]
 | |
|     ldr     r12, [lr, #0x4c]
 | |
| 
 | |
|     upd_algo0_m
 | |
| 
 | |
|     ldmfd   sp!, {r4-r10,pc}
 | |
| .pool
 | |
| 
 | |
| 
 | |
| .global upd_algo1 @ chan_rend_context *c
 | |
| upd_algo1:
 | |
|     stmfd   sp!, {r4-r10,lr}
 | |
|     mov     lr, r0
 | |
| 
 | |
|     ldr     r3, =ym_sin_tab
 | |
|     ldr     r5, =ym_tl_tab
 | |
|     ldmia   lr, {r6-r7}
 | |
|     ldr     r10, [lr, #0x54]
 | |
|     ldr     r12, [lr, #0x4c]
 | |
| 
 | |
|     upd_algo1_m
 | |
| 
 | |
|     ldmfd   sp!, {r4-r10,pc}
 | |
| .pool
 | |
| 
 | |
| 
 | |
| .global upd_algo2 @ chan_rend_context *c
 | |
| upd_algo2:
 | |
|     stmfd   sp!, {r4-r10,lr}
 | |
|     mov     lr, r0
 | |
| 
 | |
|     ldr     r3, =ym_sin_tab
 | |
|     ldr     r5, =ym_tl_tab
 | |
|     ldmia   lr, {r6-r7}
 | |
|     ldr     r10, [lr, #0x54]
 | |
|     ldr     r12, [lr, #0x4c]
 | |
| 
 | |
|     upd_algo2_m
 | |
| 
 | |
|     ldmfd   sp!, {r4-r10,pc}
 | |
| .pool
 | |
| 
 | |
| 
 | |
| .global upd_algo3 @ chan_rend_context *c
 | |
| upd_algo3:
 | |
|     stmfd   sp!, {r4-r10,lr}
 | |
|     mov     lr, r0
 | |
| 
 | |
|     ldr     r3, =ym_sin_tab
 | |
|     ldr     r5, =ym_tl_tab
 | |
|     ldmia   lr, {r6-r7}
 | |
|     ldr     r10, [lr, #0x54]
 | |
|     ldr     r12, [lr, #0x4c]
 | |
| 
 | |
|     upd_algo3_m
 | |
| 
 | |
|     ldmfd   sp!, {r4-r10,pc}
 | |
| .pool
 | |
| 
 | |
| 
 | |
| .global upd_algo4 @ chan_rend_context *c
 | |
| upd_algo4:
 | |
|     stmfd   sp!, {r4-r10,lr}
 | |
|     mov     lr, r0
 | |
| 
 | |
|     ldr     r3, =ym_sin_tab
 | |
|     ldr     r5, =ym_tl_tab
 | |
|     ldmia   lr, {r6-r7}
 | |
|     ldr     r10, [lr, #0x54]
 | |
|     ldr     r12, [lr, #0x4c]
 | |
| 
 | |
|     upd_algo4_m
 | |
| 
 | |
|     ldmfd   sp!, {r4-r10,pc}
 | |
| .pool
 | |
| 
 | |
| 
 | |
| .global upd_algo5 @ chan_rend_context *c
 | |
| upd_algo5:
 | |
|     stmfd   sp!, {r4-r10,lr}
 | |
|     mov     lr, r0
 | |
| 
 | |
|     ldr     r3, =ym_sin_tab
 | |
|     ldr     r5, =ym_tl_tab
 | |
|     ldmia   lr, {r6-r7}
 | |
|     ldr     r10, [lr, #0x54]
 | |
|     ldr     r12, [lr, #0x4c]
 | |
| 
 | |
|     upd_algo5_m
 | |
| 
 | |
|     ldmfd   sp!, {r4-r10,pc}
 | |
| .pool
 | |
| 
 | |
| 
 | |
| .global upd_algo6 @ chan_rend_context *c
 | |
| upd_algo6:
 | |
|     stmfd   sp!, {r4-r10,lr}
 | |
|     mov     lr, r0
 | |
| 
 | |
|     ldr     r3, =ym_sin_tab
 | |
|     ldr     r5, =ym_tl_tab
 | |
|     ldmia   lr, {r6-r7}
 | |
|     ldr     r10, [lr, #0x54]
 | |
|     ldr     r12, [lr, #0x4c]
 | |
| 
 | |
|     upd_algo6_m
 | |
| 
 | |
|     ldmfd   sp!, {r4-r10,pc}
 | |
| .pool
 | |
| 
 | |
| 
 | |
| .global upd_algo7 @ chan_rend_context *c
 | |
| upd_algo7:
 | |
|     stmfd   sp!, {r4-r10,lr}
 | |
|     mov     lr, r0
 | |
| 
 | |
|     ldr     r3, =ym_sin_tab
 | |
|     ldr     r5, =ym_tl_tab
 | |
|     ldmia   lr, {r6-r7}
 | |
|     ldr     r10, [lr, #0x54]
 | |
|     ldr     r12, [lr, #0x4c]
 | |
| 
 | |
|     upd_algo7_m
 | |
| 
 | |
|     ldmfd   sp!, {r4-r10,pc}
 | |
| .pool
 | |
| 
 | |
| 
 | |
| .global upd_slot1 @ chan_rend_context *c
 | |
| upd_slot1:
 | |
|     stmfd   sp!, {r4-r10,lr}
 | |
|     mov     lr, r0
 | |
| 
 | |
|     ldr     r3, =ym_sin_tab
 | |
|     ldr     r5, =ym_tl_tab
 | |
|     ldmia   lr, {r6-r7}
 | |
|     ldr     r10, [lr, #0x54]
 | |
|     ldr     r12, [lr, #0x4c]
 | |
| 
 | |
|     upd_slot1_m
 | |
|     str     r10, [lr, #0x38]
 | |
| 
 | |
|     ldmfd   sp!, {r4-r10,pc}
 | |
| .pool
 | |
| */
 | |
| 
 | |
| 
 | |
| @ lr=context, r12=pack (stereo, lastchan, disabled, lfo_enabled | pan_r, pan_l, ams[2] | AMmasks[4] | FB[4] | lfo_ampm[16])
 | |
| @ r0-r2=scratch, r3=sin_tab/scratch, r4=(length<<8)|unused[4],was_update,algo[3], r5=tl_tab/slot,
 | |
| @ r6-r7=vol_out[4], r8=eg_timer, r9=eg_timer_add[31:16], r10=op1_out, r11=buffer
 | |
| .global chan_render_loop @ chan_rend_context *ct, int *buffer, int length
 | |
| 
 | |
| chan_render_loop:
 | |
|     stmfd   sp!, {r4-r11,lr}
 | |
|     mov     lr,  r0
 | |
|     mov     r4,  r2, lsl #8      @ no more 24 bits here
 | |
|     ldr     r12, [lr, #0x4c]
 | |
|     ldr     r0,  [lr, #0x50]
 | |
|     mov     r11, r1
 | |
|     and     r0,  r0, #7
 | |
|     orr     r4,  r4, r0          @ (length<<8)|algo
 | |
|     add     r0,  lr, #0x44
 | |
|     ldmia   r0,  {r8,r9}         @ eg_timer, eg_timer_add
 | |
|     ldr     r10, [lr, #0x54]     @ op1_out
 | |
|     ldmia   lr,  {r6,r7}         @ load volumes
 | |
| 
 | |
|     tst     r12, #8              @ lfo?
 | |
|     beq     crl_loop
 | |
| 
 | |
| crl_loop_lfo:
 | |
|     add     r0, lr, #0x30
 | |
|     ldmia   r0, {r1,r2}
 | |
|     add     r2, r2, r1
 | |
|     str     r2, [lr, #0x30]
 | |
|     @ r12=lfo_ampm[31:16], r1=lfo_cnt_old, r2=lfo_cnt
 | |
|     advance_lfo_m
 | |
| 
 | |
| crl_loop:
 | |
|     subs    r4, r4, #0x100
 | |
|     bmi     crl_loop_end
 | |
| 
 | |
|     @ -- EG --
 | |
|     add     r8, r8, r9
 | |
|     cmp     r8, #EG_TIMER_OVERFLOW
 | |
|     bcc     eg_done
 | |
|     add     r0, lr, #0x3c
 | |
|     ldmia   r0, {r1,r5}         @ eg_cnt, CH
 | |
| eg_loop:
 | |
|     sub     r8, r8, #EG_TIMER_OVERFLOW
 | |
|     add     r1, r1, #1
 | |
|                                         @ SLOT1 (0)
 | |
|     @ r5=slot, r1=eg_cnt, trashes: r0,r2,r3
 | |
|     update_eg_phase_slot SLOT1
 | |
|     add     r5, r5, #SLOT_STRUCT_SIZE*2 @ SLOT2 (2)
 | |
|     update_eg_phase_slot SLOT2
 | |
|     sub     r5, r5, #SLOT_STRUCT_SIZE   @ SLOT3 (1)
 | |
|     update_eg_phase_slot SLOT3
 | |
|     add     r5, r5, #SLOT_STRUCT_SIZE*2 @ SLOT4 (3)
 | |
|     update_eg_phase_slot SLOT4
 | |
| 
 | |
|     cmp     r8, #EG_TIMER_OVERFLOW
 | |
|     subcs   r5, r5, #SLOT_STRUCT_SIZE*3
 | |
|     bcs     eg_loop
 | |
|     str     r1, [lr, #0x3c]
 | |
| 
 | |
| eg_done:
 | |
| 
 | |
|     @ -- disabled? --
 | |
|     and     r0, r12, #0xC
 | |
|     cmp     r0, #0xC
 | |
|     beq     crl_loop_lfo
 | |
|     cmp     r0, #0x4
 | |
|     beq     crl_loop
 | |
| 
 | |
|     @ -- SLOT1 --
 | |
|     ldr     r3, =ym_tl_tab
 | |
| 
 | |
|     @ lr=context, r12=pack (stereo, lastchan, disabled, lfo_enabled | pan_r, pan_l, ams[2] | AMmasks[4] | FB[4] | lfo_ampm[16])
 | |
|     @ r0-r2=scratch, r3=tl_tab, r5=scratch, r6-r7=vol_out[4], r10=op1_out
 | |
|     upd_slot1_m
 | |
| 
 | |
|     @ -- SLOT2+ --
 | |
|     and     r0, r4, #7
 | |
|     ldr     pc, [pc, r0, lsl #2]
 | |
|     nop
 | |
|     .word   crl_algo0
 | |
|     .word   crl_algo1
 | |
|     .word   crl_algo2
 | |
|     .word   crl_algo3
 | |
|     .word   crl_algo4
 | |
|     .word   crl_algo5
 | |
|     .word   crl_algo6
 | |
|     .word   crl_algo7
 | |
|     .pool
 | |
| 
 | |
| crl_algo0:
 | |
|     upd_algo0_m
 | |
|     b       crl_algo_done
 | |
|     .pool
 | |
| 
 | |
| crl_algo1:
 | |
|     upd_algo1_m
 | |
|     b       crl_algo_done
 | |
|     .pool
 | |
| 
 | |
| crl_algo2:
 | |
|     upd_algo2_m
 | |
|     b       crl_algo_done
 | |
|     .pool
 | |
| 
 | |
| crl_algo3:
 | |
|     upd_algo3_m
 | |
|     b       crl_algo_done
 | |
|     .pool
 | |
| 
 | |
| crl_algo4:
 | |
|     upd_algo4_m
 | |
|     b       crl_algo_done
 | |
|     .pool
 | |
| 
 | |
| crl_algo5:
 | |
|     upd_algo5_m
 | |
|     b       crl_algo_done
 | |
|     .pool
 | |
| 
 | |
| crl_algo6:
 | |
|     upd_algo6_m
 | |
|     b       crl_algo_done
 | |
|     .pool
 | |
| 
 | |
| crl_algo7:
 | |
|     upd_algo7_m
 | |
|     .pool
 | |
| 
 | |
| 
 | |
| crl_algo_done:
 | |
|     @ -- WRITE SAMPLE --
 | |
|     tst     r0, r0
 | |
|     beq     ctl_sample_skip
 | |
|     orr     r4, r4, #8              @ have_output
 | |
|     tst     r12, #1
 | |
|     beq     ctl_sample_mono
 | |
| 
 | |
|     tst     r12, #0x20              @ L
 | |
|     ldrne   r1, [r11]
 | |
|     addeq   r11, r11, #4
 | |
|     addne   r1, r0, r1
 | |
|     strne   r1, [r11], #4
 | |
|     tst     r12, #0x10              @ R
 | |
|     ldrne   r1, [r11]
 | |
|     addeq   r11, r11, #4
 | |
|     addne   r1, r0, r1
 | |
|     strne   r1, [r11], #4
 | |
|     b       crl_do_phase
 | |
| 
 | |
| ctl_sample_skip:
 | |
|     and     r1, r12, #1
 | |
|     add     r1, r1,  #1
 | |
|     add     r11,r11, r1, lsl #2
 | |
|     b       crl_do_phase
 | |
| 
 | |
| ctl_sample_mono:
 | |
|     ldr     r1, [r11]
 | |
|     add     r1, r0, r1
 | |
|     str     r1, [r11], #4
 | |
| 
 | |
| crl_do_phase:
 | |
|     @ -- PHASE UPDATE --
 | |
|     add     r5, lr, #0x10
 | |
|     ldmia   r5, {r0-r1}
 | |
|     add     r5, lr, #0x20
 | |
|     ldmia   r5, {r2-r3}
 | |
|     add     r5, lr, #0x10
 | |
|     add     r0, r0, r2
 | |
|     add     r1, r1, r3
 | |
|     stmia   r5!,{r0-r1}
 | |
|     ldmia   r5, {r0-r1}
 | |
|     add     r5, lr, #0x28
 | |
|     ldmia   r5, {r2-r3}
 | |
|     add     r5, lr, #0x18
 | |
|     add     r0, r0, r2
 | |
|     add     r1, r1, r3
 | |
|     stmia   r5, {r0-r1}
 | |
| 
 | |
|     tst     r12, #8
 | |
|     bne     crl_loop_lfo
 | |
|     b       crl_loop
 | |
| 
 | |
| 
 | |
| crl_loop_end:
 | |
|     str     r8,  [lr, #0x44]     @ eg_timer
 | |
|     str     r12, [lr, #0x4c]     @ pack (for lfo_ampm)
 | |
|     str     r4,  [lr, #0x50]     @ was_update
 | |
|     str     r10, [lr, #0x54]     @ op1_out
 | |
|     ldmfd   sp!, {r4-r11,pc}
 | |
| 
 | |
| .pool
 | |
| 
 |