source: buchla-68k/ram/seexec.s@ 8325447

Last change on this file since 8325447 was 8325447, checked in by Thomas Lopatic <thomas@…>, 7 years ago

Removed _ prefix.

  • Property mode set to 100644
File size: 14.2 KB
Line 
1| ------------------------------------------------------------------------------
2| seexec.s -- score event execution driver
3| Version 40 -- 1988-10-06 -- D.N. Lynx Crowe
4
5| struct s_entry *
6| se_exec(ep, sd)
7| struct s_entry *ep;
8| short sd;
9
10| Executes the event at 'ep', scrolling in direction 'sd'.
11
12| ------------------------------------------------------------------------------
13 .text
14
15 .xdef se_exec
16
17 .xdef BadEvnt
18
19 .xdef xevent
20
21 .xref asgvce
22 .xref clkset
23 .xref getasg
24 .xref gettun
25 .xref procpfl
26 .xref selscor
27 .xref setdyn
28 .xref setloc
29 .xref setsv
30 .xref settmpo
31 .xref settune
32 .xref setv2gi
33
34 .xref anrs
35 .xref var2src
36 .xref curasg
37 .xref curintp
38 .xref cursect
39 .xref grpmode
40 .xref grpstat
41 .xref ins2grp
42 .xref nxtflag
43 .xref recsw
44 .xref s_trns
45 .xref trgtab
46 .xref varmode
47 .xref vce2grp
48 .xref vce2trg
49 .xref veltab
50
51 .page
52
53| parameter offsets
54| -----------------
55P_EP = 8 | WORD - 'ep' parameter offset
56P_SD = 12 | WORD - 'sd' parameter offset
57
58| event structure offsets -- MUST match score.h definitions
59| ----------------------- ------------------------------
60| offset length
61| ------ ------
62E_TIME = 0 | LONG
63E_SIZE = 4 | BYTE
64E_TYPE = 5 | BYTE
65E_DATA1 = 6 | BYTE
66E_NOTE = 6 | BYTE
67E_DATA2 = 7 | BYTE
68E_GROUP = 7 | BYTE
69E_BAK = 8 | LONG
70E_FWD = 12 | LONG
71E_DN = 16 | LONG
72E_VEL = 16 | WORD
73E_DATA4 = 18 | WORD
74E_UP = 20 | LONG
75E_LFT = 24 | LONG
76E_RGT = 28 | LONG
77
78| Miscellaneous constants
79| -----------------------
80N_ETYPES = 25 | number of event types
81
82M_KSTATE = 0x01 | keys status bit
83N_KSTATE = 0xFE | keys status bit complement
84
85D_BAK = 1 | code for backward scrolling
86
87LCL_PRT = 2 | 0-origin local port number
88LCL_PCH = 0x1080 | port and channel for trigger
89
90 .page
91
92| A few words about se_exec:
93
94| se_exec has to be very fast, so it's written in assembly language,
95| rather than C, which is usually pretty good, but not quite good enough
96| for this application. The faster this routine runs, the higher the
97| tempo we can keep up with. If this code is fast enough, we end up
98| hardware limited by the timer.
99
100se_exec: link a6,#0 | link stack frames
101 movea.l P_EP(a6),a0 | get event pointer 'ep' into a0
102 move.l a0,_xevent | save in xevent
103 move.b E_TYPE(a0),d1 | get event type into d1.W
104 andi.w #0x007F,d1 | ... and mask off new-data flag
105 cmp.b #N_ETYPES,d1 | see if it's valid
106 blt sexc1 | jump if it is
107
108BadEvnt: move.l a0,d0 | setup to return pointer we got
109 bra done | exit
110
111exexit: movea.l _xevent,a0 | point at next event
112 move.l E_FWD(a0),d0 | ...
113
114done: unlk a6 | done -- unlink stack frames
115 rts | return to caller
116
117sexc1: lea sextab,a1 | get base of dispatch table
118 lsl.w #2,d1 | multiplty event by 4 for index
119 movea.l 0(a1,d1.W),a2 | get address of event routine
120 jmp (a2) | jump to event execution routine
121
122| On entry, the individual execution routines only depend on a0 pointing at the
123| event they were dispatched for.
124
125| The usual C function register usage conventions apply:
126
127| d0..d2 and a0..a2 are used for scratch, and are not preserved.
128
129| d3..d6 and a3..a5 are register variables, and are preserved.
130| a6 = frame pointer, a7 = stack pointer, and are preserved.
131
132 .page
133
134| exnbeg -- execute note begin
135| ------ ------------------
136| If things need to be sped up, we could incorporate the functions of
137| asgvce() here, rather than calling it. asgvce() could also be re-written in
138| assembly language to make it a shade faster.
139
140exnbeg: cmpi.w #D_BAK,P_SD(a6) | check direction
141 beq nendex | if backward, treat as note end
142
143nbegex: clr.w d1 | clear d1
144 move.b E_GROUP(a0),d1 | get group number
145 add.w d1,d1 | ... * 2
146 lea grpstat,a1 | point at grpstat
147 tst.w 0(a1,d1.W) | see if group is enabled
148 beq exexit | done if not
149
150 move.b E_NOTE(a0),d1 | d1 = note number nn (0..127)
151 move.w #LCL_PCH,d2 | put port and channel in d2
152 add.w d1,d2 | d2 = trg
153 lea trgtab,a1 | point at trgtab[trg]
154 move.b 0(a1,d2.W),d0 | ...
155 or.b #M_KSTATE,d0 | set trigger table entry on
156 move.b d0,0(a1,d2.W) | ...
157 lea veltab,a1 | point at veltab
158 add.w d2,d2 | ...
159 move.w E_VEL(a0),0(a1,d2.W) | put velocity in veltab
160 move.w E_VEL(a0),-(a7) | put velocity on the stack
161 move.w d1,-(a7) | put note number on the stack
162 move.w #1,-(a7) | put channel on the stack
163 move.w #LCL_PRT,-(a7) | put port on the stack
164 move.b E_GROUP(a0),d1 | d1 = group number (0..11)
165 move.w d1,-(a7) | put group number on the stack
166 jsr asgvce | start the note
167 add.l #10,a7 | clean up the stack
168 bra exexit | done
169
170 .page
171
172| exnend -- execute note end
173| ------ ----------------
174| If things need to be sped up, we could incorporate the functions of
175| procpfl() here, rather than calling it. procpfl() could also be re-written in
176| assembly language to make it a shade faster.
177
178exnend: cmpi.w #D_BAK,P_SD(a6) | check direction
179 beq nbegex | if backward, treat as beginning
180
181nendex: clr.w d1 | clear d1
182 move.b E_GROUP(a0),d1 | get group number
183 add.w d1,d1 | ... * 2
184 lea grpstat,a1 | point at grpstat
185 tst.w 0(a1,d1.W) | check group status
186 beq exexit | done if disabled
187
188 move.b E_NOTE(a0),d1 | d1 = note number nn (0..127)
189 move.w #LCL_PCH,d2 | put port and channel in d2
190 add.w d1,d2 | d2 = trg * 2
191 add.w d2,d2 | ...
192 lea trgtab,a1 | set trigger table entry off
193 move.b 0(a1,d2.W),d0 | ...
194 and.b #N_KSTATE,d0 | ...
195 move.b d0,0(a1,d2.W) | ...
196 bne exexit | done if note still active
197
198 .page
199
200 lsr.w #1,d2 | adjust d2
201 clr.w d1 | set loop index
202 lea vce2trg,a2 | point at vce2trg table
203
204exnend1: cmp.w (a2),d2 | see if this voice uses trg
205 bne exnend2 | jump if not
206
207 move.w #-1,(a2) | set entry to -1
208 move.l a2,-(a7) | save a2 on stack
209 move.w d1,-(a7) | save d1 on stack
210 move.w d2,-(a7) | save d2 on stack
211 lea vce2grp,a1 | put group on stack
212 move.w d1,d0 | ...
213 add.w d0,d0 | ...
214 move.w 0(a1,d0.W),-(a7) | ...
215 move.w d2,-(a7) | put trg on stack
216 jsr procpfl | process sustained voices
217 addq.l #4,a7 | clean up stack
218 move.w (a7)+,d2 | restore d2
219 move.w (a7)+,d1 | restore d1
220 movea.l (a7)+,a2 | restore a2
221
222exnend2: addq.l #2,a2 | point at next vce2trg entry
223 addq.w #1,d1 | loop until all are checked
224 cmp.w #12,d1 | ...
225 bne exnend1 | ...
226
227 bra exexit | done
228
229 .page
230
231| exsbgn -- execute section begin
232| ------ ---------------------
233exsbgn: clr.w d0 | get section number
234 move.b E_DATA1(a0),d0 | ...
235 move.w d0,cursect | set section number
236 bra exexit | done
237
238| exasgn -- execute assignment event
239| ------ ------------------------
240exasgn: clr.w d0 | get assignment
241 move.b E_DATA1(a0),d0 | ...
242 move.w d0,-(a7) | getasg(curasg = asgn)
243 move.w d0,curasg | ...
244 jsr getasg | ...
245 tst.w (a7)+ | ...
246 bra exexit | done
247
248| extune -- execute tuning event
249| ------ --------------------
250extune: clr.w d0 | get tuning
251 move.b E_DATA1(a0),d0 | ...
252 move.w d0,-(a7) | gettun(tuning)
253 jsr gettun | ...
254 tst.w (a7)+ | ...
255 bra exexit | done
256
257| extrns -- execute transposition event
258| ------ ---------------------------
259extrns: clr.w d0 | get group number
260 move.b E_DATA1(a0),d0 | ...
261 add.w d0,d0 | ... as an index in d0
262 lea grpstat,a1 | check grpstat[grp]
263 tst.w 0(a1,d0.W) | ...
264 beq exexit | done if disabled
265
266 lea s_trns,a1 | set group transposition
267 move.w E_LFT(a0),0(a1,d0.W) | ...
268 jsr settune | ...
269 bra exexit | done
270
271 .page
272
273| extmpo -- execute tempo event
274| ------ -------------------
275extmpo: clr.w d0 | get tempo
276 move.b E_DATA1(a0),d0 | ...
277 move.w d0,-(a7) | settmpo(tempo)
278 jsr settmpo | ...
279 tst.w (a7)+ | ...
280 bra exexit | done
281
282| exstop -- execute stop event
283| ------ ------------------
284exstop: clr.w -(a7) | stop the clock
285 jsr clkset | ...
286 tst.w (a7)+ | ...
287 bra exexit | that's all, folks
288
289| exintp -- execute interpolate event
290| ------ -------------------------
291exintp: move.w E_DATA1(a0),curintp | set interpolate value
292 bra exexit | done
293
294 .page
295
296| exinst -- execute instrument change event
297| ------ -------------------------------
298exinst: clr.w d0 | get group number
299 move.b E_DATA1(a0),d0 | ... in d0
300 add.w d0,d0 | ... as a word offset
301 lea grpstat,a1 | check grpstat[grp]
302 tst.w 0(a1,d0.W) | ...
303 beq exexit | done if not enabled
304
305 lea ins2grp,a1 | point at ins2grp[]
306 clr.w d0 | get instrument number
307 move.b E_DATA2(a0),d0 | ... in d0
308 clr.w d1 | get group number
309 move.b E_DATA1(a0),d1 | ... in d1
310 move.w d1,-(a7) | put group number on stack
311 add.w d1,d1 | make d1 a word pointer
312 move.w 0(a1,d1.W),d2 | get ins2grp[group]
313 and.w #0xFF00,d2 | mask off GTAG1..GTAG8
314 or.w d0,d2 | OR in new instrument number
315 move.w d2,0(a1,d1.W) | set ins2grp[group]
316 jsr setv2gi | setv2gi(group)
317 tst.w (a7)+ | clean up stack
318 bra exexit | done
319
320 .page
321
322| exdyn -- execute dynamics event
323| ----- ----------------------
324exdyn: clr.w d0 | get group number
325 move.b E_DATA1(a0),d0 | ... in d0
326 add.w d0,d0 | ... as a word offset
327 lea grpstat,a1 | check grpstat[grp]
328 tst.w 0(a1,d0.W) | ...
329 beq exexit | done if not enabled
330
331 clr.w d0 | get dynamics
332 move.b E_DATA2(a0),d0 | ... in d0
333 clr.w d1 | get group number
334 move.b E_DATA1(a0),d1 | ... in d1
335 move.w d0,-(a7) | setdyn(group, dyn)
336 move.w d1,-(a7) | ...
337 jsr setdyn | ...
338 adda.l #4,a7 | clean up stack
339 bra exexit | done
340
341| exlocn -- execute location event
342| ------ ----------------------
343exlocn: clr.w d0 | get group number
344 move.b E_DATA1(a0),d0 | ... in d0
345 add.w d0,d0 | ... as a word offset
346 lea grpstat,a1 | check grpstat[grp]
347 tst.w 0(a1,d0.W) | ...
348 beq exexit | done if not enabled
349
350 clr.w d0 | get location
351 move.b E_DATA2(a0),d0 | ... in d0
352 clr.w d1 | get group number
353 move.b E_DATA1(a0),d1 | ... in d1
354 move.w d0,-(a7) | setloc(group, loc)
355 move.w d1,-(a7) | ...
356 jsr setloc | ...
357 adda.l #4,a7 | clean up stack
358 bra exexit | done
359
360 .page
361
362| exanrs -- execute analog resolution event
363| ------ -------------------------------
364exanrs: move.b E_DATA1(a0),d0 | get group number
365 andi.w #0x000F,d0 | ... in d0
366 add.w d0,d0 | ... as a word offset
367 lea grpstat,a1 | check grpstat[grp]
368 tst.w 0(a1,d0.W) | ...
369 beq exexit | done if not enabled
370
371 clr.w d1 | get variable / group numbers
372 move.b E_DATA1(a0),d1 | ...
373 add.w d1,d1 | convert to word index
374 clr.w d0 | get resolution
375 move.b E_DATA2(a0),d0 | ... in d0
376 lea anrs,a1 | point at resolution table base
377 move.w d0,0(a1,d1.W) | save resolution in table
378 bra exexit | done
379
380| exanvl -- execute analog value event
381| ------ --------------------------
382exanvl: move.b E_DATA1(a0),d0 | get group number
383 andi.w #0x000F,d0 | ... in d0
384 add.w d0,d0 | ... as a word offset
385 lea grpstat,a1 | check grpstat[grp]
386 tst.w 0(a1,d0.W) | ...
387 beq exexit | done if not enabled
388
389 move.w E_DN(a0),-(a7) | put value on stack
390 clr.w d2 | get variable / group numbers
391 move.b E_DATA1(a0),d2 | ... into d2
392 move.w d2,d1 | extract group number
393 andi.w #0x000F,d1 | ... into d1
394 lsr.w #3,d2 | extract variable number
395 andi.w #0x001E,d2 | ... as a word index in d2
396 lea var2src,a1 | point at variable map
397 move.w 0(a1,d2.W),-(a7) | put source number on stack
398 move.w d1,-(a7) | put group number on stack
399 jsr setsv | setsv(group, src, val)
400 adda.l #6,a7 | clean up stack
401 bra exexit | done
402
403| exnext -- next score
404| ------ ----------
405exnext: move.w #1,nxtflag | set next score flag
406 bra exexit | done
407
408 .page
409
410| expnch -- execute punch in/out
411| ------ --------------------
412expnch: tst.w recsw | recording ?
413 beq exexit | ignore if not
414
415 tst.w E_DATA1(a0) | punch in ?
416 bne expnch5 | jump if so
417
418| punch out
419
420 lea grpmode,a1 | setup for group modes
421 move.w #11,d0 | ...
422
423expnch0: cmpi.w #2,(a1) | in record mode ?
424 bne expnch1 | jump if not
425
426 clr.w (a1) | set to play mode
427
428expnch1: addq.l #2,a1 | point at next entry
429 dbra d0,expnch0 | loop through all groups
430
431 lea varmode,a1 | setup for variable modes
432 move.w #5,d1 | set variable count
433
434expnch4: clr.w d0 | clear offset
435
436expnch2: cmpi.w #2,0(a1,d0.W) | in record mode ?
437 bne expnch3 | jump if not
438
439 clr.w 0(a1,d0.W) | set to play mode
440
441expnch3: addq.w #2,d0 | update offset
442 cmpi.w #24,d0 | check for final group
443 bne expnch2 | loop through all groups
444
445 add.l #32,a1 | point at next variable
446 dbra d1,expnch4 | loop through all variables
447
448 bra exexit
449
450 .page
451
452| punch in
453
454expnch5: lea grpmode,a1 | setup for group modes
455 move.w #11,d0 | ...
456
457expnch6: cmpi.w #1,(a1) | in standby mode ?
458 bne expnch7 | jump if not
459
460 move.w #2,(a1) | set to record mode
461
462expnch7: addq.l #2,a1 | point at next entry
463 dbra d0,expnch6 | loop through all groups
464
465 lea varmode,a1 | setup for variable modes
466 move.w #5,d1 | set variable count
467
468expnch10: clr.w d0 | clear offset
469
470expnch8: cmpi.w #1,0(a1,d0.W) | in standby mode ?
471 bne expnch9 | jump if not
472
473 move.w #2,0(a1,d0.W) | set to record mode
474
475expnch9: addq.w #2,d0 | update offset
476 cmpi.w #24,d0 | check for final group
477 bne expnch8 | loop through all groups
478
479 adda.l #32,a1 | point at next variable
480 dbra d1,expnch10 | loop through all variables
481
482 bra exexit
483
484 .page
485
486| sextab -- score execution dispatch table -- MUST match score.h definitions
487| ------ ----------------------------------------------------------------
488sextab: .dc.l exexit | 0 null
489 .dc.l exexit | 1 score begin
490 .dc.l exsbgn | 2 section begin
491 .dc.l exexit | 3 section end
492 .dc.l exinst | 4 instrument change
493 .dc.l exnbeg | 5 note begin
494 .dc.l exnend | 6 note end
495 .dc.l exstop | 7 stop
496 .dc.l exintp | 8 interpolate
497 .dc.l extmpo | 9 tempo
498 .dc.l extune | 10 tuning
499 .dc.l exexit | 11 group status
500 .dc.l exlocn | 12 location
501 .dc.l exdyn | 13 dynamics
502 .dc.l exanvl | 14 analog value
503 .dc.l exanrs | 15 analog resolution
504 .dc.l exasgn | 16 I/O assign
505 .dc.l extrns | 17 transposition
506 .dc.l exexit | 18 repeat
507 .dc.l expnch | 19 punch in/out
508 .dc.l exexit | 20 -unused- (polyphonic pressure)
509 .dc.l exexit | 21 score end
510 .dc.l exexit | 22 -unused- (channel pressure)
511 .dc.l exexit | 23 bar marker
512 .dc.l exnext | 24 next score
513
514 .bss
515
516| Variable storage areas
517| ----------------------
518| globals:
519| --------
520_xevent: .ds.l 1 | next event pointer
521
522 .end
Note: See TracBrowser for help on using the repository browser.