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

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

Converted assembly language files.

  • Property mode set to 100644
File size: 14.3 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
100_se_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.