home *** CD-ROM | disk | FTP | other *** search
/ Large Pack of OldSkool DOS MOD Trackers / goattracker_2.67_stereo.zip / src / altplayer.s next >
Text File  |  2008-04-01  |  53KB  |  1,737 lines

  1. ;-------------------------------------------------------------------------------
  2. ; GoatTracker V2.63 stereo alternative SID write order playroutine
  3. ;
  4. ; NOTE: This playroutine source code does not fall under the GPL license!
  5. ; Use it, or song binaries created from it freely for any purpose, commercial
  6. ; or noncommercial.
  7. ;
  8. ; NOTE 2: This code is in the format of Magnus Lind's assembler from Exomizer.
  9. ; Does not directly compile on DASM etc.
  10. ;-------------------------------------------------------------------------------
  11.  
  12.         ;Defines will be inserted by the relocator here
  13.  
  14. mt_temp1        = zpbase+0
  15. mt_temp2        = zpbase+1
  16.  
  17.         ;Defines for the music data
  18.         ;Patterndata notes
  19.  
  20. ENDPATT         = $00
  21. INS             = $00
  22. FX              = $40
  23. FXONLY          = $50
  24. NOTE            = $60
  25. REST            = $bd
  26. KEYOFF          = $be
  27. KEYON           = $bf
  28. FIRSTPACKEDREST = $c0
  29. PACKEDREST      = $00
  30.  
  31.         ;Effects
  32.  
  33. DONOTHING       = $00
  34. PORTAUP         = $01
  35. PORTADOWN       = $02
  36. TONEPORTA       = $03
  37. VIBRATO         = $04
  38. SETAD           = $05
  39. SETSR           = $06
  40. SETWAVE         = $07
  41. SETWAVEPTR      = $08
  42. SETPULSEPTR     = $09
  43. SETFILTPTR      = $0a
  44. SETFILTCTRL     = $0b
  45. SETFILTCUTOFF   = $0c
  46. SETMASTERVOL    = $0d
  47. SETFUNKTEMPO    = $0e
  48. SETTEMPO        = $0f
  49.  
  50.         ;Orderlist commands
  51.  
  52. REPEAT          = $d0
  53. TRANSDOWN       = $e0
  54. TRANS           = $f0
  55. TRANSUP         = $f0
  56. LOOPSONG        = $ff
  57.  
  58.         ;Wave,pulse,filttable comands
  59.  
  60. LOOPWAVE        = $ff
  61. LOOPPULSE       = $ff
  62. LOOPFILT        = $ff
  63. SETPULSE        = $80
  64. SETFILTER       = $80
  65. SETCUTOFF       = $00
  66.  
  67.                 .ORG (base)
  68.  
  69.         ;Jump table
  70.  
  71.                 jmp mt_init
  72.                 jmp mt_play
  73.               .IF (SOUNDSUPPORT != 0)
  74.                 jmp mt_playsfx
  75.               .ENDIF
  76.               .IF (VOLSUPPORT != 0)
  77.                 jmp mt_setmastervol
  78.               .ENDIF
  79.  
  80.         ;Author info
  81.  
  82.               .IF (NOAUTHORINFO == 0)
  83.  
  84. authorinfopos   = base + $20
  85. checkpos1:
  86.               .IF ((authorinfopos - checkpos1) > 15)
  87. mt_tick0jumptbl:
  88.                 .BYTE (mt_tick0_0 % 256)
  89.                 .BYTE (mt_tick0_12 % 256)
  90.                 .BYTE (mt_tick0_12 % 256)
  91.                 .BYTE (mt_tick0_34 % 256)
  92.                 .BYTE (mt_tick0_34 % 256)
  93.                 .BYTE (mt_tick0_5 % 256)
  94.                 .BYTE (mt_tick0_6 % 256)
  95.                 .BYTE (mt_tick0_7 % 256)
  96.                 .BYTE (mt_tick0_8 % 256)
  97.                 .BYTE (mt_tick0_9 % 256)
  98.                 .BYTE (mt_tick0_a % 256)
  99.                 .BYTE (mt_tick0_b % 256)
  100.                 .BYTE (mt_tick0_c % 256)
  101.                 .BYTE (mt_tick0_d % 256)
  102.                 .BYTE (mt_tick0_e % 256)
  103.                 .BYTE (mt_tick0_f % 256)
  104.               .ENDIF
  105.  
  106. checkpos2:
  107.               .IF ((authorinfopos - checkpos2) > 4)
  108. mt_effectjumptbl:
  109.                 .BYTE (mt_effect_0 % 256)
  110.                 .BYTE (mt_effect_12 % 256)
  111.                 .BYTE (mt_effect_12 % 256)
  112.                 .BYTE (mt_effect_3 % 256)
  113.                 .BYTE (mt_effect_4 % 256)
  114.               .ENDIF
  115.  
  116. checkpos3:
  117.               .IF ((authorinfopos - checkpos3) > 1)
  118. mt_funktempotbl:
  119.                 .BYTE (8,5)
  120.               .ENDIF
  121.  
  122.         ;This is pretty stupid way of filling left-out space, but .ORG
  123.         ;seemed to bug
  124.  
  125. checkpos4:
  126.               .IF ((authorinfopos - checkpos4) > 0) .BYTE (0) .ENDIF
  127. checkpos5:
  128.               .IF ((authorinfopos - checkpos5) > 0) .BYTE (0) .ENDIF
  129. checkpos6:
  130.               .IF ((authorinfopos - checkpos6) > 0) .BYTE (0) .ENDIF
  131.  
  132. mt_author:
  133.  
  134.                 .BYTE (0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
  135.                 .BYTE (0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
  136.               .ENDIF
  137.  
  138.         ;0 Instrument vibrato
  139.  
  140. mt_tick0_0:
  141.               .IF (NOEFFECTS == 0)
  142.               .IF (NOINSTRVIB == 0)
  143.                 lda mt_insvibparam-1,y
  144.                 jmp mt_tick0_34
  145.               .ELSE
  146.               .IF (NOVIB == 0)
  147.                 jmp mt_tick0_34
  148.               .ENDIF
  149.               .ENDIF
  150.               .ENDIF
  151.  
  152.         ;1,2 Portamentos
  153.  
  154.  
  155. mt_tick0_12:
  156.               .IF (NOVIB == 0)
  157.                 tay
  158.                 lda #$00
  159.                 sta mt_chnvibtime,x
  160.                 tya
  161.               .ENDIF
  162.  
  163.         ;3,4 Toneportamento, Vibrato
  164.  
  165. mt_tick0_34:
  166.               .IF (NOEFFECTS == 0)
  167.               .IF ((NOTONEPORTA == 0) || (NOPORTAMENTO == 0) || (NOVIB == 0))
  168.                 sta mt_chnparam,x
  169.                 lda mt_chnnewfx,x
  170.                 sta mt_chnfx,x
  171.               .ENDIF
  172.                 rts
  173.               .ENDIF
  174.  
  175.         ;5 Set AD
  176.  
  177. mt_tick0_5:
  178.               .IF (NOSETAD == 0)
  179.                 sta mt_chnad,x
  180.                 rts
  181.               .ENDIF
  182.  
  183.         ;6 Set Sustain/Release
  184.  
  185. mt_tick0_6:
  186.               .IF (NOSETSR == 0)
  187.                 sta mt_chnsr,x
  188.                 rts
  189.               .ENDIF
  190.  
  191.         ;7 Set waveform
  192.  
  193. mt_tick0_7:
  194.               .IF (NOSETWAVE == 0)
  195.                 sta mt_chnwave,x
  196.                 rts
  197.               .ENDIF
  198.  
  199.         ;8 Set wavepointer
  200.  
  201. mt_tick0_8:
  202.               .IF (NOSETWAVEPTR == 0)
  203.                 sta mt_chnwaveptr,x
  204.               .IF (NOWAVEDELAY == 0)
  205.                 lda #$00                        ;Make sure possible delayed
  206.                 sta mt_chnwavetime,x            ;waveform execution goes
  207.               .ENDIF                            ;correctly
  208.                 rts
  209.               .ENDIF
  210.  
  211.         ;9 Set pulsepointer
  212.  
  213. mt_tick0_9:
  214.               .IF (NOSETPULSEPTR == 0)
  215.                 sta mt_chnpulseptr,x
  216.                 lda #$00                        ;Reset pulse step duration
  217.                 sta mt_chnpulsetime,x
  218.                 rts
  219.               .ENDIF
  220.  
  221.         ;a Set filtpointer
  222.  
  223. mt_tick0_a:     
  224.               .IF (NOSETFILTPTR == 0)
  225.                 cpx #21
  226.                 bcs mt_tick0_a_sid2
  227.               .IF (NOFILTERMOD == 0)
  228.                 ldy #$00
  229.                 sty mt_filttime+1
  230.               .ENDIF
  231. mt_tick0_a_step:
  232.                 sta mt_filtstep+1
  233.                 rts
  234.               .ENDIF
  235.  
  236. mt_tick0_a_sid2:
  237.               .IF (NOSETFILTPTR == 0)
  238.               .IF (NOFILTERMOD == 0)
  239.                 ldy #$00
  240.                 sty mt_filttime_sid2+1
  241.               .ENDIF
  242. mt_tick0_a_step_sid2:
  243.                 sta mt_filtstep_sid2+1
  244.                 rts
  245.               .ENDIF
  246.  
  247.         ;b Set filtcontrol (channels & resonance)
  248.  
  249. mt_tick0_b:
  250.               .IF (NOSETFILTCTRL == 0)
  251.                 cpx #21
  252.                 bcs mt_tick0_b_sid2
  253.                 sta mt_filtctrl+1
  254.                 cmp #$00
  255.               .IF (NOSETFILTPTR == 0)
  256.                 beq mt_tick0_a_step          ;If 0, stop also step-programming
  257.               .ELSE
  258.                 bne mt_tick0_b_noset
  259.                 sta mt_filtstep+1
  260. mt_tick0_b_noset:
  261.               .ENDIF
  262.                 rts
  263.               .ENDIF
  264.  
  265. mt_tick0_b_sid2:
  266.               .IF (NOSETFILTCTRL == 0)
  267.                 sta mt_filtctrl_sid2+1
  268.                 cmp #$00
  269.               .IF (NOSETFILTPTR == 0)
  270.                 beq mt_tick0_a_step_sid2          ;If 0, stop also step-programming
  271.               .ELSE
  272.                 bne mt_tick0_b_noset_sid2
  273.                 sta mt_filtstep_sid2+1
  274. mt_tick0_b_noset_sid2:
  275.               .ENDIF
  276.                 rts
  277.               .ENDIF
  278.  
  279.  
  280.         ;c Set cutoff
  281.  
  282. mt_tick0_c:
  283.               .IF (NOSETFILTCUTOFF == 0)
  284.                 cpx #21
  285.                 bcs mt_tick0_c_sid2
  286.                 sta mt_filtcutoff+1
  287.                 rts
  288.               .ENDIF
  289.  
  290. mt_tick0_c_sid2:
  291.               .IF (NOSETFILTCUTOFF == 0)
  292.                 sta mt_filtcutoff_sid2+1
  293.                 rts
  294.               .ENDIF
  295.  
  296.         ;d Set mastervolume / timing mark
  297.  
  298. mt_tick0_d:
  299.               .IF (NOSETMASTERVOL == 0)
  300.               .IF (NOAUTHORINFO == 0)
  301.                 cmp #$10
  302.                 bcs mt_tick0_d_timing
  303.               .ENDIF
  304. mt_setmastervol:
  305.                 sta mt_masterfader+1
  306.                 rts
  307.               .IF (NOAUTHORINFO == 0)
  308. mt_tick0_d_timing:
  309.                 sta mt_author+31
  310.                 rts
  311.               .ENDIF
  312.               .ENDIF
  313.  
  314.         ;e Funktempo
  315.  
  316. mt_tick0_e:
  317.               .IF (NOFUNKTEMPO == 0)
  318.                 tay
  319.                 lda mt_speedlefttbl-1,y
  320.                 sta mt_funktempotbl
  321.                 lda mt_speedrighttbl-1,y
  322.                 sta mt_funktempotbl+1
  323.                 lda #$00
  324.               .IF (NOCHANNELTEMPO == 0)
  325.                 beq mt_tick0_f_setglobaltempo
  326.               .ENDIF
  327.               .ENDIF
  328.  
  329.         ;f Set Tempo
  330.  
  331. mt_tick0_f:
  332.               .IF ((NOCHANNELTEMPO == 0) && (NOGLOBALTEMPO == 0))
  333.                 bmi mt_tick0_f_setchantempo     ;Channel or global tempo?
  334.               .ENDIF
  335. mt_tick0_f_setglobaltempo:
  336.               .IF (NOGLOBALTEMPO == 0)
  337.                 sta mt_chntempo
  338.                 sta mt_chntempo+7
  339.                 sta mt_chntempo+14
  340.                 sta mt_chntempo+21
  341.                 sta mt_chntempo+28
  342.                 sta mt_chntempo+35                
  343.                 rts
  344.               .ENDIF
  345. mt_tick0_f_setchantempo:
  346.               .IF (NOCHANNELTEMPO == 0)
  347.                 and #$7f
  348.                 sta mt_chntempo,x
  349.                 rts
  350.               .ENDIF
  351.  
  352.         ;Continuous effect code
  353.  
  354.         ;0 Instrument vibrato
  355.  
  356.               .IF (NOINSTRVIB == 0)
  357. mt_effect_0_delay:
  358.                 dec mt_chnvibdelay,x
  359. mt_effect_0_donothing:
  360.                 jmp mt_done
  361. mt_effect_0:    beq mt_effect_0_donothing         ;Speed 0 = no vibrato at all
  362.                 lda mt_chnvibdelay,x
  363.                 bne mt_effect_0_delay
  364.               .ELSE
  365. mt_effect_0:
  366. mt_effect_0_donothing:
  367.                 jmp mt_done
  368.               .ENDIF
  369.  
  370.         ;4 Vibrato
  371.  
  372. mt_effect_4:
  373.               .IF (NOVIB == 0)
  374.               .IF (NOCALCULATEDSPEED == 0)
  375.                 lda mt_speedlefttbl-1,y
  376.               .IF (NONORMALSPEED == 0)
  377.                 bmi mt_effect_4_nohibyteclear
  378.                 ldy #$00                        ;Clear speed highbyte
  379.                 sty <mt_temp2
  380.               .ENDIF
  381. mt_effect_4_nohibyteclear:
  382.                 and #$7f
  383.                 sta mt_effect_4_speedcmp+1
  384.               .ELSE
  385.                 lda #$00                        ;Clear speed highbyte
  386.                 sta <mt_temp2
  387.               .ENDIF
  388.                 lda mt_chnvibtime,x
  389.                 bmi mt_effect_4_nodir
  390.               .IF (NOCALCULATEDSPEED != 0)
  391.                 cmp mt_speedlefttbl-1,y
  392.               .ELSE
  393. mt_effect_4_speedcmp:
  394.                 cmp #$00
  395.               .ENDIF
  396.                 bcc mt_effect_4_nodir2
  397.                 beq mt_effect_4_nodir
  398.                 eor #$ff
  399. mt_effect_4_nodir:
  400.                 clc
  401. mt_effect_4_nodir2:
  402.                 adc #$02
  403. mt_vibdone:
  404.                 sta mt_chnvibtime,x
  405.                 lsr
  406.                 bcc mt_freqadd
  407.                 bcs mt_freqsub
  408.               .ENDIF
  409.  
  410.         ;1,2,3 Portamentos
  411.  
  412. mt_effect_3:
  413.               .IF (NOTONEPORTA == 0)
  414.                 tya
  415.                 beq mt_effect_3_found           ;Speed $00 = tie note
  416.               .ENDIF
  417. mt_effect_12:
  418.               .IF ((NOTONEPORTA == 0) || (NOPORTAMENTO == 0))
  419.               .IF (NOCALCULATEDSPEED != 0)
  420.                 lda mt_speedlefttbl-1,y
  421.                 sta <mt_temp2
  422.               .ENDIF
  423.               .ENDIF
  424.               .IF (NOPORTAMENTO == 0)
  425.  
  426.               .IF (NOWAVECMD != 0)
  427.                 lda mt_chnfx,x
  428.               .ELSE
  429. mt_effectnum:
  430.                 lda #$00
  431.               .ENDIF
  432.                 cmp #$02
  433.                 bcc mt_freqadd
  434.                 beq mt_freqsub
  435.               .ELSE
  436.               .IF (NOTONEPORTA == 0)
  437.                 sec
  438.               .ENDIF
  439.               .ENDIF
  440.               .IF (NOTONEPORTA == 0)
  441.                 ldy mt_chnnote,y
  442.                 lda mt_chnfreqlo,x              ;Calculate offset to the
  443.                 sbc mt_freqtbllo-FIRSTNOTE,y    ;right frequency
  444.                 pha
  445.                 lda mt_chnfreqhi,x
  446.                 sbc mt_freqtblhi-FIRSTNOTE,y
  447.                 tay
  448.                 pla
  449.                 bcs mt_effect_3_down            ;If positive, have to go down
  450.  
  451. mt_effect_3_up:
  452.                 adc <mt_temp1                   ;Add speed to offset
  453.                 tya                             ;If changes sign, we're done
  454.                 adc <mt_temp2
  455.                 bpl mt_effect_3_found
  456.               .ENDIF
  457.  
  458.  
  459.               .IF ((NOTONEPORTA == 0) || (NOPORTAMENTO == 0) || (NOVIB == 0))
  460. mt_freqadd:
  461.                 lda mt_chnfreqlo,x
  462.                 adc <mt_temp1
  463.                 sta mt_chnfreqlo,x
  464.                 lda mt_chnfreqhi,x
  465.                 adc <mt_temp2
  466.                 jmp mt_storefreqhi
  467.               .ENDIF
  468.  
  469.               .IF (NOTONEPORTA == 0)
  470. mt_effect_3_down:
  471.                 sbc <mt_temp1                   ;Subtract speed from offset
  472.                 tya                             ;If changes sign, we're done
  473.                 sbc <mt_temp2
  474.                 bmi mt_effect_3_found
  475.               .ENDIF
  476.  
  477.               .IF ((NOTONEPORTA == 0) || (NOPORTAMENTO == 0) || (NOVIB == 0))
  478. mt_freqsub:
  479.                 lda mt_chnfreqlo,x
  480.                 sbc <mt_temp1
  481.                 sta mt_chnfreqlo,x
  482.                 lda mt_chnfreqhi,x
  483.                 sbc <mt_temp2
  484.                 jmp mt_storefreqhi
  485.               .ENDIF
  486.  
  487. mt_effect_3_found:
  488.               .IF (NOTONEPORTA == 0)
  489.               .IF (NOCALCULATEDSPEED == 0)
  490.                 lda mt_chnnote,x
  491.                 jmp mt_wavenoteabs
  492.               .ELSE
  493.                 ldy mt_chnnote,y
  494.                 jmp mt_wavenote
  495.               .ENDIF
  496.               .ENDIF
  497.  
  498.         ;Init routine
  499.  
  500. mt_init:
  501.               .IF (NUMSONGS > 1)
  502.                 asl
  503.                 sta mt_init+5
  504.                 asl
  505.                 adc #$00
  506.               .ENDIF
  507.                 sta mt_initsongnum+1
  508.                 rts
  509.  
  510.         ;Play soundeffect -routine
  511.  
  512.               .IF (SOUNDSUPPORT != 0)
  513.         ;Sound FX init routine
  514.  
  515. mt_playsfx:     sta mt_playsfxlo+1
  516.                 sty mt_playsfxhi+1
  517.                 lda mt_chnsfx,x                   ;Need a priority check?
  518.                 beq mt_playsfxok
  519.                 tya                               ;Check address highbyte
  520.                 cmp mt_chnsfxhi,x
  521.                 bcc mt_playsfxskip                ;Lower than current -> skip
  522.                 bne mt_playsfxok                  ;Higher than current -> OK
  523.                 lda mt_playsfxlo+1                ;Check address lowbyte
  524.                 cmp mt_chnsfxlo,x
  525.                 bcc mt_playsfxskip                ;Lower than current -> skip
  526. mt_playsfxok:   lda #$01
  527.                 sta mt_chnsfx,x
  528. mt_playsfxlo:   lda #$00
  529.                 sta mt_chnsfxlo,x
  530. mt_playsfxhi:   lda #$00
  531.                 sta mt_chnsfxhi,x
  532. mt_playsfxskip: rts
  533.               .ENDIF
  534.  
  535.         ;Set mastervolume -routine
  536.  
  537.               .IF ((VOLSUPPORT != 0) && (NOSETMASTERVOL != 0))
  538. mt_setmastervol:
  539.                 sta mt_masterfader+1
  540.                 rts
  541.               .ENDIF
  542.  
  543.         ;Playroutine
  544.  
  545. mt_play:        ldx #$00                        ;Channel index
  546.  
  547.         ;Song initialization
  548.  
  549. mt_initsongnum:
  550.                 ldy #$00
  551.                 bmi mt_filtstep
  552.                 txa
  553.                 ldx #NUMCHANNELS * 14 - 1
  554. mt_resetloop:
  555.                 sta mt_chnsongptr,x             ;Reset sequencer + voice
  556.                 dex                             ;variables on all channels
  557.                 bpl mt_resetloop
  558.                 sta SIDBASE+$15                       ;Reset filter cutoff lowbyte
  559.                 sta SID2BASE+$15
  560.                 sta mt_filtctrl+1             ;Switch filter off & reset
  561.                 sta mt_filtctrl_sid2+1
  562.               .IF (NOFILTER == 0)
  563.                 sta mt_filtstep+1             ;step-programming
  564.                 sta mt_filtstep_sid2+1
  565.               .ENDIF
  566.                 stx mt_initsongnum+1          ;Reset initflag
  567.                 tax
  568.                 jsr mt_initchn
  569.                 ldx #$07
  570.                 jsr mt_initchn
  571.                 ldx #$0e
  572.                 jsr mt_initchn
  573.                 ldx #$15
  574.                 jsr mt_initchn
  575.                 ldx #$1c
  576.                 jsr mt_initchn
  577.                 ldx #$23
  578. mt_initchn:
  579.               .IF (NUMSONGS > 1)
  580.                 tya
  581.                 iny
  582.                 sta mt_chnsongnum,x             ;Store index to songtable
  583.               .ENDIF
  584. mt_defaulttempo:
  585.                 lda #DEFAULTTEMPO               ;Set default tempo
  586.                 sta mt_chntempo,x
  587.                 lda #$01
  588.                 sta mt_chncounter,x             ;Reset counter
  589.                 sta mt_chninstr,x               ;Reset instrument
  590.                 jmp mt_loadregswave
  591.  
  592.         ;Filter execution
  593.  
  594. mt_filtstep:
  595.               .IF (NOFILTER == 0)
  596.                 ldy #$00                        ;See if filter stopped
  597.                 beq mt_filtdone
  598.               .IF (NOFILTERMOD == 0)
  599. mt_filttime:
  600.                 lda #$00                        ;See if time left for mod.
  601.                 bne mt_filtmod                  ;step
  602.               .ENDIF
  603. mt_newfiltstep:
  604.                 lda mt_filttimetbl-1,y          ;$80-> = set filt parameters
  605.                 beq mt_setcutoff                ;$00 = set cutoff
  606.               .IF (NOFILTERMOD == 0)
  607.                 bpl mt_newfiltmod
  608.               .ENDIF
  609. mt_setfilt:
  610.                 asl                             ;Set passband
  611.                 sta mt_filttype+1
  612.                 lda mt_filtspdtbl-1,y           ;Set resonance/channel
  613.                 sta mt_filtctrl+1
  614.                 lda mt_filttimetbl,y            ;Check for cutoff setting
  615.                 bne mt_nextfiltstep2            ;following immediately
  616. mt_setcutoff2:
  617.                 iny
  618. mt_setcutoff:
  619.                 lda mt_filtspdtbl-1,y           ;Take cutoff value
  620.                 sta mt_filtcutoff+1
  621.               .IF (NOFILTERMOD == 0)
  622.                 jmp mt_nextfiltstep
  623. mt_newfiltmod:
  624.                 sta mt_filttime+1               ;$01-$7f = new modulation step
  625. mt_filtmod:   
  626.                 lda mt_filtspdtbl-1,y           ;Take filt speed
  627.                 clc
  628.                 adc mt_filtcutoff+1
  629.                 sta mt_filtcutoff+1
  630.                 dec mt_filttime+1
  631.                 bne mt_storecutoff
  632.               .ENDIF
  633. mt_nextfiltstep:
  634.                 lda mt_filttimetbl,y           ;Jump in filttable?
  635. mt_nextfiltstep2:
  636.                 cmp #LOOPFILT
  637.                 iny
  638.                 tya
  639.                 bcc mt_nofiltjump
  640.                 lda mt_filtspdtbl-1,y          ;Take jump point
  641. mt_nofiltjump:
  642.                 sta mt_filtstep+1
  643. mt_filtdone:
  644. mt_filtcutoff:
  645.                 lda #$00
  646. mt_storecutoff:
  647.                 sta SIDBASE+$16
  648.               .ENDIF
  649. mt_filtctrl:
  650.                 lda #$00
  651.                 sta SIDBASE+$17
  652. mt_filttype:
  653.                 lda #$00
  654. mt_masterfader:
  655.                 ora #$0f                        ;Master volume fader
  656.                 sta SIDBASE+$18
  657.  
  658.         ;Second filter execution
  659.  
  660. mt_filtstep_sid2:
  661.               .IF (NOFILTER == 0)
  662.                 ldy #$00                        ;See if filter stopped
  663.                 beq mt_filtdone_sid2
  664.               .IF (NOFILTERMOD == 0)
  665. mt_filttime_sid2:
  666.                 lda #$00                        ;See if time left for mod.
  667.                 bne mt_filtmod_sid2                  ;step
  668.               .ENDIF
  669. mt_newfiltstep_sid2:
  670.                 lda mt_filttimetbl-1,y          ;$80-> = set filt parameters
  671.                 beq mt_setcutoff_sid2                ;$00 = set cutoff
  672.               .IF (NOFILTERMOD == 0)
  673.                 bpl mt_newfiltmod_sid2
  674.               .ENDIF
  675. mt_setfilt_sid2:
  676.                 asl                             ;Set passband
  677.                 sta mt_filttype_sid2+1
  678.                 lda mt_filtspdtbl-1,y           ;Set resonance/channel
  679.                 sta mt_filtctrl_sid2+1
  680.                 lda mt_filttimetbl,y            ;Check for cutoff setting
  681.                 bne mt_nextfiltstep2_sid2            ;following immediately
  682. mt_setcutoff2_sid2:
  683.                 iny
  684. mt_setcutoff_sid2:
  685.                 lda mt_filtspdtbl-1,y           ;Take cutoff value
  686.                 sta mt_filtcutoff_sid2+1
  687.               .IF (NOFILTERMOD == 0)
  688.                 jmp mt_nextfiltstep_sid2
  689. mt_newfiltmod_sid2:
  690.                 sta mt_filttime_sid2+1               ;$01-$7f = new modulation step
  691. mt_filtmod_sid2:
  692.                 lda mt_filtspdtbl-1,y           ;Take filt speed
  693.                 clc
  694.                 adc mt_filtcutoff_sid2+1
  695.                 sta mt_filtcutoff_sid2+1
  696.                 dec mt_filttime_sid2+1
  697.                 bne mt_storecutoff_sid2
  698.               .ENDIF
  699. mt_nextfiltstep_sid2:
  700.                 lda mt_filttimetbl,y           ;Jump in filttable?
  701. mt_nextfiltstep2_sid2:
  702.                 cmp #LOOPFILT
  703.                 iny
  704.                 tya
  705.                 bcc mt_nofiltjump_sid2
  706.                 lda mt_filtspdtbl-1,y          ;Take jump point
  707. mt_nofiltjump_sid2:
  708.                 sta mt_filtstep_sid2+1
  709. mt_filtdone_sid2:
  710. mt_filtcutoff_sid2:
  711.                 lda #$00
  712. mt_storecutoff_sid2:
  713.                 sta SID2BASE+$16
  714.               .ENDIF
  715. mt_filtctrl_sid2:
  716.                 lda #$00
  717.                 sta SID2BASE+$17
  718. mt_filttype_sid2:
  719.                 lda #$00
  720.                 ora mt_masterfader+1           ;Master volume fader
  721.                 sta SID2BASE+$18
  722.  
  723.         ;Channel execution
  724.  
  725.                 jsr mt_execchn
  726.                 ldx #$07
  727.                 jsr mt_execchn
  728.                 ldx #$0e
  729.                 jsr mt_execchn
  730.                 ldx #$15
  731.                 jsr mt_execchn
  732.                 ldx #$1c
  733.                 jsr mt_execchn
  734.                 ldx #$23
  735.  
  736. mt_execchn:
  737.                 dec mt_chncounter,x               ;See if tick 0
  738.                 beq mt_tick0
  739.  
  740.         ;Ticks 1-n
  741.  
  742. mt_notick0:
  743.                 bpl mt_effects
  744.                 lda mt_chntempo,x               ;Reload tempo if negative
  745.  
  746.               .IF (NOFUNKTEMPO == 0)
  747.                 cmp #$02
  748.                 bcs mt_nofunktempo              ;Funktempo: bounce between
  749.                 tay                             ;funktable indexes 0,1
  750.                 eor #$01
  751.                 sta mt_chntempo,x
  752.                 lda mt_funktempotbl,y
  753.                 sbc #$00
  754.               .ENDIF
  755.  
  756. mt_nofunktempo:
  757.                 sta mt_chncounter,x
  758. mt_effects:
  759.                 jmp mt_waveexec
  760.  
  761.         ;Sequencer repeat
  762.  
  763. mt_repeat:
  764.               .IF (NOREPEAT == 0)
  765.                 sbc #REPEAT
  766.                 inc mt_chnrepeat,x
  767.                 cmp mt_chnrepeat,x
  768.                 bne mt_nonewpatt
  769. mt_repeatdone:
  770.                 lda #$00
  771.                 sta mt_chnrepeat,x
  772.                 beq mt_repeatdone2
  773.               .ENDIF
  774.  
  775.         ;Tick 0
  776.  
  777. mt_tick0:
  778.               .IF (NOEFFECTS == 0)
  779.                 ldy mt_chnnewfx,y               ;Setup tick 0 FX jumps
  780.                 lda mt_tick0jumptbl,y
  781.                 sta mt_tick0jump1+1
  782.                 sta mt_tick0jump2+1
  783.               .ENDIF
  784.  
  785.         ;Sequencer advance
  786.  
  787. mt_checknewpatt:
  788.                 lda mt_chnpattptr,x             ;Fetch next pattern?
  789.                 bne mt_nonewpatt
  790. mt_sequencer:
  791.                 ldy mt_chnsongnum,y
  792.                 lda mt_songtbllo,y              ;Get address of sequence
  793.                 sta <mt_temp1
  794.                 lda mt_songtblhi,y
  795.                 sta <mt_temp2
  796.                 ldy mt_chnsongptr,y
  797.                 lda (mt_temp1),y                ;Get pattern from sequence
  798.                 cmp #LOOPSONG                   ;Check for loop
  799.                 bcc mt_noloop
  800.                 iny
  801.                 lda (mt_temp1),y
  802.                 tay
  803.                 lda (mt_temp1),y
  804. mt_noloop:
  805.               .IF (NOTRANS == 0)
  806.                 cmp #TRANSDOWN                  ;Check for transpose
  807.                 bcc mt_notrans
  808.                 sbc #TRANS
  809.                 sta mt_chntrans,x
  810.                 iny
  811.                 lda (mt_temp1),y
  812.               .ENDIF
  813. mt_notrans:
  814.               .IF (NOREPEAT == 0)
  815.                 cmp #REPEAT                     ;Check for repeat
  816.                 bcs mt_repeat
  817.               .ENDIF
  818.                 sta mt_chnpattnum,x             ;Store pattern number
  819. mt_repeatdone2:
  820.                 iny
  821.                 tya
  822.                 sta mt_chnsongptr,x             ;Store songposition
  823.  
  824.         ;New note start
  825.  
  826. mt_nonewpatt:
  827.                 ldy mt_chninstr,y
  828.               .IF (FIXEDPARAMS == 0)
  829.                 lda mt_insgatetimer-1,y
  830.                 sta mt_chngatetimer,x
  831.               .ENDIF
  832.                 lda mt_chnnewnote,x             ;Test new note init flag
  833.                 beq mt_nonewnoteinit
  834. mt_newnoteinit:
  835.                 sec
  836.                 sbc #NOTE
  837.                 sta mt_chnnote,x
  838.                 lda #$00
  839.               .IF (NOEFFECTS == 0)
  840.               .IF ((NOTONEPORTA == 0) || (NOPORTAMENTO == 0) || (NOVIB == 0))
  841.                 sta mt_chnfx,x                  ;Reset effect
  842.               .ENDIF
  843.               .ENDIF
  844.                 sta mt_chnnewnote,x             ;Reset newnote action
  845.               .IF (NOINSTRVIB == 0)
  846.                 lda mt_insvibdelay-1,y          ;Load instrument vibrato
  847.                 sta mt_chnvibdelay,x
  848.               .IF (NOEFFECTS == 0)
  849.                 lda mt_insvibparam-1,y
  850.                 sta mt_chnparam,x
  851.               .ENDIF
  852.               .ENDIF
  853.               .IF (NOTONEPORTA == 0)
  854.                 lda mt_chnnewfx,x               ;If toneportamento, skip
  855.                 cmp #TONEPORTA                  ;most of note init
  856.                 beq mt_nonewnoteinit
  857.               .ENDIF
  858.  
  859.                 lda mt_insad-1,y                ;Load Attack/Decay
  860.                 sta mt_chnad,x
  861.                 lda mt_inssr-1,y                ;Load Sustain/Release
  862.                 sta mt_chnsr,x
  863.  
  864.               .IF (NOPULSE == 0)
  865.                 lda mt_inspulseptr-1,y          ;Load pulseptr (if nonzero)
  866.                 beq mt_skippulse
  867.                 sta mt_chnpulseptr,x
  868.               .IF (NOPULSEMOD == 0)
  869.                 lda #$00                        ;Reset pulse step duration
  870.                 sta mt_chnpulsetime,x
  871.               .ENDIF
  872.               .ENDIF
  873. mt_skippulse:
  874.               .IF (NOFILTER == 0)
  875.                 cpx #21
  876.                 lda mt_insfiltptr-1,y         ;Load filtptr (if nonzero)
  877.                 beq mt_skipfilt
  878.                 bcs mt_loadfilt_sid2
  879.  
  880. mt_loadfilt:
  881.                 sta mt_filtstep+1
  882.               .IF (NOFILTERMOD == 0)
  883.                 lda #$00
  884.                 sta mt_filttime+1
  885.               .ENDIF
  886.                 bcc mt_skipfilt
  887. mt_loadfilt_sid2:
  888.                 sta mt_filtstep_sid2+1
  889.               .IF (NOFILTERMOD == 0)
  890.                 lda #$00
  891.                 sta mt_filttime_sid2+1
  892.               .ENDIF
  893.               .ENDIF
  894. mt_skipfilt:
  895.               .IF (FIXEDPARAMS == 0)
  896.                 lda mt_insfirstwave-1,y         ;Load first frame waveform
  897.               .IF (NOFIRSTWAVECMD == 0)
  898.                 beq mt_skipwave
  899.                 cmp #$fe
  900.                 bcs mt_skipwave2                ;Skip waveform but load gate
  901.               .ENDIF
  902.               .ELSE
  903.                 lda #FIRSTWAVEPARAM
  904.               .ENDIF
  905.                 sta mt_chnwave,x
  906.               .IF ((NUMLEGATOINSTR > 0) || (NOFIRSTWAVECMD == 0))
  907.                 lda #$ff
  908. mt_skipwave2:
  909.                 sta mt_chngate,x                ;Reset gateflag
  910.               .ELSE
  911.                 inc mt_chngate,x
  912.               .ENDIF
  913. mt_skipwave:
  914.                 lda mt_inswaveptr-1,y           ;Load waveptr
  915.                 sta mt_chnwaveptr,x
  916.               .IF (NOEFFECTS == 0)
  917.                 lda mt_chnnewparam,x            ;Execute tick 0 FX after
  918. mt_tick0jump1:
  919.                 jsr mt_tick0_0                  ;newnote init
  920.               .ENDIF
  921.                 jmp mt_loadregs
  922.  
  923.               .IF (NOWAVECMD == 0)
  924. mt_wavecmd:
  925.                 jmp mt_execwavecmd
  926.               .ENDIF
  927.  
  928.         ;Tick 0 effect execution
  929.  
  930. mt_nonewnoteinit:
  931.               .IF (NOEFFECTS == 0)
  932.                 lda mt_chnnewparam,x            ;No new note init: exec tick 0
  933. mt_tick0jump2:
  934.                 jsr mt_tick0_0                  ;FX, and wavetable afterwards
  935.               .ENDIF
  936.  
  937.         ;Wavetable execution
  938.  
  939. mt_waveexec:
  940.                 ldy mt_chnwaveptr,y
  941.                 beq mt_wavedone
  942.                 lda mt_wavetbl-1,y
  943.               .IF (NOWAVEDELAY == 0)
  944.                 cmp #$10                        ;0-15 used as delay
  945.                 bcs mt_nowavedelay              ;+ no wave change
  946.                 cmp mt_chnwavetime,x
  947.                 beq mt_nowavechange
  948.                 inc mt_chnwavetime,x
  949.                 bne mt_wavedone
  950. mt_nowavedelay:
  951.                 sbc #$10
  952.               .ELSE
  953.                 beq mt_nowavechange
  954.               .ENDIF
  955.               .IF (NOWAVECMD == 0)
  956.                 cmp #$e0
  957.                 bcs mt_nowavechange
  958.               .ENDIF
  959.                 sta mt_chnwave,x
  960. mt_nowavechange:
  961.                 lda mt_wavetbl,y
  962.                 cmp #LOOPWAVE                  ;Check for wavetable jump
  963.                 iny
  964.                 tya
  965.                 bcc mt_nowavejump
  966.               .IF (NOWAVECMD != 0)
  967.                 clc
  968.               .ENDIF
  969.                 lda mt_notetbl-1,y
  970. mt_nowavejump:
  971.                 sta mt_chnwaveptr,x
  972.               .IF (NOWAVEDELAY == 0)
  973.                 lda #$00
  974.                 sta mt_chnwavetime,x
  975.               .ENDIF
  976.  
  977.               .IF (NOWAVECMD == 0)
  978.                 lda mt_wavetbl-2,y
  979.                 cmp #$e0
  980.                 bcs mt_wavecmd
  981.               .ENDIF
  982.  
  983.                 lda mt_notetbl-2,y
  984.  
  985.               .IF ((NOTONEPORTA == 0) || (NOPORTAMENTO == 0) || (NOVIB == 0))
  986.                 bne mt_wavefreq                 ;No frequency-change?
  987.  
  988.         ;No frequency-change / continuous effect execution
  989.  
  990. mt_wavedone:
  991.               .IF (REALTIMEOPTIMIZATION != 0)
  992.                 lda mt_chncounter,x             ;No continuous effects on tick0
  993.               .IF (PULSEOPTIMIZATION != 0)
  994.                 beq mt_gatetimer
  995.               .ELSE
  996.                 beq mt_done
  997.               .ENDIF
  998.               .ENDIF
  999.               .IF (NOEFFECTS == 0)
  1000.                 ldy mt_chnfx,y
  1001.               .IF (NOWAVECMD == 0)
  1002.               .IF (.DEFINED(mt_effectnum))
  1003.                 sty mt_effectnum+1
  1004.               .ENDIF
  1005.               .ENDIF
  1006.                 lda mt_effectjumptbl,y
  1007.                 sta mt_effectjump+1
  1008.                 ldy mt_chnparam,y
  1009.               .ELSE
  1010.                 ldy mt_chninstr,y
  1011.                 lda mt_insvibparam-1,y
  1012.                 tay
  1013.               .ENDIF
  1014. mt_setspeedparam:
  1015.               .IF (NOCALCULATEDSPEED != 0)
  1016.                 lda mt_speedrighttbl-1,y
  1017.                 sta <mt_temp1
  1018.               .ELSE
  1019.               .IF (NONORMALSPEED == 0)
  1020.                 lda mt_speedlefttbl-1,y
  1021.                 bmi mt_calculatedspeed
  1022. mt_normalspeed:
  1023.                 sta <mt_temp2
  1024.                 lda mt_speedrighttbl-1,y
  1025.                 sta <mt_temp1
  1026.                 jmp mt_effectjump
  1027.               .ELSE
  1028.               .IF (NOZEROSPEED == 0)
  1029.                 bne mt_calculatedspeed
  1030. mt_zerospeed:
  1031.                 sty <mt_temp1
  1032.                 sty <mt_temp2
  1033.                 beq mt_effectjump
  1034.               .ENDIF
  1035.               .ENDIF
  1036. mt_calculatedspeed:
  1037.                 lda mt_speedrighttbl-1,y
  1038.                 sta mt_cscount+1
  1039.                 sty mt_csresty+1
  1040.                 ldy mt_chnlastnote,y
  1041.                 lda mt_freqtbllo+1-FIRSTNOTE,y
  1042.                 sec
  1043.                 sbc mt_freqtbllo-FIRSTNOTE,y
  1044.                 sta <mt_temp1
  1045.                 lda mt_freqtblhi+1-FIRSTNOTE,y
  1046.                 sbc mt_freqtblhi-FIRSTNOTE,y
  1047. mt_cscount:     ldy #$00
  1048.                 beq mt_csresty
  1049. mt_csloop:      lsr
  1050.                 ror <mt_temp1
  1051.                 dey
  1052.                 bne mt_csloop
  1053. mt_csresty:     ldy #$00
  1054.                 sta <mt_temp2
  1055.               .ENDIF
  1056. mt_effectjump:
  1057.                 jmp mt_effect_0
  1058.               .ELSE
  1059.                 beq mt_wavedone
  1060.               .ENDIF
  1061.               
  1062.         ;Setting note frequency
  1063.  
  1064. mt_wavefreq:
  1065.                 bpl mt_wavenoteabs
  1066.                 adc mt_chnnote,x
  1067.                 and #$7f
  1068. mt_wavenoteabs:
  1069.               .IF (NOCALCULATEDSPEED == 0)
  1070.                 sta mt_chnlastnote,x
  1071.               .ENDIF
  1072.                 tay
  1073. mt_wavenote:
  1074.               .IF (NOVIB == 0)
  1075.                 lda #$00                        ;Reset vibrato phase
  1076.                 sta mt_chnvibtime,x
  1077.               .ENDIF
  1078.                 lda mt_freqtbllo-FIRSTNOTE,y
  1079.                 sta mt_chnfreqlo,x
  1080.                 lda mt_freqtblhi-FIRSTNOTE,y
  1081. mt_storefreqhi:
  1082.                 sta mt_chnfreqhi,x
  1083.  
  1084.  
  1085.         ;Check for new note fetch
  1086.  
  1087.               .IF ((NOTONEPORTA != 0) && (NOPORTAMENTO != 0) && (NOVIB != 0))
  1088. mt_wavedone:
  1089.               .ENDIF
  1090. mt_done:
  1091.               .IF (PULSEOPTIMIZATION != 0)
  1092.                 lda mt_chncounter,x             ;Check for gateoff timer
  1093. mt_gatetimer:
  1094.               .IF (FIXEDPARAMS == 0)
  1095.                 cmp mt_chngatetimer,x
  1096.               .ELSE
  1097.                 cmp #GATETIMERPARAM
  1098.               .ENDIF
  1099.  
  1100.                 beq mt_getnewnote               ;Fetch new notes if equal
  1101.               .ENDIF
  1102.  
  1103.         ;Pulse execution
  1104.               .IF (NOPULSE == 0)
  1105. mt_pulseexec:
  1106.                 ldy mt_chnpulseptr,y            ;See if pulse stopped
  1107.                 beq mt_pulseskip
  1108.               .IF (PULSEOPTIMIZATION != 0)
  1109.                 ora mt_chnpattptr,x             ;Skip when sequencer executed
  1110.                 beq mt_pulseskip
  1111.               .ENDIF
  1112.               .IF (NOPULSEMOD == 0)
  1113.                 lda mt_chnpulsetime,x           ;Pulse step counter time left?
  1114.                 bne mt_pulsemod
  1115.               .ENDIF
  1116. mt_newpulsestep:
  1117.                 lda mt_pulsetimetbl-1,y         ;Set pulse, or new modulation
  1118.               .IF (NOPULSEMOD == 0)
  1119.                 bpl mt_newpulsemod              ;step?
  1120.               .ENDIF
  1121. mt_setpulse:
  1122.               .IF (SIMPLEPULSE == 0)
  1123.                 sta mt_chnpulsehi,x             ;Highbyte
  1124.               .ENDIF
  1125.                 lda mt_pulsespdtbl-1,y          ;Lowbyte
  1126.                 sta mt_chnpulselo,x
  1127.               .IF (NOPULSEMOD == 0)
  1128.                 jmp mt_nextpulsestep
  1129. mt_newpulsemod:
  1130.                 sta mt_chnpulsetime,x
  1131. mt_pulsemod:
  1132.               .IF (SIMPLEPULSE == 0)
  1133.                 lda mt_pulsespdtbl-1,y          ;Take pulse speed
  1134.                 clc
  1135.                 bpl mt_pulseup
  1136.                 dec mt_chnpulsehi,x
  1137. mt_pulseup:
  1138.                 adc mt_chnpulselo,x             ;Add pulse lowbyte
  1139.                 sta mt_chnpulselo,x
  1140.                 bcc mt_pulsenotover
  1141.                 inc mt_chnpulsehi,x
  1142.  
  1143. mt_pulsenotover:
  1144.               .ELSE
  1145.                 lda mt_chnpulselo,x
  1146.                 clc
  1147.                 adc mt_pulsespdtbl-1,y
  1148.                 adc #$00
  1149.                 sta mt_chnpulselo,x
  1150.  
  1151.               .ENDIF
  1152.                 dec mt_chnpulsetime,x
  1153.                 bne mt_pulsedone2
  1154.               .ENDIF
  1155.  
  1156. mt_nextpulsestep:
  1157.                 lda mt_pulsetimetbl,y           ;Jump in pulsetable?
  1158.                 cmp #LOOPPULSE
  1159.                 iny
  1160.                 tya
  1161.                 bcc mt_nopulsejump
  1162.                 lda mt_pulsespdtbl-1,y          ;Take jump point
  1163. mt_nopulsejump:
  1164.                 sta mt_chnpulseptr,x
  1165. mt_pulsedone:
  1166. mt_pulsedone2:
  1167. mt_pulseskip:
  1168.               .ENDIF
  1169.  
  1170.               .IF (PULSEOPTIMIZATION == 0)
  1171.                 lda mt_chncounter,x             ;Check for gateoff timer
  1172. mt_gatetimer:
  1173.               .IF (FIXEDPARAMS == 0)
  1174.                 cmp mt_chngatetimer,x
  1175.               .ELSE
  1176.                 cmp #GATETIMERPARAM
  1177.               .ENDIF
  1178.  
  1179.                 beq mt_getnewnote               ;Fetch new notes if equal
  1180.               .ENDIF
  1181.  
  1182.                 jmp mt_loadregs
  1183.  
  1184.         ;New note fetch
  1185.  
  1186. mt_getnewnote:
  1187.                 ldy mt_chnpattnum,y
  1188.                 lda mt_patttbllo,y
  1189.                 sta <mt_temp1
  1190.                 lda mt_patttblhi,y
  1191.                 sta <mt_temp2
  1192.                 ldy mt_chnpattptr,y
  1193.                 lda (mt_temp1),y
  1194.                 cmp #FX
  1195.                 bcc mt_instr                    ;Instr. change
  1196.               .IF (NOEFFECTS == 0)
  1197.                 cmp #NOTE
  1198.                 bcc mt_fx                       ;FX
  1199.               .ENDIF
  1200.                 cmp #FIRSTPACKEDREST
  1201.                 bcc mt_note                     ;Note only
  1202.  
  1203.         ;Packed rest handling
  1204.  
  1205. mt_packedrest:
  1206.                 lda mt_chnpackedrest,x
  1207.                 bne mt_packedrestnonew
  1208.                 lda (mt_temp1),y
  1209. mt_packedrestnonew:
  1210.                 adc #$00
  1211.                 sta mt_chnpackedrest,x
  1212.                 beq mt_rest
  1213.                 bne mt_loadregs
  1214.  
  1215.         ;Instrument change
  1216.  
  1217. mt_instr:
  1218.                 sta mt_chninstr,x               ;Instrument change, followed
  1219.                 iny
  1220.                 lda (mt_temp1),y                ;by either FX or note
  1221.  
  1222.               .IF (NOEFFECTS == 0)
  1223.                 cmp #NOTE
  1224.                 bcs mt_note
  1225.  
  1226.         ;Effect change
  1227.  
  1228. mt_fx:
  1229.                 cmp #FXONLY                     ;Note follows?
  1230.                 and #$0f
  1231.                 sta mt_chnnewfx,x
  1232.                 beq mt_fx_noparam               ;Effect 0 - no param.
  1233.                 iny
  1234.                 lda (mt_temp1),y
  1235.                 sta mt_chnnewparam,x
  1236. mt_fx_noparam:
  1237.                 bcs mt_rest
  1238. mt_fx_getnote:
  1239.                 iny
  1240.                 lda (mt_temp1),y
  1241.               .ENDIF
  1242.  
  1243.         ;Note handling
  1244.  
  1245. mt_note:
  1246.                 cmp #REST                   ;Rest or gateoff/on?
  1247.               .IF (NOGATE == 0)
  1248.                 bcc mt_normalnote
  1249.               .ENDIF
  1250.                 beq mt_rest
  1251. mt_gate:
  1252.               .IF (NOGATE == 0)
  1253.                 ora #$f0
  1254.                 bne mt_setgate
  1255.               .ENDIF
  1256.  
  1257.         ;Prepare for note start; perform hardrestart
  1258.  
  1259. mt_normalnote:
  1260.               .IF (NOTRANS == 0)
  1261.                 adc mt_chntrans,x
  1262.               .ENDIF
  1263.                 sta mt_chnnewnote,x
  1264.               .IF (NOTONEPORTA == 0)
  1265.                 lda mt_chnnewfx,x           ;If toneportamento, no gateoff
  1266.                 cmp #TONEPORTA
  1267.                 beq mt_rest
  1268.               .ENDIF
  1269.               .IF (((NUMHRINSTR > 0) && (NUMNOHRINSTR > 0)) || (NUMLEGATOINSTR > 0))
  1270.                 lda mt_chninstr,x
  1271.                 cmp #FIRSTNOHRINSTR         ;Instrument order:
  1272.               .IF (NUMLEGATOINSTR > 0)
  1273.                 bcs mt_nohr_legato          ;With HR - no HR - legato
  1274.               .ELSE
  1275.                 bcs mt_skiphr
  1276.               .ENDIF
  1277.               .ENDIF
  1278.               .IF (NUMHRINSTR > 0)
  1279.                 lda #ADPARAM                ;Hard restart
  1280.                 sta mt_chnad,x
  1281.                 lda #SRPARAM
  1282.                 sta mt_chnsr,x
  1283.               .ENDIF
  1284. mt_skiphr:
  1285.                 lda #$fe
  1286. mt_setgate:
  1287.                 sta mt_chngate,x
  1288.  
  1289.         ;Check for end of pattern
  1290.  
  1291. mt_rest:
  1292.                 iny
  1293.                 lda (mt_temp1),y
  1294.                 beq mt_endpatt
  1295.                 tya
  1296. mt_endpatt:
  1297.                 sta mt_chnpattptr,x
  1298.  
  1299.         ;Load voice registers
  1300.  
  1301. mt_loadregs:
  1302.               .IF (SOUNDSUPPORT != 0)
  1303.                 ldy mt_chnsfx,y
  1304.                 bne mt_sfxexec
  1305.               .ENDIF
  1306.  
  1307. mt_loadregswave:
  1308.                 cpx #21
  1309.                 bcs mt_loadregswave_sid2
  1310.  
  1311. mt_loadregswave_sid1:
  1312.                 lda mt_chnwave,x
  1313.                 and mt_chngate,x
  1314.                 sta SIDBASE+$04,x
  1315.                 lda mt_chnfreqlo,x
  1316.                 sta SIDBASE+$00,x
  1317.                 lda mt_chnfreqhi,x
  1318.                 sta SIDBASE+$01,x
  1319.                 lda mt_chnpulselo,x
  1320.               .IF (SIMPLEPULSE == 0)
  1321.                 sta SIDBASE+$02,x
  1322.                 lda mt_chnpulsehi,x
  1323.                 sta SIDBASE+$03,x
  1324.               .ELSE
  1325.                 sta SIDBASE+$02,x
  1326.                 sta SIDBASE+$03,x
  1327.               .ENDIF
  1328.               .IF (SOUNDSUPPORT != 0)
  1329.                 lda mt_chnsfx,x
  1330.                 bne mt_loadskipadsr
  1331.               .ENDIF
  1332.                 lda mt_chnad,x
  1333.                 sta SIDBASE+$05,x
  1334.                 lda mt_chnsr,x
  1335.                 sta SIDBASE+$06,x
  1336. mt_loadskipadsr:
  1337.                 rts
  1338.  
  1339.  
  1340.               .IF (NUMLEGATOINSTR > 0)
  1341. mt_nohr_legato:
  1342.                 cmp #FIRSTLEGATOINSTR
  1343.                 bcc mt_skiphr
  1344.                 bcs mt_rest
  1345.               .ENDIF
  1346.  
  1347. mt_loadregswave_sid2:
  1348.                 lda mt_chnwave,x
  1349.                 and mt_chngate,x
  1350.                 sta SID2BASE-21+$04,x
  1351.                 lda mt_chnfreqlo,x
  1352.                 sta SID2BASE-21+$00,x
  1353.                 lda mt_chnfreqhi,x
  1354.                 sta SID2BASE-21+$01,x
  1355.                 lda mt_chnpulselo,x
  1356.               .IF (SIMPLEPULSE == 0)
  1357.                 sta SID2BASE-21+$02,x
  1358.                 lda mt_chnpulsehi,x
  1359.                 sta SID2BASE-21+$03,x
  1360.               .ELSE
  1361.                 sta SID2BASE-21+$02,x
  1362.                 sta SID2BASE-21+$03,x
  1363.               .ENDIF
  1364.               .IF (SOUNDSUPPORT != 0)
  1365.                 lda mt_chnsfx,x
  1366.                 bne mt_loadskipadsr_sid2
  1367.               .ENDIF
  1368.                 lda mt_chnad,x
  1369.                 sta SID2BASE-21+$05,x
  1370.                 lda mt_chnsr,x
  1371.                 sta SID2BASE-21+$06,x
  1372. mt_loadskipadsr_sid2:
  1373.                 rts
  1374.  
  1375.         ;Sound FX code
  1376.  
  1377.               .IF (SOUNDSUPPORT != 0)
  1378.  
  1379. mt_sfxexec:     lda mt_chnsfxlo,x
  1380.                 sta <mt_temp1
  1381.                 lda mt_chnsfxhi,x
  1382.                 sta <mt_temp2
  1383.                 lda #$fe
  1384.                 sta mt_chngate,x
  1385.                 lda #$00
  1386.                 sta mt_chnwaveptr,x
  1387.                 inc mt_chnsfx,x
  1388.                 cpx #21
  1389.                 bcs mt_sfxexec_sid2
  1390.  
  1391.                 cpy #$02
  1392.                 beq mt_sfxexec_frame0
  1393.                 bcs mt_sfxexec_framen
  1394.                 sta SIDBASE+$05,x                ;Hardrestart before sound FX
  1395.                 sta SIDBASE+$06,x                ;begins
  1396.                 jmp mt_loadregswave_sid1
  1397. mt_sfxexec_frame0:
  1398.                 tay
  1399.                 lda (mt_temp1),y           ;Load ADSR
  1400.                 sta SIDBASE+$05,x
  1401.                 iny
  1402.                 lda (mt_temp1),y
  1403.                 sta SIDBASE+$06,x
  1404.                 iny
  1405.                 lda (mt_temp1),y           ;Load pulse
  1406.                 sta SIDBASE+$02,x
  1407.                 sta SIDBASE+$03,x
  1408.                 lda #$09                   ;Testbit
  1409. mt_sfxexec_wavechg:
  1410.                 sta mt_chnwave,x
  1411.                 sta SIDBASE+$04,x
  1412. mt_sfxexec_done:
  1413.                 rts
  1414. mt_sfxexec_framen:
  1415.                 lda (mt_temp1),y
  1416.                 bne mt_sfxexec_noend
  1417. mt_sfxexec_end:
  1418.                 sta mt_chnsfx,x
  1419.                 beq mt_sfxexec_wavechg
  1420. mt_sfxexec_noend:
  1421.                 tay
  1422.                 lda mt_freqtbllo-$80,y        ;Get frequency
  1423.                 sta SIDBASE+$00,x
  1424.                 lda mt_freqtblhi-$80,y
  1425.                 sta SIDBASE+$01,x
  1426.                 ldy mt_chnsfx,y
  1427.                 lda (mt_temp1),y              ;Then take a look at the next
  1428.                 beq mt_sfxexec_done           ;byte
  1429.                 cmp #$82                      ;Is it a waveform or a note?
  1430.                 bcs mt_sfxexec_done
  1431.                 inc mt_chnsfx,x
  1432.                 bcc mt_sfxexec_wavechg
  1433.  
  1434. mt_sfxexec_sid2:
  1435.                 cpy #$02
  1436.                 beq mt_sfxexec_frame0_sid2
  1437.                 bcs mt_sfxexec_framen_sid2
  1438.                 sta SID2BASE-21+$05,x                ;Hardrestart before sound FX
  1439.                 sta SID2BASE-21+$06,x                ;begins
  1440.                 jmp mt_loadregswave_sid2
  1441. mt_sfxexec_frame0_sid2:
  1442.                 tay
  1443.                 lda (mt_temp1),y           ;Load ADSR
  1444.                 sta SID2BASE-21+$05,x
  1445.                 iny
  1446.                 lda (mt_temp1),y
  1447.                 sta SID2BASE-21+$06,x
  1448.                 iny
  1449.                 lda (mt_temp1),y           ;Load pulse
  1450.                 sta SID2BASE-21+$02,x
  1451.                 sta SID2BASE-21+$03,x
  1452.                 lda #$09                   ;Testbit
  1453. mt_sfxexec_wavechg_sid2:
  1454.                 sta mt_chnwave,x
  1455.                 sta SID2BASE-21+$04,x
  1456. mt_sfxexec_done_sid2:
  1457.                 rts
  1458. mt_sfxexec_framen_sid2:
  1459.                 lda (mt_temp1),y
  1460.                 bne mt_sfxexec_noend_sid2
  1461. mt_sfxexec_end_sid2:
  1462.                 sta mt_chnsfx,x
  1463.                 beq mt_sfxexec_wavechg_sid2
  1464. mt_sfxexec_noend_sid2:
  1465.                 tay
  1466.                 lda mt_freqtbllo-$80,y        ;Get frequency
  1467.                 sta SID2BASE-21+$00,x
  1468.                 lda mt_freqtblhi-$80,y
  1469.                 sta SID2BASE-21+$01,x
  1470.                 ldy mt_chnsfx,y
  1471.                 lda (mt_temp1),y              ;Then take a look at the next
  1472.                 beq mt_sfxexec_done_sid2           ;byte
  1473.                 cmp #$82                      ;Is it a waveform or a note?
  1474.                 bcs mt_sfxexec_done_sid2
  1475.                 inc mt_chnsfx,x
  1476.                 bcc mt_sfxexec_wavechg_sid2
  1477.  
  1478.               .ENDIF
  1479.  
  1480.         ;Wavetable command exec
  1481.  
  1482.               .IF (NOWAVECMD == 0)
  1483. mt_execwavecmd:
  1484.                 and #$0f
  1485.                 sta <mt_temp1
  1486.                 lda mt_notetbl-2,y
  1487.                 sta <mt_temp2
  1488.                 ldy <mt_temp1
  1489.               .IF ((NOTONEPORTA == 0) || (NOPORTAMENTO == 0) || (NOVIB == 0))
  1490.                 cpy #$05
  1491.                 bcs mt_execwavetick0
  1492. mt_execwavetickn:
  1493.               .IF (.DEFINED(mt_effectnum))
  1494.                 sty mt_effectnum+1
  1495.               .ENDIF
  1496.                 lda mt_effectjumptbl,y
  1497.                 sta mt_effectjump+1
  1498.                 ldy <mt_temp2
  1499.                 jmp mt_setspeedparam
  1500.               .ENDIF
  1501. mt_execwavetick0:
  1502.                 lda mt_tick0jumptbl,y
  1503.                 sta mt_execwavetick0jump+1
  1504.                 lda <mt_temp2
  1505. mt_execwavetick0jump:
  1506.                 jsr mt_tick0_0
  1507.                 jmp mt_done
  1508.               .ENDIF
  1509.  
  1510.               .IF (NOEFFECTS == 0)
  1511.               .IF (!.DEFINED(mt_tick0jumptbl))
  1512. mt_tick0jumptbl:
  1513.                 .BYTE (mt_tick0_0 % 256)
  1514.                 .BYTE (mt_tick0_12 % 256)
  1515.                 .BYTE (mt_tick0_12 % 256)
  1516.                 .BYTE (mt_tick0_34 % 256)
  1517.                 .BYTE (mt_tick0_34 % 256)
  1518.                 .BYTE (mt_tick0_5 % 256)
  1519.                 .BYTE (mt_tick0_6 % 256)
  1520.                 .BYTE (mt_tick0_7 % 256)
  1521.                 .BYTE (mt_tick0_8 % 256)
  1522.                 .BYTE (mt_tick0_9 % 256)
  1523.                 .BYTE (mt_tick0_a % 256)
  1524.                 .BYTE (mt_tick0_b % 256)
  1525.                 .BYTE (mt_tick0_c % 256)
  1526.                 .BYTE (mt_tick0_d % 256)
  1527.                 .BYTE (mt_tick0_e % 256)
  1528.                 .BYTE (mt_tick0_f % 256)
  1529.               .ENDIF
  1530.               .ENDIF
  1531.  
  1532.               .IF (NOEFFECTS == 0)
  1533.               .IF (!.DEFINED(mt_effectjumptbl))
  1534.               .IF ((NOTONEPORTA == 0) || (NOPORTAMENTO == 0) || (NOVIB == 0))
  1535. mt_effectjumptbl:
  1536.                 .BYTE (mt_effect_0 % 256)
  1537.                 .BYTE (mt_effect_12 % 256)
  1538.                 .BYTE (mt_effect_12 % 256)
  1539.                 .BYTE (mt_effect_3 % 256)
  1540.                 .BYTE (mt_effect_4 % 256)
  1541.               .ENDIF
  1542.               .ENDIF
  1543.               .ENDIF
  1544.  
  1545.               .IF (!.DEFINED(mt_funktempotbl))
  1546.               .IF (NOFUNKTEMPO == 0)
  1547. mt_funktempotbl:
  1548.                 .BYTE (8,5)
  1549.               .ENDIF
  1550.               .ENDIF
  1551.  
  1552.               .IF ((NOEFFECTS == 0) || (NOWAVEDELAY == 0) || (NOTRANS == 0) || (NOREPEAT == 0) || (FIXEDPARAMS == 0) || (BUFFEREDWRITES != 0) || (NOCALCULATEDSPEED == 0))
  1553.  
  1554.               ;Normal channel variables
  1555.  
  1556. mt_chnsongptr:
  1557.                 .BYTE (0)
  1558. mt_chntrans:
  1559.                 .BYTE (0)
  1560. mt_chnrepeat:
  1561.                 .BYTE (0)
  1562. mt_chnpattptr:
  1563.                 .BYTE (0)
  1564. mt_chnpackedrest:
  1565.                 .BYTE (0)
  1566. mt_chnnewfx:
  1567.                 .BYTE (0)
  1568. mt_chnnewparam:
  1569.                 .BYTE (0)
  1570.  
  1571.                 .BYTE (0,0,0,0,0,0,0)
  1572.                 .BYTE (0,0,0,0,0,0,0)
  1573.                 .BYTE (0,0,0,0,0,0,0)
  1574.                 .BYTE (0,0,0,0,0,0,0)
  1575.                 .BYTE (0,0,0,0,0,0,0)              
  1576.  
  1577.  
  1578. mt_chnfx:
  1579.                 .BYTE (0)
  1580. mt_chnparam:
  1581.                 .BYTE (0)
  1582. mt_chnnewnote:
  1583.                 .BYTE (0)
  1584. mt_chnwaveptr:
  1585.                 .BYTE (0)
  1586. mt_chnwave:
  1587.                 .BYTE (0)
  1588. mt_chnpulseptr:
  1589.                 .BYTE (0)
  1590. mt_chnpulsetime:
  1591.                 .BYTE (0)
  1592.  
  1593.                 .BYTE (0,0,0,0,0,0,0)
  1594.                 .BYTE (0,0,0,0,0,0,0)
  1595.                 .BYTE (0,0,0,0,0,0,0)
  1596.                 .BYTE (0,0,0,0,0,0,0)
  1597.                 .BYTE (0,0,0,0,0,0,0)
  1598.  
  1599. mt_chnsongnum:
  1600.                 .BYTE (0)
  1601. mt_chnpattnum:
  1602.                 .BYTE (0)
  1603. mt_chntempo:
  1604.                 .BYTE (0)
  1605. mt_chncounter:
  1606.                 .BYTE (0)
  1607. mt_chnnote:
  1608.                 .BYTE (0)
  1609. mt_chninstr:
  1610.                 .BYTE (1)
  1611. mt_chngate:
  1612.                 .BYTE ($fe)
  1613.  
  1614.                 .BYTE (1,0,0,0,0,1,$fe)
  1615.                 .BYTE (2,0,0,0,0,1,$fe)
  1616.                 .BYTE (3,0,0,0,0,1,$fe)
  1617.                 .BYTE (4,0,0,0,0,1,$fe)
  1618.                 .BYTE (5,0,0,0,0,1,$fe)
  1619.  
  1620. mt_chnvibtime:
  1621.                 .BYTE (0)
  1622. mt_chnvibdelay:
  1623.                 .BYTE (0)
  1624. mt_chnwavetime:
  1625.                 .BYTE (0)
  1626. mt_chnfreqlo:
  1627.                 .BYTE (0)
  1628. mt_chnfreqhi:
  1629.                 .BYTE (0)
  1630. mt_chnpulselo:
  1631.                 .BYTE (0)
  1632. mt_chnpulsehi:
  1633.                 .BYTE (0)
  1634.  
  1635.                 .BYTE (0,0,0,0,0,0,0)
  1636.                 .BYTE (0,0,0,0,0,0,0)
  1637.                 .BYTE (0,0,0,0,0,0,0)
  1638.                 .BYTE (0,0,0,0,0,0,0)
  1639.                 .BYTE (0,0,0,0,0,0,0)
  1640.  
  1641.  
  1642.               .IF ((BUFFEREDWRITES != 0) || (FIXEDPARAMS == 0) || (NOCALCULATEDSPEED == 0))
  1643. mt_chnad:
  1644.                 .BYTE (0)
  1645. mt_chnsr:
  1646.                 .BYTE (0)
  1647. mt_chnsfx:
  1648.                 .BYTE (0)
  1649. mt_chnsfxlo:
  1650.                 .BYTE (0)
  1651. mt_chnsfxhi:
  1652.                 .BYTE (0)
  1653. mt_chngatetimer:
  1654.                 .BYTE (0)
  1655. mt_chnlastnote:
  1656.                 .BYTE (0)
  1657.  
  1658.                 .BYTE (0,0,0,0,0,0,0)
  1659.                 .BYTE (0,0,0,0,0,0,0)
  1660.                 .BYTE (0,0,0,0,0,0,0)
  1661.                 .BYTE (0,0,0,0,0,0,0)
  1662.                 .BYTE (0,0,0,0,0,0,0)
  1663.  
  1664.               .ENDIF
  1665.  
  1666.               .ELSE
  1667.  
  1668.               ;Optimized channel variables
  1669.  
  1670. mt_chnsongptr:
  1671.                 .BYTE (0)
  1672. mt_chnpattptr:
  1673.                 .BYTE (0)
  1674. mt_chnpackedrest:
  1675.                 .BYTE (0)
  1676. mt_chnnewnote:
  1677.                 .BYTE (0)
  1678. mt_chnwaveptr:
  1679.                 .BYTE (0)
  1680. mt_chnwave:
  1681.                 .BYTE (0)
  1682. mt_chnpulseptr:
  1683.                 .BYTE (0)
  1684.  
  1685.                 .BYTE (0,0,0,0,0,0,0)
  1686.                 .BYTE (0,0,0,0,0,0,0)
  1687.                 .BYTE (0,0,0,0,0,0,0)
  1688.                 .BYTE (0,0,0,0,0,0,0)
  1689.                 .BYTE (0,0,0,0,0,0,0)
  1690.  
  1691. mt_chnpulsetime:
  1692.                 .BYTE (0)
  1693. mt_chnpulselo:
  1694.                 .BYTE (0)
  1695. mt_chnpulsehi:
  1696.                 .BYTE (0)
  1697. mt_chnvibtime:
  1698.                 .BYTE (0)
  1699. mt_chnvibdelay:
  1700.                 .BYTE (0)
  1701. mt_chnfreqlo:
  1702.                 .BYTE (0)
  1703. mt_chnfreqhi:
  1704.                 .BYTE (0)
  1705.  
  1706.                 .BYTE (0,0,0,0,0,0,0)
  1707.                 .BYTE (0,0,0,0,0,0,0)
  1708.                 .BYTE (0,0,0,0,0,0,0)
  1709.                 .BYTE (0,0,0,0,0,0,0)
  1710.                 .BYTE (0,0,0,0,0,0,0)
  1711.  
  1712. mt_chnsongnum:
  1713.                 .BYTE (0)
  1714. mt_chnpattnum:
  1715.                 .BYTE (0)
  1716. mt_chntempo:
  1717.                 .BYTE (0)
  1718. mt_chncounter:
  1719.                 .BYTE (0)
  1720. mt_chnnote:
  1721.                 .BYTE (0)
  1722. mt_chninstr:
  1723.                 .BYTE (1)
  1724. mt_chngate:
  1725.                 .BYTE ($fe)
  1726.  
  1727.                 .BYTE (1,0,0,0,0,1,$fe)
  1728.                 .BYTE (2,0,0,0,0,1,$fe)
  1729.                 .BYTE (3,0,0,0,0,1,$fe)
  1730.                 .BYTE (4,0,0,0,0,1,$fe)
  1731.                 .BYTE (5,0,0,0,0,1,$fe)
  1732.  
  1733.               .ENDIF
  1734.  
  1735.         ;Songdata & frequencytable will be inserted by the relocator here
  1736.  
  1737.