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

Last change on this file since 8325447 was 8325447, checked in by Thomas Lopatic <thomas@…>, 2 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.