home *** CD-ROM | disk | FTP | other *** search
/ Merciful 3 / Merciful_Release_3.bin / software / o / octamed / octamedv6.12.lha / programmers / pro8player.a < prev    next >
Text File  |  1995-04-12  |  77KB  |  2,293 lines

  1. ;============================================================================
  2. ;   pro8player.a
  3. ;   ~~~~~~~~~~~
  4. ; $VER: pro8player 6.0 (08.03.1995)
  5. ;
  6. ; The music player routine for MMD0/MMD1/MMD2 MED/OctaMED
  7. ; eight channel modules.
  8. ;
  9. ; Copyright © 1995 Teijo Kinnunen and RBF Software.
  10. ;
  11. ; Written by Teijo Kinnunen.
  12. ; Comments/questions/bug reports can be sent to:
  13. ;   Teijo Kinnunen
  14. ;   Oksantie 19
  15. ;   FIN-86300  OULAINEN
  16. ;   FINLAND
  17. ;   email: kinnunen@stekt.oulu.fi
  18. ;
  19. ; See OctaMED docs for conditions about using these routines.
  20. ; Comments/questions about distribution and usage conditions
  21. ; should be directed to RBF Software. (Email: rbfsoft@cix.compulink.co.uk)
  22. ;
  23. ;============================================================================
  24.  
  25. ;****** Feature control ******
  26. ;
  27. AUDDEV      EQU 1   ;1 = allocate channels using audio.device
  28. CHECK       EQU 1   ;1 = do range checkings (track, sample in mem etc.)
  29. IFFMOCT     EQU 1   ;1 = play IFF multi-octave samples correctly
  30. HOLD        EQU 1   ;1 = handle hold/decay
  31. PLAYMMD0    EQU 1   ;1 = play old MMD0 modules
  32. ;============================================================================
  33.  
  34. ; The MMD structure offsets
  35. mmd_id      EQU 0
  36. mmd_modlen  EQU 4
  37. mmd_songinfo    EQU 8
  38. ; these two for MMD2s only!
  39. mmd_psecnum EQU 12
  40. mmd_pseq    EQU 14
  41. ;
  42. mmd_blockarr    EQU 16
  43. mmd_smplarr EQU 24
  44. mmd_expdata EQU 32
  45. mmd_pstate  EQU 40 ; <0 = play song, 0 = don't play, >0 = play block
  46. mmd_pblock  EQU 42
  47. mmd_pline   EQU 44
  48. mmd_pseqnum EQU 46
  49. mmd_actplayline EQU 48
  50. mmd_counter EQU 50
  51. mmd_songsleft   EQU 51
  52.  
  53. ; The Song structure
  54. ; Instrument data here (504 bytes = 63 * 8)
  55. msng_numblocks  EQU 504
  56. msng_songlen    EQU 506
  57. msng_playseq    EQU 508
  58. msng_deftempo   EQU 764
  59. msng_playtransp EQU 766
  60. msng_flags  EQU 767
  61. msng_flags2 EQU 768
  62. msng_tempo2 EQU 769
  63. ; msng_trkvol applies to MMD0/MMD1 only.
  64. msng_trkvol EQU 770
  65. msng_mastervol  EQU 786
  66. msng_numsamples EQU 787
  67. ; Fields below apply to MMD2 modules only.
  68. msng_pseqs  EQU 508
  69. msng_sections   EQU 512
  70. msng_trkvoltbl  EQU 516
  71. msng_numtracks  EQU 520
  72. msng_numpseqs   EQU 522
  73.  
  74. ; Instrument data
  75. inst_repeat EQU 0
  76. inst_replen EQU 2
  77. inst_midich EQU 4
  78. inst_midipreset EQU 5
  79. inst_svol   EQU 6
  80. inst_strans EQU 7
  81.  
  82. ; Audio hardware offsets
  83. ac_ptr  EQU $00
  84. ac_len  EQU $04
  85. ac_per  EQU $06
  86. ac_vol  EQU $08
  87. ac_end  EQU $0C
  88. ac_rest EQU $10
  89. ac_mask EQU $14
  90. ac_rhw  EQU $16
  91.  
  92. TDSZ    EQU 52
  93.  
  94.         SECTION "text",CODE
  95.  
  96. ;**************************************************************************
  97. ;*
  98. ;*      8 CHANNEL PLAY ROUTINE
  99. ;*
  100. ;**************************************************************************
  101.  
  102. ; This code does the magic 8 channel thing (mixing).
  103. MAGIC_8TRK  MACRO
  104.         move.b  0(a3,d6.w),d3
  105.         add.l   d1,d6
  106.         addx.w  d0,d6
  107.         add.b   0(a4,d7.w),d3
  108.         add.l   d2,d7
  109.         move.b  d3,(a1)+
  110.         addx.w  d0,d7
  111.         ENDM
  112.  
  113. _ChannelO8  clr.w   trk_prevper(a5)
  114.         movea.l trk_audioaddr(a5),a0
  115.         clr.w   ac_per(a0)
  116. xco8        rts
  117.  
  118. _PlayNote8: ;d7(w) = trk #, d1 = note #, d3(w) = instr # a3 = addr of instr
  119.         movea.l mmd_smplarr(a2),a0
  120.         add.w   d3,d3           ;d3 = instr.num << 2
  121.         add.w   d3,d3
  122.         move.l  0(a0,d3.w),d5       ;get address of instrument
  123.     IFNE    CHECK
  124.         beq.s   xco8
  125.     ENDC
  126. inmem8:     add.b   msng_playtransp(a4),d1  ;add play transpose
  127.         add.b   inst_strans(a3),d1  ;and instr. transpose
  128.     IFNE    CHECK
  129.         tst.b   inst_midich(a3)
  130.         bne.s   xco8        ;MIDI
  131.     ENDC
  132.         clr.b   trk_vibroffs(a5)    ;clr vibrato offset
  133.         move.l  d5,a0
  134.         subq.b  #1,d1
  135.     IFNE    CHECK
  136.         tst.w   4(a0)
  137.         bmi.s   xco8        ;Synth
  138.     ENDC
  139. tlwtst08:   tst.b   d1
  140.         bpl.s   notenot2low8
  141.         add.b   #12,d1  ;note was too low, octave up
  142.         bra.s   tlwtst08
  143. notenot2low8:   cmp.b   #62,d1
  144.         ble.s   endpttest8
  145.         sub.b   #12,d1  ;note was too high, octave down
  146. endpttest8:
  147.         moveq   #0,d2
  148.         moveq   #0,d3
  149.         moveq   #6,d4   ;skip (stereo+hdr) offset
  150.         lea _periodtable+32-DB(a6),a1
  151.         move.b  trk_finetune(a5),d2 ;finetune value
  152.         add.b   d2,d2
  153.         add.b   d2,d2       ;multiply by 4...
  154.         ext.w   d2      ;extend
  155.         movea.l 0(a1,d2.w),a1   ;period table address
  156.         move.w  4(a0),d0    ;(Instr hdr in a0)
  157.         btst    #5,d0
  158.         beq.s   gid_nostereo
  159.         move.b  d7,d5
  160.         and.b   #3,d5
  161.         beq.s   gid_nostereo    ;ch 0/4 = play left (norm.)
  162.         cmp.b   #3,d5
  163.         beq.s   gid_nostereo    ;also for ch 3/7
  164.         add.l   (a0),d4     ;play right channel
  165. gid_nostereo
  166.     IFNE    IFFMOCT
  167.         and.w   #$F,d0
  168.         bne.s   gid_notnormal   ;note # in d1 (0 - ...)
  169.     ENDC
  170. gid_cont_ext    move.l  a1,trk_periodtbl(a5)
  171.         add.b   d1,d1
  172.         move.w  0(a1,d1.w),d5 ;put period to d5
  173.         move.l  a0,d0
  174.         move.l  (a0),d1     ;length
  175.         add.l   d4,d0       ;skip hdr and stereo
  176.         add.l   d0,d1       ;sample end pointer
  177.         move.w  inst_repeat(a3),d2
  178.         move.w  inst_replen(a3),d3
  179.     IFNE    IFFMOCT
  180.         bra gid_setrept
  181. gid_addtable    dc.b    0,6,12,18,24,30
  182. gid_divtable    dc.b    31,7,3,15,63,127
  183. gid_notnormal   cmp.w   #7,d0
  184.         blt.s   gid_not_ext
  185.         suba.w  #48,a1
  186.         bra.s   gid_cont_ext
  187. gid_not_ext move.l  d7,-(sp)
  188.         moveq   #0,d7
  189.         move.w  d1,d7
  190.         divu    #12,d7  ;octave #
  191.         move.l  d7,d5
  192.         cmp.w   #6,d7   ;if oct > 5, oct = 5
  193.         blt.s   nohioct
  194.         moveq   #5,d7
  195. nohioct     swap    d5  ;note number in this oct (0-11) is in d5
  196.         move.l  (a0),d1
  197.         cmp.w   #6,d0
  198.         ble.s   nounrecit
  199.         moveq   #6,d0
  200. nounrecit   add.b   gid_addtable-1(pc,d0.w),d7
  201.         move.b  gid_divtable-1(pc,d0.w),d0
  202.         divu    d0,d1   ;get length of the highest octave
  203.         swap    d1
  204.         clr.w   d1
  205.         swap    d1
  206.         move.l  d1,d0       ;d0 and d1 = length of the 1st oct
  207.         move.w  inst_repeat(a3),d2
  208.         move.w  inst_replen(a3),d3
  209.         moveq   #0,d6
  210.         move.b  shiftcnt(pc,d7.w),d6
  211.         lsl.w   d6,d2
  212.         lsl.w   d6,d3
  213.         lsl.w   d6,d1
  214.         move.b  mullencnt(pc,d7.w),d6
  215.         mulu    d6,d0       ;offset of this oct from 1st oct
  216.         add.l   a0,d0       ;add base address to offset
  217.         add.l   d4,d0       ;skip header + stereo
  218.         add.l   d0,d1
  219.         move.l  a1,trk_periodtbl(a5)
  220.         add.b   octstart(pc,d7.w),d5
  221.         add.b   d5,d5
  222.         move.w  0(a1,d5.w),d5
  223.         move.l  (sp)+,d7
  224.         bra.s   gid_setrept
  225. shiftcnt:   dc.b    4,3,2,1,1,0,2,2,1,1,0,0,1,1,0,0,0,0
  226.         dc.b    3,3,2,2,1,0,5,4,3,2,1,0,6,5,4,3,2,1
  227. mullencnt:  dc.b    15,7,3,1,1,0,3,3,1,1,0,0,1,1,0,0,0,0
  228.         dc.b    7,7,3,3,1,0,31,15,7,3,1,0,63,31,15,7,3,1
  229. octstart:   dc.b    12,12,12,12,24,24,0,12,12,24,24,36,0,12,12,24,36,36
  230.         dc.b    0,12,12,24,24,24,12,12,12,12,12,12,12,12,12,12,12,12
  231.     ENDC
  232. gid_setrept add.l   d2,d2
  233.         add.l   d0,d2       ;rep. start pointer
  234.         cmp.w   #1,d3
  235.         bhi.s   gid_noreplen2
  236.         moveq   #0,d3       ;no repeat
  237.         bra.s   gid_cont
  238. gid_noreplen2   add.l   d3,d3
  239.         add.l   d2,d3       ;rep. end pointer
  240.  
  241. gid_cont    moveq   #0,d4
  242.         move.w  trk_soffset(a5),d4
  243.         add.l   d4,d0
  244.         cmp.l   d0,d1
  245.         bhi.s   pn_nooffsovf8
  246.         sub.l   d4,d0
  247. pn_nooffsovf8   movea.l trk_audioaddr(a5),a1 ;base of this channel's regs
  248.         move.l  d0,(a1)     ;put it in ac_ptr
  249.         moveq   #0,d4
  250.         move.b  trk_previnstr(a5),d4
  251.         lea flags-DB(a6),a0
  252.         btst    #0,0(a0,d4.w)       ;test flags.SSFLG_LOOP
  253.         bhi.s   repeat8
  254.  
  255.         tst.b   trk_split(a5)
  256.         beq.s   pn8_nosplit0
  257.         clr.l   ac_rest(a1)
  258.         subq.l  #1,d1
  259.         move.l  d1,ac_end(a1)
  260.         bra.s   retsn18
  261.  
  262. pn8_nosplit0    sub.l   d0,d1
  263.         lsr.l   #1,d1
  264.         move.w  d1,ac_len(a1)
  265.         move.l  #_chipzero,ac_rest(a1)
  266.         move.w  #1,ac_end(a1)
  267.         bra.s   retsn18
  268.  
  269. repeat8:    tst.b   trk_split(a5)
  270.         bne.s   pn8_split1
  271.         move.l  d3,d1
  272.         sub.l   d0,d1
  273.         lsr.l   #1,d1
  274.         move.w  d1,ac_len(a1)
  275.         move.l  d2,ac_rest(a1)  ;remember rep. start
  276.         sub.l   d2,d3
  277.         lsr.l   #1,d3
  278.         move.w  d3,ac_end(a1)   ;remember rep. length
  279.         bra.s   retsn18
  280.  
  281. pn8_split1  move.l  d2,ac_rest(a1)
  282.         move.l  d3,ac_end(a1)
  283. retsn18:    move.w  d5,ac_per(a1)   ;getinsdata puts period to d5
  284.         move.w  d5,trk_prevper(a5)
  285. retsn28:    rts
  286.  
  287. _IntHandler8:   movem.l d2-d7/a2-a4,-(sp)
  288.         lea DB,a6
  289.         lea trksplit-DB(a6),a2
  290.         move.w  currchsize2-DB(a6),d4
  291. ; ================ 8 channel handling (buffer swap) ======
  292.         move.w  #1600,d0
  293.         not.b   whichbuff-DB(a6)    ;swap buffer
  294.         bne.s   usebuff1
  295.         tst.b   (a2)+
  296.         beq.s   tnspl0
  297.         move.l  a1,$a0(a0)
  298.         move.w  d4,$a4(a0)
  299. tnspl0      lea 1600(a1),a5
  300.         tst.b   (a2)+
  301.         beq.s   tnspl1
  302.         move.l  a5,$b0(a0)
  303.         move.w  d4,$b4(a0)
  304. tnspl1      adda.w  d0,a5
  305.         tst.b   (a2)+
  306.         beq.s   tnspl2
  307.         move.l  a5,$c0(a0)
  308.         move.w  d4,$c4(a0)
  309. tnspl2      adda.w  d0,a5
  310.         tst.b   (a2)
  311.         beq.s   buffset
  312.         move.l  a5,$d0(a0)
  313.         move.w  d4,$d4(a0)
  314.         bra.s   buffset
  315. usebuff1    lea 800(a1),a1
  316.         tst.b   (a2)+
  317.         beq.s   tnspl0b
  318.         move.l  a1,$a0(a0)
  319.         move.w  d4,$a4(a0)
  320. tnspl0b     lea 1600(a1),a5
  321.         tst.b   (a2)+
  322.         beq.s   tnspl1b
  323.         move.l  a5,$b0(a0)
  324.         move.w  d4,$b4(a0)
  325. tnspl1b     adda.w  d0,a5
  326.         tst.b   (a2)+
  327.         beq.s   tnspl2b
  328.         move.l  a5,$c0(a0)
  329.         move.w  d4,$c4(a0)
  330. tnspl2b     tst.b   (a2)
  331.         beq.s   buffset
  332.         adda.w  d0,a5
  333.         move.l  a5,$d0(a0)
  334.         move.w  d4,$d4(a0)
  335. buffset     move.w  #1<<7,$9c(a0)
  336.         lea tmpvol-DB(a6),a2
  337.         move.b  (a2)+,$a9(a0)
  338.         move.b  (a2)+,$b9(a0)
  339.         move.b  (a2)+,$c9(a0)
  340.         move.b  (a2),$d9(a0)
  341.         tst.b   _hq-DB(a6)
  342.         beq.s   nohq
  343.         move.l  #2031616,d3 ;124 * 16384
  344.         bra.s   startfillb
  345. nohq        move.l  #3719168,d3 ;227 * 16384
  346. ; ============== fill buffers ============
  347. startfillb  moveq   #0,d4       ;mask for DMA
  348.         lea track0hw-DB(a6),a2
  349.         tst.b   trksplit-DB(a6)
  350.         bne.s   tspl0c
  351.         bsr.w   pushregs
  352.         bra.s   tnspl0c
  353. tspl0c      bsr.s   fillbuf
  354.         movea.l a5,a1
  355. tnspl0c     lea track1hw-DB(a6),a2
  356.         tst.b   trksplit+1-DB(a6)
  357.         bne.s   tspl1c
  358.         bsr.w   pushregs
  359.         bra.s   tnspl1c
  360. tspl1c      bsr.s   fillbuf
  361.         movea.l a5,a1
  362. tnspl1c     lea track2hw-DB(a6),a2
  363.         tst.b   trksplit+2-DB(a6)
  364.         bne.s   tspl2c
  365.         bsr.w   pushregs
  366.         bra.s   tnspl2c
  367. tspl2c      bsr.s   fillbuf
  368.         movea.l a5,a1
  369. tnspl2c     lea track3hw-DB(a6),a2
  370.         tst.b   trksplit+3-DB(a6)
  371.         bne.s   tspl3c
  372.         bsr.w   pushregs
  373.         bra.w   do_play8
  374. tspl3c      bsr.s   fillbuf
  375.         bra.w   do_play8
  376. ; =========================================================
  377. ;calculate channel A period
  378. fillbuf:    move.l  d3,d7
  379.         move.w  ac_per(a2),d6
  380.         beq.s   setpzero0
  381.         move.l  d7,d2
  382.         divu    d6,d2
  383.         moveq   #0,d1
  384.         move.w  d2,d1
  385.         add.l   d1,d1
  386.         add.l   d1,d1
  387. ;get channel A addresses
  388.         move.l  ac_end(a2),a5
  389.         move.l  (a2),d0
  390.         beq.s   setpzero0
  391. chA_dfnd    move.l  d0,a3   ;a3 = start address, a5 = end address
  392. ;calc bytes before end
  393.         mulu    currchsize-DB(a6),d2
  394.         clr.w   d2
  395.         swap    d2
  396. ; d2 = # of bytes/fill
  397.         add.l   a3,d2   ;d2 = end position after this fill
  398.         sub.l   a5,d2   ;subtract sample end
  399.         bmi.s   norestart0
  400.         move.l  ac_rest(a2),d0
  401.         beq.s   rst0end
  402.         move.l  d0,(a2)
  403.         move.l  d0,a3
  404.         bra.s   norestart0
  405. rst0end     clr.l   (a2)
  406. setpzero0   lea zerodata-DB(a6),a3
  407.         moveq   #0,d1
  408. norestart0
  409. ;channel B period
  410.         move.w  SIZE4TRKHW+ac_per(a2),d6
  411.         beq.s   setpzero0b
  412.         divu    d6,d7
  413.         moveq   #0,d2
  414.         move.w  d7,d2
  415.         add.l   d2,d2
  416.         add.l   d2,d2
  417. ;channel B addresses
  418.         move.l  SIZE4TRKHW+ac_end(a2),a5
  419.         move.l  SIZE4TRKHW(a2),d0
  420.         beq.s   setpzero0b
  421.         move.l  d0,a4
  422.         mulu    currchsize-DB(a6),d7
  423.         clr.w   d7
  424.         swap    d7
  425.         add.l   a4,d7
  426.         sub.l   a5,d7
  427.         bmi.s   norestart0b
  428.         move.l  SIZE4TRKHW+ac_rest(a2),d0
  429.         beq.s   rst0endb
  430.         move.l  d0,SIZE4TRKHW(a2)
  431.         move.l  d0,a4
  432.         bra.s   norestart0b
  433. rst0endb    clr.l   SIZE4TRKHW(a2)
  434. setpzero0b  lea zerodata-DB(a6),a4
  435.         moveq   #0,d2
  436. norestart0b moveq   #0,d6
  437.         moveq   #0,d7
  438.         moveq   #0,d0
  439.         move.w  d3,-(sp)
  440.         swap    d1
  441.         swap    d2
  442.         lea 1600(a1),a5 ;get addr. of next buffer
  443.         tst.b   _hq-DB(a6)
  444.         bne.w   magic_hq
  445.         move.w  currchszcnt-DB(a6),d5
  446. do8trkmagic
  447.         MAGIC_8TRK  ;20 times..
  448.         MAGIC_8TRK
  449.         MAGIC_8TRK
  450.         MAGIC_8TRK
  451.         MAGIC_8TRK
  452.         MAGIC_8TRK
  453.         MAGIC_8TRK
  454.         MAGIC_8TRK
  455.         MAGIC_8TRK
  456.         MAGIC_8TRK
  457.         MAGIC_8TRK
  458.         MAGIC_8TRK
  459.         MAGIC_8TRK
  460.         MAGIC_8TRK
  461.         MAGIC_8TRK
  462.         MAGIC_8TRK
  463.         MAGIC_8TRK
  464.         MAGIC_8TRK
  465.         MAGIC_8TRK
  466.         MAGIC_8TRK
  467.  
  468.         dbf d5,do8trkmagic  ;do until cnt zero
  469. end8trkmagic    swap    d6
  470.         swap    d7
  471.         clr.w   d6
  472.         clr.w   d7
  473.         swap    d6
  474.         swap    d7
  475.         add.l   d6,(a2)
  476.         add.l   d7,SIZE4TRKHW(a2)
  477.         move.w  (sp)+,d3
  478.         rts
  479. ; The following code is executed only in HQ-mode
  480. magic_hq    move.w  currchsize2-DB(a6),d5
  481.         lsr.w   #1,d5
  482.         subq.w  #1,d5
  483. dohq8trkmagic   ;this runs quite efficiently in a cache
  484.         MAGIC_8TRK
  485.         MAGIC_8TRK
  486.         MAGIC_8TRK
  487.         MAGIC_8TRK
  488.         dbf d5,dohq8trkmagic
  489.         bra.s   end8trkmagic
  490.  
  491. _Wait1line: move.l  d0,-(sp)
  492.         moveq   #$79,d0
  493. wl0:        move.b  $dff007,d1
  494. wl1:        cmp.b   $dff007,d1
  495.         beq.s   wl1
  496.         dbf d0,wl0
  497.         move.l  (sp)+,d0
  498.         rts
  499. ; ========== this channel is not splitted
  500. pushregs    move.l  ac_rhw(a2),a3       ;address of real hardware
  501.         tst.w   ac_per(a2)
  502.         beq.s   pregs_stop
  503.         move.w  ac_per(a2),ac_per(a3)   ;push new period
  504.         move.l  (a2),d0 ;ac_ptr
  505.         beq.s   pregs_nonewp
  506.         move.w  ac_mask(a2),d1
  507.         move.w  d1,$96(a0)  ;stop DMA of curr. channel
  508.         or.w    d1,d4
  509.         clr.l   (a2)+
  510.         move.l  d0,(a3)+    ;to real ac_ptr
  511.         move.w  (a2),(a3)   ;push ac_len
  512. pregs_nonewp    lea 800(a1),a1  ;next buffer
  513.         rts
  514. pregs_stop  move.w  ac_mask(a2),d1
  515.         move.w  d1,$96(a0)
  516.         bra.s   pregs_nonewp
  517. ; ========== should we start DMA of non-splitted channels?
  518. do_play8    tst.w   d4
  519.         beq.s   do_play8_b  ;no.
  520.         bsr.s   _Wait1line
  521.         bset    #15,d4
  522.         move.w  d4,$96(a0)
  523.         bsr.s   _Wait1line
  524.         lsr.b   #1,d4
  525.         bcc.s   plr_nos8dma0
  526.         move.l  track0hw+ac_rest-DB(a6),$a0(a0)
  527.         move.w  track0hw+ac_end-DB(a6),$a4(a0)
  528. plr_nos8dma0    lsr.b   #1,d4
  529.         bcc.s   plr_nos8dma1
  530.         move.l  track1hw+ac_rest-DB(a6),$b0(a0)
  531.         move.w  track1hw+ac_end-DB(a6),$b4(a0)
  532. plr_nos8dma1    lsr.b   #1,d4
  533.         bcc.s   plr_nos8dma2
  534.         move.l  track2hw+ac_rest-DB(a6),$c0(a0)
  535.         move.w  track2hw+ac_end-DB(a6),$c4(a0)
  536. plr_nos8dma2    lsr.b   #1,d4
  537.         bcc.s   do_play8_b
  538.         move.l  track3hw+ac_rest-DB(a6),$d0(a0)
  539.         move.w  track3hw+ac_end-DB(a6),$d4(a0)
  540. ; ========== player starts here...
  541. do_play8_b  movea.l _module8-DB(a6),a2
  542.         move.l  a2,d0
  543.         beq.w   plr_exit
  544.         move.l  mmd_songinfo(a2),a4
  545.         moveq   #0,d3
  546.         lea mmd_counter(a2),a0
  547.         move.b  (a0),d3
  548.         addq.b  #1,d3
  549.         cmp.b   msng_tempo2(a4),d3
  550.         bge.s   plr_pnewnote8   ;play new note
  551.         move.b  d3,(a0)
  552.         bra.w   nonewnote   ;do just fx
  553. ; --- new note!! first get address of current block
  554. plr_pnewnote8:  clr.b   (a0)
  555.         tst.w   blkdelay-DB(a6)
  556.         beq.s   plr_noblkdelay8
  557.         subq.w  #1,blkdelay-DB(a6)
  558.         bne.w   nonewnote
  559. ; -------- GET ADDRESS OF NOTE DATA --------------------------------------
  560. plr_noblkdelay8 move.w  mmd_pblock(a2),d0
  561.         bsr.w   GetNoteDataAddr
  562.         moveq   #0,d7       ;number of track
  563.         moveq   #0,d4
  564.     IFNE    PLAYMMD0
  565.         cmp.b   #'1',3(a2)
  566.         sge d5      ;d5 set -> >= MMD1
  567.     ENDC
  568.         lea trackdata8-DB(a6),a1
  569. ; -------- TRACK LOOP (FOR EACH TRACK) -----------------------------------
  570. plr_loop0:  movea.l (a1)+,a5    ;get address of this track's struct
  571. ; ---------------- get the note numbers
  572.         moveq   #0,d3
  573.     IFNE    PLAYMMD0
  574.         tst.b   d5
  575.         bne.s   plr_mmd1_1
  576.         move.b  (a3)+,d0
  577.         move.b  (a3),d3
  578.         addq.l  #2,a3
  579.         lsr.b   #4,d3
  580.         bclr    #7,d0
  581.         beq.s   plr_bseti4
  582.         bset    #4,d3
  583. plr_bseti4  bclr    #6,d0
  584.         beq.s   plr_bseti5
  585.         bset    #5,d3
  586. plr_bseti5  move.b  d0,trk_currnote(a5)
  587.         beq.s   plr_nngok
  588.         move.b  d0,(a5)
  589.         bra.s   plr_nngok
  590. plr_mmd1_1
  591.     ENDC
  592.         move.b  (a3)+,d0    ;get the number of this note
  593.         bpl.s   plr_nothinote
  594.         moveq   #0,d0
  595. plr_nothinote   move.b  d0,trk_currnote(a5)
  596.         beq.s   plr_nosetprevn
  597.         move.b  d0,(a5)
  598. plr_nosetprevn  move.b  (a3),d3     ;instrument number
  599.         addq.l  #3,a3       ;adv. to next track
  600. ; ---------------- check if there's an instrument number
  601. plr_nngok   and.w   #$3F,d3
  602.         beq.s   noinstnum
  603. ; ---------------- finally, save the number
  604.         subq.b  #1,d3
  605.         move.b  d3,trk_previnstr(a5) ;remember instr. number!
  606. ; ---------------- get the pointer of data's of this sample in Song-struct
  607.         move.w  d3,d1
  608.         asl.w   #3,d3
  609.         lea 0(a4,d3.w),a0   ;a0 contains now address of it
  610.         move.l  a0,trk_previnstra(a5)
  611.         move.b  inst_strans(a0),trk_stransp(a5)
  612. ; ---------------- set volume to 64
  613.         movea.l trk_audioaddr(a5),a0
  614.         movea.l ac_vol(a0),a0   ;ptr to volume hardware register
  615.         moveq   #64,d0
  616.         move.b  d0,(a0)
  617.         move.b  d0,trk_prevvol(a5)
  618. ; ---------------- remember some values of this instrument
  619.         lea holdvals-DB(a6),a0
  620.         adda.w  d1,a0
  621.     IFNE    HOLD
  622.         move.b  (a0),trk_inithold(a5)       ;hold
  623.     ENDC
  624.         move.b  2*63(a0),trk_finetune(a5)   ;finetune
  625. ; ---------------- remember transpose
  626.         clr.w   trk_soffset(a5)     ;sample offset
  627.         clr.b   trk_miscflags(a5)   ;misc.
  628. noinstnum   addq.w  #1,d7
  629.         cmp.w   numtracks-DB(a6),d7
  630.         blt plr_loop0
  631.         bsr.w   DoPreFXLoop
  632. ; -------- NOTE PLAYING LOOP ---------------------------------------------
  633.         moveq   #0,d7
  634.         lea trackdata8-DB(a6),a1
  635. plr_loop2   movea.l (a1)+,a5
  636.         tst.b   trk_fxtype(a5)
  637.         bne.s   plr_loop2_end
  638.         move.b  trk_currnote(a5),d1
  639.         beq.s   plr_loop2_end
  640. ; ---------------- play
  641.         move.l  a1,-(sp)
  642.         ext.w   d1
  643.         moveq   #0,d3
  644.         move.b  trk_previnstr(a5),d3    ;instr #
  645.         movea.l trk_previnstra(a5),a3   ;instr data address
  646.         move.b  trk_inithold(a5),trk_noteoffcnt(a5) ;initialize hold
  647.         bne.s   plr_nohold0     ;not 0 -> OK
  648.         st  trk_noteoffcnt(a5)  ;0 -> hold = 0xff (-1)
  649. ; ---------------- and finally:
  650. plr_nohold0 bsr _PlayNote8      ;play it
  651.         move.l  (sp)+,a1
  652. plr_loop2_end   addq.w  #1,d7
  653.         cmp.w   numtracks-DB(a6),d7
  654.         blt.s   plr_loop2
  655. ; -------- THE REST... ---------------------------------------------------
  656.         bsr.s   AdvSngPtr
  657. nonewnote   bsr.w   DoFX
  658. plr_exit    movem.l (sp)+,d2-d7/a2-a4
  659.         moveq   #1,d0
  660.         rts
  661.  
  662. AdvSngPtr   move.l  mmd_pblock(a2),fxplineblk-DB(a6) ;store pline/block for fx
  663.         move.w  nextblockline-DB(a6),d1
  664.         beq.s   plr_advlinenum
  665.         clr.w   nextblockline-DB(a6)
  666.         subq.w  #1,d1
  667.         bra.s   plr_linenumset
  668. plr_advlinenum  move.w  mmd_pline(a2),d1    ;get current line #
  669.         addq.w  #1,d1           ;advance line number
  670. plr_linenumset  cmp.w   numlines-DB(a6),d1  ;advance block?
  671.         bhi.s   plr_chgblock        ;yes.
  672.         tst.b   nextblock-DB(a6)    ;command F00/1Dxx?
  673.         beq.w   plr_nochgblock      ;no, don't change block
  674. ; -------- CHANGE BLOCK? -------------------------------------------------
  675. plr_chgblock    tst.b   nxtnoclrln-DB(a6)
  676.         bne.s   plr_noclrln
  677.         moveq   #0,d1           ;clear line number
  678. plr_noclrln tst.w   mmd_pstate(a2)      ;play block or play song
  679.         bpl.w   plr_nonewseq        ;play block only...
  680.         cmp.b   #'2',3(a2)      ;MMD2?
  681.         bne.s   plr_noMMD2_0
  682. ; ********* BELOW CODE FOR MMD2 ONLY ************************************
  683. ; -------- CHANGE SEQUENCE -----------------------------------------------
  684. plr_skipseq move.w  mmd_pseq(a2),d0     ;actually stored as << 2
  685.         movea.l msng_pseqs(a4),a1   ;ptr to playseqs
  686.         movea.l 0(a1,d0.w),a0       ;a0 = ptr to curr PlaySeq
  687.         move.w  mmd_pseqnum(a2),d0  ;get play sequence number
  688.         tst.b   nextblock-DB(a6)
  689.         bmi.s   plr_noadvseq        ;Bxx sets nextblock to -1
  690.         addq.w  #1,d0           ;advance sequence number
  691. plr_noadvseq    cmp.w   40(a0),d0       ;is this the highest seq number??
  692.         blt.s   plr_notagain        ;no.
  693. ; -------- CHANGE SECTION ------------------------------------------------
  694.         move.w  mmd_psecnum(a2),d0  ;get section number
  695.         addq.w  #1,d0           ;increase..
  696.         cmp.w   msng_songlen(a4),d0 ;highest section?
  697.         blt.s   plr_nohisec
  698.         moveq   #0,d0           ;yes.
  699. plr_nohisec move.w  d0,mmd_psecnum(a2)  ;push back.
  700.         add.w   d0,d0
  701.         movea.l msng_sections(a4),a0    ;section table
  702.         move.w  0(a0,d0.w),d0       ;new playseqlist number
  703.         add.w   d0,d0
  704.         add.w   d0,d0
  705.         move.w  d0,mmd_pseq(a2)
  706.         movea.l 0(a1,d0.w),a0       ;a0 = ptr to new PlaySeq
  707.         moveq   #0,d0           ;playseq OFFSET = 0
  708. ; -------- FETCH BLOCK NUMBER FROM SEQUENCE ------------------------------
  709. plr_notagain    move.w  d0,mmd_pseqnum(a2)  ;remember new playseq pos
  710.         add.w   d0,d0
  711.         move.w  42(a0,d0.w),d0      ;get number of the block
  712.         bpl.s   plr_changeblk   ;neg. values for future expansion
  713.         bra.s   plr_skipseq ;(skip them)
  714. ; ********* BELOW CODE FOR MMD0/MMD1 ONLY *******************************
  715. plr_noMMD2_0    move.w  mmd_pseqnum(a2),d0  ;get play sequence number
  716.         tst.b   nextblock-DB(a6)
  717.         bmi.s   plr_noadvseq_b      ;Bxx sets nextblock to -1
  718.         addq.w  #1,d0           ;advance sequence number
  719. plr_noadvseq_b  cmp.w   msng_songlen(a4),d0 ;is this the highest seq number??
  720.         blt.s   plr_notagain_b      ;no.
  721.         moveq   #0,d0           ;yes: restart song
  722. plr_notagain_b  move.b  d0,mmd_pseqnum+1(a2)    ;remember new playseq-#
  723.         lea msng_playseq(a4),a0 ;offset of sequence table
  724.         move.b  0(a0,d0.w),d0       ;get number of the block
  725. ; ********* BELOW CODE FOR BOTH FORMATS *********************************
  726. plr_changeblk
  727.     IFNE    CHECK
  728.         cmp.w   msng_numblocks(a4),d0   ;beyond last block??
  729.         blt.s   plr_nolstblk        ;no..
  730.         moveq   #0,d0           ;play block 0
  731.     ENDC
  732. plr_nolstblk    move.w  d0,mmd_pblock(a2)   ;store block number
  733. plr_nonewseq    clr.w   nextblock-DB(a6)    ;clear this if F00 set it
  734. ; ------------------------------------------------------------------------
  735. plr_nochgblock  move.w  d1,mmd_pline(a2)    ;set new line number
  736.  
  737.     IFNE    HOLD
  738.         lea trackdata8-DB(a6),a5
  739.         move.w  mmd_pblock(a2),d0   ;pblock
  740.         bsr.w   GetBlockAddr
  741.         move.w  mmd_pline(a2),d0    ;play line
  742.         move.b  msng_tempo2(a4),d3  ;interrupts/note
  743.     IFNE    PLAYMMD0
  744.         cmp.b   #'1',3(a2)
  745.         bge.s   plr_mmd1_2
  746.         move.b  (a0),d7         ;# of tracks
  747.         move.w  d0,d1
  748.         add.w   d0,d0   ;d0 * 2
  749.         add.w   d1,d0   ;+ d0 = d0 * 3
  750.         mulu    d7,d0
  751.         lea 2(a0,d0.w),a3
  752.         subq.b  #1,d7
  753. plr_chkholdb    movea.l (a5)+,a1        ;track data
  754.         tst.b   trk_noteoffcnt(a1)  ;hold??
  755.         bmi.s   plr_holdendb        ;no.
  756.         move.b  (a3),d1         ;get the 1st byte..
  757.         bne.s   plr_hold1b
  758.         move.b  1(a3),d1
  759.         and.b   #$f0,d1
  760.         beq.s   plr_holdendb        ;don't hold
  761.         bra.s   plr_hold2b
  762. plr_hold1b  and.b   #$3f,d1         ;note??
  763.         beq.s   plr_hold2b      ;no, cont hold..
  764.         move.b  1(a3),d1
  765.         and.b   #$0f,d1         ;get cmd
  766.         subq.b  #3,d1           ;is there command 3 (slide)
  767.         bne.s   plr_holdendb        ;no -> end holding
  768. plr_hold2b  add.b   d3,trk_noteoffcnt(a1)   ;continue holding...
  769. plr_holdendb    addq.l  #3,a3       ;next note
  770.         dbf d7,plr_chkholdb
  771.         rts
  772. plr_mmd1_2
  773.     ENDC
  774.         move.w  (a0),d7     ;# of tracks
  775.         add.w   d0,d0
  776.         add.w   d0,d0       ;d0 = d0 * 4
  777.         mulu    d7,d0
  778.         lea 8(a0,d0.l),a3
  779.         subq.b  #1,d7
  780. plr_chkhold movea.l (a5)+,a1        ;track data
  781.         tst.b   trk_noteoffcnt(a1)  ;hold??
  782.         bmi.s   plr_holdend     ;no.
  783.         move.b  (a3),d1         ;get the 1st byte..
  784.         bne.s   plr_hold1
  785.         move.b  1(a3),d0
  786.         and.b   #$3F,d0
  787.         beq.s   plr_holdend     ;don't hold
  788.         bra.s   plr_hold2
  789. plr_hold1   and.b   #$7f,d1         ;note??
  790.         beq.s   plr_hold2       ;no, cont hold..
  791.         move.b  2(a3),d1
  792.         subq.b  #3,d1           ;is there command 3 (slide)
  793.         bne.s   plr_holdend     ;no -> end holding
  794. plr_hold2   add.b   d3,trk_noteoffcnt(a1)   ;continue holding...
  795. plr_holdend addq.l  #4,a3       ;next note
  796.         dbf d7,plr_chkhold
  797.     ENDC
  798.         rts
  799.  
  800. ; *******************************************************************
  801. ; DoPreFXLoop:  Loop and call DoPreFX
  802. ; *******************************************************************
  803. DoPreFXLoop:
  804. ; -------- PRE-FX COMMAND HANDLING LOOP ----------------------------------
  805.         moveq   #0,d5   ;command page count
  806. plr_loop1   move.w  mmd_pblock(a2),d0
  807.         bsr.w   GetBlockAddr
  808.         move.w  d5,d1
  809.         move.w  mmd_pline(a2),d2
  810.         bsr.w   GetCmdPointer
  811.         movea.l a0,a3
  812.         moveq   #0,d7   ;clear track count
  813.         lea trackdata8-DB(a6),a1
  814. plr_loop1_1 movea.l (a1)+,a5
  815.         clr.b   trk_fxtype(a5)
  816.         move.b  (a3),d0         ;command #
  817.         beq.s   plr_loop1_end
  818.         moveq   #0,d4
  819.         move.b  1(a3),d4        ;data byte
  820.     IFNE    PLAYMMD0
  821.         cmp.b   #3,d6           ;if adv == 3 -> MMD0
  822.         bne.s   doprefx_mmd12mask
  823.         and.w   #$0F,d0
  824.         bra.s   doprefx_mmd0maskd
  825. doprefx_mmd12mask
  826.     ENDC
  827.         and.w   #$1F,d0
  828. doprefx_mmd0maskd
  829.         bsr.s   DoPreFX
  830.         or.b    d0,trk_fxtype(a5)
  831. plr_loop1_end   adda.w  d6,a3           ;next track...
  832.         addq.w  #1,d7
  833.         cmp.w   numtracks-DB(a6),d7
  834.         blt.s   plr_loop1_1
  835.         addq.w  #1,d5
  836.         cmp.w   numpages-DB(a6),d5
  837.         bls.s   plr_loop1
  838.         rts
  839.  
  840. ; *******************************************************************
  841. ; DoPreFX: Perform effects that must be handled before note playing
  842. ; *******************************************************************
  843. ; args:     a6 = DB         d0 = command number (w)
  844. ;       a5 = track data     d5 = note number
  845. ;       a4 = song       d4 = data
  846. ;                   d7 = track #
  847. ; returns:  d0 = 0: play - d0 = 1: don't play
  848.  
  849. rtplay      MACRO
  850.         moveq   #0,d0
  851.         rts
  852.         ENDM
  853. rtnoplay    MACRO
  854.         moveq   #1,d0
  855.         rts
  856.         ENDM
  857.  
  858. DoPreFX:    add.b   d0,d0   ;* 2
  859.         move.w  f_table(pc,d0.w),d0
  860.         jmp fst(pc,d0.w)
  861. f_table     dc.w    fx-fst,fx-fst,fx-fst,f_03-fst,fx-fst,fx-fst,fx-fst,fx-fst
  862.         dc.w    f_08-fst,f_09-fst,fx-fst,f_0b-fst,f_0c-fst,fx-fst,fx-fst,f_0f-fst
  863.         dc.w    fx-fst,fx-fst,fx-fst,fx-fst,fx-fst,f_15-fst,f_16-fst,fx-fst
  864.         dc.w    fx-fst,f_19-fst,fx-fst,fx-fst,fx-fst,f_1d-fst,f_1e-fst,f_1f-fst
  865. fst
  866. ; ---------------- tempo (F)
  867. f_0f        tst.b   d4      ;test effect qual..
  868.         beq fx0fchgblck ;if effect qualifier (last 2 #'s)..
  869.         cmp.b   #$f0,d4     ;..is zero, go to next block
  870.         bhi.s   fx0fspecial ;if it's F1-FF something special
  871. ; ---------------- just an ordinary "change tempo"-request
  872.         moveq   #0,d0       ;will happen!!!
  873.         move.b  d4,d0
  874.         bsr _SetTempo   ;change The Tempo
  875. fx      rtplay
  876. ; ---------------- no, it was FFx, something special will happen!!
  877. fx0fspecial:    cmp.b   #$f2,d4
  878.         beq.s   f_1f
  879.         cmp.b   #$f4,d4
  880.         beq.s   f_1f
  881.         cmp.b   #$f5,d4
  882.         bne.s   isfxfe
  883. ; ---------------- FF2 (or 1Fxx)
  884. f_1f
  885.     IFNE    HOLD
  886.         move.b  trk_inithold(a5),trk_noteoffcnt(a5) ;initialize hold
  887.         bne.s   f_1frts         ;not 0 -> OK
  888.         st  trk_noteoffcnt(a5)  ;0 -> hold = 0xff (-1)
  889.     ENDC
  890. f_1frts     rtnoplay
  891. isfxfe:     cmp.b   #$fe,d4
  892.         bne.s   notcmdfe
  893. ; ---------------- it was FFE, stop playing
  894.         clr.w   mmd_pstate(a2)
  895.         bsr.w   _End8Play
  896.         addq.l  #8,sp   ;2 subroutine levels
  897.         bra.w   plr_exit
  898. f_ffe_no8   rtplay
  899. notcmdfe:   cmp.b   #$fd,d4 ;change period
  900.         bne.s   isfxff
  901. ; ---------------- FFD, change the period, don't replay the note
  902.         move.l  trk_periodtbl(a5),d1    ;period table
  903.         beq.s   f_1frts
  904.         movea.l d1,a0
  905.         move.b  trk_currnote(a5),d0
  906.         subq.b  #1,d0    ;sub 1 to make "real" note number
  907.     IFNE    CHECK
  908.         bmi.s   f_1frts
  909.     ENDC
  910.         add.b   msng_playtransp(a4),d0
  911.         add.b   trk_stransp(a5),d0
  912.         add.w   d0,d0
  913.         bmi.s   f_1frts
  914.         move.w  0(a0,d0.w),trk_prevper(a5) ;get & push the period
  915.         rtnoplay
  916. isfxff:     cmp.b   #$ff,d4     ;note off??
  917.         bne.s   f_ff_rts
  918.         bsr.w   _ChannelO8
  919. f_ff_rts    rtplay
  920. ; ---------------- F00, called Pattern Break in ST
  921. fx0fchgblck:    move.b  #1,nextblock-DB(a6)
  922.         bra.s   f_ff_rts
  923. ; ---------------- change volume
  924. f_0c        btst    #4,msng_flags(a4)   ;look at flags
  925.         bne.s   volhex8
  926.         move.b  d4,d1       ;get again
  927.         lsr.b   #4,d4       ;get number from left
  928.         mulu    #10,d4      ;number of tens
  929.         and.b   #$0f,d1     ;this time don't get tens
  930.         add.b   d1,d4       ;add them
  931. volhex8
  932.     IFNE    CHECK
  933.         cmp.b   #64,d4
  934.         bhi.s   go_nocmd8
  935.     ENDC
  936.         movea.l trk_audioaddr(a5),a0
  937.         movea.l ac_vol(a0),a0
  938.         move.b  d4,(a0)
  939. go_nocmd8   rtplay
  940. ; ---------------- tempo2 change??
  941. f_09
  942.     IFNE    CHECK
  943.         and.b   #$1F,d4
  944.         bne.s   fx9chk
  945.         moveq   #$20,d4
  946.     ENDC
  947. fx9chk:     move.b  d4,msng_tempo2(a4)
  948. f_09_rts    rtplay
  949. ; ---------------- block delay
  950. f_1e        tst.w   blkdelay-DB(a6)
  951.         bne.s   f_1e_rts
  952.         addq.w  #1,d4
  953.         move.w  d4,blkdelay-DB(a6)
  954. f_1e_rts    rtplay
  955. ; ---------------- finetune
  956. f_15
  957.     IFNE    CHECK
  958.         cmp.b   #7,d4
  959.         bgt.s   f_15_rts
  960.         cmp.b   #-8,d4
  961.         blt.s   f_15_rts
  962.     ENDC
  963.         move.b  d4,trk_finetune(a5)
  964. f_15_rts    rtplay
  965. ; ---------------- repeat loop
  966. f_16        tst.b   d4
  967.         bne.s   plr_dorpt
  968.         move.w  mmd_pline(a2),rptline-DB(a6)
  969.         bra.s   f_16_rts
  970. plr_dorpt   tst.w   rptcounter-DB(a6)
  971.         beq.s   plr_newrpt
  972.         subq.w  #1,rptcounter-DB(a6)
  973.         beq.s   f_16_rts
  974.         bra.s   plr_setrptline
  975. plr_newrpt  move.b  d4,rptcounter+1-DB(a6)
  976. plr_setrptline  move.w  rptline-DB(a6),d0
  977.         addq.w  #1,d0
  978.         move.w  d0,nextblockline-DB(a6)
  979. f_16_rts    rtplay
  980. ; ---------------- note off time set??
  981. f_08
  982.     IFNE    HOLD
  983.         and.b   #$0f,d4
  984.         move.b  d4,trk_inithold(a5) ;right = hold
  985.     ENDC
  986.         rtplay
  987. ; ---------------- sample begin offset
  988. f_19        lsl.w   #8,d4
  989.         move.w  d4,trk_soffset(a5)
  990. f_19_rts    rtplay
  991. ; ---------------- cmd Bxx, "position jump"
  992. f_0b
  993.     IFNE    CHECK
  994.         cmp.b   #'2',3(a2)
  995.         beq.s   chk0b_mmd2
  996.         cmp.w   msng_songlen(a4),d4
  997.         bhi.s   f_0b_rts
  998.         bra.s   chk0b_end
  999. chk0b_mmd2  move.w  mmd_pseq(a2),d0     ;get seq number
  1000.         movea.l msng_pseqs(a4),a0   ;ptr to playseqs
  1001.         movea.l 0(a0,d0.w),a0       ;a0 = ptr to curr PlaySeq
  1002.         cmp.w   40(a0),d4       ;test song length
  1003.         bhi.s   f_0b_rts
  1004. chk0b_end
  1005.     ENDC
  1006.         move.w  d4,mmd_pseqnum(a2)
  1007.         st  nextblock-DB(a6)    ; = 1
  1008. f_0b_rts    rtplay
  1009. ; ---------------- cmd 1Dxx, jump to next seq, line # specified
  1010. f_1d        move.w  #$1ff,nextblock-DB(a6)
  1011.         addq.w  #1,d4
  1012.         move.w  d4,nextblockline-DB(a6)
  1013.         rtplay
  1014. ; ---------------- try portamento (3)
  1015. f_03        moveq   #0,d0
  1016.         move.b  trk_currnote(a5),d0
  1017.         subq.b  #1,d0       ;subtract note number
  1018.         bmi.s   plr_setfx3spd   ;0 -> set new speed
  1019.         move.l  trk_periodtbl(a5),d1
  1020.         beq.s   f_03_rts
  1021.         movea.l d1,a0
  1022.         add.b   msng_playtransp(a4),d0  ;play transpose
  1023.         add.b   trk_stransp(a5),d0 ;and instrument transpose
  1024.         bmi.s   f_03_rts    ;again.. too low
  1025.         add.w   d0,d0
  1026.         move.w  0(a0,d0.w),trk_porttrgper(a5) ;period of this note is the target
  1027. plr_setfx3spd:  tst.b   d4      ;qual??
  1028.         beq.s   f_03_rts    ;0 -> do nothing
  1029.         move.b  d4,trk_prevportspd(a5)  ;store speed
  1030. f_03_rts    rtnoplay
  1031.  
  1032. ; *******************************************************************
  1033. ; DoFX: Handle effects, hold/fade etc.
  1034. ; *******************************************************************
  1035. DoFX        moveq   #0,d3
  1036.         move.b  mmd_counter(a2),d3
  1037.     IFNE    HOLD
  1038.         lea trackdata8-DB(a6),a1
  1039. ; Loop 1: Hold/Fade handling
  1040.         moveq   #0,d7   ;clear track count
  1041. dofx_loop1  movea.l (a1)+,a5
  1042. ; *******************************************************************
  1043. ; HoldAndFade: Handle hold/fade
  1044. ; *******************************************************************
  1045. ; args:     a5 = track data
  1046. ;       a6 = DB
  1047. ;       d7 = track #
  1048. ; scratches:    d0, d1, a0, a1
  1049.  
  1050. HoldAndFade tst.b   trk_noteoffcnt(a5)
  1051.         bmi.s   plr_haf_dofx
  1052.         subq.b  #1,trk_noteoffcnt(a5)
  1053.         bpl.s   plr_haf_dofx
  1054.         bsr.w   _ChannelO8  ;hold time expired
  1055. plr_haf_dofx    addq.w  #1,d7
  1056.         cmp.w   numtracks-DB(a6),d7
  1057.         blt.s   dofx_loop1
  1058.     ENDC
  1059. ; Loop 2: Track command handling
  1060.         moveq   #0,d5   ;command page count
  1061. dofx_loop2  move.w  fxplineblk-DB(a6),d0
  1062.         bsr.w   GetBlockAddr
  1063.         movea.l a0,a3
  1064.     IFNE    PLAYMMD0
  1065.         cmp.b   #'1',3(a2)
  1066.         bge.s   dofx_sbd_nommd0
  1067.         bsr.w   StoreBlkDimsMMD0
  1068.         bra.s   dofx_sbd_mmd0
  1069. dofx_sbd_nommd0
  1070.     ENDC
  1071.         bsr.w   StoreBlockDims
  1072. dofx_sbd_mmd0   move.w  d5,d1
  1073.         move.w  fxplineblk+2-DB(a6),d2
  1074.         movea.l a3,a0
  1075.         bsr.s   GetCmdPointer
  1076.         movea.l a0,a3
  1077.         moveq   #0,d7   ;clear track count
  1078.         lea trackdata8-DB(a6),a1
  1079. dofx_loop2_1    movea.l (a1)+,a5
  1080.         moveq   #0,d4
  1081.         move.b  (a3),d0         ;command #
  1082.         move.b  1(a3),d4        ;data byte
  1083.     IFNE    PLAYMMD0
  1084.         cmp.b   #3,d6           ;if adv == 3 -> MMD0
  1085.         bne.s   dofx_mmd12mask
  1086.         and.w   #$0F,d0
  1087.         bra.s   dofx_mmd0maskd
  1088. dofx_mmd12mask
  1089.     ENDC
  1090.         and.w   #$1F,d0
  1091. dofx_mmd0maskd  bsr.w   ChannelFX
  1092. dofx_lend2_1    adda.w  d6,a3           ;next track...
  1093.         addq.w  #1,d7
  1094.         cmp.w   numtracks-DB(a6),d7
  1095.         blt.s   dofx_loop2_1
  1096.         addq.w  #1,d5
  1097.         cmp.w   numpages-DB(a6),d5
  1098.         bls.s   dofx_loop2
  1099. ; Loop 3: Updating audio hardware
  1100.         moveq   #0,d7   ;clear track count
  1101.         lea trackdata8-DB(a6),a1
  1102. dofx_loop3  movea.l (a1)+,a5
  1103. ; *******************************************************************
  1104. ; UpdatePerVol: Update audio registers (period & volume) after FX
  1105. ; *******************************************************************
  1106. UpdatePerVol    move.w  trk_prevper(a5),d1
  1107.         add.w   trk_vibradjust(a5),d1
  1108.         movea.l trk_audioaddr(a5),a0
  1109.         sub.w   trk_arpadjust(a5),d1
  1110.         clr.l   trk_vibradjust(a5)  ;clr both adjusts
  1111.         move.w  d1,ac_per(a0)
  1112. dofx_lend3  addq.w  #1,d7
  1113.         cmp.w   numtracks-DB(a6),d7
  1114.         blt.s   dofx_loop3
  1115.         rts
  1116.  
  1117. ; *******************************************************************
  1118. ; GetCmdPointer: Return command pointer for track 0
  1119. ; *******************************************************************
  1120. ; args:     a0 = block pointer
  1121. ;       d1 = page number
  1122. ;       d2 = line number
  1123. ;       a2 = module
  1124. ; result:   a0 = command pointer (i.e. trk 0 note + 2)
  1125. ;       d6 = track advance (bytes)
  1126. ; scratches:    d0, d1, d2, a0
  1127. ; Note: no num_pages check! If numpages > 0 it can be assumed that
  1128. ; extra pages exist.
  1129.  
  1130. GetCmdPointer
  1131.     IFNE    PLAYMMD0
  1132.         cmp.b   #'1',3(a2)
  1133.         blt.s   GetCmdPtrMMD0
  1134.     ENDC
  1135.         mulu    (a0),d2     ;d2 = line # * numtracks
  1136.         add.l   d2,d2       ;d2 *= 2...
  1137.         subq.w  #1,d1
  1138.         bmi.s   gcp_page0
  1139.         movea.l 4(a0),a0
  1140.         movea.l 12(a0),a0
  1141.         add.w   d1,d1
  1142.         add.w   d1,d1
  1143.         movea.l 4(a0,d1.w),a0   ;command data
  1144.         adda.l  d2,a0
  1145.         moveq   #2,d6
  1146.         rts
  1147. gcp_page0   add.l   d2,d2       ;d2 *= 4
  1148.         lea 10(a0,d2.l),a0  ;offs: 4 = header, 2 = note
  1149.         moveq   #4,d6       ;track advance (bytes)
  1150.         rts
  1151.     IFNE    PLAYMMD0
  1152. GetCmdPtrMMD0   moveq   #0,d0
  1153.         move.b  (a0),d0     ;get numtracks
  1154.         mulu    d0,d2       ;line # * numtracks
  1155.         move.w  d2,d0
  1156.         add.w   d2,d2
  1157.         add.w   d0,d2       ; *= 3...
  1158.         lea 3(a0,d2.l),a0   ;offs: 2 = header, 1 = note
  1159.         moveq   #3,d6
  1160.         rts
  1161.     ENDC
  1162.  
  1163. ; *******************************************************************
  1164. ; GetBlockAddr: Return pointer to block
  1165. ; *******************************************************************
  1166. ; args:     d0 = block number
  1167. ; result:   a0 = block pointer
  1168. ; scratches: d0, a0
  1169.  
  1170. GetBlockAddr    movea.l mmd_blockarr(a2),a0
  1171.         add.w   d0,d0
  1172.         add.w   d0,d0
  1173.         movea.l 0(a0,d0.w),a0
  1174.         rts
  1175.  
  1176. ; *******************************************************************
  1177. ; GetNoteDataAddr: Check & return addr. of current note
  1178. ; *******************************************************************
  1179. ;args:      d0 = pblock     a6 = DB
  1180. ;returns:   a3 = address
  1181. ;scratches: d0, a0, d1
  1182.  
  1183. GetNoteDataAddr bsr.w   GetBlockAddr
  1184.         movea.l a0,a3
  1185.     IFNE    PLAYMMD0
  1186.         cmp.b   #'1',3(a2)
  1187.         blt.s   GetNDAddrMMD0
  1188.     ENDC
  1189.         bsr.w   StoreBlockDims
  1190.         move.w  numlines-DB(a6),d1
  1191.         move.w  mmd_pline(a2),d0
  1192.         cmp.w   d1,d0       ;check if block end exceeded...
  1193.         bls.s   plr_nolinex
  1194.         move.w  d1,d0
  1195. plr_nolinex add.w   d0,d0
  1196.         add.w   d0,d0   ;d0 = d0 * 4
  1197.         mulu    (a3),d0
  1198.         lea 8(a3,d0.l),a3   ;address of current note
  1199.         rts
  1200.  
  1201.     IFNE    PLAYMMD0
  1202. GetNDAddrMMD0   bsr.w   StoreBlkDimsMMD0
  1203.         move.w  numlines-DB(a6),d1
  1204.         move.w  mmd_pline(a2),d0
  1205.         cmp.w   d1,d0       ;check if block end exceeded...
  1206.         bls.s   plr_nolinex2
  1207.         move.w  d1,d0
  1208. plr_nolinex2    move.w  d0,d1
  1209.         add.w   d0,d0
  1210.         add.w   d1,d0   ;d0 = d0 * 3
  1211.         moveq   #0,d1
  1212.         move.b  (a3),d1 ;numtracks
  1213.         mulu    d1,d0
  1214.         lea 2(a3,d0.l),a3   ;address of current note
  1215.         rts
  1216.     ENDC
  1217.  
  1218. ; *******************************************************************
  1219. ; StoreBlockDims: Store block dimensions
  1220. ; *******************************************************************
  1221. ; args:     a0 = block ptr, a6 = DB
  1222.  
  1223. StoreBlockDims  move.w  (a0)+,d0
  1224.         cmp.w   #8,d0
  1225.         ble.s   sbd_lt8
  1226.         moveq   #8,d0
  1227. sbd_lt8     move.w  d0,numtracks-DB(a6) ;numtracks & lines
  1228.         move.w  (a0)+,numlines-DB(a6)
  1229.         tst.l   (a0)            :BlockInfo
  1230.         beq.s   sbd_1page
  1231.         movea.l (a0),a0
  1232.         move.l  12(a0),d0       ;BlockInfo.pagetable
  1233.         beq.s   sbd_1page
  1234.         movea.l d0,a0
  1235.         move.w  (a0),numpages-DB(a6)    ;num_pages
  1236.         rts
  1237. sbd_1page   clr.w   numpages-DB(a6)
  1238.         rts
  1239.  
  1240.     IFNE    PLAYMMD0
  1241. StoreBlkDimsMMD0
  1242.         clr.w   numpages-DB(a6)
  1243.         moveq   #0,d0
  1244.         move.b  (a0)+,d0        ;numtracks
  1245.         cmp.w   #8,d0
  1246.         ble.s   sbd_lt8_2
  1247.         moveq   #8,d0
  1248. sbd_lt8_2   move.w  d0,numtracks-DB(a6)
  1249.         move.b  (a0),d0         ;numlines
  1250.         move.w  d0,numlines-DB(a6)
  1251.         rts
  1252.     ENDC
  1253.  
  1254. ; *******************************************************************
  1255. ; ChannelFX:    Do an effect on a channel
  1256. ; *******************************************************************
  1257. ;args:                  d3 = counter
  1258. ;       a4 = song struct    d4 = command qual (long, byte used)
  1259. ;       a5 = track data ptr 
  1260. ;       a6 = DB         d0 = command (long, byte used)
  1261. ;                   d7 = track (channel) number
  1262. ;scratches: d0, d1, d4, a0
  1263.  
  1264. ChannelFX   add.b   d0,d0   ;* 2
  1265.         move.w  fx_table(pc,d0.w),d0
  1266.         jmp fxs(pc,d0.w)
  1267. fx_table    dc.w    fx_00-fxs,fx_01-fxs,fx_02-fxs,fx_03-fxs,fx_04-fxs
  1268.         dc.w    fx_05-fxs,fx_06-fxs,fx_07-fxs,fx_xx-fxs,fx_xx-fxs
  1269.         dc.w    fx_0a-fxs,fx_xx-fxs,fx_xx-fxs,fx_0d-fxs,fx_xx-fxs
  1270.         dc.w    fx_0f-fxs
  1271.         dc.w    fx_xx-fxs,fx_11-fxs,fx_12-fxs,fx_13-fxs,fx_14-fxs
  1272.         dc.w    fx_xx-fxs,fx_xx-fxs,fx_xx-fxs,fx_18-fxs,fx_xx-fxs
  1273.         dc.w    fx_1a-fxs,fx_1b-fxs,fx_xx-fxs,fx_xx-fxs,fx_xx-fxs
  1274.         dc.w    fx_1f-fxs
  1275. fxs:
  1276. ;   **************************************** Effect 01 ******
  1277. fx_01       tst.b   d3
  1278.         bne.s   fx_01nocnt0
  1279.         btst    #5,msng_flags(a4)   ;FLAG_STSLIDE??
  1280.         bne.s   fx_01rts
  1281. fx_01nocnt0 move.w  trk_prevper(a5),d0
  1282.         sub.w   d4,d0
  1283.         cmp.w   #113,d0
  1284.         bge.s   fx_01noovf
  1285.         move.w  #113,d0
  1286. fx_01noovf  move.w  d0,trk_prevper(a5)
  1287. fx_xx       ;fx_xx is just a RTS
  1288. fx_01rts    rts
  1289. ;   **************************************** Effect 11 ******
  1290. fx_11       tst.b   d3
  1291.         bne.s   fx_11rts
  1292.         sub.w   d4,trk_prevper(a5)
  1293. fx_11rts    rts
  1294. ;   **************************************** Effect 02 ******
  1295. fx_02       tst.b   d3
  1296.         bne.s   fx_02nocnt0
  1297.         btst    #5,msng_flags(a4)
  1298.         bne.s   fx_02rts
  1299. fx_02nocnt0 add.w   d4,trk_prevper(a5)
  1300. fx_02rts    rts
  1301. ;   **************************************** Effect 12 ******
  1302. fx_12       tst.b   d3
  1303.         bne.s   fx_12rts
  1304.         add.w   d4,trk_prevper(a5)
  1305. fx_12rts    rts
  1306. ;   **************************************** Effect 00 ******
  1307. fx_00       tst.b   d4  ;both fxqualifiers are 0s: no arpeggio
  1308.         beq.s   fx_00rts
  1309.         move.l  d3,d0
  1310.         divu    #3,d0
  1311.         swap    d0
  1312.         subq.b  #1,d0
  1313.         bgt.s   fx_arp2
  1314.         blt.s   fx_arp0
  1315.         and.b   #$0f,d4
  1316.         bra.s   fx_doarp
  1317. fx_arp0     lsr.b   #4,d4
  1318.         bra.s   fx_doarp
  1319. fx_arp2     moveq   #0,d4
  1320. fx_doarp:   move.b  (a5),d0
  1321.         subq.b  #1,d0       ;-1 to make it 0 - 127
  1322.         add.b   msng_playtransp(a4),d0  ;add play transpose
  1323.         add.b   trk_stransp(a5),d0  ;add instrument transpose
  1324.         add.b   d0,d4
  1325.         move.l  trk_periodtbl(a5),d1
  1326.         beq.s   fx_00rts
  1327.         movea.l d1,a0
  1328.         add.b   d0,d0
  1329.         move.w  0(a0,d0.w),d0   ;base note period
  1330.         add.b   d4,d4
  1331.         sub.w   0(a0,d4.w),d0   ;calc difference from base note
  1332.         move.w  d0,trk_arpadjust(a5)
  1333. fx_00rts    rts
  1334. ;   **************************************** Effect 04 ******
  1335. fx_14       move.b  #6,trk_vibshift(a5)
  1336.         bra.s   vib_cont
  1337. fx_04       move.b  #5,trk_vibshift(a5)
  1338. vib_cont    tst.b   d3
  1339.         bne.s   nonvib
  1340.         move.b  d4,d1
  1341.         beq.s   nonvib
  1342.         and.w   #$0f,d1
  1343.         beq.s   plr_chgvibspd
  1344.         move.w  d1,trk_vibrsz(a5)
  1345. plr_chgvibspd   and.b   #$f0,d4
  1346.         beq.s   nonvib
  1347.         lsr.b   #3,d4
  1348.         and.b   #$3e,d4
  1349.         move.b  d4,trk_vibrspd(a5)
  1350. nonvib      move.b  trk_vibroffs(a5),d0
  1351.         lsr.b   #2,d0
  1352.         and.w   #$1f,d0
  1353.         moveq   #0,d1
  1354.         move.b  sinetable(pc,d0.w),d0
  1355.         ext.w   d0
  1356.         muls    trk_vibrsz(a5),d0
  1357.         move.b  trk_vibshift(a5),d1
  1358.         asr.w   d1,d0
  1359.         move.w  d0,trk_vibradjust(a5)
  1360.         move.b  trk_vibrspd(a5),d0
  1361.         add.b   d0,trk_vibroffs(a5)
  1362. fx_04rts    rts
  1363. sinetable:  dc.b    0,25,49,71,90,106,117,125,127,125,117,106,90,71,49
  1364.         dc.b    25,0,-25,-49,-71,-90,-106,-117,-125,-127,-125,-117
  1365.         dc.b    -106,-90,-71,-49,-25,0
  1366. ;   **************************************** Effect 06 ******
  1367. fx_06:      tst.b   d3
  1368.         bne.s   fx_06nocnt0
  1369.         btst    #5,msng_flags(a4)
  1370.         bne.s   fx_04rts
  1371. fx_06nocnt0 bsr.s   plr_volslide        ;Volume slide
  1372.         bra.s   nonvib          ;+ Vibrato
  1373. ;   **************************************** Effect 07 ******
  1374. fx_07       tst.b   d3
  1375.         bne.s   nontre
  1376.         move.b  d4,d1
  1377.         beq.s   nontre
  1378.         and.w   #$0f,d1
  1379.         beq.s   plr_chgtrespd
  1380.         move.w  d1,trk_tremsz(a5)
  1381. plr_chgtrespd   and.b   #$f0,d4
  1382.         beq.s   nontre
  1383.         lsr.b   #2,d4
  1384.         and.b   #$3e,d4
  1385.         move.b  d4,trk_tremspd(a5)
  1386. nontre      move.b  trk_tremoffs(a5),d0
  1387.         lsr.b   #3,d0
  1388.         and.w   #$1f,d0
  1389.         lea sinetable(pc),a0
  1390.         move.b  0(a0,d0.w),d1
  1391.         ext.w   d1
  1392.         muls    trk_tremsz(a5),d1
  1393.         asr.w   #7,d1
  1394.         move.b  trk_tremspd(a5),d0
  1395.         add.b   d0,trk_tremoffs(a5)
  1396.         add.b   trk_prevvol(a5),d1
  1397.         bpl.s   tre_pos
  1398.         moveq   #0,d1
  1399. tre_pos     cmp.b   #64,d1
  1400.         ble.s   tre_no2hi
  1401.         moveq   #64,d1
  1402. tre_no2hi   move.b  d1,trk_tempvol(a5)
  1403.         rts
  1404. ;   ********* VOLUME SLIDE FUNCTION *************************
  1405. plr_volslide    move.b  d4,d0
  1406.         moveq   #0,d1
  1407.         move.b  trk_prevvol(a5),d1 ;move previous vol to d1
  1408.         and.b   #$f0,d0
  1409.         bne.s   crescendo
  1410.         sub.b   d4,d1   ;sub from prev. vol
  1411. voltest0    bpl.s   novolover64
  1412.         moveq   #0,d1   ;volumes under zero not accepted
  1413.         bra.s   novolover64
  1414. crescendo:  lsr.b   #4,d0
  1415.         add.b   d0,d1
  1416. voltest     cmp.b   #64,d1
  1417.         ble.s   novolover64
  1418.         moveq   #64,d1
  1419. novolover64 movea.l trk_audioaddr(a5),a0
  1420.         movea.l ac_vol(a0),a0
  1421.         move.b  d1,(a0)
  1422. volsl_rts   rts
  1423. ;   **************************************** Effect 0D/0A ***
  1424. fx_0a:
  1425. fx_0d:      tst.b   d3
  1426.         bne.s   plr_volslide
  1427.         btst    #5,msng_flags(a4)
  1428.         beq.s   plr_volslide
  1429.         rts
  1430. ;   **************************************** Effect 05 ******
  1431. fx_05:      tst.b   d3
  1432.         bne.s   fx_05nocnt0
  1433.         btst    #5,msng_flags(a4)
  1434.         bne.s   fx_05rts
  1435. fx_05nocnt0 bsr.s   plr_volslide
  1436.         bra.s   fx_03nocnt0
  1437. fx_05rts    rts
  1438. ;   **************************************** Effect 1A ******
  1439. fx_1a       tst.b   d3
  1440.         bne.s   volsl_rts
  1441.         move.b  trk_prevvol(a5),d1
  1442.         add.b   d4,d1
  1443.         bra.s   voltest
  1444. ;   **************************************** Effect 1B ******
  1445. fx_1b       tst.b   d3
  1446.         bne.s   volsl_rts
  1447.         move.b  trk_prevvol(a5),d1
  1448.         sub.b   d4,d1
  1449.         bra.s   voltest0
  1450. ;   **************************************** Effect 03 ******
  1451. fx_03       tst.b   d3
  1452.         bne.s   fx_03nocnt0
  1453.         btst    #5,msng_flags(a4)
  1454.         bne.s   fx_03rts
  1455. fx_03nocnt0 move.w  trk_porttrgper(a5),d0   ;d0 = target period
  1456.         beq.s   fx_03rts
  1457.         move.w  trk_prevper(a5),d1  ;d1 = curr. period
  1458.         move.b  trk_prevportspd(a5),d4  ;get prev. speed
  1459.         cmp.w   d0,d1
  1460.         bhi.s   subper  ;curr. period > target period
  1461.         add.w   d4,d1   ;add the period
  1462.         cmp.w   d0,d1
  1463.         bge.s   targreached
  1464.         bra.s   targnreach
  1465. subper:     sub.w   d4,d1   ;subtract
  1466.         cmp.w   d0,d1   ;compare current period to target period
  1467.         bgt.s   targnreach
  1468. targreached:    move.w  trk_porttrgper(a5),d1 ;eventually push target period
  1469.         clr.w   trk_porttrgper(a5) ;now we can forget everything
  1470. targnreach: move.w  d1,trk_prevper(a5)
  1471. fx_03rts    rts
  1472. ;   **************************************** Effect 13 ******
  1473. fx_13:      cmp.b   #3,d3
  1474.         bge.s   fx_13rts    ;if counter < 3
  1475.         neg.w   d4
  1476.         move.w  d4,trk_vibradjust(a5)   ;subtract effect qual...
  1477. fx_13rts    rts
  1478. ;   **************************************** Effect 18 ******
  1479. fx_18       cmp.b   d4,d3
  1480.         bne.s   fx_18rts
  1481.         clr.b   trk_prevvol(a5)
  1482. fx_18rts    rts
  1483. ;   **************************************** Effect 1F ******
  1484. fx_1f       move.b  d4,d1
  1485.         lsr.b   #4,d4       ;note delay
  1486.         beq.s   nonotedelay
  1487.         cmp.b   d4,d3       ;compare to counter
  1488.         blt.s   fx_18rts    ;tick not reached
  1489.         bne.s   nonotedelay
  1490.         bra playfxnote  ;trigger note
  1491. nonotedelay and.w   #$0f,d1     ;retrig?
  1492.         beq.s   fx_18rts
  1493.         moveq   #0,d0
  1494.         move.b  d3,d0
  1495.         divu    d1,d0
  1496.         swap    d0      ;get modulo of counter/tick
  1497.         tst.w   d0
  1498.         bne.s   fx_18rts
  1499.         bra playfxnote  ;retrigger
  1500. ;   **************************************** Effect 0F ******
  1501. ;   see below...
  1502. ;   *********************************************************
  1503.  
  1504. ; **** a separate routine for handling command 0F
  1505. fx_0f       cmp.b   #$f1,d4
  1506.         bne.s   no0ff1
  1507.         cmp.b   #3,d3
  1508.         beq.s   playfxnote
  1509.         rts
  1510. no0ff1:     cmp.b   #$f2,d4
  1511.         bne.s   no0ff2
  1512.         cmp.b   #3,d3
  1513.         beq.s   playfxnote
  1514.         rts
  1515. no0ff2:     cmp.b   #$f3,d4
  1516.         bne.s   no0ff3
  1517.         move.b  d3,d0
  1518.         beq.s   cF_rts
  1519.         and.b   #1,d0       ;is 2 or 4
  1520.         bne.s   cF_rts
  1521. playfxnote: moveq   #0,d1
  1522.         move.b  trk_currnote(a5),d1 ;get note # of curr. note
  1523.         beq.s   cF_rts
  1524.         move.b  trk_noteoffcnt(a5),d0   ;get hold counter
  1525.         bmi.s   pfxn_nohold     ;no hold, or hold over
  1526.         add.b   d3,d0           ;increase by counter val
  1527.         bra.s   pfxn_hold
  1528. pfxn_nohold move.b  trk_inithold(a5),d0 ;get initial hold
  1529.         bne.s   pfxn_hold
  1530.         st  d0
  1531. pfxn_hold   move.b  d0,trk_noteoffcnt(a5)
  1532.         movem.l a1/a3/d3/d6,-(sp)
  1533.         moveq   #0,d3
  1534.         move.b  trk_previnstr(a5),d3    ;and prev. sample #
  1535.         movea.l trk_previnstra(a5),a3
  1536.         bsr _PlayNote8
  1537.         movem.l (sp)+,a1/a3/d3/d6
  1538. cF_rts      rts
  1539. no0ff3:     cmp.b   #$f4,d4     ;triplet cmd 1
  1540.         bne.s   no0ff4
  1541.         moveq   #0,d0
  1542.         move.b  msng_tempo2(a4),d0
  1543.         divu    #3,d0
  1544.         cmp.b   d0,d3
  1545.         beq.s   playfxnote
  1546.         rts
  1547. no0ff4      cmp.b   #$f5,d4     ;triplet cmd 2
  1548.         bne.s   no0ff5
  1549.         moveq   #0,d0
  1550.         move.b  msng_tempo2(a4),d0
  1551.         divu    #3,d0
  1552.         add.w   d0,d0
  1553.         cmp.b   d0,d3
  1554.         beq.s   playfxnote
  1555.         rts
  1556. no0ff5      cmp.b   #$f8,d4     ;f8 = filter off
  1557.         beq.s   plr_filteroff
  1558.         cmp.b   #$f9,d4     ;f9 = filter on
  1559.         bne.s   cF_rts
  1560.         bclr    #1,$bfe001
  1561.         bset    #0,msng_flags(a4)
  1562.         rts
  1563. plr_filteroff:  bset    #1,$bfe001
  1564.         bclr    #0,msng_flags(a4)
  1565.         rts
  1566.  
  1567. _SetTempo:  move.l  _module8-DB(a6),d1
  1568.         beq.s   ST_x
  1569.         movea.l d1,a0
  1570.         movea.l mmd_songinfo(a0),a0
  1571.         move.w  d0,msng_deftempo(a0)
  1572.         tst.w   d0
  1573.         ble.s   ST_maxszcnt
  1574.         cmp.w   #9,d0
  1575.         bls.s   ST_nodef8tempo
  1576. ST_maxszcnt moveq   #10,d0
  1577. ST_nodef8tempo  add.b   #9,d0
  1578.         move.b  d0,currchszcnt-DB+1(a6)
  1579.         tst.b   msng_flags(a0)  ;test SLOWHQ compatibility flag
  1580.         lea eightchsizes-10-DB(a6),a0
  1581.         bmi.s   ST_slowhq   ;SLOWHQ set
  1582.         tst.b   _hq-DB(a6)
  1583.         beq.s   ST_nohq
  1584.         move.b  10(a0,d0.w),d0  ;get buffersize / 4
  1585.         add.w   d0,d0       ;->buffersize / 2
  1586.         bra.s   ST_hqcont
  1587. ST_slowhq   move.b  0(a0,d0.w),d0
  1588.         add.w   d0,d0
  1589.         bra.s   ST_hqcont
  1590. ST_nohq     move.b  0(a0,d0.w),d0   ;get buffersize / 2
  1591. ST_hqcont   move.w  d0,currchsize2-DB(a6)
  1592.         asl.w   #3,d0       ;get buffersize * 4
  1593.         move.w  d0,currchsize-DB(a6)
  1594. ST_x        rts
  1595.  
  1596. _Rem8chan:  move.l  a6,-(sp)
  1597.         lea DB,a6
  1598.         move.b  eightrkon-DB(a6),d0
  1599.         beq.s   no8init
  1600.         clr.b   eightrkon-DB(a6)
  1601.         move.w  #1<<7,$dff09a
  1602.         move.l  prevaud-DB(a6),d0
  1603.         beq.s   no8init
  1604.         move.l  d0,a1
  1605.         move.l  4,a6
  1606.         moveq   #7,d0
  1607.         jsr -$a2(a6)
  1608. no8init     move.l  (sp)+,a6
  1609.         rts
  1610.  
  1611. _End8Play:  tst.b   play8
  1612.         beq.s   noend8play
  1613.         move.w  #1<<7,$dff09a
  1614.         move.w  #$F,$dff096
  1615.         clr.b   play8
  1616. noend8play  rts
  1617.  
  1618. ; *************************************************************************
  1619. ; *************************************************************************
  1620. ; ***********          P U B L I C   F U N C T I O N S          ***********
  1621. ; *************************************************************************
  1622. ; *************************************************************************
  1623.  
  1624.         xdef    _PlayModule8
  1625.         xdef    _InitPlayer8,_RemPlayer8,_StopPlayer8
  1626.         xdef    _ContModule8
  1627.  
  1628. ; *************************************************************************
  1629. ; InitModule8(a0 = module) -- extract expansion data etc.. from the module
  1630. ; *************************************************************************
  1631.  
  1632. _InitModule8:   movem.l a2-a3/a6/d2,-(sp)
  1633.         lea DB,a6
  1634.         move.l  a0,d0
  1635.         beq.w   IM_exit         ;0 => xit
  1636.         lea holdvals-DB(a6),a2
  1637.         movea.l mmd_songinfo(a0),a3
  1638.         move.l  mmd_expdata(a0),d0  ;expdata...
  1639.         beq.s   IM_clrhlddec        ;none here
  1640.         move.l  d0,a1
  1641.         move.l  4(a1),d0        ;exp_smp
  1642.         beq.s   IM_clrhlddec    ;again.. nothing
  1643.         move.l  d0,a0       ;InstrExt...
  1644.         move.w  8(a1),d2    ;# of entries
  1645.         beq.s   IM_clrhlddec
  1646.         subq.w  #1,d2       ;- 1 (for dbf)
  1647.         move.w  10(a1),d0   ;entry size
  1648. IM_loop1    clr.b   63(a2)      ;clear finetune
  1649.         cmp.w   #3,d0
  1650.         ble.s   IM_noftune
  1651.         move.b  3(a0),63(a2)
  1652. IM_noftune  clr.b   126(a2)     ;clear flags
  1653.         cmp.w   #6,d0
  1654.         blt.s   IM_noflags
  1655.         move.b  5(a0),126(a2)   ;InstrExt.flags -> flags
  1656.         bra.s   IM_gotflags
  1657. IM_noflags  cmp.w   #1,inst_replen(a3)
  1658.         bls.s   IM_gotflags
  1659.         bset    #0,126(a2)
  1660. IM_gotflags move.b  (a0),(a2)+  ;InstrExt.hold -> holdvals
  1661.         adda.w  d0,a0       ;ptr to next InstrExt
  1662.         addq.l  #8,a3       ;next instrument...
  1663.         dbf d2,IM_loop1
  1664.         bra.s   IM_exit
  1665. IM_clrhlddec    moveq   #125,d0     ;no InstrExt => clear holdvals/decays
  1666. IM_loop2    clr.b   (a2)+
  1667.         dbf d0,IM_loop2
  1668. ; -------- For (very old) MMDs, with no InstrExt, set flags/SSFLG_LOOP.
  1669.         lea flags,a2
  1670.         moveq   #62,d0
  1671. IM_loop4    cmp.w   #1,inst_replen(a3)
  1672.         bls.s   IM_noreptflg
  1673.         bset    #0,(a2)
  1674. IM_noreptflg    addq.l  #1,a2
  1675.         addq.l  #8,a3       ;next inst
  1676.         dbf d0,IM_loop4
  1677. IM_exit     movem.l (sp)+,a2-a3/a6/d2
  1678.         rts
  1679.  
  1680.  
  1681. ; *************************************************************************
  1682. ; ContModule8(a0 = module) -- continue playing
  1683. ; *************************************************************************
  1684. _ContModule8    bsr.w   _End8Play
  1685.         moveq   #0,d0
  1686.         bra.s   contpoint8
  1687. ; *************************************************************************
  1688. ; PlayModule8(a0 = module)  -- init and play a module
  1689. ; *************************************************************************
  1690. _PlayModule8:   st  d0
  1691. contpoint8  move.l  a6,-(sp)
  1692.         lea DB,a6
  1693.         movem.l a0/d0,-(sp)
  1694.         bsr _InitModule8
  1695.         movem.l (sp)+,a0/d0
  1696.     IFNE    AUDDEV
  1697.         tst.b   audiodevopen-DB(a6)
  1698.         beq PM_end      ;resource allocation failure
  1699.     ENDC
  1700.         move.l  a0,d1
  1701.         beq.w   PM_end      ;module failure
  1702.         bsr.w   _End8Play
  1703.         clr.l   _module8-DB(a6)
  1704.         clr.l   tmpvol-DB(a6)
  1705.         move.w  _modnum8,d1
  1706.         beq.s   PM_modfound
  1707. PM_nextmod  tst.l   mmd_expdata(a0)
  1708.         beq.s   PM_modfound
  1709.         move.l  mmd_expdata(a0),a1
  1710.         tst.l   (a1)
  1711.         beq.s   PM_modfound     ;no more modules here!
  1712.         move.l  (a1),a0
  1713.         subq.w  #1,d1
  1714.         bgt.s   PM_nextmod
  1715. PM_modfound cmp.b   #'T',3(a0)
  1716.         bne.s   PM_nomodT
  1717.         move.b  #'0',3(a0)  ;change MCNT to MCN0
  1718. PM_nomodT   movea.l mmd_songinfo(a0),a1     ;song
  1719.         move.b  msng_tempo2(a1),mmd_counter(a0) ;init counter
  1720.         btst    #0,msng_flags(a1)
  1721.         bne.s   PM_filon
  1722.         bset    #1,$bfe001
  1723.         bra.s   PM_filset
  1724. PM_filon    bclr    #1,$bfe001
  1725. PM_filset   tst.b   d0
  1726.         beq.s   PM_noclr
  1727.         clr.l   mmd_pline(a0)
  1728.         clr.l   rptline-DB(a6)
  1729.         clr.w   blkdelay-DB(a6)
  1730. ; ---------- Set 'pblock' and 'pseq' to correct values...
  1731. PM_noclr    cmp.b   #'2',3(a0)
  1732.         bne.s   PM_oldpbset
  1733.         move.w  mmd_psecnum(a0),d1
  1734.         move.l  a2,-(sp)        ;need extra register
  1735.         movea.l msng_sections(a1),a2
  1736.         add.w   d1,d1
  1737.         move.w  0(a2,d1.w),d1       ;get sequence number
  1738.         add.w   d1,d1
  1739.         add.w   d1,d1
  1740.         move.w  d1,mmd_pseq(a0)
  1741.         movea.l msng_pseqs(a1),a2
  1742.         movea.l 0(a2,d1.w),a2       ;PlaySeq...
  1743.         move.w  mmd_pseqnum(a0),d1
  1744.         add.w   d1,d1
  1745.         move.w  42(a2,d1.w),d1      ;and the correct block..
  1746.         move.l  (sp)+,a2
  1747.         bra.s   PM_setblk
  1748. PM_oldpbset move.w  mmd_pseqnum(a0),d1
  1749.         add.w   #msng_playseq,d1
  1750.         move.b  0(a1,d1.w),d1       ;get first playseq entry
  1751.         ext.w   d1
  1752. PM_setblk   move.w  d1,mmd_pblock(a0)
  1753.         move.w  #-1,mmd_pstate(a0)
  1754.         move.l  a0,_module8-DB(a6)
  1755.         move.l  mmd_expdata(a0),d0
  1756.         beq.s   PM_start
  1757.         movea.l d0,a0
  1758.         lea 36(a0),a0   ;track split mask
  1759.         bsr.s   _SetChMode
  1760. PM_start    bsr.s   _Start8Play
  1761. PM_end      move.l  (sp)+,a6
  1762.         rts
  1763.  
  1764. _SetChMode  ;a0 = address of 4 UBYTEs
  1765.         movem.l a2/d2,-(sp)
  1766.         lea trksplit-DB(a6),a2
  1767.         lea t038+trk_split-DB(a6),a1
  1768.         moveq   #3,d0
  1769.         moveq   #0,d1
  1770. scm_loop    lsr.b   #1,d1
  1771.         move.b  (a0)+,d2
  1772.         beq.s   scm_split
  1773.         moveq   #0,d2
  1774.         bra.s   scm_nosplit
  1775. scm_split   or.b    #8,d1
  1776.         st  d2
  1777. scm_nosplit move.b  d2,(a1)
  1778.         move.b  d2,4*TDSZ(a1)
  1779.         lea TDSZ(a1),a1
  1780.         move.b  d2,(a2)+
  1781.         dbf d0,scm_loop
  1782.         move.w  d1,chdmamask-DB(a6)
  1783.         movem.l (sp)+,a2/d2
  1784. rts:        rts
  1785.  
  1786. _Start8Play:    ;d0 = pstate
  1787.         lea _audiobuff,a0
  1788.         move.w  #1600-1,d1
  1789. clrbuffloop:    clr.l   (a0)+       ;clear track buffers
  1790.         dbf d1,clrbuffloop
  1791.         move.l  _module8-DB(a6),d0
  1792.         beq.s   rts
  1793.         move.l  d0,a0
  1794.         movea.l mmd_songinfo(a0),a0
  1795.         move.w  msng_deftempo(a0),d0    ;get deftempo
  1796.         bsr.w   _SetTempo
  1797.         lea $dff000,a0
  1798.         move.w  currchsize2-DB(a6),d0
  1799.         move.w  d0,$a4(a0)  ;set audio buffer sizes
  1800.         move.w  d0,$b4(a0)  ;according to tempo selection
  1801.         move.w  d0,$c4(a0)
  1802.         move.w  d0,$d4(a0)
  1803.         tst.b   _hq-DB(a6)
  1804.         bne.s   s8p_hq
  1805.         move.w  #227,d1
  1806.         bra.s   s8p_nohq
  1807. s8p_hq      move.w  #124,d1
  1808. s8p_nohq    move.w  d1,$a6(a0)
  1809.         move.w  d1,$b6(a0)
  1810.         move.w  d1,$c6(a0)
  1811.         move.w  d1,$d6(a0)
  1812.         move.l  #_audiobuff,$a0(a0)
  1813.         move.l  #_audiobuff+800,$b0(a0)
  1814.         move.l  #_audiobuff+1600,$c0(a0)
  1815.         move.l  #_audiobuff+2400,$d0(a0)
  1816.         moveq   #64,d1
  1817.         move.w  d1,$a8(a0)
  1818.         move.w  d1,$b8(a0)
  1819.         move.w  d1,$c8(a0)
  1820.         move.w  d1,$d8(a0)
  1821.         clr.b   whichbuff-DB(a6)
  1822.         movea.l 4,a1
  1823.         move.w  #$4000,$9a(a0)
  1824.         addq.b  #1,$126(a1)
  1825.         lea track0hw-DB(a6),a1
  1826.         moveq   #7,d1
  1827. clrtrkloop  clr.l   (a1)
  1828.         clr.w   ac_per(a1)
  1829.         adda.w  #SIZE4TRKHW/4,a1
  1830.         dbf d1,clrtrkloop
  1831.         move.w  #$F,$dff096 ;audio DMA off
  1832.         bsr.w   _Wait1line  ;wait until all stopped
  1833.         st  play8-DB(a6)
  1834.         move.w  #$8080,$9a(a0)
  1835.         move.w  chdmamask-DB(a6),d1
  1836.         bset    #15,d1
  1837.         move.w  d1,$96(a0)
  1838.         movea.l 4,a1
  1839.         subq.b  #1,$126(a1)
  1840.         bge.s   x8play
  1841.         move.w  #$c000,$9a(a0)
  1842. x8play      rts
  1843. ; *************************************************************************
  1844. ; InitPlayer8() -- allocate interrupt, audio, serial port etc...
  1845. ; *************************************************************************
  1846. _InitPlayer8:   bsr.s   _AudioInit
  1847.         tst.l   d0
  1848.         bne.s   IP_error
  1849.         rts
  1850. IP_error    bsr.s   _RemPlayer8
  1851.         moveq   #-1,d0
  1852.         rts
  1853. ; *************************************************************************
  1854. ; StopPlayer8() -- stop music
  1855. ; *************************************************************************
  1856. _StopPlayer8:   move.l  _module8,d0
  1857.         beq.s   SP_nomod
  1858.         movea.l d0,a0
  1859.         clr.w   mmd_pstate(a0)
  1860.         clr.l   _module8
  1861. SP_nomod    bra.w   _End8Play
  1862.  
  1863. ; *************************************************************************
  1864. ; RemPlayer8() -- free interrupt, audio, serial port etc..
  1865. ; *************************************************************************
  1866. _RemPlayer8:    bsr.s   _StopPlayer8
  1867. ;       vvvvvvvvvvvvvvvv  to _AudioRem
  1868. ; *************************************************************************
  1869. _AudioRem:  movem.l a5-a6,-(sp)
  1870.         lea DB,a5
  1871.         bsr.w   _Rem8chan
  1872.     IFNE    AUDDEV
  1873.         movea.l 4,a6
  1874.         tst.b   audiodevopen-DB(a5)
  1875.         beq.s   rem2
  1876.         clr.b   audiodevopen-DB(a5)
  1877.         move.w  #$000f,$dff096  ;stop audio DMA
  1878. ;   +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ close audio.device
  1879.         lea allocreq-DB(a5),a1
  1880.         jsr -$1c2(a6)   ;CloseDevice()
  1881. rem2:       moveq   #0,d0
  1882.         move.b  sigbitnum-DB(a5),d0
  1883.         bmi.s   rem3
  1884. ;   +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ free signal bit
  1885.         jsr -$150(a6)   ;FreeSignal()
  1886.         st  sigbitnum-DB(a5)
  1887.     ENDC
  1888. rem3:       movem.l (sp)+,a5-a6
  1889.         rts
  1890.  
  1891. _AudioInit: movem.l a4/a6/d2-d3,-(sp)
  1892.         lea DB,a4
  1893.         movea.l 4.w,a6
  1894.     IFNE    AUDDEV
  1895.         moveq   #0,d2
  1896. ;   +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ alloc signal bit
  1897.         moveq   #1,d2
  1898.         moveq   #-1,d0
  1899.         jsr -$14a(a6)   ;AllocSignal()
  1900.         tst.b   d0
  1901.         bmi.w   initerr
  1902.         move.b  d0,sigbitnum-DB(a4)
  1903. ;   +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ prepare IORequest
  1904.         lea allocport-DB(a4),a1
  1905.         move.b  d0,15(a1)   ;set mp_SigBit
  1906.         move.l  a1,-(sp)
  1907.         suba.l  a1,a1
  1908.         jsr -$126(a6)   ;FindTask(0)
  1909.         move.l  (sp)+,a1
  1910.         move.l  d0,16(a1)   ;set mp_SigTask
  1911.         lea reqlist-DB(a4),a0
  1912.         move.l  a0,(a0)     ;NEWLIST begins...
  1913.         addq.l  #4,(a0)
  1914.         clr.l   4(a0)
  1915.         move.l  a0,8(a0)    ;NEWLIST ends...
  1916. ;   +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ open audio.device
  1917.         moveq   #2,d2
  1918.         lea allocreq-DB(a4),a1
  1919.         lea audiodevname-DB(a4),a0
  1920.         moveq   #0,d0
  1921.         moveq   #0,d1
  1922.         jsr -$1bc(a6)   ;OpenDevice()
  1923.         tst.b   d0
  1924.         bne.w   initerr
  1925.         st.b    audiodevopen-DB(a4)
  1926.     ENDC
  1927.         move.w  #1<<7,$dff09a   ;Init 8 channel stuff
  1928.         moveq   #7,d0       ;Audio channel 0 interrupt
  1929.         lea audiointerrupt-DB(a4),a1
  1930.         jsr -$a2(a6)    ;SetIntVector()
  1931.         move.l  d0,prevaud-DB(a4)
  1932.         st  eightrkon-DB(a4)
  1933.         moveq   #0,d0
  1934. initret:    movem.l (sp)+,a4/a6/d2-d3
  1935.         rts
  1936. initerr:    move.l  d2,d0
  1937.         bra.s   initret
  1938.  
  1939.         DATA
  1940.         XDEF    _hq
  1941. DB:     ;Data base pointer
  1942.     IFNE    AUDDEV
  1943. sigbitnum   dc.b    -1
  1944. audiodevopen    dc.b    0
  1945. allocm      dc.b    $F,0
  1946.     ENDC
  1947. chdmamask   dc.w    0
  1948. trksplit    dc.b    0,0,0,0
  1949.         even
  1950.     IFNE    AUDDEV
  1951. allocport   dc.l    0,0 ;succ, pred
  1952.         dc.b    4,0 ;NT_MSGPORT
  1953.         dc.l    0   ;name
  1954.         dc.b    0,0 ;flags = PA_SIGNAL
  1955.         dc.l    0   ;task
  1956. reqlist     dc.l    0,0,0   ;list head, tail and tailpred
  1957.         dc.b    5,0
  1958. allocreq    dc.l    0,0
  1959.         dc.b    0,127   ;NT_UNKNOWN, use maximum priority (127)
  1960.         dc.l    0,allocport ;name, replyport
  1961.         dc.w    68      ;length
  1962.         dc.l    0   ;io_Device
  1963.         dc.l    0   ;io_Unit
  1964.         dc.w    0   ;io_Command
  1965.         dc.b    0,0 ;io_Flags, io_Error
  1966.         dc.w    0   ;ioa_AllocKey
  1967.         dc.l    allocm  ;ioa_Data
  1968.         dc.l    1   ;ioa_Length
  1969.         dc.w    0,0,0   ;ioa_Period, Volume, Cycles
  1970.         dc.w    0,0,0,0,0,0,0,0,0,0 ;ioa_WriteMsg
  1971. audiodevname    dc.b    'audio.device',0
  1972.     ENDC
  1973.         even
  1974.  
  1975. zerodata    dc.w    0
  1976. whichbuff   dc.w    0
  1977.  
  1978. track0hw    dc.l    0,0,tmpvol,0,0
  1979.         dc.w    $0001,$df,$f0a0
  1980. track1hw    dc.l    0,0,tmpvol+1,0,0
  1981.         dc.w    $0002,$df,$f0b0
  1982. track2hw    dc.l    0,0,tmpvol+2,0,0
  1983.         dc.w    $0004,$df,$f0c0
  1984. track3hw    dc.l    0,0,tmpvol+3,0,0
  1985.         dc.w    $0008,$df,$f0d0
  1986. track4hw    dc.l    0,0,tmpvol,0,0
  1987.         dc.w    0,0,0
  1988. track5hw    dc.l    0,0,tmpvol+1,0,0
  1989.         dc.w    0,0,0
  1990. track6hw    dc.l    0,0,tmpvol+2,0,0
  1991.         dc.w    0,0,0
  1992. track7hw    dc.l    0,0,tmpvol+3,0,0
  1993.         dc.w    0,0,0
  1994. SIZE4TRKHW  equ 4*$1A
  1995.  
  1996. tmpvol      dc.b    0,0,0,0
  1997.  
  1998. audintname  dc.b    'OctaMED AudioInterrupt',0
  1999.         even
  2000. audiointerrupt  dc.w    0,0,0,0,0
  2001.         dc.l    audintname,_audiobuff,_IntHandler8
  2002. prevaud     dc.l    0
  2003. play8       dc.b    0
  2004. eightrkon   dc.b    0
  2005.  
  2006. t038:       ds.b    18
  2007.         dc.l    track0hw
  2008.         ds.b    52-(18+4+1)
  2009.         dc.b    $ff
  2010.         ds.b    18
  2011.         dc.l    track1hw
  2012.         ds.b    52-(18+4+1)
  2013.         dc.b    $ff
  2014.         ds.b    18
  2015. t238        dc.l    track2hw
  2016.         ds.b    52-(18+4+1)
  2017.         dc.b    $ff
  2018.         ds.b    18
  2019.         dc.l    track3hw
  2020.         ds.b    52-(18+4+1)
  2021.         dc.b    $ff
  2022. t4158       ds.b    18
  2023.         dc.l    track4hw
  2024.         ds.b    52-(18+4+1)
  2025.         dc.b    $ff
  2026.         ds.b    18
  2027.         dc.l    track5hw
  2028.         ds.b    52-(18+4+1)
  2029.         dc.b    $ff
  2030.         ds.b    18
  2031. t6158       dc.l    track6hw
  2032.         ds.b    52-(18+4+1)
  2033.         dc.b    $ff
  2034.         ds.b    18
  2035.         dc.l    track7hw
  2036.         ds.b    52-(18+4+1)
  2037.         dc.b    $ff
  2038.         
  2039. trackdata8  dc.l    t038,t038+TDSZ,t038+2*TDSZ,t038+3*TDSZ
  2040.         dc.l    t4158,t4158+TDSZ,t4158+2*TDSZ,t4158+3*TDSZ
  2041.  
  2042. blkdelay    dc.w    0   ;block delay (PT PatternDelay)
  2043.  
  2044. eightchsizes    dc.b    110,120,130,140,150,160,170,180,190,200
  2045.         dc.b    101,110,119,128,137,146,156,165,174,183 ;HQ sizes
  2046. currchsize  dc.w    0   ;<< 3
  2047. currchsize2 dc.w    0
  2048. currchszcnt dc.w    0
  2049.  
  2050. nextblock   dc.b    0 ;\ DON'T SEPARATE
  2051. nxtnoclrln  dc.b    0 :/
  2052. numtracks   dc.w    0
  2053. numlines    dc.w    0
  2054. numpages    dc.w    0
  2055. nextblockline   dc.w    0
  2056. rptline     dc.w    0
  2057. rptcounter  dc.w    0
  2058. _module8    dc.l    0
  2059. fxplineblk  dc.l    0
  2060. _hq     dc.b    1
  2061.  
  2062.         EVEN
  2063. holdvals    ds.b    63
  2064. finetunes   ds.b    63
  2065. flags       ds.b    63
  2066.         EVEN
  2067.  
  2068.     IFNE    IFFMOCT
  2069.     dc.w    3424,3232,3048,2880,2712,2560,2416,2280,2152,2032,1920,1812
  2070.     dc.w    1712,1616,1524,1440,1356,1280,1208,1140,1076,1016,960,906
  2071.     ENDC
  2072. per0    dc.w    856,808,762,720,678,640,604,570,538,508,480,453
  2073.     dc.w    428,404,381,360,339,320,302,285,269,254,240,226
  2074.     dc.w    214,202,190,180,170,160,151,143,135,127,120,113
  2075.     dc.w    214,202,190,180,170,160,151,143,135,127,120,113
  2076.     dc.w    214,202,190,180,170,160,151,143,135,127,120,113
  2077.     dc.w    214,202,190,180,170,160,151,143,135,127,120,113
  2078.     IFNE    IFFMOCT
  2079.     dc.w    3400,3209,3029,2859,2699,2547,2404,2269,2142,2022,1908,1801
  2080.     dc.w    1700,1605,1515,1430,1349,1274,1202,1135,1071,1011,954,901
  2081.     ENDC
  2082. per1    dc.w    850,802,757,715,674,637,601,567,535,505,477,450
  2083.     dc.w    425,401,379,357,337,318,300,284,268,253,239,225
  2084.     dc.w    213,201,189,179,169,159,150,142,134,126,119,113
  2085.     dc.w    213,201,189,179,169,159,150,142,134,126,119,113
  2086.     dc.w    213,201,189,179,169,159,150,142,134,126,119,113
  2087.     dc.w    213,201,189,179,169,159,150,142,134,126,119,113
  2088.     IFNE    IFFMOCT
  2089.     dc.w    3376,3187,3008,2839,2680,2529,2387,2253,2127,2007,1895,1788
  2090.     dc.w    1688,1593,1504,1419,1340,1265,1194,1127,1063,1004,947,894
  2091.     ENDC
  2092. per2    dc.w    844,796,752,709,670,632,597,563,532,502,474,447
  2093.     dc.w    422,398,376,355,335,316,298,282,266,251,237,224
  2094.     dc.w    211,199,188,177,167,158,149,141,133,125,118,112
  2095.     dc.w    211,199,188,177,167,158,149,141,133,125,118,112
  2096.     dc.w    211,199,188,177,167,158,149,141,133,125,118,112
  2097.     dc.w    211,199,188,177,167,158,149,141,133,125,118,112
  2098.     IFNE    IFFMOCT
  2099.     dc.w    3352,3164,2986,2819,2660,2511,2370,2237,2112,1993,1881,1776
  2100.     dc.w    1676,1582,1493,1409,1330,1256,1185,1119,1056,997,941,888
  2101.     ENDC
  2102. per3    dc.w    838,791,746,704,665,628,592,559,528,498,470,444
  2103.     dc.w    419,395,373,352,332,314,296,280,264,249,235,222
  2104.     dc.w    209,198,187,176,166,157,148,140,132,125,118,111
  2105.     dc.w    209,198,187,176,166,157,148,140,132,125,118,111
  2106.     dc.w    209,198,187,176,166,157,148,140,132,125,118,111
  2107.     dc.w    209,198,187,176,166,157,148,140,132,125,118,111
  2108.     IFNE    IFFMOCT
  2109.     dc.w    3328,3141,2965,2799,2641,2493,2353,2221,2097,1979,1868,1763
  2110.     dc.w    1664,1571,1482,1399,1321,1247,1177,1111,1048,989,934,881
  2111.     ENDC
  2112. per4    dc.w    832,785,741,699,660,623,588,555,524,495,467,441
  2113.     dc.w    416,392,370,350,330,312,294,278,262,247,233,220
  2114.     dc.w    208,196,185,175,165,156,147,139,131,124,117,110
  2115.     dc.w    208,196,185,175,165,156,147,139,131,124,117,110
  2116.     dc.w    208,196,185,175,165,156,147,139,131,124,117,110
  2117.     dc.w    208,196,185,175,165,156,147,139,131,124,117,110
  2118.     IFNE    IFFMOCT
  2119.     dc.w    3304,3119,2944,2778,2622,2475,2336,2205,2081,1965,1854,1750
  2120.     dc.w    1652,1559,1472,1389,1311,1238,1168,1103,1041,982,927,875
  2121.     ENDC
  2122. per5    dc.w    826,779,736,694,655,619,584,551,520,491,463,437
  2123.     dc.w    413,390,368,347,328,309,292,276,260,245,232,219
  2124.     dc.w    206,195,184,174,164,155,146,138,130,123,116,109
  2125.     dc.w    206,195,184,174,164,155,146,138,130,123,116,109
  2126.     dc.w    206,195,184,174,164,155,146,138,130,123,116,109
  2127.     dc.w    206,195,184,174,164,155,146,138,130,123,116,109
  2128.     IFNE    IFFMOCT
  2129.     dc.w    3280,3096,2922,2758,2603,2457,2319,2189,2066,1950,1841,1738
  2130.     dc.w    1640,1548,1461,1379,1302,1229,1160,1095,1033,975,920,869
  2131.     ENDC
  2132. per6    dc.w    820,774,730,689,651,614,580,547,516,487,460,434
  2133.     dc.w    410,387,365,345,325,307,290,274,258,244,230,217
  2134.     dc.w    205,193,183,172,163,154,145,137,129,122,115,109
  2135.     dc.w    205,193,183,172,163,154,145,137,129,122,115,109
  2136.     dc.w    205,193,183,172,163,154,145,137,129,122,115,109
  2137.     dc.w    205,193,183,172,163,154,145,137,129,122,115,109
  2138.     IFNE    IFFMOCT
  2139.     dc.w    3256,3073,2901,2738,2584,2439,2302,2173,2051,1936,1827,1725
  2140.     dc.w    1628,1537,1450,1369,1292,1220,1151,1087,1026,968,914,862
  2141.     ENDC
  2142. per7    dc.w    814,768,725,684,646,610,575,543,513,484,457,431
  2143.     dc.w    407,384,363,342,323,305,288,272,256,242,228,216
  2144.     dc.w    204,192,181,171,161,152,144,136,128,121,114,108
  2145.     dc.w    204,192,181,171,161,152,144,136,128,121,114,108
  2146.     dc.w    204,192,181,171,161,152,144,136,128,121,114,108
  2147.     dc.w    204,192,181,171,161,152,144,136,128,121,114,108
  2148.     IFNE    IFFMOCT
  2149.     dc.w    3628,3424,3232,3051,2880,2718,2565,2421,2285,2157,2036,1922
  2150.     dc.w    1814,1712,1616,1525,1440,1359,1283,1211,1143,1079,1018,961
  2151.     ENDC
  2152. per_8   dc.w    907,856,808,762,720,678,640,604,570,538,508,480
  2153.     dc.w    453,428,404,381,360,339,320,302,285,269,254,240
  2154.     dc.w    226,214,202,190,180,170,160,151,143,135,127,120
  2155.     dc.w    226,214,202,190,180,170,160,151,143,135,127,120
  2156.     dc.w    226,214,202,190,180,170,160,151,143,135,127,120
  2157.     dc.w    226,214,202,190,180,170,160,151,143,135,127,120
  2158.     IFNE    IFFMOCT
  2159.     dc.w    3588,3387,3197,3017,2848,2688,2537,2395,2260,2133,2014,1901
  2160.     dc.w    1794,1693,1598,1509,1424,1344,1269,1197,1130,1067,1007,950
  2161.     ENDC
  2162. per_7   dc.w    900,850,802,757,715,675,636,601,567,535,505,477
  2163.     dc.w    450,425,401,379,357,337,318,300,284,268,253,238
  2164.     dc.w    225,212,200,189,179,169,159,150,142,134,126,119
  2165.     dc.w    225,212,200,189,179,169,159,150,142,134,126,119
  2166.     dc.w    225,212,200,189,179,169,159,150,142,134,126,119
  2167.     dc.w    225,212,200,189,179,169,159,150,142,134,126,119
  2168.     IFNE    IFFMOCT
  2169.     dc.w    3576,3375,3186,3007,2838,2679,2529,2387,2253,2126,2007,1894
  2170.     dc.w    1788,1688,1593,1504,1419,1339,1264,1193,1126,1063,1003,947
  2171.     ENDC
  2172. per_6   dc.w    894,844,796,752,709,670,632,597,563,532,502,474
  2173.     dc.w    447,422,398,376,355,335,316,298,282,266,251,237
  2174.     dc.w    223,211,199,188,177,167,158,149,141,133,125,118
  2175.     dc.w    223,211,199,188,177,167,158,149,141,133,125,118
  2176.     dc.w    223,211,199,188,177,167,158,149,141,133,125,118
  2177.     dc.w    223,211,199,188,177,167,158,149,141,133,125,118
  2178.     IFNE    IFFMOCT
  2179.     dc.w    3548,3349,3161,2984,2816,2658,2509,2368,2235,2110,1991,1879
  2180.     dc.w    1774,1674,1580,1492,1408,1329,1254,1184,1118,1055,996,940
  2181.     ENDC
  2182. per_5   dc.w    887,838,791,746,704,665,628,592,559,528,498,470
  2183.     dc.w    444,419,395,373,352,332,314,296,280,264,249,235
  2184.     dc.w    222,209,198,187,176,166,157,148,140,132,125,118
  2185.     dc.w    222,209,198,187,176,166,157,148,140,132,125,118
  2186.     dc.w    222,209,198,187,176,166,157,148,140,132,125,118
  2187.     dc.w    222,209,198,187,176,166,157,148,140,132,125,118
  2188.     IFNE    IFFMOCT
  2189.     dc.w    3524,3326,3140,2963,2797,2640,2492,2352,2220,2095,1978,1867
  2190.     dc.w    1762,1663,1570,1482,1399,1320,1246,1176,1110,1048,989,933
  2191.     ENDC
  2192. per_4   dc.w    881,832,785,741,699,660,623,588,555,524,494,467
  2193.     dc.w    441,416,392,370,350,330,312,294,278,262,247,233
  2194.     dc.w    220,208,196,185,175,165,156,147,139,131,123,117
  2195.     dc.w    220,208,196,185,175,165,156,147,139,131,123,117
  2196.     dc.w    220,208,196,185,175,165,156,147,139,131,123,117
  2197.     dc.w    220,208,196,185,175,165,156,147,139,131,123,117
  2198.     IFNE    IFFMOCT
  2199.     dc.w    3500,3304,3118,2943,2778,2622,2475,2336,2205,2081,1964,1854
  2200.     dc.w    1750,1652,1559,1472,1389,1311,1237,1168,1102,1041,982,927
  2201.     ENDC
  2202. per_3   dc.w    875,826,779,736,694,655,619,584,551,520,491,463
  2203.     dc.w    437,413,390,368,347,328,309,292,276,260,245,232
  2204.     dc.w    219,206,195,184,174,164,155,146,138,130,123,116
  2205.     dc.w    219,206,195,184,174,164,155,146,138,130,123,116
  2206.     dc.w    219,206,195,184,174,164,155,146,138,130,123,116
  2207.     dc.w    219,206,195,184,174,164,155,146,138,130,123,116
  2208.     IFNE    IFFMOCT
  2209.     dc.w    3472,3277,3093,2920,2756,2601,2455,2317,2187,2064,1949,1839
  2210.     dc.w    1736,1639,1547,1460,1378,1301,1228,1159,1094,1032,974,920
  2211.     ENDC
  2212. per_2   dc.w    868,820,774,730,689,651,614,580,547,516,487,460
  2213.     dc.w    434,410,387,365,345,325,307,290,274,258,244,230
  2214.     dc.w    217,205,193,183,172,163,154,145,137,129,122,115
  2215.     dc.w    217,205,193,183,172,163,154,145,137,129,122,115
  2216.     dc.w    217,205,193,183,172,163,154,145,137,129,122,115
  2217.     dc.w    217,205,193,183,172,163,154,145,137,129,122,115
  2218.     IFNE    IFFMOCT
  2219.     dc.w    3448,3254,3072,2899,2737,2583,2438,2301,2172,2050,1935,1827
  2220.     dc.w    1724,1627,1536,1450,1368,1292,1219,1151,1086,1025,968,913
  2221.     ENDC
  2222. per_1   dc.w    862,814,768,725,684,646,610,575,543,513,484,457
  2223.     dc.w    431,407,384,363,342,323,305,288,272,256,242,228
  2224.     dc.w    216,203,192,181,171,161,152,144,136,128,121,114
  2225.     dc.w    216,203,192,181,171,161,152,144,136,128,121,114
  2226.     dc.w    216,203,192,181,171,161,152,144,136,128,121,114
  2227.     dc.w    216,203,192,181,171,161,152,144,136,128,121,114
  2228.  
  2229. _periodtable
  2230.     dc.l    per_8,per_7,per_6,per_5,per_4,per_3,per_2,per_1,per0
  2231.     dc.l    per1,per2,per3,per4,per5,per6,per7
  2232.  
  2233.     IFND    __G2
  2234.         section "datachip",bss,chip ;for A68k
  2235.     ENDC
  2236.     IFD __G2
  2237.         section "datachip",bss_c ;this is for Devpac 2
  2238.     ENDC
  2239.  
  2240.         XDEF    _modnum8
  2241. _audiobuff: ds.w    400*8
  2242. _modnum8:   ds.w    1
  2243. _chipzero:  ds.w    1
  2244.  
  2245. ; macros for entering offsets
  2246. DEFWORD MACRO
  2247. \1  EQU OFFS
  2248. OFFS    SET OFFS+2
  2249.     ENDM
  2250. DEFBYTE MACRO
  2251. \1  EQU OFFS
  2252. OFFS    SET OFFS+1
  2253.     ENDM
  2254. DEFLONG MACRO
  2255. \1  EQU OFFS
  2256. OFFS    SET OFFS+4
  2257.     ENDM
  2258.  
  2259. OFFS    SET 0
  2260. ; the track-data structure definition:
  2261.     DEFBYTE trk_prevnote    ;previous note number (0 = none, 1 = C-1..)
  2262.     DEFBYTE trk_previnstr   ;previous instrument number
  2263.     DEFBYTE trk_prevvol ;previous volume
  2264.     DEFBYTE trk_noteoffcnt  ;note-off counter (hold)
  2265.     DEFBYTE trk_inithold    ;default hold for this instrument
  2266.     DEFBYTE trk_stransp ;instrument transpose
  2267.     DEFWORD trk_soffset ;new sample offset | don't sep this and 2 below!
  2268.     DEFBYTE trk_finetune    ;finetune
  2269.     DEFBYTE trk_miscflags   ;bit: 7 = cmd 3 exists, 0 = cmd E exists
  2270.     DEFBYTE trk_currnote    ;note on CURRENT line (0 = none, 1 = C-1...)
  2271.     DEFBYTE trk_fxtype  ;fx type: 0 = norm, 1 = none, -1 = MIDI
  2272.     DEFLONG trk_previnstra  ;address of the previous instrument data
  2273.     DEFWORD trk_prevper ;previous period
  2274.     DEFLONG trk_audioaddr   ;hardware audio channel base address
  2275.     DEFLONG trk_sampleptr   ;pointer to sample
  2276.     DEFWORD trk_samplelen   ;length (>> 1)
  2277.     DEFWORD trk_porttrgper  ;portamento (cmd 3) target period
  2278.     DEFBYTE trk_vibshift    ;vibrato shift for ASR instruction
  2279.     DEFBYTE trk_vibrspd ;vibrato speed/size (cmd 4 qualifier)
  2280.     DEFWORD trk_vibrsz  ;vibrato size
  2281.     DEFLONG trk_periodtbl   ;pointer to period table
  2282.     DEFWORD trk_prevportspd ;portamento (cmd 3) speed
  2283.     DEFBYTE trk_split   ;0 = this channel not splitted (OctaMED V2)
  2284.     DEFBYTE trk_vibroffs    ;vibrato table offset \ DON'T SEPARATE
  2285.     DEFBYTE trk_tremoffs    ;tremolo table offset /
  2286.     DEFBYTE trk_tremspd ;tremolo speed
  2287.     DEFWORD trk_tremsz  ;tremolo size
  2288.     DEFWORD trk_vibradjust  ;vibrato +/- change from base period \ DON'T SEPARATE
  2289.     DEFWORD trk_arpadjust   ;arpeggio +/- change from base period/
  2290.     DEFBYTE trk_tempvol ;temporary volume (for tremolo)
  2291.     DEFBYTE pad
  2292.  
  2293.         END