Initial commit.
[amiga/xmodule.git] / Player.asm
1 **
2 **      XModule replay routine 0.1
3 **
4 **      Copyright (C) 1995,96 Bernardo Innocenti
5 **
6 **
7
8 DEBUG_VERSION   EQU     0       ; Debug Code On/Off
9 USE_CALIBRATION EQU     0       ; Calibration On/Off
10 STAND_ALONE     EQU     0       ; Start without XModule
11
12 MAXCHANNELS     EQU     32
13
14         MACHINE 68020
15
16 VersionTag MACRO
17         dc.b    '$VER: XModule_Replay 0.1 (6.1.96) © 1995,96 by Bernardo Innocenti.',$a
18         endm
19
20
21         incdir  Include:
22
23         include exec/types.i
24
25         include exec/io.i
26         include exec/macros.i
27         include exec/memory.i
28         include exec/tasks.i
29         include exec/execbase.i
30         include exec/funcdef.i
31         include hardware/intbits.i
32         include hardware/custom.i
33         include devices/audio.i
34         include dos/dos.i
35         include dos/dosextens.i
36         include graphics/gfxbase.i
37
38         include libraries/songclass.i
39
40         include Guru.i
41         include Player.i
42
43
44         xref    _DATA_BAS_
45
46 custom  EQU     $dff000
47
48
49 ShowDebug MACRO
50         IFNE    '\2',''
51         move.l  \2,-(sp)
52         ENDC
53         lea             .msg\@(pc),a0
54         move.l  sp,a1                   ; Arguments array
55         xref    KPrintF
56         jsr             KPrintF
57         IFNE    '\2',''
58         lea             4(sp),sp        ; Fix stack
59         ENDC
60         bra.s   .cont
61 .msg\@
62         dc.b    \1,$a,0
63         even
64 .cont
65         ENDM
66
67 * An harmless Enforcer hit to help debugging operations :-)
68 Enforcer MACRO
69         suba.l  \1,\1
70         clr.l   (\1)
71         ENDM
72
73
74
75 ***************************************************************************
76 * Start
77 ***************************************************************************
78
79         SECTION XMPlay,code
80
81
82 Start:
83         lea     _DATA_BAS_+32766,a4
84         NEAR    a4
85
86 * Initialize SysBase
87         move.l  4.w,a6
88         move    a6,_SysBase(a4)
89
90 * D3 is the return code for the startup message
91         moveq   #RETURN_OK,d3
92
93 * Find this task's process structure
94         suba.l  a1,a1
95         JSRLIB  FindTask
96         move.l  d0,MyTask(a4)
97         move.l  d0,a2
98
99 * Calculate ClockBase
100         move.l  ex_EClockFrequency(a6),d0
101         move.l  d0,d1
102         lsl.l   #2,d1                           ; #3 for panning support
103         add.l   d1,d0
104         move.l  d0,ClockBase                    ; Clock constant
105
106 * Open graphics.library
107         lea     GFXName(pc),a1
108         moveq.l #0,d0                           ; Library version
109         JSRLIB  OpenLibrary
110         move.l  d0,_GFXBase(a4)
111         bne.s   .gfx_ok
112
113         move.l  #ERROR_INVALID_RESIDENT_LIBRARY,d3
114 .gfx_ok
115
116         IFEQ    STAND_ALONE
117
118 * Wait for startup message
119         lea     pr_MsgPort(a2),a2       ; a2 still contains our Process structure.
120         move.l  a2,a0
121         JSRLIB  WaitPort
122
123 * Get startup message
124         move.l  a2,a0
125         JSRLIB  GetMsg
126         move.l  d0,a1
127
128 * Get parent task address
129         move.l  MN_REPLYPORT(a1),a0
130         move.l  MP_SIGTASK(a0),ParentTask(a4)
131
132 * Reply startup message
133         move.l  d3,pcmd_Err(a1)         ; Put returncode
134         JSRLIB  ReplyMsg
135
136         ENDC    STAND_ALONE
137
138         tst.l   d3                              ; Error?
139         bne.s   Exit
140
141 * Go ahead to MainLoop
142
143
144 ***************************************************************************
145 * Main loop
146 ***************************************************************************
147
148 MainLoop:
149
150         IFEQ    STAND_ALONE
151
152         moveq   #0,d1
153         moveq   #0,d0
154         move.b  MP_SIGBIT(a2),d1
155         bset.l  d1,d0
156         bset.l  #SIGBREAKB_CTRL_C,d0
157         JSRLIB  Wait
158         move.l  d0,d2                           ; Save signal bits
159
160 * Check message port
161 .checkmsg
162         move.l  a2,a0
163         JSRLIB  GetMsg
164         tst.l   d0
165         beq.s   .nomsg
166         move.l  d0,a3
167
168         ELSE
169
170         moveq   #0,d0
171
172         ENDC    STAND_ALONE
173
174 * Command Dispatcher
175         move.l  pcmd_ID(a3),d0
176         cmp.l   #PCMD_COUNT,d0                  ; Check if command is supported
177         bge.s   .unknown_msg
178
179 * Switch (pcmd_ID)
180         lsl.l   #2,d0
181         move.l  a3,a0
182         move.l  .jumptable(pc,d0),a1
183         jsr             (a1)
184
185 .reply_msg
186         IFEQ    STAND_ALONE
187         move.l  d0,pcmd_Err(a3)                 ; Set returncode
188         move.l  a3,a1
189         JSRLIB  ReplyMsg                        ; Return message to parent...
190
191         bra.s   .checkmsg                       ; ...and check for more messages
192         ELSE
193         bra.s   Exit
194         ENDC    STAND_ALONE
195
196 .unknown_msg
197         moveq   #PERR_UNKNOWN_COMMAND,d0
198         bra.s   .reply_msg
199
200 .jumptable
201         dc.l    CmdInit
202         dc.l    CmdPlay
203
204 .nomsg
205
206 * Check for abort signal
207         btst.l  #SIGBREAKB_CTRL_C,d2
208         beq.s   MainLoop
209
210 * Note: I'm falling down to Exit.
211
212
213
214 ***************************************************************************
215 * Cleanup and Exit
216 ***************************************************************************
217
218 Exit:
219
220 * Close graphics.library
221
222         move.l  _GFXBase(a4),d0
223         beq.s   .noclose
224         move.l  d0,a1
225         JSRLIB  CloseLibrary
226 .noclose
227
228
229 * Exit point.
230 * This rts will remove our process and call UnLoadSeg() on us.
231
232         rts
233
234         VersionTag
235
236 GFXName         dc.b    'graphics.library',0
237 AudioDevName    dc.b    'audio.device',0
238
239         EVEN
240
241
242
243 ***************************************************************************
244 * LONG error = CmdInit (struct PlayerCmd *pcmd, struct ExecBase *SysBase)
245 * D0                    A0                      A6
246 ***************************************************************************
247
248 CmdInit
249         move.l  a3,-(a7)                                ; Save a3
250         move.l  pcmd_Data(a0),a3                ; get SongInfo
251
252 * Allocate audio channels
253         moveq   #0,d0
254         moveq   #0,d1
255         lea     AudioDevName(pc),a0
256         lea     AllocIORequest(a4),a1
257         JSRLIB  OpenDevice
258         tst.l   d0
259         bne     .AllocFail                      ; Error
260
261 * Set audio interrupts
262         move.w  AttnFlags(a6),d0
263         btst.l  #AFB_68020,d0                   ; >= 68020 CPU ?
264         bne.s   .CPU68020                       ; yes !
265
266 .CPU68000
267         moveq   #INTB_AUD0,d0
268         lea     Audio0IRQ_000(a4),a1
269         JSRLIB  SetIntVector                    ; set new Audio0-IRQ
270         move.l  d0,_OldAudio0(a4)
271
272         moveq   #INTB_AUD1,d0
273         lea     Audio1IRQ_000(a4),a1
274         JSRLIB  SetIntVector                    ; set new Audio1-IRQ
275         move.l  d0,_OldAudio1(a4)
276         bra.s   .CalcScale
277
278 .CPU68020
279         moveq   #INTB_AUD0,d0
280         lea     Audio0IRQ_020(a4),a1
281         JSRLIB  SetIntVector                    ; set new Audio0-IRQ
282         move.l  d0,_OldAudio0(a4)
283
284         moveq   #INTB_AUD1,d0
285         lea     Audio1IRQ_020(a4),a1
286         JSRLIB  SetIntVector                    ; set new Audio1-IRQ
287         move.l  d0,_OldAudio1(a4)
288
289 .CalcScale
290
291 * Initialize ScaleFactor
292         move.w  si_MaxTracks(a3),d1
293         move.w  d1,ChannelNum(a4)
294         lsr.w   #1,d1                           ; !!!
295         moveq   #32,d0                          ; max. channels (16 for no panning!)
296         divu    d1,d0
297         move.w  d0,ScaleFactor                  ; set ScaleFactor
298
299 * Initialize player.  Warning: these calls will trash all registrers!
300         movem.l d2-d7/a2-a6,-(a7)
301         jsr     InitSVolTable(pc)
302         jsr     InitBoostTable(pc)
303         jsr     InitTracksNChannels(pc)
304         bsr     NewMixFreq                      ; MixPeriod berechnen
305         movem.l (sp)+,d2-d7/a2-a6
306
307 * Audio hardware twiddling
308         lea     custom,a0
309         move.w  #$000f,dmacon(a0)               ; Audio-DMA aus
310         move.w  #$00ff,adkcon(a0)
311         move.w  #$0780,intreq(a0)               ; Audio-Req. löschen
312         move.w  #$0780,intena(a0)               ; Audio-Int. aus
313
314         moveq   #RETURN_OK,d0
315         move.l  (a7)+,a3
316         rts
317
318 .AllocFail
319         moveq   #PERR_NO_AUDIO,d0
320         move.l  (a7)+,a3
321         rts
322
323
324
325 ***************************************************************************
326 * LONG error = CmdPlay (struct PlayerCmd *pcmd, struct ExecBase *SysBase)
327 * D0                    A0                      A6
328 ***************************************************************************
329
330 CmdPlay
331         move.l  pcmd_Data(a0),a0                                ; get SongInfo
332         move.l  a0,SongInfo
333         move.w  si_MaxTracks(a0),mt_NumCh(a4)   ; set channels
334
335         lea     mt_ChanTemp,a0
336         moveq   #MAXCHANNELS-1,d0
337         moveq   #0,d1
338 mt_clear
339         move.l  d1,(a0)+
340         move.l  d1,(a0)+
341         move.l  d1,(a0)+
342         move.l  d1,(a0)+
343         move.l  d1,(a0)+
344         move.l  d1,(a0)+
345         move.l  d1,(a0)+
346         move.l  d1,(a0)+
347         move.l  d1,(a0)+
348         move.l  d1,(a0)+
349         dbra    d0,mt_clear
350
351         bsr     mt_init2
352
353         moveq   #RETURN_OK,d0
354         rts
355
356
357         FAR
358
359
360
361 ***************************************************************************
362 * void  SetTimer (timeval)
363 *                 D0
364 ***************************************************************************
365
366 SetTimer
367         RTS                     ; !!!
368
369
370 ***************************************************************************
371 * void  SetTimer (void)
372 *
373 ***************************************************************************
374
375 SongEnd
376         RTS                     ; !!!
377
378
379 *-----------------------------------------------------------------------*
380 ;
381 ; Next Pattern
382
383 NPatt
384 ;       move.l  dtg_StopInt(a5),a0
385 ;       jsr     (a0)                    !!!!!!!!!!!!!!!!!!!
386         clr.w   mt_counter
387         clr.w   mt_PBreakPos
388         clr.b   mt_PosJumpFlag
389         clr.w   mt_PatternPos
390         addq.w  #1,mt_SongPos
391         move.w  mt_MaxPos,d0
392         cmp.w   mt_SongPos,d0
393         bne.s   NEnd
394         clr.w   mt_SongPos
395 NEnd
396 ;       move.l  dtg_StartInt(a5),a0
397 ;       jsr     (a0)                    !!!!!!!!!!!!!!!!!!!
398         rts
399
400 *-----------------------------------------------------------------------*
401 ;
402 ; Previous Pattern
403
404 PPatt
405 ;       move.l  dtg_StopInt(a5),a0      !!!!!!!!!!!!!!!!!!!
406 ;       jsr     (a0)
407         clr.w   mt_counter
408         clr.w   mt_PBreakPos
409         clr.b   mt_PosJumpFlag
410         clr.w   mt_PatternPos
411         subq.w  #1,mt_SongPos
412         bcc.s   PEnd
413         move.w  mt_MaxPos,d0
414         subq.w  #1,d0
415         move.w  d0,mt_SongPos
416 PEnd
417 ;       move.l  dtg_StartInt(a5),a0     !!!!!!!!!!!!!!!!!!
418 ;       jsr     (a0)
419         rts
420
421
422
423 *-----------------------------------------------------------------------*
424 ;
425 ; TakeTracker - Replay
426
427 ;********************************************
428 ;* ----- Protracker V1.1B Playroutine ----- *
429 ;* Lars "Zap" Hamre/Amiga Freelancers 1991  *
430 ;* Bekkeliveien 10, N-2010 STRØMMEN, Norway *
431 ;********************************************
432
433 ;---- Tempo ----
434
435 SetTempo
436         move.l  _SysBase,a4
437         move.l  ex_EClockFrequency(a4),d1
438         add.l   d1,d1
439         add.l   d1,d1
440         add.l   ex_EClockFrequency(a4),d1
441         lsr.l   #1,d1
442         cmp.w   #32,d0
443         bhs.s   setemsk
444         moveq   #32,d0
445 setemsk divu    d0,d1
446         move.l  d1,d0
447         jsr             SetTimer
448         rts
449
450 ;---- Playroutine ----
451
452         STRUCTURE PlayNote,0
453         UBYTE   pn_Note
454         UBYTE   pn_Inst
455         UBYTE   pn_Cmd
456         UBYTE   pn_Val
457         APTR    pn_Start
458         ULONG   pn_Length
459         LONG    pn_LoopStart
460         LONG    pn_Replen
461         ULONG   pn_WaveStart
462         ULONG   pn_RealLength
463         UWORD   pn_Period
464         UWORD   pn_WantedPeriod
465         UBYTE   pn_FineTune
466         UBYTE   pn_Volume
467         UBYTE   pn_TonePortDirec
468         UBYTE   pn_TonePortSpeed
469         UBYTE   pn_VibratoCmd
470         UBYTE   pn_VibratoPos
471         UBYTE   pn_TremoloCmd
472         UBYTE   pn_TremoloPos
473         UBYTE   pn_WaveControl
474         UBYTE   pn_GlissFunk
475         UBYTE   pn_SampleOffset
476         UBYTE   pn_PattPos
477         UBYTE   pn_LoopCount
478         UBYTE   pn_FunkOffset
479         LABEL   pn_SIZEOF
480
481
482 mt_init2
483
484         MOVE.L  songinfo,a0
485         move.w  si_Length(a0),mt_MaxPos
486
487         moveq   #0,d0
488         MOVE.W  si_GlobalTempo(a0),d0
489         BSR     SetTempo
490
491         MOVE.W  si_GlobalSpeed(a0),mt_speed
492         CLR.W   mt_counter
493         CLR.W   mt_SongPos
494         CLR.W   mt_PBreakPos
495         CLR.B   mt_PosJumpFlag
496         CLR.B   mt_PBreakFlag
497         CLR.B   mt_LowMask
498         CLR.B   mt_PattDelTime
499         CLR.B   mt_PattDelTime2
500         CLR.B   mt_Reset
501         CLR.W   mt_PatternPos
502
503         RTS
504
505 mt_music
506         MOVEM.L D2-D7/A2-A6,-(SP)
507         TST.B   mt_Reset
508         BEQ.S   mt_mus
509         JSR     SongEnd
510         SUBQ.B  #1,mt_Reset
511         BEQ     mt_exit
512         BSR     mt_init2
513         CLR.B   mt_Reset
514         BRA     mt_exit
515 mt_mus
516         ADDQ.W  #1,mt_counter
517         MOVE.W  mt_counter,d0
518         CMP.W   mt_speed,d0
519         BLO.S   mt_NoNewNote
520         CLR.W   mt_counter
521         TST.B   mt_PattDelTime2
522         BEQ     mt_GetNewNote
523         BSR.S   mt_NoNewAllChannels
524         BRA     mt_dskip
525
526 mt_NoNewNote
527         BSR.S   mt_NoNewAllChannels
528         BRA     mt_NoNewPosYet
529
530 mt_NoNewAllChannels
531         move.l  NoteStructure,a5
532         lea     mt_ChanTemp,a6
533         move.w  mt_NumCh,d5
534         subq.w  #1,d5
535 mt_NoNewLoop
536         bsr     mt_CheckEfx
537         lea     NoteChannel_SIZE(a5),a5
538         lea     pn_SIZEOF(a6),a6
539         dbra    d5,mt_NoNewLoop
540         RTS
541
542 mt_GetNewNote
543         move.l  songinfo,a0
544         move.l  si_Patt(a0),a1
545         move.l  si_Sequence(a0),a0
546         moveq   #0,d0
547         move.w  mt_SongPos,d0
548         add.w   d0,d0
549         move.w  (a0,d0.w),d0                    ; Put current patt number in d0
550         mulu    #pa_SIZEOF,d0
551         move.l  pa_Notes(a0,d0),a0                      ; Get pointer to tracks array
552
553         move.l  NoteStructure,a5
554         lea     mt_ChanTemp,a6
555         move.w  mt_NumCh,d5
556         subq.w  #1,d5
557
558 mt_GetNewLoop
559         bsr     mt_PlayVoice
560         lea     NoteChannel_SIZE(a5),a5
561         lea     pn_SIZEOF(a6),a6
562         dbra    d5,mt_GetNewLoop
563         BRA     mt_dskip
564
565 mt_PlayVoice
566         CMP.W   #NCHD_Ignore,nch_Stereo(a5)
567         BEQ     mt_PerNop
568         TST.L   (A6)
569         BNE.S   mt_plvskip
570         BSR     mt_PerNop
571 mt_plvskip
572         move.l  (a0)+,a4
573         moveq   #0,d0
574         move.w  d5,d0
575         add.l   d0,d0
576         add.l   d0,d0
577         move.l  (a4,d0),a4              ; Pointer to channel
578         moveq   #0,d0
579         move.w  mt_PatternPos,d0
580         add.l   d0,d0
581         add.l   d0,d0
582         move.l  (a4,d0),(a6)            ; Current note in (a6)
583
584         moveq   #0,d2
585         move.b  note_Inst(a6),d2        ; Instrument number in d2
586         TST.W   d2
587         BEQ     mt_SetRegs
588         MOVEQ   #0,d3
589
590 * Retrieve Instrument structure
591         move.l  songinfo,a1
592         lea     si_Instr(a1),a1
593         mulu    #in_SIZEOF,d2
594         lea     (a1,d2),a1
595
596         move.l  in_SampleData(a1),pn_Start(a6)
597         move.l  in_Length(a1),pn_Length(a6)
598         move.l  in_Length(a1),pn_RealLength(a6)
599         move.b  in_FineTune+1(a1),pn_FineTune(a6)
600         move.b  in_Volume(a1),pn_Volume(a6)
601         move.l  in_Repeat(a1),d3                ; Get repeat
602         tst.l   D3
603         beq.s   mt_NoLoop
604         move.l  pn_Start(a6),d2                 ; Get start
605         add.l   D3,D2                           ; Add repeat
606         move.l  D2,pn_LoopStart(a6)
607         move.l  D2,pn_WaveStart(a6)
608         move.l  in_Repeat(a1),d0                ; Get repeat
609         add.l   in_Replen(a1),d0                ; Add replen
610         move.l  d0,pn_Length(A6)
611         move.l  in_Replen(a1),pn_Replen(a6)     ; Save replen
612         MOVEQ   #0,D0
613         MOVE.B  pn_Volume(A6),D0
614         move.w  d0,nch_Volume(a5)
615         bset.b  #NCHB_Volume,nch_Changed(a5)
616         BRA.S   mt_SetRegs
617
618 mt_NoLoop
619         MOVE.L  pn_Start(a6),d2
620         ADD.L   D3,D2
621         MOVE.L  D2,pn_LoopStart(A6)
622         MOVE.L  D2,pn_WaveStart(A6)
623         MOVE.L  in_Replen(a1),pn_Replen(a6)     ; Save replen
624         MOVEQ   #0,D0
625         MOVE.B  pn_Volume(A6),D0
626         move.w  d0,nch_Volume(a5)
627         bset.b  #NCHB_Volume,nch_Changed(a5)
628
629 mt_SetRegs
630         move.b  pn_Note(a6),d0
631         beq     mt_CheckMoreEfx2        ; If no note
632         move.w  pn_Cmd(a6),D0
633         AND.W   #$FFF0,D0
634         CMP.W   #$0E50,D0               ; Check for E5
635         beq.s   mt_DoSetFineTune
636         move.b  pn_Cmd(A6),D0
637         cmp.b   #EFF_TONEPORTAMENTO,d0  ; TonePortamento
638         beq.s   mt_ChkTonePorta
639         cmp.b   #EFF_TONEPVOLSLIDE,d0
640         beq.s   mt_ChkTonePorta
641         cmp.b   #EFF_SAMPLEOFFSET,d0    ; Sample Offset
642         BNE.S   mt_SetPeriod
643         BSR     mt_CheckMoreEfx
644         BRA.S   mt_SetPeriod
645
646 mt_DoSetFineTune
647         bsr     mt_SetFineTune
648         bra.s   mt_SetPeriod
649
650 mt_ChkTonePorta
651         bsr     mt_SetTonePorta
652         bra     mt_CheckMoreEfx2
653
654 mt_SetPeriod
655         MOVEM.L D0-D1/A0-A1,-(SP)
656         moveq   #0,d1
657         move.b  pn_Note(a6),d1                  ; Find note period
658         sub.b   #24,d1                          ; Less octaves!!!
659         add.l   d1,d1                           ; Look up period table
660         move.l  d1,d0
661         lea     mt_PeriodTable,a1
662
663         MOVEQ   #0,D1
664         move.b  pn_FineTune(a6),d1
665         MULU    #MAXNOTES*2,D1
666         ADD.L   D1,A1
667         move.w  (a1,d0.w),pn_Period(a6)
668         movem.l (sp)+,d0-d1/a0-a1
669
670         MOVE.W  2(A6),D0
671         AND.W   #$0FF0,D0
672         CMP.W   #$0ED0,D0 ; Notedelay
673         BEQ     mt_CheckMoreEfx2
674
675         BTST    #2,pn_WaveControl(A6)
676         BNE.S   mt_vibnoc
677         CLR.B   pn_VibratoPos(A6)
678 mt_vibnoc
679         BTST    #6,pn_WaveControl(A6)
680         BNE.S   mt_trenoc
681         CLR.B   pn_TremoloPos(A6)
682 mt_trenoc
683         move.l  pn_Start(a6),nch_SampleStart(a5)
684         move.l  pn_Length(a6),d0
685         move.l  d0,nch_SampleLength(a5)
686         bset.b  #NCHB_Sample,nch_Changed(a5)
687         move.w  pn_Period(A6),nch_Frequency(a5)
688         bset.b  #NCHB_Frequency,nch_Changed(a5)
689 mt_CheckMoreEfx2
690         move.l  pn_LoopStart(A6),nch_RepeatStart(a5)
691         move.l  pn_Replen(A6),d0
692         move.l  d0,nch_RepeatLength(a5)
693         bset.b  #NCHB_Repeat,nch_Changed(a5)
694
695         bra     mt_CheckMoreEfx
696 mt_dskip
697         MOVE.W  mt_rsize,d0                     ; !!!
698         ADD.W   d0,mt_PatternPos
699         MOVE.B  mt_PattDelTime,d0
700         BEQ.S   mt_dskc
701         MOVE.B  d0,mt_PattDelTime2
702         CLR.B   mt_PattDelTime
703 mt_dskc TST.B   mt_PattDelTime2
704         BEQ.S   mt_dska
705         SUBQ.B  #1,mt_PattDelTime2
706         BEQ.S   mt_dska
707         MOVE.W  mt_rsize,D0
708         SUB.W   D0,mt_PatternPos
709 mt_dska TST.B   mt_PBreakFlag
710         BEQ.S   mt_nnpysk
711         SF      mt_PBreakFlag
712         MOVEQ   #0,D0
713         MOVE.W  mt_PBreakPos,D0
714         CLR.W   mt_PBreakPos
715         MULU    mt_rsize,D0
716         MOVE.W  D0,mt_PatternPos
717 mt_nnpysk
718         MOVE.W  mt_PatternPos,d0
719         CMP.W   mt_psize,d0
720         BLO.S   mt_NoNewPosYet
721 mt_NextPosition
722         MOVE.W  mt_PBreakPos,d0
723         MULU    mt_rsize,d0
724         MOVE.W  D0,mt_PatternPos
725         CLR.W   mt_PBreakPos
726         CLR.B   mt_PosJumpFlag
727         ADDQ.W  #1,mt_SongPos
728         MOVE.W  mt_SongPos,d1
729         CMP.W   mt_MaxPos,d1
730         BLO.S   mt_NoNewPosYet
731         MOVE.W  mt_StartPos,mt_SongPos
732         MOVE.B  #2,mt_Reset
733 mt_NoNewPosYet
734         TST.B   mt_PosJumpFlag
735         BNE.S   mt_NextPosition
736         jsr     NoteSignal
737 mt_exit MOVEM.L (SP)+,D2-D7/A2-A6
738         RTS
739
740 mt_CheckEfx
741         CMP.W   #NCHD_Ignore,nch_Stereo(a5)
742         BEQ     mt_Return
743         BSR     mt_UpdateFunk
744         moveq   #0,d0
745         move.b  pn_Cmd(a6),d0
746         beq.s   mt_PerNop
747         cmpi.b  #EFF_COUNT,d0
748         bge.s   mt_PerNop
749         move.l  efftable(pc),a0
750         add.l   d0,d0
751         add.l   d0,d0
752         move.l  (a0,d0),a0
753         jmp     (a0)
754
755 SetBack move.w  pn_Period(a6),nch_Frequency(a5)
756         bset.b  #NCHB_Frequency,nch_Changed(a5)
757 mt_Return
758         RTS
759
760 efftable
761         dc.l mt_PerNop                  ; EFF_NULL
762         dc.l mt_PortaUp                 ; EFF_PORTAMENTOUP
763         dc.l mt_PortaDown               ; EFF_PORTAMENTODOWN
764         dc.l mt_TonePortamento          ; EFF_TONEPORTAMENTO
765         dc.l mt_Vibrato                 ; EFF_VIBRATO
766         dc.l mt_TonePlusVolSlide        ; EFF_TONEPVOLSLIDE
767         dc.l mt_VibratoPlusVolSlide     ; EFF_VIBRATOVOLSLIDE
768         dc.l mt_Tremolo                 ; EFF_TREMOLO
769         dc.l mt_PerNop                  ; EFF_UNUSED
770         dc.l mt_PerNop                  ; EFF_SAMPLEOFFSET
771         dc.l mt_VolumeSlide             ; EFF_VOLSLIDE
772         dc.l mt_PerNop                  ; EFF_POSJUMP
773         dc.l mt_PerNop                  ; EFF_SETVOLUME
774         dc.l mt_PerNop                  ; EFF_PATTERNBREAK
775         dc.l mt_E_Commands              ; EFF_MISC
776         dc.l mt_PerNop                  ; EFF_SETSPEED
777         dc.l mt_PerNop                  ; EFF_SETTEMPO
778         dc.l mt_Arpeggio                ; EFF_ARPEGGIO
779
780
781 mt_PerNop
782         move.w  pn_Period(A6),nch_Frequency(a5)
783         bset.b  #NCHB_Frequency,nch_Changed(a5)
784         RTS
785
786 mt_Arpeggio
787         MOVEQ   #0,D0
788         MOVE.W  mt_counter,D0
789         DIVS    #3,D0
790         SWAP    D0
791         CMP.W   #0,D0
792         BEQ.S   mt_Arpeggio2
793         CMP.W   #2,D0
794         BEQ.S   mt_Arpeggio1
795         MOVEQ   #0,D0
796         MOVE.B  pn_Val(A6),D0
797         LSR.B   #4,D0
798         BRA.S   mt_Arpeggio3
799
800 mt_Arpeggio1
801         MOVEQ   #0,D0
802         MOVE.B  pn_Val(A6),D0
803         AND.B   #15,D0
804         BRA.S   mt_Arpeggio3
805
806 mt_Arpeggio2
807         MOVE.W  pn_Period(A6),D2
808         BRA.S   mt_Arpeggio4
809
810 mt_Arpeggio3
811         ASL.W   #1,D0
812         MOVEQ   #0,D1
813         MOVE.B  pn_FineTune(A6),D1
814         MULU    #36*2,D1
815         LEA     mt_PeriodTable,A0
816         ADD.L   D1,A0
817         MOVEQ   #0,D1
818         MOVE.W  pn_Period(A6),D1
819         MOVEQ   #35,D3                          ; bugfix !!!
820 mt_arploop
821         MOVE.W  (A0,D0.W),D2
822         CMP.W   (A0),D1
823         BHS.S   mt_Arpeggio4
824         ADDQ.L  #2,A0
825         DBRA    D3,mt_arploop
826         RTS
827
828 mt_Arpeggio4
829         move.w  d2,nch_Frequency(a5)
830         bset.b  #NCHB_Frequency,nch_Changed(a5)
831 ;       MOVE.W  D2,6(A5)
832         RTS
833
834 mt_FinePortaUp
835         TST.W   mt_counter
836         BNE     mt_Return
837         MOVE.B  #$0F,mt_LowMask
838 mt_PortaUp
839         MOVEQ   #0,D0
840         MOVE.B  pn_Val(A6),D0
841         AND.B   mt_LowMask,D0
842         MOVE.B  #$FF,mt_LowMask
843         SUB.W   D0,pn_Period(A6)
844         MOVE.W  pn_Period(A6),D0
845         AND.W   #$0FFF,D0
846         CMP.W   #113,D0
847         BPL.S   mt_PortaUskip
848         AND.W   #$F000,pn_Period(A6)
849         OR.W    #113,pn_Period(A6)
850 mt_PortaUskip
851         MOVE.W  pn_Period(A6),D0
852         AND.W   #$0FFF,D0
853         move.w  d0,nch_Frequency(a5)
854         bset.b  #NCHB_Frequency,nch_Changed(a5)
855         RTS
856
857 mt_FinePortaDown
858         TST.W   mt_counter
859         BNE     mt_Return
860         MOVE.B  #$0F,mt_LowMask
861 mt_PortaDown
862         CLR.W   D0
863         MOVE.B  pn_Val(A6),D0
864         AND.B   mt_LowMask,D0
865         MOVE.B  #$FF,mt_LowMask
866         ADD.W   D0,pn_Period(A6)
867         MOVE.W  pn_Period(A6),D0
868         AND.W   #$0FFF,D0
869         CMP.W   #856,D0
870         BMI.S   mt_PortaDskip
871         AND.W   #$F000,pn_Period(A6)
872         OR.W    #856,pn_Period(A6)
873 mt_PortaDskip
874         MOVE.W  pn_Period(A6),D0
875         AND.W   #$0FFF,D0
876         move.w  d0,nch_Frequency(a5)
877         bset.b  #NCHB_Frequency,nch_Changed(a5)
878         RTS
879
880 mt_SetTonePorta
881         MOVE.L  a0,-(sp)
882         MOVE.W  (A6),D2
883         AND.W   #$0FFF,D2
884         MOVEQ   #0,D0
885         MOVE.B  pn_FineTune(A6),D0
886         MULU    #36*2,D0                        ; bugfix !!!
887         LEA     mt_PeriodTable,A0
888         ADD.L   D0,A0
889         MOVEQ   #0,D0
890 mt_StpLoop
891         CMP.W   (A0,D0.W),D2
892         BHS.S   mt_StpFound
893         ADDQ.W  #2,D0
894         CMP.W   #36*2,D0                        ; bugfix !!!
895         BLO.S   mt_StpLoop
896         MOVEQ   #35*2,D0
897 mt_StpFound
898         MOVE.B  pn_FineTune(A6),D2
899         AND.B   #8,D2
900         BEQ.S   mt_StpGoss
901         TST.W   D0
902         BEQ.S   mt_StpGoss
903         SUBQ.W  #2,D0
904 mt_StpGoss
905         MOVE.W  (A0,D0.W),D2
906         MOVE.L  (SP)+,A0
907         MOVE.W  D2,pn_WantedPeriod(A6)
908         MOVE.W  pn_Period(A6),D0
909         CLR.B   pn_TonePortDirec(A6)
910         CMP.W   D0,D2
911         BEQ.S   mt_ClearTonePorta
912         BGE     mt_Return
913         MOVE.B  #1,pn_TonePortDirec(A6)
914         RTS
915
916 mt_ClearTonePorta
917         CLR.W   pn_WantedPeriod(A6)
918         RTS
919
920 mt_TonePortamento
921         MOVE.B  pn_Val(A6),D0
922         BEQ.S   mt_TonePortNoChange
923         MOVE.B  D0,pn_TonePortSpeed(A6)
924         CLR.B   pn_Val(A6)
925 mt_TonePortNoChange
926         TST.W   pn_WantedPeriod(A6)
927         BEQ     mt_Return
928         MOVEQ   #0,D0
929         MOVE.B  pn_TonePortSpeed(A6),D0
930         TST.B   pn_TonePortDirec(A6)
931         BNE.S   mt_TonePortaUp
932 mt_TonePortaDown
933         ADD.W   D0,pn_Period(A6)
934         MOVE.W  pn_WantedPeriod(A6),D0
935         CMP.W   pn_Period(A6),D0
936         BGT.S   mt_TonePortaSetPer
937         MOVE.W  pn_WantedPeriod(A6),pn_Period(A6)
938         CLR.W   pn_WantedPeriod(A6)
939         BRA.S   mt_TonePortaSetPer
940
941 mt_TonePortaUp
942         SUB.W   D0,pn_Period(A6)
943         MOVE.W  pn_WantedPeriod(A6),D0
944         CMP.W   pn_Period(A6),D0
945         BLT.S   mt_TonePortaSetPer
946         MOVE.W  pn_WantedPeriod(A6),pn_Period(A6)
947         CLR.W   pn_WantedPeriod(A6)
948
949 mt_TonePortaSetPer
950         MOVE.W  pn_Period(A6),D2
951         MOVE.B  pn_GlissFunk(A6),D0
952         AND.B   #$0F,D0
953         BEQ.S   mt_GlissSkip
954         MOVEQ   #0,D0
955         MOVE.B  pn_FineTune(A6),D0
956         MULU    #36*2,D0
957         LEA     mt_PeriodTable,A0
958         ADD.L   D0,A0
959         MOVEQ   #0,D0
960 mt_GlissLoop
961         CMP.W   (A0,D0.W),D2
962         BHS.S   mt_GlissFound
963         ADDQ.W  #2,D0
964         CMP.W   #36*2,D0
965         BLO.S   mt_GlissLoop
966         MOVEQ   #35*2,D0
967 mt_GlissFound
968         MOVE.W  (A0,D0.W),D2
969 mt_GlissSkip
970         move.w  d2,nch_Frequency(a5)
971         bset.b  #NCHB_Frequency,nch_Changed(a5)
972         RTS
973
974 mt_Vibrato
975         MOVE.B  pn_Val(A6),D0
976         BEQ.S   mt_Vibrato2
977         MOVE.B  pn_VibratoCmd(A6),D2
978         AND.B   #$0F,D0
979         BEQ.S   mt_vibskip
980         AND.B   #$F0,D2
981         OR.B    D0,D2
982 mt_vibskip
983         MOVE.B  pn_Val(A6),D0
984         AND.B   #$F0,D0
985         BEQ.S   mt_vibskip2
986         AND.B   #$0F,D2
987         OR.B    D0,D2
988 mt_vibskip2
989         MOVE.B  D2,pn_VibratoCmd(A6)
990 mt_Vibrato2
991         MOVE.B  pn_VibratoPos(A6),D0
992         LEA     mt_VibratoTable,A4
993         LSR.W   #2,D0
994         AND.W   #$001F,D0
995         MOVEQ   #0,D2
996         MOVE.B  pn_WaveControl(A6),D2
997         AND.B   #$03,D2
998         BEQ.S   mt_vib_sine
999         LSL.B   #3,D0
1000         CMP.B   #1,D2
1001         BEQ.S   mt_vib_rampdown
1002         MOVE.B  #255,D2
1003         BRA.S   mt_vib_set
1004 mt_vib_rampdown
1005         TST.B   pn_VibratoPos(A6)
1006         BPL.S   mt_vib_rampdown2
1007         MOVE.B  #255,D2
1008         SUB.B   D0,D2
1009         BRA.S   mt_vib_set
1010 mt_vib_rampdown2
1011         MOVE.B  D0,D2
1012         BRA.S   mt_vib_set
1013 mt_vib_sine
1014         MOVE.B  (A4,D0.W),D2
1015 mt_vib_set
1016         MOVE.B  pn_VibratoCmd(A6),D0
1017         AND.W   #15,D0
1018         MULU    D0,D2
1019         LSR.W   #7,D2
1020         MOVE.W  pn_Period(A6),D0
1021         TST.B   pn_VibratoPos(A6)
1022         BMI.S   mt_VibratoNeg
1023         ADD.W   D2,D0
1024         BRA.S   mt_Vibrato3
1025 mt_VibratoNeg
1026         SUB.W   D2,D0
1027 mt_Vibrato3
1028         move.w  d0,nch_Frequency(a5)
1029         bset.b  #NCHB_Frequency,nch_Changed(a5)
1030         MOVE.B  pn_VibratoCmd(A6),D0
1031         LSR.W   #2,D0
1032         AND.W   #$003C,D0
1033         ADD.B   D0,pn_VibratoPos(A6)
1034         RTS
1035
1036 mt_TonePlusVolSlide
1037         BSR     mt_TonePortNoChange
1038         BRA     mt_VolumeSlide
1039
1040 mt_VibratoPlusVolSlide
1041         BSR.S   mt_Vibrato2
1042         BRA     mt_VolumeSlide
1043
1044 mt_Tremolo
1045         MOVE.B  pn_Val(A6),D0
1046         BEQ.S   mt_Tremolo2
1047         MOVE.B  pn_TremoloCmd(A6),D2
1048         AND.B   #$0F,D0
1049         BEQ.S   mt_treskip
1050         AND.B   #$F0,D2
1051         OR.B    D0,D2
1052 mt_treskip
1053         MOVE.B  pn_Val(A6),D0
1054         AND.B   #$F0,D0
1055         BEQ.S   mt_treskip2
1056         AND.B   #$0F,D2
1057         OR.B    D0,D2
1058 mt_treskip2
1059         MOVE.B  D2,pn_TremoloCmd(A6)
1060 mt_Tremolo2
1061         MOVE.B  pn_TremoloPos(A6),D0
1062         LEA     mt_VibratoTable,A4
1063         LSR.W   #2,D0
1064         AND.W   #$001F,D0
1065         MOVEQ   #0,D2
1066         MOVE.B  pn_WaveControl(A6),D2
1067         LSR.B   #4,D2
1068         AND.B   #$03,D2
1069         BEQ.S   mt_tre_sine
1070         LSL.B   #3,D0
1071         CMP.B   #1,D2
1072         BEQ.S   mt_tre_rampdown
1073         MOVE.B  #255,D2
1074         BRA.S   mt_tre_set
1075 mt_tre_rampdown
1076         TST.B   pn_VibratoPos(A6)
1077         BPL.S   mt_tre_rampdown2
1078         MOVE.B  #255,D2
1079         SUB.B   D0,D2
1080         BRA.S   mt_tre_set
1081 mt_tre_rampdown2
1082         MOVE.B  D0,D2
1083         BRA.S   mt_tre_set
1084 mt_tre_sine
1085         MOVE.B  (A4,D0.W),D2
1086 mt_tre_set
1087         MOVE.B  pn_TremoloCmd(A6),D0
1088         AND.W   #15,D0
1089         MULU    D0,D2
1090         LSR.W   #6,D2
1091         MOVEQ   #0,D0
1092         MOVE.B  pn_Volume(A6),D0
1093         TST.B   pn_TremoloPos(A6)
1094         BMI.S   mt_TremoloNeg
1095         ADD.W   D2,D0
1096         BRA.S   mt_Tremolo3
1097 mt_TremoloNeg
1098         SUB.W   D2,D0
1099 mt_Tremolo3
1100         BPL.S   mt_TremoloSkip
1101         CLR.W   D0
1102 mt_TremoloSkip
1103         CMP.W   #$40,D0
1104         BLS.S   mt_TremoloOk
1105         MOVE.W  #$40,D0
1106 mt_TremoloOk
1107         move.w  d0,nch_Volume(a5)
1108         bset.b  #NCHB_Volume,nch_Changed(a5)
1109         MOVE.B  pn_TremoloCmd(A6),D0
1110         LSR.W   #2,D0
1111         AND.W   #$003C,D0
1112         ADD.B   D0,pn_TremoloPos(A6)
1113         RTS
1114
1115 mt_SampleOffset
1116         MOVEQ   #0,D0
1117         MOVE.B  pn_Val(A6),D0
1118         BEQ.S   mt_sononew
1119         MOVE.B  D0,pn_SampleOffset(A6)
1120 mt_sononew
1121         MOVE.B  pn_SampleOffset(A6),D0
1122         LSL.L   #7,D0
1123         CMP.L   pn_Length(A6),D0
1124         BGE.S   mt_sofskip
1125         SUB.L   D0,pn_Length(A6)
1126         LSL.L   #1,D0
1127         ADD.L   D0,pn_Start(A6)
1128         RTS
1129 mt_sofskip
1130         MOVE.L  #$0001,pn_Length(A6)
1131         RTS
1132
1133 mt_VolumeSlide
1134         MOVEQ   #0,D0
1135         MOVE.B  pn_Val(A6),D0
1136         LSR.B   #4,D0
1137         TST.B   D0
1138         BEQ.S   mt_VolSlideDown
1139 mt_VolSlideUp
1140         ADD.B   D0,pn_Volume(A6)
1141         CMP.B   #$40,pn_Volume(A6)
1142         BMI.S   mt_vsuskip
1143         MOVE.B  #$40,pn_Volume(A6)
1144 mt_vsuskip
1145         MOVE.B  pn_Volume(A6),D0
1146         move.w  d0,nch_Volume(a5)
1147         bset.b  #NCHB_Volume,nch_Changed(a5)
1148         RTS
1149
1150 mt_VolSlideDown
1151         MOVEQ   #0,D0
1152         MOVE.B  pn_Val(A6),D0
1153         AND.B   #$0F,D0
1154 mt_VolSlideDown2
1155         SUB.B   D0,pn_Volume(A6)
1156         BPL.S   mt_vsdskip
1157         CLR.B   pn_Volume(A6)
1158 mt_vsdskip
1159         MOVE.B  pn_Volume(A6),D0
1160         move.w  d0,nch_Volume(a5)
1161         bset.b  #NCHB_Volume,nch_Changed(a5)
1162         RTS
1163
1164 mt_PositionJump
1165         MOVE.W  mt_SongPos,D0
1166         ADDQ.W  #1,D0
1167         CMP.W   mt_MaxPos,D0
1168         BNE.S   mt_pj1
1169         MOVE.B  #1,mt_Reset
1170 mt_pj1  MOVE.B  pn_Val(A6),D0
1171         CMP.W   mt_SongPos,D0
1172         BNE.S   mt_pj0
1173         MOVE.B  #1,mt_Reset
1174         TST.W   mt_PatternPos
1175         BNE.S   mt_pj0
1176         MOVE.B  #2,mt_Reset
1177 mt_pj0  SUBQ.B  #1,D0
1178         MOVE.W  D0,mt_SongPos
1179         BPL.S   mt_pj2
1180         MOVE.B  #2,mt_Reset
1181 mt_pj2  CLR.W   mt_PBreakPos
1182         ST      mt_PosJumpFlag
1183         RTS
1184
1185 mt_VolumeChange
1186         MOVEQ   #0,D0
1187         MOVE.B  pn_Val(A6),D0
1188         CMP.B   #$40,D0
1189         BLS.S   mt_VolumeOk
1190         MOVEQ   #$40,D0
1191 mt_VolumeOk
1192         MOVE.B  D0,pn_Volume(A6)
1193         move.w  d0,nch_Volume(a5)
1194         bset.b  #NCHB_Volume,nch_Changed(a5)
1195         RTS
1196
1197 mt_PatternBreak
1198         MOVEQ   #0,D0
1199         MOVE.B  pn_Val(A6),D0
1200         MOVE.L  D0,D2
1201         LSR.W   #4,D0
1202         MULU    #10,D0
1203         AND.W   #$0F,D2
1204         ADD.W   D2,D0
1205         CMP.W   #63,D0
1206         BHI.S   mt_pj2
1207         MOVE.W  D0,mt_PBreakPos
1208         ST.B    mt_PosJumpFlag
1209         RTS
1210
1211 mt_SetSpeed
1212         MOVEQ   #0,D0
1213         MOVE.B  3(A6),D0
1214         BNE.S   mt_SetSpd
1215         CMP.W   #32,D0
1216         BHS     SetTempo
1217 mt_SetSpd
1218         TST.W   D0
1219         BEQ.S   mt_SetBack
1220         CLR.W   mt_counter
1221         MOVE.W  D0,mt_speed
1222 mt_SetBack
1223         RTS
1224
1225 mt_CheckMoreEfx
1226         BSR     mt_UpdateFunk
1227         MOVE.B  2(A6),D0
1228         AND.B   #$0F,D0
1229         CMP.B   #$9,D0
1230         BEQ     mt_SampleOffset
1231         CMP.B   #$B,D0
1232         BEQ     mt_PositionJump
1233         CMP.B   #$D,D0
1234         BEQ     mt_PatternBreak
1235         CMP.B   #$E,D0
1236         BEQ.S   mt_E_Commands
1237         CMP.B   #$F,D0
1238         BEQ.S   mt_SetSpeed
1239         CMP.B   #$C,D0
1240         BEQ     mt_VolumeChange
1241         BRA     mt_PerNop
1242
1243 mt_E_Commands
1244         MOVE.B  pn_Val(A6),D0           ; !!!
1245         AND.B   #$F0,D0
1246         LSR.B   #4,D0
1247 ;       BEQ.S   mt_FilterOnOff
1248         CMP.B   #1,D0
1249         BEQ     mt_FinePortaUp
1250         CMP.B   #2,D0
1251         BEQ     mt_FinePortaDown
1252         CMP.B   #3,D0
1253         BEQ.S   mt_SetGlissControl
1254         CMP.B   #4,D0
1255         BEQ.S   mt_SetVibratoControl
1256         CMP.B   #5,D0
1257         BEQ.S   mt_SetFineTune
1258         CMP.B   #6,D0
1259         BEQ.S   mt_JumpLoop
1260         CMP.B   #7,D0
1261         BEQ     mt_SetTremoloControl
1262         CMP.B   #9,D0
1263         BEQ     mt_RetrigNote
1264         CMP.B   #$A,D0
1265         BEQ     mt_VolumeFineUp
1266         CMP.B   #$B,D0
1267         BEQ     mt_VolumeFineDown
1268         CMP.B   #$C,D0
1269         BEQ     mt_NoteCut
1270         CMP.B   #$D,D0
1271         BEQ     mt_NoteDelay
1272         CMP.B   #$E,D0
1273         BEQ     mt_PatternDelay
1274         CMP.B   #$F,D0
1275         BEQ     mt_FunkIt
1276         RTS
1277
1278 mt_FilterOnOff
1279 ;       MOVE.B  pn_Val(A6),D0
1280 ;       AND.B   #1,D0
1281 ;       ASL.B   #1,D0
1282 ;       AND.B   #$FD,$BFE001
1283 ;       OR.B    D0,$BFE001
1284 ;       RTS
1285
1286 mt_SetGlissControl
1287         MOVE.B  pn_Val(A6),D0
1288         AND.B   #$0F,D0
1289         AND.B   #$F0,pn_GlissFunk(A6)
1290         OR.B    D0,pn_GlissFunk(A6)
1291         RTS
1292
1293 mt_SetVibratoControl
1294         MOVE.B  pn_Val(A6),D0
1295         AND.B   #$0F,D0
1296         AND.B   #$F0,pn_WaveControl(A6)
1297         OR.B    D0,pn_WaveControl(A6)
1298         RTS
1299
1300 mt_SetFineTune
1301         MOVE.B  pn_Val(A6),D0
1302         AND.B   #$0F,D0
1303         MOVE.B  D0,pn_FineTune(A6)
1304         RTS
1305
1306 mt_JumpLoop
1307         TST.W   mt_counter
1308         BNE     mt_Return
1309         MOVE.B  pn_Val(A6),D0
1310         AND.B   #$0F,D0
1311         BEQ.S   mt_SetLoop
1312         TST.B   pn_LoopCount(A6)
1313         BEQ.S   mt_jumpcnt
1314         SUBQ.B  #1,pn_LoopCount(A6)
1315         BEQ     mt_Return
1316 mt_jmploop      MOVE.W  pn_PattPos(A6),mt_PBreakPos
1317         ST      mt_PBreakFlag
1318         RTS
1319
1320 mt_jumpcnt
1321         MOVE.B  D0,pn_LoopCount(A6)
1322         BRA.S   mt_jmploop
1323
1324 mt_SetLoop
1325         MOVE.W  mt_PatternPos,D0
1326         LSR.W   #4,D0
1327         MOVE.B  D0,pn_PattPos(A6)
1328         RTS
1329
1330 mt_SetTremoloControl
1331         MOVE.B  pn_Val(A6),D0
1332         AND.B   #$0F,D0
1333         LSL.B   #4,D0
1334         AND.B   #$0F,pn_WaveControl(A6)
1335         OR.B    D0,pn_WaveControl(A6)
1336         RTS
1337
1338 mt_RetrigNote
1339         MOVE.L  D1,-(SP)
1340         MOVEQ   #0,D0
1341         MOVE.B  pn_Val(A6),D0
1342         AND.B   #$0F,D0
1343         BEQ.S   mt_rtnend
1344         MOVEQ   #0,D1
1345         MOVE.W  mt_counter,D1
1346         BNE.S   mt_rtnskp
1347         MOVE.W  (A6),D1
1348         AND.W   #$0FFF,D1
1349         BNE.S   mt_rtnend
1350         MOVEQ   #0,D1
1351         MOVE.W  mt_counter,D1
1352 mt_rtnskp
1353         DIVU    D0,D1
1354         SWAP    D1
1355         TST.W   D1
1356         BNE.S   mt_rtnend
1357 mt_DoRetrig
1358         move.l  pn_Start(a6),nch_SampleStart(a5)
1359         move.l  pn_Length(a6),d0
1360         move.l  d0,nch_SampleLength(a5)
1361         bset.b  #NCHB_Sample,nch_Changed(a5)
1362         move.l  pn_LoopStart(A6),nch_RepeatStart(a5)
1363         move.l  pn_Replen(A6),d0
1364         move.l  d0,nch_RepeatLength(a5)
1365         bset.b  #NCHB_Repeat,nch_Changed(a5)
1366         move.w  pn_Period(A6),nch_Frequency(a5)
1367         bset.b  #NCHB_Frequency,nch_Changed(a5)
1368 mt_rtnend
1369         move.l  (sp)+,d1
1370         rts
1371
1372 mt_VolumeFineUp
1373         TST.W   mt_counter
1374         BNE     mt_Return
1375         MOVEQ   #0,D0
1376         MOVE.B  pn_Val(A6),D0
1377         AND.B   #$F,D0
1378         BRA     mt_VolSlideUp
1379
1380 mt_VolumeFineDown
1381         TST.W   mt_counter
1382         BNE     mt_Return
1383         MOVEQ   #0,D0
1384         MOVE.B  pn_Val(A6),D0
1385         AND.B   #$0F,D0
1386         BRA     mt_VolSlideDown2
1387
1388 mt_NoteCut
1389         MOVEQ   #0,D0
1390         MOVE.B  pn_Val(A6),D0
1391         AND.B   #$0F,D0
1392         CMP.W   mt_counter,D0
1393         BNE     mt_Return
1394         CLR.B   pn_Volume(A6)
1395         MOVEQ   #0,D0
1396         move.w  d0,nch_Volume(a5)
1397         bset.b  #NCHB_Volume,nch_Changed(a5)
1398         RTS
1399
1400 mt_NoteDelay
1401         MOVEQ   #0,D0
1402         MOVE.B  pn_Val(A6),D0
1403         AND.B   #$0F,D0
1404         CMP.W   mt_counter,D0
1405         BNE     mt_Return
1406         MOVE.W  (A6),D0
1407         BEQ     mt_Return
1408         MOVE.L  D1,-(SP)
1409         BRA     mt_DoRetrig
1410
1411 mt_PatternDelay
1412         TST.W   mt_counter
1413         BNE     mt_Return
1414         MOVEQ   #0,D0
1415         MOVE.B  pn_Val(A6),D0
1416         AND.B   #$0F,D0
1417         TST.B   mt_PattDelTime2
1418         BNE     mt_Return
1419         ADDQ.B  #1,D0
1420         MOVE.B  D0,mt_PattDelTime
1421         RTS
1422
1423 mt_FunkIt
1424         TST.W   mt_counter
1425         BNE     mt_Return
1426         MOVE.B  pn_Val(A6),D0
1427         AND.B   #$0F,D0
1428         LSL.B   #4,D0
1429         AND.B   #$0F,pn_GlissFunk(A6)
1430         OR.B    D0,pn_GlissFunk(A6)
1431         TST.B   D0
1432         BEQ     mt_Return
1433 mt_UpdateFunk
1434         MOVEM.L A0/D1,-(SP)
1435         MOVEQ   #0,D0
1436         MOVE.B  pn_GlissFunk(A6),D0
1437         LSR.B   #4,D0
1438         BEQ.S   mt_funkend
1439         LEA     mt_FunkTable,A0
1440         MOVE.B  (A0,D0.W),D0
1441         ADD.B   D0,pn_FunkOffset(A6)
1442         BTST    #7,pn_FunkOffset(A6)
1443         BEQ.S   mt_funkend
1444         CLR.B   pn_FunkOffset(A6)
1445
1446         MOVE.L  pn_LoopStart(A6),D0
1447         move.l  pn_Replen(a6),d1
1448         ADD.L   D1,D0
1449         ADD.L   D1,D0
1450         MOVE.L  pn_WaveStart(A6),A0
1451         ADDQ.L  #1,A0
1452         CMP.L   D0,A0
1453         BLO.S   mt_funkok
1454         MOVE.L  pn_LoopStart(A6),A0
1455 mt_funkok
1456         MOVE.L  A0,pn_WaveStart(A6)
1457         MOVEQ   #-1,D0
1458         SUB.B   (A0),D0
1459         MOVE.B  D0,(A0)
1460 mt_funkend
1461         MOVEM.L (SP)+,A0/D1
1462         RTS
1463
1464
1465 mt_FunkTable dc.b 0,5,6,7,8,10,11,13,16,19,22,26,32,43,64,128
1466
1467 mt_VibratoTable
1468         dc.b 000,024,049,074,097,120,141,161
1469         dc.b 180,197,212,224,235,244,250,253
1470         dc.b 255,253,250,244,235,224,212,197
1471         dc.b 180,161,141,120,097,074,049,024
1472
1473 mt_PeriodTable
1474 ; Tuning 0, Normal
1475         dc.w    856,808,762,720,678,640,604,570,538,508,480,453
1476         dc.w    428,404,381,360,339,320,302,285,269,254,240,226
1477         dc.w    214,202,190,180,170,160,151,143,135,127,120,113
1478 ; Tuning 1
1479         dc.w    850,802,757,715,674,637,601,567,535,505,477,450
1480         dc.w    425,401,379,357,337,318,300,284,268,253,239,225
1481         dc.w    213,201,189,179,169,159,150,142,134,126,119,113
1482 ; Tuning 2
1483         dc.w    844,796,752,709,670,632,597,563,532,502,474,447
1484         dc.w    422,398,376,355,335,316,298,282,266,251,237,224
1485         dc.w    211,199,188,177,167,158,149,141,133,125,118,112
1486 ; Tuning 3
1487         dc.w    838,791,746,704,665,628,592,559,528,498,470,444
1488         dc.w    419,395,373,352,332,314,296,280,264,249,235,222
1489         dc.w    209,198,187,176,166,157,148,140,132,125,118,111
1490 ; Tuning 4
1491         dc.w    832,785,741,699,660,623,588,555,524,495,467,441
1492         dc.w    416,392,370,350,330,312,294,278,262,247,233,220
1493         dc.w    208,196,185,175,165,156,147,139,131,124,117,110
1494 ; Tuning 5
1495         dc.w    826,779,736,694,655,619,584,551,520,491,463,437
1496         dc.w    413,390,368,347,328,309,292,276,260,245,232,219
1497         dc.w    206,195,184,174,164,155,146,138,130,123,116,109
1498 ; Tuning 6
1499         dc.w    820,774,730,689,651,614,580,547,516,487,460,434
1500         dc.w    410,387,365,345,325,307,290,274,258,244,230,217
1501         dc.w    205,193,183,172,163,154,145,137,129,122,115,109
1502 ; Tuning 7
1503         dc.w    814,768,725,684,646,610,575,543,513,484,457,431
1504         dc.w    407,384,363,342,323,305,288,272,256,242,228,216
1505         dc.w    204,192,181,171,161,152,144,136,128,121,114,108
1506 ; Tuning -8
1507         dc.w    907,856,808,762,720,678,640,604,570,538,508,480
1508         dc.w    453,428,404,381,360,339,320,302,285,269,254,240
1509         dc.w    226,214,202,190,180,170,160,151,143,135,127,120
1510 ; Tuning -7
1511         dc.w    900,850,802,757,715,675,636,601,567,535,505,477
1512         dc.w    450,425,401,379,357,337,318,300,284,268,253,238
1513         dc.w    225,212,200,189,179,169,159,150,142,134,126,119
1514 ; Tuning -6
1515         dc.w    894,844,796,752,709,670,632,597,563,532,502,474
1516         dc.w    447,422,398,376,355,335,316,298,282,266,251,237
1517         dc.w    223,211,199,188,177,167,158,149,141,133,125,118
1518 ; Tuning -5
1519         dc.w    887,838,791,746,704,665,628,592,559,528,498,470
1520         dc.w    444,419,395,373,352,332,314,296,280,264,249,235
1521         dc.w    222,209,198,187,176,166,157,148,140,132,125,118
1522 ; Tuning -4
1523         dc.w    881,832,785,741,699,660,623,588,555,524,494,467
1524         dc.w    441,416,392,370,350,330,312,294,278,262,247,233
1525         dc.w    220,208,196,185,175,165,156,147,139,131,123,117
1526 ; Tuning -3
1527         dc.w    875,826,779,736,694,655,619,584,551,520,491,463
1528         dc.w    437,413,390,368,347,328,309,292,276,260,245,232
1529         dc.w    219,206,195,184,174,164,155,146,138,130,123,116
1530 ; Tuning -2
1531         dc.w    868,820,774,730,689,651,614,580,547,516,487,460
1532         dc.w    434,410,387,365,345,325,307,290,274,258,244,230
1533         dc.w    217,205,193,183,172,163,154,145,137,129,122,115
1534 ; Tuning -1
1535         dc.w    862,814,768,725,684,646,610,575,543,513,484,457
1536         dc.w    431,407,384,363,342,323,305,288,272,256,242,228
1537         dc.w    216,203,192,181,171,161,152,144,136,128,121,114
1538
1539 ;/* End of File */
1540
1541
1542
1543 *-----------------------------------------------------------------------*
1544 ;
1545 ; 14Bit/32Voices-NotePlayer
1546
1547 NoteSignal
1548         movem.l a2-a4,-(sp)
1549
1550         move.l  NoteInfo,d0                     ; get NoteStructure
1551         beq     AO_End
1552         move.l  d0,a4
1553
1554         move.l  nst_Channels(a4),d0             ; pointer to first channel in list
1555 AO_PlayLoop
1556         move.l  d0,a2                           ; ^NoteChannel
1557
1558         cmpi.w  #NCHD_Ignore,nch_Stereo(a2)     ; skip this channel ?
1559         beq     AO_PlayNext                     ; yes !
1560
1561         move.l  nch_NotePlayer(a2),d0           ; channel array
1562         beq     AO_PlayNext                     ; no array !
1563         move.l  d0,a3
1564
1565         move.l  (a3),a0
1566         tst.l   (a0)                            ; Channel disabled ?
1567         beq     AO_PlayNext                     ; yes !
1568
1569         move.l  4(a3),a3                        ; ^TrackStructure
1570 AO_Sample
1571         btst.b  #NCHB_Sample,nch_Changed(a2)
1572         beq.s   AO_Repeat                       ; no new sample !
1573
1574         move.l  nch_SampleStart(a2),a0
1575         move.l  nch_SampleLength(a2),d0
1576         add.l   d0,a0
1577         move.l  a0,td_SPtr(a3)                  ; Pointer auf das Sampleende
1578         neg.l   d0
1579         move.l  d0,td_SLen(a3)                  ; negative Sample-Restbytes
1580
1581         clr.l   td_LLen(a3)                     ; Kein LoopSample vorhanden
1582
1583         clr.w   td_FreC(a3)                     ; -> Kein Überlauf bei erstem Samplebyte!
1584 AO_Repeat
1585         btst.b  #NCHB_Repeat,nch_Changed(a2)
1586         beq.s   AO_Frequency                    ; no new repeat !
1587
1588         move.l  nch_RepeatStart(a2),a0
1589         move.l  nch_RepeatLength(a2),d0
1590         moveq   #2,d1
1591         cmp.l   d0,d1                           ; Repeat-Length only 1 Word ?
1592         bne.s   AO_RepSamp                      ; No !
1593         move.l  a0,a1
1594         move.b  (a1)+,d1
1595         cmp.b   (a1)+,d1                        ; Is it a NullSample ?
1596         bne.s   AO_RepSamp                      ; No !
1597         moveq   #0,d0
1598 AO_RepSamp
1599         add.l   d0,a0
1600         move.l  a0,td_LPtr(a3)                  ; LoopSample-Endadr.
1601         neg.l   d0
1602         move.l  d0,td_LLen(a3)                  ; negative LoopSample-Länge
1603 AO_Frequency
1604         btst.b  #NCHB_Frequency,nch_Changed(a2)
1605         beq.s   AO_Volume                       ; no new freq !
1606
1607         move.l  nch_Frequency(a2),td_Fre(a3)    ; Frequency for this channel
1608 AO_Volume
1609         btst.b  #NCHB_Volume,nch_Changed(a2)
1610         beq.s   AO_PlayNext                     ; no new vol !
1611
1612         moveq   #0,d0
1613         move.w  nch_Volume(a2),d0
1614         lsl.l   #6,d0
1615         divu    nst_MaxVolume(a4),d0
1616         move.w  d0,td_Vol(a3)                   ; Volume for this channel
1617 AO_PlayNext
1618         move.l  nch_NextChannel(a2),d0
1619         bne     AO_PlayLoop                     ; next channel
1620 AO_End
1621         movem.l (sp)+,a2-a4
1622         rts
1623
1624 *-----------------------------------------------------------------------*
1625 ;
1626 ; Set the master volume/balance
1627
1628 ;SetVolBal
1629 ;       move.l  NoteInfo,d0                     ; get NoteStructure
1630 ;       beq     .End
1631 ;       move.l  d0,a4
1632 ;       move.l  delibase,a5                     ; get DeliBase
1633 ;
1634 ;       move.w  dtg_SndVol(a5),d0
1635 ;       mulu    dtg_SndLBal(a5),d0
1636 ;       lsr.w   #6,d0
1637 ;       move.w  d0,Volume07                     ; left volume
1638 ;
1639 ;       move.w  dtg_SndVol(a5),d0
1640 ;       mulu    dtg_SndRBal(a5),d0
1641 ;       lsr.w   #6,d0
1642 ;       move.w  d0,Volume8F                     ; right volume
1643 ;.End
1644 ;       rts
1645
1646 *-----------------------------------------------------------------------*
1647 ;
1648 ; Set the mixing frequency
1649
1650 NewMixFreq:
1651         move.l  ClockBase(pc),d0
1652         move.l  PlayFreq,d1
1653         divu    d1,d0
1654         move.w  d0,MixPeriod
1655         move.l  ClockBase(pc),d1
1656         divu    d0,d1
1657         move.w  d1,MixFreq
1658         rts
1659
1660
1661 *-----------------------------------------------------------------------*
1662 ;
1663 ; Shut down the NotePlayer
1664
1665 NoteFinish
1666         move.l  NoteInfo,d0                     ; get NoteStructure
1667         beq     .End
1668         move.l  d0,a4                           ; copy Ptr
1669
1670         lea     custom,a0
1671         move.w  #$000f,dmacon(a0)               ; Audio-DMA aus
1672         move.w  #$00ff,adkcon(a0)
1673         move.w  #$0780,intreq(a0)               ; Audio-Req. löschen
1674         move.w  #$0780,intena(a0)               ; Audio-Int. aus
1675
1676         move.l  nst_Channels(a4),d0             ; pointer to first channel in list
1677 .FreeChan
1678         move.l  d0,a0
1679         clr.l   nch_NotePlayer(a0)              ; clear channel array pointer
1680 .FreeNext
1681         move.l  nch_NextChannel(a0),d0
1682         bne.s   .FreeChan                       ; next channel
1683
1684         moveq   #INTB_AUD1,d0
1685         move.l  _OldAudio1,a1
1686         JSRLIB  SetIntVector                    ; set old Audio1-IRQ
1687
1688         moveq   #INTB_AUD0,d0
1689         move.l  _OldAudio0,a1
1690         JSRLIB  SetIntVector                    ; set old Audio0-IRQ
1691
1692         lea     AllocIORequest,a1               ; close audio.device
1693         JSRLIB  CloseDevice
1694
1695         clr.l   NoteInfo                        ; shutdown complete
1696 .End
1697         moveq   #0,d0
1698         rts
1699
1700 *-----------------------------------------------------------------------*
1701 ;
1702 ; Boost-Value automatisch berechnen
1703
1704 CalcBoostValue
1705         tst.l   BoostFlag                       ; Boost-Wert automatisch berechnen ?
1706         beq.s   .End                            ; nein, dann raus !
1707
1708         moveq   #0,d0
1709         move.w  ChannelNum,d0
1710         lsl.w   #7,d0
1711         add.w   #128+256,d0
1712         move.w  d0,d1
1713         lsr.w   #1,d1
1714         sub.w   d1,d0
1715         move.w  #8*256,d1
1716         cmp.w   d0,d1
1717         bcc.s   .End
1718         move.w  d1,d0
1719 .End
1720         rts
1721
1722 *-----------------------------------------------------------------------*
1723 ;
1724 ; 14Bit-Output-Tabelle erzeugen (14Bit Routine by Markus "maw" Weichselbaum)
1725
1726         IFEQ USE_CALIBRATION
1727
1728 InitBoostTable
1729         lea     BitTable,a0                     ; 14Bit-Tabelle erzeugen
1730
1731         move.w  #32768-1,d0
1732         move.w  #-32768,d1
1733         move.l  BoostFactor,d2
1734 .Loop   move.w  d1,d3
1735         muls    d2,d3
1736         asr.l   #8,d3
1737         move.l  #-32768,d4
1738         cmp.l   d3,d4
1739         bgt.s   .Fail
1740         move.l  #32767,d4
1741         cmp.l   d3,d4
1742         bgt.s   .Okay
1743 .Fail   move.w  d4,d3
1744 .Okay   move.w  d3,d4                           ; ist das 16 bit sample negativ?
1745         bmi.s   .IsNeg
1746 .IsPos  lsr.w   #8,d3                           ; hi byte fertig machen
1747         lsr.b   #2,d4                           ; vom lo nehmen wir nur die oberen 6 bits
1748         bra.s   .Write
1749 .IsNeg  neg.w   d3                              ; erstmal auf positiv
1750         lsr.w   #8,d3                           ; das hi byte fertig machen
1751         neg.b   d3                              ; hi byte zurueck auf negativ
1752         neg.w   d4                              ; nochmal auf positiv
1753         lsr.b   #2,d4                           ; runter schieben
1754         neg.w   d4                              ; jetzt noch zurueck auf negativ
1755 .Write  move.b  d3,(a0)+                        ; hier haben wir das hi byte
1756         move.b  d4,(a0)+                        ; hier haben wir das lo byte
1757         addq.w  #2,d1
1758         dbra    d0,.Loop
1759         rts
1760
1761         ENDC
1762
1763 *-----------------------------------------------------------------------*
1764 ;
1765 ; 14Bit-Output-Tabelle erzeugen (14Bit Routine by Christian Buchner)
1766
1767         IFNE USE_CALIBRATION
1768
1769 TABLE_ENTRIES   EQU     32768
1770
1771 InitBoostTable  movem.l a2-a3/d2-d7,-(sp)
1772
1773                 lea     CalibData+128,a2
1774
1775 .negative       move.l  a2,a1                   ; count the number of steps
1776                 moveq   #128-1,d0               ; in the negative range
1777                 moveq   #0,d5
1778 .count1         move.b  -(a1),d1
1779                 ext.w   d1
1780                 ext.l   d1
1781                 add.l   d1,d5
1782                 dbra    d0,.count1              ; d5=number of steps
1783
1784                 move.l  #256*TABLE_ENTRIES/2,d6
1785                 divu    BoostFactor+2,d6        ; divide by boost factor
1786                 divu    d6,d5                   ; calculate stepsize (d5) and
1787                 moveq   #0,d7
1788                 swap    d5
1789                 move.w  d5,d7                   ; fractional part (d7)
1790                 clr.w   d5
1791                 swap    d5
1792                 move.w  d6,a3
1793
1794                 lea     BTable,a0               ; place at the middle of table
1795                 move.w  #TABLE_ENTRIES/2-1,d0   ; number of negative values -1
1796                 moveq   #-1,d1                  ; HI value
1797                 moveq   #-1,d2                  ; LO value
1798                 moveq   #0,d3                   ; counter
1799 .fetchnext1     move.b  (a2,d1.w),d4            ; add calibtable to counter
1800                 ext.w   d4
1801                 add.w   d4,d3
1802                 add.w   d4,d2                   ; maximize LO value
1803 .outerloop1     tst.w   d3
1804                 bgt.s   .positive1
1805 .negative1      subq.w  #1,d1
1806                 cmp.w   #$FF7F,d1
1807                 beq.s   .fillup1
1808                 bra.s   .fetchnext1
1809 .positive1      move.b  d2,-(a0)                ; store LO and HI value
1810                 move.b  d1,-(a0)
1811                 sub.w   d5,d2                   ; subtract step size
1812                 sub.w   d5,d3                   ; decrement counter
1813                 sub.w   d7,d6                   ; sum up fractional part
1814                 bpl.s   .repeat1
1815                 add.w   a3,d6
1816                 subq.w  #1,d2                   ; decrement lo value
1817                 subq.w  #1,d3                   ; decrement counter
1818 .repeat1        dbra    d0,.outerloop1
1819                 bra.s   .positive
1820
1821 .fillup1        move.w  #$8000,-(a0)            ; fill up the rest of the
1822                 dbra    d0,.fillup1             ; table with negative minimum
1823
1824 .positive       move.l  a2,a1                   ; count the number of steps
1825                 moveq   #128-1,d0               ; in the positive range
1826                 moveq   #0,d5
1827 .count2         move.b  (a1)+,d1
1828                 ext.w   d1
1829                 ext.l   d1
1830                 add.l   d1,d5
1831                 dbra    d0,.count2              ; d5=number of steps
1832
1833                 move.l  #256*TABLE_ENTRIES/2,d6
1834                 divu    BoostFactor+2,d6        ; divide by boost factor
1835                 divu    d6,d5                   ; calculate stepsize (d5) and
1836                 moveq   #0,d7
1837                 swap    d5
1838                 move.w  d5,d7                   ; fractional part (d7)
1839                 clr.w   d5
1840                 swap    d5
1841                 move.w  d6,a3
1842
1843                 lea     BTable,a0               ; place at the middle of table
1844                 move.w  #TABLE_ENTRIES/2-1,d0   ; number of positive values -1
1845                 moveq   #0,d1                   ; HI value
1846                 moveq   #0,d2                   ; LO value
1847                 moveq   #0,d3                   ; counter
1848 .fetchnext2     move.b  (a2,d1.w),d4            ; add calibtable to counter
1849                 ext.w   d4
1850                 add.w   d4,d3
1851 .outerloop2     tst.w   d3
1852                 bgt.s   .positive2
1853 .negative2      addq.w  #1,d1                   ; increment HI value
1854                 cmp.w   #$80,d1
1855                 beq.s   .fillup2
1856                 sub.w   d4,d2                   ; reset LO value
1857                 bra.s   .fetchnext2
1858 .positive2      move.b  d1,(a0)+                ; store HI and LO value
1859                 move.b  d2,(a0)+
1860                 add.w   d5,d2                   ; add step size
1861                 sub.w   d5,d3                   ; decrement counter
1862                 sub.w   d7,d6                   ; sum up fractional part
1863                 bpl.s   .repeat2
1864                 add.w   a3,d6
1865                 addq.w  #1,d2                   ; increment LO value
1866                 subq.w  #1,d3                   ; decrement counter
1867 .repeat2        dbra    d0,.outerloop2
1868                 bra.s   .finished
1869
1870 .fillup2        move.w  #$7F7E,(a0)+            ; fill up the rest of the
1871                 dbra    d0,.fillup2             ; table with positive maximum
1872
1873 .finished       movem.l (sp)+,a2-a3/d2-d7
1874                 rts
1875
1876         ENDC
1877
1878 *-----------------------------------------------------------------------*
1879 ;
1880 ; Volume-Tabelle (signed) erzeugen
1881
1882 InitSVolTable
1883         lea     VTable,a0                       ; Volume-Tabelle erzeugen
1884
1885         moveq   #65-1,d2
1886         moveq   #0,d4
1887         move.w  ScaleFactor,d5
1888 .Loop1  moveq   #0,d0
1889         move.w  #256-1,d1
1890 .Loop2  move.w  d0,d3
1891         ext.w   d3
1892         muls    d4,d3                           ; Tabellennummer (0...64) * Samplewert
1893         lsr.l   #2,d3
1894         andi.w  #~1,d3
1895         move.w  d3,(a0)+
1896         addq.w  #1,d0
1897         dbra    d1,.Loop2
1898         add.w   d5,d4                           ; > 1 = Oversampling
1899         dbra    d2,.Loop1
1900         rts
1901
1902 *-----------------------------------------------------------------------*
1903 ;
1904 ; Volume-Tabelle (unsigned) erzeugen
1905
1906 InitUVolTable
1907         lea     VTable,a0                       ; Volume-Tabelle erzeugen
1908
1909         moveq   #65-1,d2
1910         moveq   #0,d4
1911         move.w  ScaleFactor,d5
1912 .Loop1  moveq   #-128,d0
1913         move.w  #256-1,d1
1914 .Loop2  move.w  d0,d3
1915         ext.w   d3
1916         muls    d4,d3                           ; Tabellennummer (0...64) * Samplewert
1917         lsr.l   #2,d3
1918         andi.w  #~1,d3
1919         move.w  d3,(a0)+
1920         addq.w  #1,d0
1921         dbra    d1,.Loop2
1922         add.w   d5,d4                           ; > 1 = Oversampling
1923         dbra    d2,.Loop1
1924         rts
1925
1926 *-----------------------------------------------------------------------*
1927 ;
1928 ; Alle 32 Software-Tracks initialisieren
1929
1930 InitTracksNChannels
1931         lea     T00Data(pc),a0
1932         lea     QuietInstr(pc),a1
1933         moveq   #32-1,d0
1934 .Loop   move.l  (a1),td_SPtr(a0)                ; Zum Abspielen vorbereiten
1935         move.l  4(a1),td_SLen(a0)
1936         move.l  8(a1),td_LPtr(a0)
1937         move.l  12(a1),td_LLen(a0)
1938         move.w  #64,td_Vol(a0)                  ; Volle Lautstärke
1939         move.l  #8287,td_Fre(a0)                ; C 0
1940         clr.w   td_FreC(a0)
1941         lea     td_SIZE(a0),a0
1942         dbra    d0,.Loop
1943
1944 * Alle 4 Audiokanäle initialisieren:
1945
1946         lea     custom+aud0,a0
1947         moveq   #4-1,d0
1948 .Init   move.l  #EmptyCBuf,ac_ptr(a0)           ; Erstmal nichts spielen!
1949         move.w  #MBuf_SIZE/2,ac_len(a0)
1950         move.w  MixPeriod(pc),ac_per(a0)
1951         move.w  #0,ac_vol(a0)
1952         adda.w  #ac_SIZEOF,a0
1953         dbra    d0,.Init
1954
1955         clr.w   C03BufOff                       ; Erste Songdaten kommen in Buffer 0
1956         clr.w   C12BufOff
1957         rts
1958
1959 *-----------------------------------------------------------------------*
1960 ;
1961 ; Init Sound
1962
1963 InitSnd
1964         move.l  NoteInfo,d0                     ; get NoteStructure
1965         beq.s   .End
1966         move.l  d0,a4
1967
1968         bsr     InitTracksNChannels
1969
1970         IFNE DEBUG_VERSION
1971         move.l  #InitSndTxt,-(sp)
1972         lea     InformationFmt(pc),a0
1973         bsr     WriteInfoTxt
1974         addq.w  #4,sp
1975         ENDC
1976 .End
1977         rts
1978
1979 *-----------------------------------------------------------------------*
1980 ;
1981 ; Remove Sound
1982
1983 EndSnd
1984         move.l  NoteInfo,d0                     ; get NoteStructure
1985         beq.s   .End
1986         move.l  d0,a4
1987
1988         bsr     InitTracksNChannels
1989
1990         IFNE DEBUG_VERSION
1991         move.l  #EndSndTxt,-(sp)
1992         lea     InformationFmt(pc),a0
1993         bsr     WriteInfoTxt
1994         addq.w  #4,sp
1995         ENDC
1996 .End
1997         rts
1998
1999 *-----------------------------------------------------------------------*
2000 ;
2001 ; Start playing
2002
2003 StartSnd
2004         lea     custom,a0
2005         move.w  #$800f,dmacon(a0)               ; Audio-DMA an
2006         move.w  #$00ff,adkcon(a0)
2007         move.w  #$0780,intreq(a0)               ; Audio-Req. löschen
2008         move.w  #$8180,intena(a0)               ; Audio-Int. an
2009         moveq   #64,d0
2010         move.w  d0,aud0+ac_vol(a0)
2011         move.w  d0,aud1+ac_vol(a0)
2012         moveq   #1,d0
2013         move.w  d0,aud2+ac_vol(a0)
2014         move.w  d0,aud3+ac_vol(a0)
2015 .End
2016         rts
2017
2018 *-----------------------------------------------------------------------*
2019 ;
2020 ; Stop playing
2021
2022 StopSnd
2023         lea     custom,a0
2024         move.w  #$000f,dmacon(a0)               ; Audio-DMA aus
2025         move.w  #$00ff,adkcon(a0)
2026         move.w  #$0780,intreq(a0)               ; Audio-Req. löschen
2027         move.w  #$0780,intena(a0)               ; Audio-Int. aus
2028 .End
2029         rts
2030
2031 *-----------------------------------------------------------------------*
2032 ;
2033 ; Audio-Interrupts für 68000 und 68010
2034
2035 * Tracks 00-0F zusammenmischen:
2036
2037 Int0_000:
2038
2039 * Achtung! Soeben begann das Abspielen des beim
2040 * letzten Interrupt gefüllten Channel-Buffers!
2041
2042         move.w  MixPeriod(pc),d0
2043         lea     Softy0IRQ_000,a1
2044         cmpi.b  #NT_SOFTINT,LN_TYPE(a1)
2045         bne.s   .Period
2046         addi.w  #32,d0                          ; step down
2047         move.w  d0,MixPeriod
2048         move.l  ClockBase(pc),d1
2049         divu    d0,d1
2050         move.w  d1,MixFreq
2051 .Period
2052         move.w  d0,aud0+ac_per(a0)
2053         move.w  d0,aud3+ac_per(a0)
2054         move.w  d0,aud1+ac_per(a0)
2055         move.w  d0,aud2+ac_per(a0)
2056
2057         JSRLIB  Cause
2058
2059         move.w  #INTF_AUD0,custom+intreq        ; AudioInt-Request löschen
2060         rts
2061
2062 Soft0_000:
2063         movem.l d2-d7/a2-a6,-(sp)
2064
2065 * Das rechenaufwendige Mixen passiert im Softint
2066
2067         lea     custom,a0
2068
2069 ;       move.w  #$f00,color(a0)
2070
2071         lea     T00Data(pc),a2
2072         move.w  Volume07(pc),d2
2073         bsr     MixChannel_000
2074
2075         lea     T01Data(pc),a2
2076         move.w  Volume07(pc),d2
2077         bsr     MixChannel_000
2078
2079         lea     T02Data(pc),a2
2080         move.w  Volume07(pc),d2
2081         bsr     MixChannel_000
2082
2083         lea     T03Data(pc),a2
2084         move.w  Volume07(pc),d2
2085         bsr     MixChannel_000
2086
2087         lea     T04Data(pc),a2
2088         move.w  Volume07(pc),d2
2089         bsr     MixChannel_000
2090
2091         lea     T05Data(pc),a2
2092         move.w  Volume07(pc),d2
2093         bsr     MixChannel_000
2094
2095         lea     T06Data(pc),a2
2096         move.w  Volume07(pc),d2
2097         bsr     MixChannel_000
2098
2099         lea     T07Data(pc),a2
2100         move.w  Volume07(pc),d2
2101         bsr     MixChannel_000
2102
2103         lea     T08Data(pc),a2
2104         move.w  Volume07(pc),d2
2105         bsr     MixChannel_000
2106
2107         lea     T09Data(pc),a2
2108         move.w  Volume07(pc),d2
2109         bsr     MixChannel_000
2110
2111         lea     T0AData(pc),a2
2112         move.w  Volume07(pc),d2
2113         bsr     MixChannel_000
2114
2115         lea     T0BData(pc),a2
2116         move.w  Volume07(pc),d2
2117         bsr     MixChannel_000
2118
2119         lea     T0CData(pc),a2
2120         move.w  Volume07(pc),d2
2121         bsr     MixChannel_000
2122
2123         lea     T0DData(pc),a2
2124         move.w  Volume07(pc),d2
2125         bsr     MixChannel_000
2126
2127         lea     T0EData(pc),a2
2128         move.w  Volume07(pc),d2
2129         bsr     MixChannel_000
2130
2131         lea     T0FData(pc),a2
2132         move.w  Volume07(pc),d2
2133         bsr     MixChannel_000
2134
2135 ;       move.w  #$00f,color(a0)
2136
2137         lea     C0Buf,a2                ; Mix-Buffer konvertieren & löschen
2138         adda.w  C03BufOff(pc),a2
2139         move.l  a2,aud0+ac_ptr(a0)
2140         lea     C3Buf,a3
2141         adda.w  C03BufOff(pc),a3
2142         move.l  a3,aud3+ac_ptr(a0)
2143         lea     MBuffer,a4
2144         lea     BTable,a5
2145         move.w  #MBuf_SIZE/2-1,d0
2146         moveq   #0,d1
2147 .Convert
2148         movem.w (a4),d2-d3
2149         move.l  d1,(a4)+
2150         move.b  0(a5,d2.w),(a2)+        ; hier haben wir das hi byte
2151         move.b  0(a5,d3.w),(a2)+
2152         move.b  1(a5,d2.w),(a3)+        ; hier haben wir das lo byte
2153         move.b  1(a5,d3.w),(a3)+
2154         dbra    d0,.Convert
2155
2156         eor.w   #MBuf_SIZE,C03BufOff    ; Buffer flippen
2157
2158 ;       move.w  #$000,color(a0)
2159
2160         movem.l (sp)+,d2-d7/a2-a6
2161         rts
2162
2163
2164 * Tracks 10-1F zusammenmischen:
2165
2166 Int1_000:
2167
2168 * Achtung! Soeben begann das Abspielen des beim
2169 * letzten Interrupt gefüllten Channel-Buffers!
2170
2171         move.w  MixPeriod(pc),d0
2172         lea     Softy1IRQ_000,a1
2173         cmpi.b  #NT_SOFTINT,LN_TYPE(a1)
2174         bne.s   .Period
2175         addi.w  #32,d0                          ; step down
2176         move.w  d0,MixPeriod
2177         move.l  ClockBase(pc),d1
2178         divu    d0,d1
2179         move.w  d1,MixFreq
2180 .Period
2181         move.w  d0,aud0+ac_per(a0)
2182         move.w  d0,aud3+ac_per(a0)
2183         move.w  d0,aud1+ac_per(a0)
2184         move.w  d0,aud2+ac_per(a0)
2185
2186         JSRLIB  Cause
2187
2188         move.w  #INTF_AUD1,custom+intreq        ; AudioInt-Request löschen
2189         rts
2190
2191 Soft1_000:
2192         movem.l d2-d7/a2-a6,-(sp)
2193
2194 * Das rechenaufwendige Mixen passiert im Softint
2195
2196         lea     custom,a0
2197
2198 ;       move.w  #$0f0,color(a0)
2199
2200         lea     T10Data(pc),a2
2201         move.w  Volume8F(pc),d2
2202         bsr     MixChannel_000
2203
2204         lea     T11Data(pc),a2
2205         move.w  Volume8F(pc),d2
2206         bsr     MixChannel_000
2207
2208         lea     T12Data(pc),a2
2209         move.w  Volume8F(pc),d2
2210         bsr     MixChannel_000
2211
2212         lea     T13Data(pc),a2
2213         move.w  Volume8F(pc),d2
2214         bsr     MixChannel_000
2215
2216         lea     T14Data(pc),a2
2217         move.w  Volume8F(pc),d2
2218         bsr     MixChannel_000
2219
2220         lea     T15Data(pc),a2
2221         move.w  Volume8F(pc),d2
2222         bsr     MixChannel_000
2223
2224         lea     T16Data(pc),a2
2225         move.w  Volume8F(pc),d2
2226         bsr     MixChannel_000
2227
2228         lea     T17Data(pc),a2
2229         move.w  Volume8F(pc),d2
2230         bsr     MixChannel_000
2231
2232         lea     T18Data(pc),a2
2233         move.w  Volume8F(pc),d2
2234         bsr     MixChannel_000
2235
2236         lea     T19Data(pc),a2
2237         move.w  Volume8F(pc),d2
2238         bsr     MixChannel_000
2239
2240         lea     T1AData(pc),a2
2241         move.w  Volume8F(pc),d2
2242         bsr     MixChannel_000
2243
2244         lea     T1BData(pc),a2
2245         move.w  Volume8F(pc),d2
2246         bsr     MixChannel_000
2247
2248         lea     T1CData(pc),a2
2249         move.w  Volume8F(pc),d2
2250         bsr     MixChannel_000
2251
2252         lea     T1DData(pc),a2
2253         move.w  Volume8F(pc),d2
2254         bsr     MixChannel_000
2255
2256         lea     T1EData(pc),a2
2257         move.w  Volume8F(pc),d2
2258         bsr     MixChannel_000
2259
2260         lea     T1FData(pc),a2
2261         move.w  Volume8F(pc),d2
2262         bsr     MixChannel_000
2263
2264 ;       move.w  #$00f,color(a0)
2265
2266         lea     C1Buf,a2                ; Mix-Buffer konvertieren & löschen
2267         adda.w  C12BufOff(pc),a2
2268         move.l  a2,aud1+ac_ptr(a0)
2269         lea     C2Buf,a3
2270         adda.w  C12BufOff(pc),a3
2271         move.l  a3,aud2+ac_ptr(a0)
2272         lea     MBuffer,a4
2273         lea     BTable,a5
2274         move.w  #MBuf_SIZE/2-1,d0
2275         moveq   #0,d1
2276 .Convert
2277         movem.w (a4),d2-d3
2278         move.l  d1,(a4)+
2279         move.b  0(a5,d2.w),(a2)+        ; hier haben wir das hi byte
2280         move.b  0(a5,d3.w),(a2)+
2281         move.b  1(a5,d2.w),(a3)+        ; hier haben wir das lo byte
2282         move.b  1(a5,d3.w),(a3)+
2283         dbra    d0,.Convert
2284
2285         eor.w   #MBuf_SIZE,C12BufOff    ; Buffer flippen
2286
2287 ;       move.w  #$000,color(a0)
2288
2289         movem.l (sp)+,d2-d7/a2-a6
2290         rts
2291
2292
2293 *
2294 * Ein Sample zum Play-Buffer dazumixen
2295 *
2296 * D2   = Gesamt-Volume des Channels
2297 * A2   = ^TrackData des zu mixenden Tracks
2298 *
2299
2300 MixChannel_000:
2301         move.l  td_SPtr(a2),a3          ; Pointer auf das Sampleende
2302         move.l  td_SLen(a2),d3          ; negative Restbytes des Samples
2303         bmi.s   .MxCalc                 ; noch nicht am Sampleende angekommen!
2304         move.l  td_LLen(a2),d3          ; ist ein Loop-Sample vorhanden ?
2305         bpl     .MxEnd                  ; Kein Loopsample da, also raus!
2306         move.l  td_LPtr(a2),a3          ; Pointer auf das Loopende
2307 .MxCalc mulu.w  td_Vol(a2),d2           ; Volume des Samples
2308         lsr.w   #6,d2
2309         add.w   d2,d2
2310         lsl.w   #8,d2
2311         lea     VTable,a4               ; ^Volume-Table
2312         adda.l  d2,a4
2313         move.l  td_Fre(a2),d5           ; individuelle Sample-Frequency
2314         divu    MixFreq(pc),d5          ; globale Mix-Frequency
2315         moveq   #0,d4
2316         move.w  d5,d4                   ; Period-Vorkommastellen
2317         clr.w   d5
2318         divu    MixFreq(pc),d5          ; Period-Nachkommastellen
2319         moveq   #0,d6
2320         move.w  td_FreC(a2),d6          ; Period-Nachkomma-Zähler
2321         move.w  d4,d7
2322         mulu    #MBuf_SIZE,d7
2323         move.w  d5,d0
2324         mulu    #MBuf_SIZE,d0
2325         add.l   d6,d0
2326         clr.w   d0
2327         swap    d0
2328         add.l   d0,d7
2329         add.l   d3,d7                   ; Restbytes nach dem Mixen
2330
2331 *
2332 * Hauptschleife - Registerbelegung:
2333 * D0.W = Temp.Register für die Samplebytes
2334 * D1.W = Temp.Register für die Samplewords
2335 * D2.W = Zähler für die MixLoop
2336 * D3.L = Restbytes vom Sample
2337 * D4.L = Vorkomma Faktor
2338 * D5.W = Nachkomma Faktor
2339 * D6.W = Nachkomma Zähler
2340 * D7   = Restbytes nach dem Mixen
2341 * A0   =
2342 * A1   =
2343 * A2   = Zeiger auf TrackData des Tracks
2344 * A3   = Zeiger auf das Ende des Samples
2345 * A4   = Zeiger auf Volume-Tabelle des Samples
2346 * A5   = Zeiger auf den Mix-Buffer
2347 * A6   =
2348 *
2349
2350 .MxSamp lea     MBuffer,a5              ; Pointer auf den Mix-Buffer
2351         move.w  #MBuf_SIZE/2-1,d2       ; Zähler, bis MixBuffer voll
2352
2353         tst.l   d7                      ; wird das Sampleende beim Mixen erreicht ?
2354         bmi     .MxTst2                 ; Nein, dann schnelle Mix-Routine benutzen!
2355
2356 .MxTst1 tst.w   d4                      ; Period-Vorkommastellen Null?
2357         bne.s   .MxLop3                 ; Nein, dann normale Mix-Routine benutzen!
2358         moveq   #1,d4
2359
2360         adda.l  d3,a3
2361         moveq   #0,d0
2362         move.b  (a3)+,d0                ; erstes Samplebyte holen
2363         add.w   d0,d0
2364         move.w  0(a4,d0.w),d1
2365 .MxLop0 add.w   d1,(a5)+
2366         add.w   d5,d6                   ; Sample fortschalten
2367         bcc.s   .MxLop1
2368         add.l   d4,d3
2369         bmi.s   .MxGet1                 ; noch nicht am Sampleende angekommen!
2370         add.l   td_LLen(a2),d3          ; ist ein Loop-Sample vorhanden ?
2371         bpl.s   .MxPerC                 ; Kein Loopsample da, also raus!
2372         move.l  td_LPtr(a2),a3          ; Pointer auf das Loopende
2373         adda.l  d3,a3
2374 .MxGet1 moveq   #0,d0
2375         move.b  (a3)+,d0                ; ein Sample zum Buffer dazumixen
2376         add.w   d0,d0
2377         move.w  0(a4,d0.w),d1
2378 .MxLop1 add.w   d1,(a5)+
2379         add.w   d5,d6                   ; Sample fortschalten
2380         bcc.s   .MxLop2
2381         add.l   d4,d3
2382         bmi.s   .MxGet2                 ; noch nicht am Sampleende angekommen!
2383         add.l   td_LLen(a2),d3          ; ist ein Loop-Sample vorhanden ?
2384         bpl.s   .MxPerC                 ; Kein Loopsample da, also raus!
2385         move.l  td_LPtr(a2),a3          ; Pointer auf das Loopende
2386         adda.l  d3,a3
2387 .MxGet2 moveq   #0,d0
2388         move.b  (a3)+,d0                ; ein Sample zum Buffer dazumixen
2389         add.w   d0,d0
2390         move.w  0(a4,d0.w),d1
2391 .MxLop2 dbra    d2,.MxLop0              ; bis MixBuffer voll
2392         add.l   d3,d4
2393         suba.l  d4,a3
2394         bra.s   .MxPerC
2395
2396 .MxLop3 moveq   #0,d0
2397         move.b  0(a3,d3.l),d0           ; ein Sample zum Buffer dazumixen
2398         add.w   d0,d0
2399         move.w  0(a4,d0.w),d1
2400         add.w   d1,(a5)+
2401         add.w   d5,d6                   ; Sample fortschalten
2402         addx.l  d4,d3
2403         bmi.s   .MxLop4                 ; noch nicht am Sampleende angekommen!
2404         add.l   td_LLen(a2),d3          ; ist ein Loop-Sample vorhanden ?
2405         bpl.s   .MxPerC                 ; Kein Loopsample da, also raus!
2406         move.l  td_LPtr(a2),a3          ; Pointer auf das Loopende
2407 .MxLop4 moveq   #0,d0
2408         move.b  0(a3,d3.l),d0           ; ein Sample zum Buffer dazumixen
2409         add.w   d0,d0
2410         move.w  0(a4,d0.w),d1
2411         add.w   d1,(a5)+
2412         add.w   d5,d6                   ; Sample fortschalten
2413         addx.l  d4,d3
2414         bmi.s   .MxLop5                 ; noch nicht am Sampleende angekommen!
2415         add.l   td_LLen(a2),d3          ; ist ein Loop-Sample vorhanden ?
2416         bpl.s   .MxPerC                 ; Kein Loopsample da, also raus!
2417         move.l  td_LPtr(a2),a3          ; Pointer auf das Loopende
2418 .MxLop5 dbra    d2,.MxLop3              ; bis MixBuffer voll
2419
2420 .MxPerC move.w  d6,td_FreC(a2)          ; Neuer Stand des Runtersample-Zählers
2421 .MxSPtr move.l  a3,td_SPtr(a2)          ; Endadresse des Samples sichern
2422 .MxSLen move.l  d3,td_SLen(a2)          ; Neue Position im Sample erreicht
2423
2424 .MxEnd  rts
2425
2426 .MxTst2 tst.w   d4                      ; Period-Vorkommastellen Null?
2427         bne.s   .MxLop9                 ; Nein, dann normale Mix-Routine benutzen!
2428         moveq   #1,d4
2429
2430         adda.l  d3,a3
2431         move.l  d7,d3
2432         moveq   #0,d0
2433         move.b  (a3)+,d0                ; erstes Samplebyte holen
2434         add.w   d0,d0
2435         move.w  0(a4,d0.w),d1
2436 .MxLop6 add.w   d1,(a5)+
2437         add.w   d5,d6                   ; Sample fortschalten
2438         bcc.s   .MxLop7
2439         moveq   #0,d0
2440         move.b  (a3)+,d0                ; ein Sample zum Buffer dazumixen
2441         add.w   d0,d0
2442         move.w  0(a4,d0.w),d1
2443 .MxLop7 add.w   d1,(a5)+
2444         add.w   d5,d6                   ; Sample fortschalten
2445         bcc.s   .MxLop8
2446         moveq   #0,d0
2447         move.b  (a3)+,d0                ; ein Sample zum Buffer dazumixen
2448         add.w   d0,d0
2449         move.w  0(a4,d0.w),d1
2450 .MxLop8 dbra    d2,.MxLop6              ; bis MixBuffer voll
2451         add.l   d3,d4
2452         suba.l  d4,a3
2453         bra.s   .MxPerC
2454
2455 .MxLop9 moveq   #0,d0
2456         move.b  0(a3,d3.l),d0           ; ein Sample zum Buffer dazumixen
2457         add.w   d0,d0
2458         move.w  0(a4,d0.w),d1
2459         add.w   d1,(a5)+
2460         add.w   d5,d6                   ; Sample fortschalten
2461         addx.l  d4,d3
2462         moveq   #0,d0
2463         move.b  0(a3,d3.l),d0           ; ein Sample zum Buffer dazumixen
2464         add.w   d0,d0
2465         move.w  0(a4,d0.w),d1
2466         add.w   d1,(a5)+
2467         add.w   d5,d6                   ; Sample fortschalten
2468         addx.l  d4,d3
2469         dbra    d2,.MxLop9              ; bis MixBuffer voll
2470         bra.s   .MxPerC
2471
2472 *-----------------------------------------------------------------------*
2473 ;
2474 ; Audio-Interrupts für 68020 und höher
2475
2476 * Tracks 00-0F zusammenmischen:
2477
2478 Int0_020:
2479
2480 * Achtung! Soeben begann das Abspielen des beim
2481 * letzten Interrupt gefüllten Channel-Buffers!
2482
2483         move.w  MixPeriod(pc),d0
2484         lea     Softy0IRQ_020,a1
2485         cmpi.b  #NT_SOFTINT,LN_TYPE(a1)
2486         bne.s   .Period
2487         addi.w  #32,d0                          ; step down
2488         move.w  d0,MixPeriod
2489         move.l  ClockBase(pc),d1
2490         divu    d0,d1
2491         move.w  d1,MixFreq
2492 .Period
2493         move.w  d0,aud0+ac_per(a0)
2494         move.w  d0,aud3+ac_per(a0)
2495         move.w  d0,aud1+ac_per(a0)
2496         move.w  d0,aud2+ac_per(a0)
2497
2498         JSRLIB  Cause
2499
2500         move.w  #INTF_AUD0,custom+intreq        ; AudioInt-Request löschen
2501         rts
2502
2503 Soft0_020:
2504         movem.l d2-d7/a2-a6,-(sp)
2505
2506 * Das rechenaufwendige Mixen passiert im Softint
2507
2508         lea     custom,a0
2509
2510 ;       move.w  #$f00,color(a0)
2511
2512         lea     T00Data(pc),a2
2513         move.w  Volume07(pc),d2
2514         bsr     MixChannel_020
2515
2516         lea     T01Data(pc),a2
2517         move.w  Volume07(pc),d2
2518         bsr     MixChannel_020
2519
2520         lea     T02Data(pc),a2
2521         move.w  Volume07(pc),d2
2522         bsr     MixChannel_020
2523
2524         lea     T03Data(pc),a2
2525         move.w  Volume07(pc),d2
2526         bsr     MixChannel_020
2527
2528         lea     T04Data(pc),a2
2529         move.w  Volume07(pc),d2
2530         bsr     MixChannel_020
2531
2532         lea     T05Data(pc),a2
2533         move.w  Volume07(pc),d2
2534         bsr     MixChannel_020
2535
2536         lea     T06Data(pc),a2
2537         move.w  Volume07(pc),d2
2538         bsr     MixChannel_020
2539
2540         lea     T07Data(pc),a2
2541         move.w  Volume07(pc),d2
2542         bsr     MixChannel_020
2543
2544         lea     T08Data(pc),a2
2545         move.w  Volume07(pc),d2
2546         bsr     MixChannel_020
2547
2548         lea     T09Data(pc),a2
2549         move.w  Volume07(pc),d2
2550         bsr     MixChannel_020
2551
2552         lea     T0AData(pc),a2
2553         move.w  Volume07(pc),d2
2554         bsr     MixChannel_020
2555
2556         lea     T0BData(pc),a2
2557         move.w  Volume07(pc),d2
2558         bsr     MixChannel_020
2559
2560         lea     T0CData(pc),a2
2561         move.w  Volume07(pc),d2
2562         bsr     MixChannel_020
2563
2564         lea     T0DData(pc),a2
2565         move.w  Volume07(pc),d2
2566         bsr     MixChannel_020
2567
2568         lea     T0EData(pc),a2
2569         move.w  Volume07(pc),d2
2570         bsr     MixChannel_020
2571
2572         lea     T0FData(pc),a2
2573         move.w  Volume07(pc),d2
2574         bsr     MixChannel_020
2575
2576 ;       move.w  #$00f,color(a0)
2577
2578         lea     C0Buf,a2                ; Mix-Buffer konvertieren & löschen
2579         adda.w  C03BufOff(pc),a2
2580         move.l  a2,aud0+ac_ptr(a0)
2581         lea     C3Buf,a3
2582         adda.w  C03BufOff(pc),a3
2583         move.l  a3,aud3+ac_ptr(a0)
2584         lea     MBuffer,a4
2585         lea     BTable,a5
2586         move.w  #MBuf_SIZE/2-1,d0
2587         moveq   #0,d1
2588 .Convert
2589         movem.w (a4),d2-d3
2590         move.l  d1,(a4)+
2591         move.b  0(a5,d2.w),(a2)+        ; hier haben wir das hi byte
2592         move.b  0(a5,d3.w),(a2)+
2593         move.b  1(a5,d2.w),(a3)+        ; hier haben wir das lo byte
2594         move.b  1(a5,d3.w),(a3)+
2595         dbra    d0,.Convert
2596
2597         eor.w   #MBuf_SIZE,C03BufOff    ; Buffer flippen
2598
2599 ;       move.w  #$000,color(a0)
2600
2601         movem.l (sp)+,d2-d7/a2-a6
2602         rts
2603
2604
2605 * Tracks 10-1F zusammenmischen:
2606
2607 Int1_020:
2608
2609 * Achtung! Soeben begann das Abspielen des beim
2610 * letzten Interrupt gefüllten Channel-Buffers!
2611
2612         move.w  MixPeriod(pc),d0
2613         lea     Softy1IRQ_020,a1
2614         cmpi.b  #NT_SOFTINT,LN_TYPE(a1)
2615         bne.s   .Period
2616         addi.w  #32,d0                          ; step down
2617         move.w  d0,MixPeriod
2618         move.l  ClockBase(pc),d1
2619         divu    d0,d1
2620         move.w  d1,MixFreq
2621 .Period
2622         move.w  d0,aud0+ac_per(a0)
2623         move.w  d0,aud3+ac_per(a0)
2624         move.w  d0,aud1+ac_per(a0)
2625         move.w  d0,aud2+ac_per(a0)
2626
2627         JSRLIB  Cause
2628
2629         move.w  #INTF_AUD1,custom+intreq        ; AudioInt-Request löschen
2630         rts
2631
2632 Soft1_020:
2633         movem.l d2-d7/a2-a6,-(sp)
2634
2635 * Das rechenaufwendige Mixen passiert im Softint
2636
2637         lea     custom,a0
2638
2639 ;       move.w  #$0f0,color(a0)
2640
2641         lea     T10Data(pc),a2
2642         move.w  Volume8F(pc),d2
2643         bsr     MixChannel_020
2644
2645         lea     T11Data(pc),a2
2646         move.w  Volume8F(pc),d2
2647         bsr     MixChannel_020
2648
2649         lea     T12Data(pc),a2
2650         move.w  Volume8F(pc),d2
2651         bsr     MixChannel_020
2652
2653         lea     T13Data(pc),a2
2654         move.w  Volume8F(pc),d2
2655         bsr     MixChannel_020
2656
2657         lea     T14Data(pc),a2
2658         move.w  Volume8F(pc),d2
2659         bsr     MixChannel_020
2660
2661         lea     T15Data(pc),a2
2662         move.w  Volume8F(pc),d2
2663         bsr     MixChannel_020
2664
2665         lea     T16Data(pc),a2
2666         move.w  Volume8F(pc),d2
2667         bsr     MixChannel_020
2668
2669         lea     T17Data(pc),a2
2670         move.w  Volume8F(pc),d2
2671         bsr     MixChannel_020
2672
2673         lea     T18Data(pc),a2
2674         move.w  Volume8F(pc),d2
2675         bsr     MixChannel_020
2676
2677         lea     T19Data(pc),a2
2678         move.w  Volume8F(pc),d2
2679         bsr     MixChannel_020
2680
2681         lea     T1AData(pc),a2
2682         move.w  Volume8F(pc),d2
2683         bsr     MixChannel_020
2684
2685         lea     T1BData(pc),a2
2686         move.w  Volume8F(pc),d2
2687         bsr     MixChannel_020
2688
2689         lea     T1CData(pc),a2
2690         move.w  Volume8F(pc),d2
2691         bsr     MixChannel_020
2692
2693         lea     T1DData(pc),a2
2694         move.w  Volume8F(pc),d2
2695         bsr     MixChannel_020
2696
2697         lea     T1EData(pc),a2
2698         move.w  Volume8F(pc),d2
2699         bsr     MixChannel_020
2700
2701         lea     T1FData(pc),a2
2702         move.w  Volume8F(pc),d2
2703         bsr     MixChannel_020
2704
2705 ;       move.w  #$00f,color(a0)
2706
2707         lea     C1Buf,a2                ; Mix-Buffer konvertieren & löschen
2708         adda.w  C12BufOff(pc),a2
2709         move.l  a2,aud1+ac_ptr(a0)
2710         lea     C2Buf,a3
2711         adda.w  C12BufOff(pc),a3
2712         move.l  a3,aud2+ac_ptr(a0)
2713         lea     MBuffer,a4
2714         lea     BTable,a5
2715         move.w  #MBuf_SIZE/2-1,d0
2716         moveq   #0,d1
2717 .Convert
2718         movem.w (a4),d2-d3
2719         move.l  d1,(a4)+
2720         move.b  0(a5,d2.w),(a2)+        ; hier haben wir das hi byte
2721         move.b  0(a5,d3.w),(a2)+
2722         move.b  1(a5,d2.w),(a3)+        ; hier haben wir das lo byte
2723         move.b  1(a5,d3.w),(a3)+
2724         dbra    d0,.Convert
2725
2726         eor.w   #MBuf_SIZE,C12BufOff    ; Buffer flippen
2727
2728 ;       move.w  #$000,color(a0)
2729
2730         movem.l (sp)+,d2-d7/a2-a6
2731         rts
2732
2733
2734 *
2735 * Ein Sample zum Play-Buffer dazumixen
2736 *
2737 * D2   = Gesamt-Volume des Channels
2738 * A2   = ^TrackData des zu mixenden Tracks
2739 *
2740
2741 MixChannel_020:
2742         move.l  td_SPtr(a2),a3          ; Pointer auf das Sampleende
2743         move.l  td_SLen(a2),d3          ; negative Restbytes des Samples
2744         bmi.s   .MxCalc                 ; noch nicht am Sampleende angekommen!
2745         move.l  td_LLen(a2),d3          ; ist ein Loop-Sample vorhanden ?
2746         bpl     .MxEnd                  ; Kein Loopsample da, also raus!
2747         move.l  td_LPtr(a2),a3          ; Pointer auf das Loopende
2748 .MxCalc mulu.w  td_Vol(a2),d2           ; Volume des Samples
2749         lsr.w   #6,d2
2750         add.w   d2,d2
2751         lsl.w   #8,d2
2752         lea     VTable,a4               ; ^Volume-Table
2753         adda.l  d2,a4
2754         move.l  td_Fre(a2),d5           ; individuelle Sample-Frequency
2755         divu    MixFreq(pc),d5          ; globale Mix-Frequency
2756         moveq   #0,d4
2757         move.w  d5,d4                   ; Period-Vorkommastellen
2758         clr.w   d5
2759         divu    MixFreq(pc),d5          ; Period-Nachkommastellen
2760         moveq   #0,d6
2761         move.w  td_FreC(a2),d6          ; Period-Nachkomma-Zähler
2762         move.w  d4,d7
2763         mulu    #MBuf_SIZE,d7
2764         move.w  d5,d0
2765         mulu    #MBuf_SIZE,d0
2766         add.l   d6,d0
2767         clr.w   d0
2768         swap    d0
2769         add.l   d0,d7
2770         add.l   d3,d7                   ; Restbytes nach dem Mixen
2771
2772 *
2773 * Hauptschleife - Registerbelegung:
2774 * D0.W = Temp.Register für die Samplebytes
2775 * D1.W = Temp.Register für die Samplewords
2776 * D2.W = Zähler für die MixLoop
2777 * D3.L = Restbytes vom Sample
2778 * D4.L = Vorkomma Faktor
2779 * D5.W = Nachkomma Faktor
2780 * D6.W = Nachkomma Zähler
2781 * D7   = Restbytes nach dem Mixen
2782 * A0   =
2783 * A1   =
2784 * A2   = Zeiger auf TrackData des Tracks
2785 * A3   = Zeiger auf das Ende des Samples
2786 * A4   = Zeiger auf Volume-Tabelle des Samples
2787 * A5   = Zeiger auf den Mix-Buffer
2788 * A6   =
2789 *
2790
2791 .MxSamp lea     MBuffer,a5              ; Pointer auf den Mix-Buffer
2792         move.w  #MBuf_SIZE/2-1,d2       ; Zähler, bis MixBuffer voll
2793
2794         tst.l   d7                      ; wird das Sampleende beim Mixen erreicht ?
2795         bmi     .MxTst2                 ; Nein, dann schnelle Mix-Routine benutzen!
2796
2797 .MxTst1 moveq   #0,d0
2798         tst.w   d4                      ; Period-Vorkommastellen Null?
2799         bne.s   .MxLop3                 ; Nein, dann normale Mix-Routine benutzen!
2800         moveq   #1,d4
2801
2802         adda.l  d3,a3
2803         move.b  (a3)+,d0                ; erstes Samplebyte holen
2804         move.w  0(a4,d0.w*2),d1
2805 .MxLop0 add.w   d1,(a5)+
2806         add.w   d5,d6                   ; Sample fortschalten
2807         bcc.s   .MxLop1
2808         add.l   d4,d3
2809         bmi.s   .MxGet1                 ; noch nicht am Sampleende angekommen!
2810         add.l   td_LLen(a2),d3          ; ist ein Loop-Sample vorhanden ?
2811         bpl.s   .MxPerC                 ; Kein Loopsample da, also raus!
2812         move.l  td_LPtr(a2),a3          ; Pointer auf das Loopende
2813         adda.l  d3,a3
2814 .MxGet1 move.b  (a3)+,d0                ; ein Sample zum Buffer dazumixen
2815         move.w  0(a4,d0.w*2),d1
2816 .MxLop1 add.w   d1,(a5)+
2817         add.w   d5,d6                   ; Sample fortschalten
2818         bcc.s   .MxLop2
2819         add.l   d4,d3
2820         bmi.s   .MxGet2                 ; noch nicht am Sampleende angekommen!
2821         add.l   td_LLen(a2),d3          ; ist ein Loop-Sample vorhanden ?
2822         bpl.s   .MxPerC                 ; Kein Loopsample da, also raus!
2823         move.l  td_LPtr(a2),a3          ; Pointer auf das Loopende
2824         adda.l  d3,a3
2825 .MxGet2 move.b  (a3)+,d0                ; ein Sample zum Buffer dazumixen
2826         move.w  0(a4,d0.w*2),d1
2827 .MxLop2 dbra    d2,.MxLop0              ; bis MixBuffer voll
2828         add.l   d3,d4
2829         suba.l  d4,a3
2830         bra.s   .MxPerC
2831
2832 .MxLop3 move.b  0(a3,d3.l),d0           ; ein Sample zum Buffer dazumixen
2833         move.w  0(a4,d0.w*2),d1
2834         add.w   d1,(a5)+
2835         add.w   d5,d6                   ; Sample fortschalten
2836         addx.l  d4,d3
2837         bmi.s   .MxLop4                 ; noch nicht am Sampleende angekommen!
2838         add.l   td_LLen(a2),d3          ; ist ein Loop-Sample vorhanden ?
2839         bpl.s   .MxPerC                 ; Kein Loopsample da, also raus!
2840         move.l  td_LPtr(a2),a3          ; Pointer auf das Loopende
2841 .MxLop4 move.b  0(a3,d3.l),d0           ; ein Sample zum Buffer dazumixen
2842         move.w  0(a4,d0.w*2),d1
2843         add.w   d1,(a5)+
2844         add.w   d5,d6                   ; Sample fortschalten
2845         addx.l  d4,d3
2846         bmi.s   .MxLop5                 ; noch nicht am Sampleende angekommen!
2847         add.l   td_LLen(a2),d3          ; ist ein Loop-Sample vorhanden ?
2848         bpl.s   .MxPerC                 ; Kein Loopsample da, also raus!
2849         move.l  td_LPtr(a2),a3          ; Pointer auf das Loopende
2850 .MxLop5 dbra    d2,.MxLop3              ; bis MixBuffer voll
2851
2852 .MxPerC move.w  d6,td_FreC(a2)          ; Neuer Stand des Runtersample-Zählers
2853 .MxSPtr move.l  a3,td_SPtr(a2)          ; Endadresse des Samples sichern
2854 .MxSLen move.l  d3,td_SLen(a2)          ; Neue Position im Sample erreicht
2855
2856 .MxEnd  rts
2857
2858 .MxTst2 moveq   #0,d0
2859         tst.w   d4                      ; Period-Vorkommastellen Null?
2860         bne.s   .MxLop9                 ; Nein, dann normale Mix-Routine benutzen!
2861         moveq   #1,d4
2862
2863         adda.l  d3,a3
2864         move.l  d7,d3
2865         move.b  (a3)+,d0                ; erstes Samplebyte holen
2866         move.w  0(a4,d0.w*2),d1
2867 .MxLop6 add.w   d1,(a5)+
2868         add.w   d5,d6                   ; Sample fortschalten
2869         bcc.s   .MxLop7
2870         move.b  (a3)+,d0                ; ein Sample zum Buffer dazumixen
2871         move.w  0(a4,d0.w*2),d1
2872 .MxLop7 add.w   d1,(a5)+
2873         add.w   d5,d6                   ; Sample fortschalten
2874         bcc.s   .MxLop8
2875         move.b  (a3)+,d0                ; ein Sample zum Buffer dazumixen
2876         move.w  0(a4,d0.w*2),d1
2877 .MxLop8 dbra    d2,.MxLop6              ; bis MixBuffer voll
2878         add.l   d3,d4
2879         suba.l  d4,a3
2880         bra.s   .MxPerC
2881
2882 .MxLop9 move.b  0(a3,d3.l),d0           ; ein Sample zum Buffer dazumixen
2883         move.w  0(a4,d0.w*2),d1
2884         add.w   d1,(a5)+
2885         add.w   d5,d6                   ; Sample fortschalten
2886         addx.l  d4,d3
2887         move.b  0(a3,d3.l),d0           ; ein Sample zum Buffer dazumixen
2888         move.w  0(a4,d0.w*2),d1
2889         add.w   d1,(a5)+
2890         add.w   d5,d6                   ; Sample fortschalten
2891         addx.l  d4,d3
2892         dbra    d2,.MxLop9              ; bis MixBuffer voll
2893         bra.s   .MxPerC
2894
2895 *-----------------------------------------------------------------------*
2896 ;
2897 ; Daten für die Audio-Interrupt Routine
2898
2899         CNOP    0,4
2900
2901 ClockBase:      dc.l    0       ;Clock-Konstante
2902 MixPeriod:      dc.w    256     ;Gesamt-Period für alle Kanäle
2903 MixFreq:        dc.w    8287    ;Gesamt-Frequenz für alle Kanäle
2904
2905 * Variablen der Audio-Interrupt-Routine:
2906
2907 Volume07:       dc.w    64      ;Channel-Volumes für links und rechts
2908 Volume8F:       dc.w    64
2909
2910 C03BufOff:      dc.w    0       ;Buffer-Flip-Offset (0 oder MBuf_SIZE)
2911 C12BufOff:      dc.w    0
2912
2913
2914 * 32 Track-Data-Strukturen:
2915
2916         rsreset
2917 td_SPtr rs.l    1       ; Zeiger auf das Sampleende
2918 td_SLen rs.l    1       ; negative Sample-Restbytes
2919 td_LPtr rs.l    1       ; Endadr. des Loopteils
2920 td_LLen rs.l    1       ; negative Länge des Loopteils
2921 td_Vol  rs.w    1       ; Volume-Wert 0...64
2922 td_Fre  rs.l    1       ; Frequenz-Wert
2923 td_FreC rs.w    1       ; Frequenz-Nachkomma-Zähler
2924 td_SIZE rs.l    0
2925
2926
2927 T00Data:        ds.b    td_SIZE
2928 T01Data:        ds.b    td_SIZE
2929 T02Data:        ds.b    td_SIZE
2930 T03Data:        ds.b    td_SIZE
2931 T04Data:        ds.b    td_SIZE
2932 T05Data:        ds.b    td_SIZE
2933 T06Data:        ds.b    td_SIZE
2934 T07Data:        ds.b    td_SIZE
2935 T08Data:        ds.b    td_SIZE
2936 T09Data:        ds.b    td_SIZE
2937 T0AData:        ds.b    td_SIZE
2938 T0BData:        ds.b    td_SIZE
2939 T0CData:        ds.b    td_SIZE
2940 T0DData:        ds.b    td_SIZE
2941 T0EData:        ds.b    td_SIZE
2942 T0FData:        ds.b    td_SIZE
2943 T10Data:        ds.b    td_SIZE
2944 T11Data:        ds.b    td_SIZE
2945 T12Data:        ds.b    td_SIZE
2946 T13Data:        ds.b    td_SIZE
2947 T14Data:        ds.b    td_SIZE
2948 T15Data:        ds.b    td_SIZE
2949 T16Data:        ds.b    td_SIZE
2950 T17Data:        ds.b    td_SIZE
2951 T18Data:        ds.b    td_SIZE
2952 T19Data:        ds.b    td_SIZE
2953 T1AData:        ds.b    td_SIZE
2954 T1BData:        ds.b    td_SIZE
2955 T1CData:        ds.b    td_SIZE
2956 T1DData:        ds.b    td_SIZE
2957 T1EData:        ds.b    td_SIZE
2958 T1FData:        ds.b    td_SIZE
2959
2960
2961 * Stummes Instrument:
2962
2963 QuietInstr:
2964         dc.l    QuietInstr      ; Endadresse
2965         dc.l    0               ; Restlänge
2966         dc.l    QuietInstr      ; Ende LoopSample
2967         dc.l    0               ; Länge LoopSample
2968
2969
2970
2971 *-----------------------------------------------------------------------*
2972
2973 ;
2974 ;
2975         SECTION GenieTabBuff,BSS
2976 ;
2977 ;
2978
2979 * Umrechnungs-Tabelle für versch. Lautstärken:
2980 * (wird durch NoteInit initialisiert)
2981
2982 VTable: ds.w    256*65
2983
2984
2985 *-----------------------------------------------------------------------*
2986
2987 ;
2988 ;
2989         SECTION GenieBitBuff,BSS
2990 ;
2991 ;
2992
2993 * Umrechnungs-Tabelle für 14Bit Ausgabe:
2994 * (wird beim Start initialisiert)
2995
2996 BitTable:
2997         ds.b    256*128
2998 BTable:
2999         ds.b    256*128
3000
3001
3002 *-----------------------------------------------------------------------*
3003
3004 ;
3005 ;
3006         SECTION GenieMixBuff,BSS
3007 ;
3008 ;
3009
3010 * Mix-Buffer:
3011
3012 MBuf_SIZE       equ     200
3013
3014 MBuffer:
3015         ds.w    MBuf_SIZE
3016 MBufferEnd:
3017
3018
3019
3020 *-----------------------------------------------------------------------*
3021 ;
3022 ; NoteChannels - From TakeTracker player
3023
3024 ;
3025 ;
3026         SECTION NoteChan,BSS
3027 ;
3028 ;
3029
3030 NoteChannels    ds.b    NoteChannel_SIZE*32
3031
3032
3033
3034 *-----------------------------------------------------------------------*
3035
3036 ;
3037 ;
3038         SECTION GenieSampBuff,BSS_C
3039 ;
3040 ;
3041
3042 * Channel-Buffer:
3043
3044 CBuffers:
3045 C0Buf:  ds.b    MBuf_SIZE
3046         ds.b    MBuf_SIZE       ;Für Double-Buffering!
3047 C1Buf:  ds.b    MBuf_SIZE
3048         ds.b    MBuf_SIZE       ;Für Double-Buffering!
3049 C2Buf:  ds.b    MBuf_SIZE
3050         ds.b    MBuf_SIZE       ;Für Double-Buffering!
3051 C3Buf:  ds.b    MBuf_SIZE
3052         ds.b    MBuf_SIZE       ;Für Double-Buffering!
3053 CBuffersEnd:
3054
3055 EmptyCBuf:
3056         ds.b    MBuf_SIZE
3057
3058
3059 *-----------------------------------------------------------------------*
3060
3061         section __MERGED,data
3062
3063
3064 **********************************************************************
3065 * Player Data
3066 **********************************************************************
3067
3068 MyTask          dc.l    0
3069 ParentTask      dc.l    0
3070
3071 ; Library bases
3072
3073 _SysBase        dc.l    0
3074 _GFXBase        dc.l    0
3075
3076 retval          dc.l    0
3077
3078 _OldAudio0:     dc.l    0       ; Old audio interrupt vectors
3079 _OldAudio1:     dc.l    0
3080
3081 NoteInfo:       dc.l    0
3082
3083 PlayFreq        dc.l    14433
3084 ScaleFactor     dc.w    0
3085 ChannelNum      dc.w    0
3086 BoostFlag       dc.l    1       ; Automatic Volume Boost Calculation
3087 BoostFactor     dc.l    0
3088
3089
3090
3091 **********************************************************************
3092 * From TakeTracker player
3093 **********************************************************************
3094
3095 delibase        dc.l 0
3096
3097 songinfo        dc.l 0
3098 mt_size         dc.l 0
3099
3100 mt_NumCh        dc.w 0
3101 mt_rsize        dc.w 0
3102 mt_psize        dc.w 0
3103
3104 NotePlay        dc.l NoteStructure
3105
3106 NoteStructure   dc.l NoteChannels               ; NoteChannel Array
3107                 dc.l NSTF_Period!NSTF_Signed!NSTF_8Bit  ; 8-Bit signed sample data
3108                 dc.l 28867                      ; max. frequency
3109                 dc.w 64                         ; max. volume
3110                 dcb.b 18,0
3111
3112 mt_ChanTemp     ds.b    pn_SIZEOF * MAXCHANNELS
3113
3114 mt_speed        dc.w 0
3115 mt_counter      dc.w 0
3116 mt_SongPos      dc.w 0
3117 mt_StartPos     dc.w 0
3118 mt_MaxPos       dc.w 0
3119 mt_PBreakPos    dc.w 0
3120 mt_PatternPos   dc.w 0
3121 mt_PosJumpFlag  dc.b 0
3122 mt_PBreakFlag   dc.b 0
3123 mt_LowMask      dc.b 0
3124 mt_PattDelTime  dc.b 0
3125 mt_PattDelTime2 dc.b 0
3126 mt_Reset        dc.b 0
3127
3128
3129 **********************************************************************
3130 * AudioInterrupts
3131 **********************************************************************
3132
3133 Audio0IRQ_000
3134         dc.l 0                  ; Succ
3135         dc.l 0                  ; Pred
3136         dc.b NT_INTERRUPT       ; Type
3137         dc.b 0                  ; Pri
3138         dc.l audiointname       ; Name
3139         dc.l 0                  ; Data
3140         dc.l Int0_000           ; Code
3141
3142 Audio1IRQ_000
3143         dc.l 0                  ; Succ
3144         dc.l 0                  ; Pred
3145         dc.b NT_INTERRUPT       ; Type
3146         dc.b 0                  ; Pri
3147         dc.l audiointname       ; Name
3148         dc.l 0                  ; Data
3149         dc.l Int1_000           ; Code
3150
3151 Audio0IRQ_020
3152         dc.l 0                  ; Succ
3153         dc.l 0                  ; Pred
3154         dc.b NT_INTERRUPT       ; Type
3155         dc.b 0                  ; Pri
3156         dc.l audiointname       ; Name
3157         dc.l 0                  ; Data
3158         dc.l Int0_020           ; Code
3159
3160 Audio1IRQ_020
3161         dc.l 0                  ; Succ
3162         dc.l 0                  ; Pred
3163         dc.b NT_INTERRUPT       ; Type
3164         dc.b 0                  ; Pri
3165         dc.l audiointname       ; Name
3166         dc.l 0                  ; Data
3167         dc.l Int1_020           ; Code
3168
3169
3170 **********************************************************************
3171 * SoftInterrupts
3172 **********************************************************************
3173
3174 Softy0IRQ_000
3175         dc.l 0                                  ; Succ
3176         dc.l 0                                  ; Pred
3177         dc.b NT_INTERRUPT                       ; Type
3178         dc.b 0                                  ; Pri
3179         dc.l audiointname                       ; Name
3180         dc.l 0                                  ; Data
3181         dc.l Soft0_000                          ; Code
3182
3183 Softy1IRQ_000
3184         dc.l 0                                  ; Succ
3185         dc.l 0                                  ; Pred
3186         dc.b NT_INTERRUPT                       ; Type
3187         dc.b 0                                  ; Pri
3188         dc.l audiointname                       ; Name
3189         dc.l 0                                  ; Data
3190         dc.l Soft1_000                          ; Code
3191
3192
3193 Softy0IRQ_020
3194         dc.l 0                                  ; Succ
3195         dc.l 0                                  ; Pred
3196         dc.b NT_INTERRUPT                       ; Type
3197         dc.b 0                                  ; Pri
3198         dc.l audiointname                       ; Name
3199         dc.l 0                                  ; Data
3200         dc.l Soft0_020                          ; Code
3201
3202 Softy1IRQ_020
3203         dc.l 0                                  ; Succ
3204         dc.l 0                                  ; Pred
3205         dc.b NT_INTERRUPT                       ; Type
3206         dc.b 0                                  ; Pri
3207         dc.l audiointname                       ; Name
3208         dc.l 0                                  ; Data
3209         dc.l Soft1_020                          ; Code
3210
3211
3212 **********************************************************************
3213 * AudioRequest
3214 **********************************************************************
3215
3216 AllocIORequest:
3217         dc.l 0                  ; LN_SUCC
3218         dc.l 0                  ; LN_PRED
3219         dc.b 0                  ; LN_TYPE
3220         dc.b ADALLOC_MAXPREC    ; LN_PRI
3221         dc.l 0                  ; LN_NAME
3222
3223         dc.l 0                  ; message reply port
3224         dc.w 0                  ; message len in bytes
3225
3226         dc.l 0                  ; device node pointer
3227         dc.l 0                  ; unit (driver private)
3228         dc.w 0                  ; device command
3229         dc.b 0                  ; special flags
3230         dc.b 0                  ; error or warning code
3231         dc.w 0                  ; ioa_AllocKey
3232         dc.l ChannelMap         ; ioa_Data
3233         dc.l 1                  ; ioa_Length
3234         dc.w 0                  ; ioa_Period
3235         dc.w 0                  ; ioa_Volume
3236         dc.w 0                  ; ioa_Cycles
3237         dc.l 0                  ; LN_SUCC
3238         dc.l 0                  ; LN_PRED
3239         dc.b 0                  ; LN_TYPE
3240         dc.b 0                  ; LN_PRI
3241         dc.l 0                  ; LN_NAME
3242         dc.l 0                  ; message reply port
3243         dc.w 0                  ; message len in bytes
3244
3245
3246 ChannelMap      dc.b $0f                        ; Alle Kanäle belegen
3247
3248 audiointname    dc.b 'XModule Player',0
3249         even
3250
3251         END