-
Notifications
You must be signed in to change notification settings - Fork 1
/
mmc5.s
121 lines (120 loc) · 2.55 KB
/
mmc5.s
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
;
; Nintendo MMC5 expansion sound
;
ft_update_mmc5:
lda var_PlayerFlags
bne :+
lda #$00
sta $5015
rts
:
.if .defined(USE_LINEARPITCH) ;;; ;; ;
lda var_SongFlags
and #FLAG_LINEARPITCH
beq :+
jsr ft_load_ntsc_table
ldx #MMC5_OFFSET
jsr ft_linear_fetch_pitch
jsr ft_linear_fetch_pitch
:
.endif ; ;; ;;;
ldx #$00
@ChannelLoop: ; MMC5 pulse channels
lda var_ch_Note + MMC5_OFFSET, x ; Kill channel if note = off
bne :+ ; branch
jmp @KillChannel
; Calculate volume
: lda var_ch_DutyCurrent + MMC5_OFFSET, x
and #$03
sta var_Temp2
lda var_ch_LengthCounter + MMC5_OFFSET, x ;;; ;; ;
and #$01
beq :+
lda var_ch_VolColumn + MMC5_OFFSET, x ; do not automatically kill channel when hardware envelope is enabled
asl a
and #$F0
ora var_ch_Volume + MMC5_OFFSET, x
tay
lda ft_volume_table, y ; ignore tremolo
bpl @DoneVolume ; always ; ;; ;;;
: lda var_ch_VolColumn + MMC5_OFFSET, x ; Kill channel if volume column = 0
asl a
and #$F0
bne :+ ;;; ;; ; branch
jmp @KillChannel
: sta var_Temp
lda var_ch_Volume + MMC5_OFFSET, x ; Kill channel if volume = 0
beq @KillChannel
ora var_Temp
tay
; Write to registers
lda ft_volume_table, y
sec
sbc var_ch_TremoloResult + MMC5_OFFSET, x
bpl :+
lda #$00
: bne :+
lda var_ch_VolColumn + MMC5_OFFSET, x
beq :+
lda #$01
:
@DoneVolume:
ldy var_Temp2
ora ft_duty_table, y ; Add volume
sta var_Temp ;;; ;; ; allow length counter and envelope
txa
asl a
asl a
tay
lda var_ch_LengthCounter + MMC5_OFFSET, x
and #$03
eor #$03
asl a
asl a
asl a
asl a
ora var_Temp ; ;; ;;;
sta $5000, y ; y == 0 || y == 4
iny
iny
; Period table isn't limited to $7FF anymore
lda var_ch_PeriodCalcHi + MMC5_OFFSET, x
and #$F8
beq :+
lda #$03
sta var_ch_PeriodCalcHi + MMC5_OFFSET, x
lda #$FF
sta var_ch_PeriodCalcLo + MMC5_OFFSET, x
: lda var_ch_PeriodCalcLo + MMC5_OFFSET, x
sta $5000, y ; y == 2 || y == 6
iny
lda var_ch_LengthCounter + MMC5_OFFSET, x ;;; ;; ;
and #$03
beq :+
lda var_ch_Trigger + MMC5_OFFSET, x
bne :++
beq @Next ; always
: lda var_ch_PeriodCalcHi + MMC5_OFFSET, x
cmp var_ch_PrevFreqHighMMC5, x
beq @Next ; always
sta var_ch_PrevFreqHighMMC5, x
: lda var_ch_LengthCounter + MMC5_OFFSET, x
and #$F8
ora var_ch_PeriodCalcHi + MMC5_OFFSET, x
sta $5000, y
iny ; ;; ;;;
jmp @Next
@KillChannel:
lda #$30
cpx #$01
beq :+
sta $5000
bne @Next ; always
: sta $5004
@Next:
inx
cpx #CH_COUNT_MMC5
bcs :+
ldy #$04
jmp @ChannelLoop
: rts