source: buchla-68k/orig/RAM/SEEXEC.S@ b8080f6

Last change on this file since b8080f6 was 3ae31e9, checked in by Thomas Lopatic <thomas@…>, 8 years ago

Imported original source code.

  • Property mode set to 100755
File size: 14.9 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 .equ 8 * WORD - 'ep' parameter offset
56P_SD .equ 12 * WORD - 'sd' parameter offset
57*
58* event structure offsets -- MUST match score.h definitions
59* ----------------------- ------------------------------
60* offset length
61* ------ ------
62E_TIME .equ 0 * LONG
63E_SIZE .equ 4 * BYTE
64E_TYPE .equ 5 * BYTE
65E_DATA1 .equ 6 * BYTE
66E_NOTE .equ 6 * BYTE
67E_DATA2 .equ 7 * BYTE
68E_GROUP .equ 7 * BYTE
69E_BAK .equ 8 * LONG
70E_FWD .equ 12 * LONG
71E_DN .equ 16 * LONG
72E_VEL .equ 16 * WORD
73E_DATA4 .equ 18 * WORD
74E_UP .equ 20 * LONG
75E_LFT .equ 24 * LONG
76E_RGT .equ 28 * LONG
77*
78* Miscellaneous constants
79* -----------------------
80N_ETYPES .equ 25 * number of event types
81*
82M_KSTATE .equ $01 * keys status bit
83N_KSTATE .equ $FE * keys status bit complement
84*
85D_BAK .equ 1 * code for backward scrolling
86*
87LCL_PRT .equ 2 * 0-origin local port number
88LCL_PCH .equ $1080 * 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 #$007F,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 #$FF00,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 #$000F,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 #$000F,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 #$000F,d1 * ... into d1
394 lsr.w #3,d2 * extract variable number
395 andi.w #$001E,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.