home *** CD-ROM | disk | FTP | other *** search
/ Large Pack of OldSkool DOS MOD Trackers / goattracker_2.73.zip / src / altplayer.s next >
Text File  |  2014-07-23  |  55KB  |  1,848 lines

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