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

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

Fix * in comments.

  • 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.