-
Notifications
You must be signed in to change notification settings - Fork 8
/
auxmem.audio.s
157 lines (147 loc) · 6.1 KB
/
auxmem.audio.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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
* AUXMEM.AUDIO.S
* (c) Bobbi 2022 GPLv3
*
* Applecorn audio and buffer management code.
* This auxiliary memory code implements OSWORD &07 and &08, enqueueing events
* for the audio engine that lives in main memory (MAINMEM.AUDIO.S).
*
BYTE0F
BYTE15
BYTE8A
BYTE91
BYTE98
BYTE99
BUFFLUSH
BUFFLUSHALL
BUFINSERT
BUFREM
BUFINS
BUFCNP
RTS
* OSWORD &07 - Make a sound
* On entry: (OSCTRL),Y points to eight byte parameter block (2 bytes each for
* channel, amplitude, pitch, duration)
WORD07 INY
LDA (OSCTRL),Y ; Get channel system bits
DEY
CMP #$20 ; Sound system is %000xxxxx:xxxxxxxx
BCS :RTS ; *TO DO* Should pass to service call
LDA (OSCTRL),Y ; Get channel number/flush byte
ORA #$04 ; Convert to buffer number 4-7
AND #$0F ; Mask off flush nybble
PHA ; Stash
LDA (OSCTRL),Y ; Get channel number/flush byte
AND #$F0 ; Mask off channel number nybble
BEQ :WAITLOOP ; If no flush, skip
PLX ; Buffer num -> X
PHX
PHY
BIT :RTS ; Set V, means flush buffer
JSR CNPHND ; Go flush buffer
PLY
:WAITLOOP CLI ; Allow IRQS for a few cycles
SEI ; (So queue can be emptied)
LDA $C000 ; See if key pressed
BPL :NOKEY
EOR #$80
JSR KBDCHKESC ; Was Escape pressed?
BIT ESCFLAG
* ; *TO DO* Replace above with JSR ESCPOLL
BMI :ESCAPE ; If so, bail!
:NOKEY PLX ; Buffer num -> X
PHX
CLV ; Ask to count buffer
SEC ; Ask for space remaining
JSR CNPHND ; Go count it
CPX #3 ; Less than 4 bytes remaining?
BMI :WAITLOOP
PLX ; Buffer num -> X
INY ; Point to channel num MSB
LDA (OSCTRL),Y
JSR INSHND ; Insert into queue X
INY ; Point to amplitude LSB
LDA (OSCTRL),Y
JSR INSHND ; Insert into queue X
INY ; Point to amplitude MSB
INY ; Point to pitch LSB
LDA (OSCTRL),Y
JSR INSHND ; Insert into queue X
INY ; Point to pitch MSB
INY ; Point to duration LSB
LDA (OSCTRL),Y
JSR INSHND ; Insert into queue X
:RTS RTS
:ESCAPE PLX ; Fix up stack
STA KBDSTRB ; Ack keypress
RTS
* OSWORD &08 - Envelope
* On entry: (OSCTRL),Y points to 14 byte parameter block
* Supports 4 envelopes for now, could be extended for more
WORD08 LDA (OSCTRL),Y ; Get envelope number
DEC A ; Make it zero-based
CMP #$15 ; Check in range
BPL :RTS ; Ignore if out of range
TAX
LDA #$00
:L0 CPX #$00 ; Calculate EnvNum * 13
BEQ :S1 ; Faster to do n*12+n to get n*13
CLC
ADC #13
DEX
BRA :L0
:S1 TAX ; Dest offset in X
INY ; Skip over env number parm
:L1 LDA (OSCTRL),Y ; Copy CB to mainmem
>>> WRTMAIN
STA ENVBUF0,X
>>> WRTAUX
INY
INX
CPY #14
BNE :L1
:RTS RTS
* Insert value into buffer (INSV)
* On entry: A is value, X is buffer number.
* On exit: A, X, Y preserved. C clear on success.
* Stub that calls into main memory
INSHND PHA ; Preserve all regs
PHX
PHY
PHX ; X->Y for transfer
PLY
>>> XF2MAIN,MAININS
INSHNDRET >>> IENTAUX ; Do NOT enable interrupts
PHA ; A->Flags after transfer
PLP
PLY ; Recover all regs
PLX
PLA
RTS
* Count space in buffer or purge buffer (CNPV)
* On entry: X is buffer number. V set means purge, V clear means count.
* C set means space left, C clear means entries used
* On exit: For purge, X & Y are preserved.
* For count, value in X (Y=0).
* A undef. V,C flags preserved.
* Stub that calls into main memory
CNPHND PHP
PHX
PHY
PHP ; Flags->A for transfer
PLA
PHX ; X->Y for transfer
PLY
>>> XF2MAIN,MAINCNP
CNPHNDRET1 >>> IENTAUX ; Return after count
PHY ; Y->X after transfer
PLX
PLY ; Discard stacked Y
PLY ; Discard stacked X
LDY #$00 ; Y=0 for count
PLP
RTS
CNPHNDRET2 >>> IENTAUX ; Return after purge
PLY ; Recover X,Y and flags
PLX
PLP
RTS