File:
[RetroPC.NET] /
np2 /
wince /
arm /
opngeng.s
Revision
1.4:
download - view:
text,
annotated -
select for diffs
Wed Dec 24 23:01:56 2003 JST (21 years, 10 months ago) by
yui
Branches:
MAIN
CVS tags:
VER_0_82_x64,
VER_0_82,
VER_0_81A,
VER_0_81,
VER_0_80,
VER_0_79,
VER_0_78,
VER_0_77,
VER_0_76,
VER_0_75,
VER_0_74,
VER_0_73,
HEAD
fix psg (T.Yui)
FMDIV_BITS equ 8
FMDIV_ENT equ (1 << FMDIV_BITS)
FMVOL_SFTBIT equ 4
SIN_BITS equ 8
EVC_BITS equ 7
ENV_BITS equ 16
KF_BITS equ 6
FREQ_BITS equ 20
ENVTBL_BIT equ 14
SINTBL_BIT equ 14
TL_BITS equ (FREQ_BITS+2)
OPM_OUTSB equ (TL_BITS + 2 - 16)
SIN_ENT equ (1 << SIN_BITS)
EVC_ENT equ (1 << EVC_BITS)
EC_ATTACK equ 0
EC_DECAY equ (EVC_ENT << ENV_BITS)
EC_OFF equ ((2 * EVC_ENT) << ENV_BITS)
EM_ATTACK equ 4
EM_DECAY1 equ 3
EM_DECAY2 equ 2
EM_RELEASE equ 1
EM_OFF equ 0
; s_detune1 equ 0
S1_TOTALLEVEL equ 4
S1_DECAYLEVEL equ 8
; s_attack equ 12
; s_decay1 equ 16
; s_decay2 equ 20
; s_release equ 24
S1_FREQ_CNT equ 28
S1_FREQ_INC equ 32
; s_multiple equ 36
; s_keyscale equ 40
S1_ENV_MODE equ 41
; s_envraito equ 42
; s_ssgeg1 equ 43
S1_ENV_CNT equ 44
S1_ENV_END equ 48
S1_ENV_INC equ 52
; s_env_inc_attack equ 56
S1_ENVINCDECAY1 equ 60
S1_ENVINCDECAY2 equ 64
; s_env_inc_release equ 68
S_SIZE equ 72
; C_algorithm equ (S_SIZE * 4 + 0)
C_FEEDBACK equ (S_SIZE * 4 + 1)
C_PLAYING equ (S_SIZE * 4 + 2)
C_OUTSLOT equ (S_SIZE * 4 + 3)
C_OP1FB equ (S_SIZE * 4 + 4)
C_CONNECT1 equ (S_SIZE * 4 + 8)
C_CONNECT3 equ (S_SIZE * 4 + 12)
C_CONNECT2 equ (S_SIZE * 4 + 16)
C_CONNECT4 equ (S_SIZE * 4 + 20)
; C_keynote equ (S_SIZE * 4 + 24)
; C_keyfunc equ (S_SIZE * 4 + 40)
; C_kcode equ (S_SIZE * 4 + 44)
; C_pan equ (S_SIZE * 4 + 48)
; C_extop equ (S_SIZE * 4 + 49)
; C_stereo equ (S_SIZE * 4 + 50)
; C_padding2 equ (S_SIZE * 4 + 51)
C_SIZE equ (S_SIZE * 4 + 52)
G_PLAYCHANNELS equ 0
G_PLAYING equ 4
G_FEEDBACK2 equ 8
G_FEEDBACK3 equ 12
G_FEEDBACK4 equ 16
G_OUTDL equ 20
G_OUTDC equ 24
G_OUTDR equ 28
G_CALCREMAIN equ 32
; G_keyreg equ 36
T_ORG equ 24
T_CALC1024 equ (0 - T_ORG)
T_FMVOL equ (4 - T_ORG)
T_ratebit equ (8 - T_ORG)
T_vr_en equ (12 - T_ORG)
T_vr_l equ (16 - T_ORG)
T_vr_r equ (20 - T_ORG)
T_sintable equ (24 - T_ORG)
T_envtable equ (24 - T_ORG + SIN_ENT * 4)
T_envcurve equ (24 - T_ORG + SIN_ENT * 4 + EVC_ENT * 4)
IMPORT opnch
IMPORT opngen
IMPORT opncfg
EXPORT opngen_getpcm
EXPORT opngen_getpcmvr
AREA .text, CODE, READONLY
; r0 Temporary Register
; r1 Offset
; r2 Counter
; r3 Temporary Register
; r4 Temporary Register
; r5 channel counter
; r6 OPNCH
; r7 OPNCH base
; r8 L
; r9 R
; r10 opngen Fix
; r11 opncfg Fix
; r12 Temporary Register
MACRO
$label SLTFREQ $o, $upd
$label ldr r3, [r6, #($o + S1_ENV_INC)] ; calc env
ldr r4, [r6, #($o + S1_ENV_CNT)]
ldr r12, [r6, #($o + S1_ENV_END)]
;
add r3, r3, r4
cmp r3, r12
bcs $upd
MEND
MACRO
$label SLTOUT $o, $fd, $cn
$label mov r4, r3 lsr #ENV_BITS
subs r12, r4, #EVC_ENT
addcc r12, r11, #T_envcurve ; r12 = opntbl.envcurve
ldr r0, [r6, #($o + S1_TOTALLEVEL)]
ldrcc r12, [r12, r4 lsl #2]
str r3, [r6, #($o + S1_ENV_CNT)]
ldr r4, [r6, #($o + S1_FREQ_CNT)]
ldr r3, [r6, #($o + S1_FREQ_INC)] ; freq
subs r0, r0, r12
ldr r12, [r10, $fd]
add r3, r3, r4
str r3, [r6, #($o + S1_FREQ_CNT)]
bls $label.ed
add r3, r3, r12
add r0, r11, r0 lsl #2
mov r3, r3 lsl #(32 - FREQ_BITS)
add r12, r11, #T_sintable ; r12 = opntbl.sintable
mov r3, r3 lsr #(32 - SIN_BITS)
ldr r4, [r6, $cn]
ldr r0, [r0, #T_envtable]
ldr r3, [r12, r3 lsl #2]
ldr r12, [r4]
mul r0, r3, r0
;
add r12, r12, r0 asr #(ENVTBL_BIT + SINTBL_BIT - TL_BITS)
str r12, [r4]
$label.ed
MEND
MACRO
$label SLTUPD $r, $o, $m
$label ldrb r3, [r6, #($o + S1_ENV_MODE)]
;
;
sub r3, r3, #1
cmp r3, #EM_ATTACK
addcc pc, pc, r3 lsl #2
b $label.off ; EM_OFF
b $label.rel ; EM_RELEASE
b $label.dc2 ; EM_DECAY2
b $label.dc1 ; EM_DECAY1
$label.att strb r3, [r6, #($o + S1_ENV_MODE)]
ldr r0, [r6, #($o + S1_DECAYLEVEL)]
ldr r4, [r6, #($o + S1_ENVINCDECAY1)]
mov r3, #EC_DECAY
str r0, [r6, #($o + S1_ENV_END)]
str r4, [r6, #($o + S1_ENV_INC)]
b $r
$label.dc1 strb r3, [r6, #($o + S1_ENV_MODE)]
mov r0, #EC_OFF
ldr r4, [r6, #($o + S1_ENVINCDECAY2)]
ldr r3, [r6, #($o + S1_DECAYLEVEL)]
str r0, [r6, #($o + S1_ENV_END)]
str r4, [r6, #($o + S1_ENV_INC)]
b $r
$label.rel strb r3, [r6, #($o + S1_ENV_MODE)]
$label.dc2 add r3, r12, #1
ldrb r4, [r6, #C_PLAYING]
mov r0, #0
str r3, [r6, #($o + S1_ENV_END)]
str r0, [r6, #($o + S1_ENV_INC)]
and r4, r4, $m
strb r4, [r6, #C_PLAYING]
$label.off mov r3, #EC_OFF
b $r
MEND
opngen_getpcm
opngen_getpcmvr
cmp r2, #0
moveq pc, lr
ldr r12, dcd_opngen
ldr r3, [r12, #G_PLAYING]
cmp r3, #0
moveq pc, lr
stmdb sp!, {r4 - r11, lr}
ldr r7, dcd_opnch
mov r10, r12
ldr r11, dcd_opncfg
ldr lr, [r10, #G_CALCREMAIN]
ldr r3, [r10, #G_OUTDL]
ldr r4, [r10, #G_OUTDR]
getpcm_lp rsb r0, lr, #0
mul r8, r0, r3
mul r9, r0, r4
add lr, lr, #FMDIV_ENT
mksmp_lp mov r12, #0
str r12, [r10, #G_OUTDL]
str r12, [r10, #G_OUTDC]
str r12, [r10, #G_OUTDR]
ldr r5, [r10, #G_PLAYCHANNELS]
sub r5, r12, r5, lsl #8
mov r6, r7
slotcalc_lp ldrb r0, [r6, #C_PLAYING]
ldrb r12, [r6, #C_OUTSLOT]
tst r0, r12
beq slot5calc
add r5, r5, #1
mov r12, #0
str r12, [r10, #G_FEEDBACK2]
str r12, [r10, #G_FEEDBACK3]
str r12, [r10, #G_FEEDBACK4]
slot1calc SLTFREQ 0, slot1update
s1calcenv mov r12, r3, lsr #ENV_BITS
subs r4, r12, #EVC_ENT
addcc r4, r11, #T_envcurve ; r4 = opntbl.envcurve
ldr r0, [r6, #S1_TOTALLEVEL]
ldrcc r4, [r4, r12 lsl #2]
str r3, [r6, #S1_ENV_CNT]
ldr r12, [r6, #S1_FREQ_CNT]
ldr r3, [r6, #S1_FREQ_INC] ; freq
subs r0, r0, r4
ldrb r4, [r6, #C_FEEDBACK]
add r3, r3, r12
str r3, [r6, #S1_FREQ_CNT]
bls slot2calc
ldr r12, [r6, #C_OP1FB]
cmp r4, #0
addne r3, r3, r12 asr r4 ; back!
add r4, r11, #T_sintable ; r1 = opntbl.sintable
mov r3, r3 lsl #(32 - FREQ_BITS)
add r0, r11, r0 lsl #2
mov r3, r3 lsr #(32 - SIN_BITS)
ldr r0, [r0, #T_envtable]
ldr r3, [r4, r3 lsl #2]
ldr r4, [r6, #C_CONNECT1]
mul r0, r3, r0
mov r3, r0 asr #(ENVTBL_BIT + SINTBL_BIT - TL_BITS)
strne r3, [r6, #C_OP1FB]
addne r3, r3, r12
subne r3, r3, r3 asr #31 ; adjust....
movne r3, r3 asr #1
cmp r4, #0
ldrne r0, [r4]
streq r3, [r10, #G_FEEDBACK2]
streq r3, [r10, #G_FEEDBACK3]
streq r3, [r10, #G_FEEDBACK4]
addne r0, r0, r3
strne r0, [r4]
slot2calc SLTFREQ (S_SIZE * 1), slot2update
s2calcenv SLTOUT (S_SIZE * 1), #G_FEEDBACK2, #C_CONNECT2
slot3calc SLTFREQ (S_SIZE * 2), slot3update
s3calcenv SLTOUT (S_SIZE * 2), #G_FEEDBACK3, #C_CONNECT3
slot4calc SLTFREQ (S_SIZE * 3), slot4update
s4calcenv SLTOUT (S_SIZE * 3), #G_FEEDBACK4, #C_CONNECT4
slot5calc add r6, r6, #C_SIZE
adds r5, r5, #256
bcc slotcalc_lp
ldr r0, [r10, #G_OUTDC]
ldr r3, [r10, #G_OUTDL]
ldr r4, [r10, #G_OUTDR]
ldr r12, [r11, #T_CALC1024]
add r3, r3, r0
add r4, r4, r0
mov r3, r3, asr #FMVOL_SFTBIT
mov r4, r4, asr #FMVOL_SFTBIT
subs lr, lr, r12
addle r12, lr, r12
mla r8, r12, r3, r8
mla r9, r12, r4, r9
bgt mksmp_lp
ldr r0, [r11, #T_FMVOL]
mov r8, r8 asr #FMDIV_BITS
mov r9, r9 asr #FMDIV_BITS
mul r8, r0, r8
ldr r12, [r1]
mul r9, r0, r9
ldr r0, [r1, #4]
add r12, r12, r8 asr #(OPM_OUTSB + FMDIV_BITS + 1 + 6 - FMVOL_SFTBIT - 8)
str r12, [r1], #4
add r0, r0, r9 asr #(OPM_OUTSB + FMDIV_BITS + 1 + 6 - FMVOL_SFTBIT - 8)
str r0, [r1], #4
subs r2, r2, #1
bne getpcm_lp
str r3, [r10, #G_OUTDL]
str r4, [r10, #G_OUTDR]
str lr, [r10, #G_CALCREMAIN]
strb r5, [r10, #G_PLAYING]
ldmia sp!, {r4 - r11, pc}
dcd_opngen dcd opngen
dcd_opnch dcd opnch
dcd_opncfg dcd opncfg + T_ORG
slot1update SLTUPD s1calcenv, (S_SIZE * 0), #&fe
slot2update SLTUPD s2calcenv, (S_SIZE * 1), #&fd
slot3update SLTUPD s3calcenv, (S_SIZE * 2), #&fb
slot4update SLTUPD s4calcenv, (S_SIZE * 3), #&f7
END
RetroPC.NET-CVS <cvs@retropc.net>