home *** CD-ROM | disk | FTP | other *** search
/ modiromppu / modiromppu.iso / PROGRAMS / ORGPACKS / SADT2.ZIP / QDPLAY.ASM < prev    next >
Assembly Source File  |  1995-05-28  |  42KB  |  1,810 lines

  1. Dosseg
  2. ;
  3. ; Quick 'n' Dirty play    for Surprise! Adlib Tracker SA2 files (version 9)
  4. ;
  5. .Model Small
  6. .Stack 40H
  7. .286
  8. locals
  9.  
  10. .Data
  11.  
  12. NoAdlib         db 7,"No Adlib found!$"
  13.  
  14. .Code
  15.  
  16. include memtools.blk
  17.  
  18. locals
  19. .286
  20.  
  21. fname db 130 dup (0)
  22. fsong dw ?
  23.  
  24. Okt1 equ 0010000000000000B
  25. Okt2 equ 0010010000000000B
  26. Okt3 equ 0010100000000000B
  27. Okt4 equ 0010110000000000B
  28. Okt5 equ 0011000000000000B
  29. Okt6 equ 0011010000000000B
  30. Okt7 equ 0011100000000000B
  31. Okt8 equ 0011110000000000B
  32.  
  33. _patternorder   equ 966
  34. _songlength     equ 1096
  35. _restart        equ 1097
  36. _bpm            equ 1098
  37. _arpeggio       equ 1100
  38. _acommands      equ 1356
  39. _trackorder     equ 1612
  40. _channels       equ 2188
  41. _trackdata      equ 2190
  42.  
  43.  
  44. Adwrite macro r,w
  45.         mov     dx,388h
  46.         mov     al,r
  47.         out     dx,al
  48.         call    waitlong
  49.         mov     dx,389h
  50.         mov     al,w
  51.         out     dx,al
  52. endm
  53.  
  54. NoteTab dw 0                                                         ; dummy note
  55.         dw Okt1+343,Okt1+363,Okt1+385,Okt1+408,Okt1+432,Okt1+458
  56.         dw Okt1+485,Okt1+514,Okt1+544,Okt1+577,Okt1+611,Okt1+647     ; Oktave3
  57.         dw Okt2+343,Okt2+363,Okt2+385,Okt2+408,Okt2+432,Okt2+458
  58.         dw Okt2+485,Okt2+514,Okt2+544,Okt2+577,Okt2+611,Okt2+647     ; Oktave3
  59.         dw Okt3+343,Okt3+363,Okt3+385,Okt3+408,Okt3+432,Okt3+458
  60.         dw Okt3+485,Okt3+514,Okt3+544,Okt3+577,Okt3+611,Okt3+647     ; Oktave3
  61.         dw Okt4+343,Okt4+363,Okt4+385,Okt4+408,Okt4+432,Okt4+458
  62.         dw Okt4+485,Okt4+514,Okt4+544,Okt4+577,Okt4+611,Okt4+647     ; Oktave4
  63.         dw Okt5+343,Okt5+363,Okt5+385,Okt5+408,Okt5+432,Okt5+458
  64.         dw Okt5+485,Okt5+514,Okt5+544,Okt5+577,Okt5+611,Okt5+647     ; Oktave5
  65.         dw Okt6+343,Okt6+363,Okt6+385,Okt6+408,Okt6+432,Okt6+458
  66.         dw Okt6+485,Okt6+514,Okt6+544,Okt6+577,Okt6+611,Okt6+647     ; Oktave6
  67.         dw Okt7+343,Okt7+363,Okt7+385,Okt7+408,Okt7+432,Okt7+458
  68.         dw Okt7+485,Okt7+514,Okt7+544,Okt7+577,Okt7+611,Okt7+647     ; Oktave7
  69.         dw Okt8+343,Okt8+363,Okt8+385,Okt8+408,Okt8+432,Okt8+458
  70.         dw Okt8+485,Okt8+514,Okt8+544,Okt8+577,Okt8+611,Okt8+647;    ; Oktave8
  71.         dw 16 dup (Okt8+647)
  72.  
  73. InsTab  dw 32 dup (0)
  74.  
  75. Register_map db 0,1,2,8,9,10,16,17,18
  76.  
  77. Vibratotab db    0, 24, 49, 74, 97,120,141,161
  78.            db  180,197,212,224,235,244,250,253
  79.            db  255,253,250,244,235,224,212,197
  80.            db  180,161,141,120, 97, 74, 49, 24
  81.  
  82. arpeggio_table  db 0,1,2,0,1,2,0,1,2,0,1,2,0,1,2,0,1,2,0,1,2,0,1,2,0,1,2,0,1,2,0,1
  83.  
  84. channel_active  db 9 dup (0)
  85. channel_ins     db 9 dup (0)
  86. channel_note    db 9 dup (0)
  87. channel_note2   db 9 dup (0)
  88. channel_vol2    db 9 dup (0)    ; connector
  89. channel_vol     db 9 dup (0)    ; carrier
  90. channel_vpos    db 9 dup (0)
  91. channel_vspeed  db 9 dup (0)
  92. channel_vdepth  db 9 dup (0)
  93. channel_eff     dw 9 dup (0)
  94. channel_freq    dw 9 dup (0)
  95. channel_fshift  dw 9 dup (0)
  96. channel_pdest   dw 9 dup (0)
  97. channel_pspeed  dw 9 dup (0)
  98. channel_aspeed  db 9 dup (0)
  99. channel_acurpos db 9 dup (0)
  100. channel_acursp  db 9 dup (0)
  101. channel_vsubt   db 9 dup (0)
  102. channel_segment db 9 dup (0)
  103.  
  104. mainvol         db 64           ; 64 = max, 0 = min
  105. count           db 0
  106. Register_bypass db 246 dup (0)
  107. current_pos     db 9 dup (0)
  108. current_speed   db 9 dup (6)
  109. s_count         db 9 dup (0)
  110. current_line    db 9 dup (0)
  111. work_pattern    dw 9 dup (_trackorder)
  112. position_jump   db 9 dup (0)
  113. new_position    db 9 dup (0)
  114. break_pos       db 9 dup (0)
  115. pattern_break   db 9 dup (0)
  116. polling         db 1
  117. segments        dw 9 dup (0)
  118. stopped         db 9 dup (1)
  119.  
  120. segnum          dw 0
  121. current_bpm     dw 0
  122.  
  123. waitlong proc
  124. ;
  125. ; waits 23.3 ys
  126. ;
  127.         rept 35
  128.         in      al,dx
  129.         endm
  130.         ret
  131. waitlong endp
  132.  
  133.  
  134. Fastwrite proc
  135.         cmp     cs:Register_bypass[bx],ah
  136.         je      f_w_1
  137.  
  138.         mov     cs:Register_bypass[bx],ah
  139.  
  140.         mov     dx,388h
  141.         mov     al,bl
  142.         out     dx,al
  143.         call    waitlong
  144.         mov     dx,389h
  145.         mov     al,ah
  146.         out     dx,al
  147. f_w_1:
  148.         ret
  149. Fastwrite endp
  150.  
  151.  
  152. WriteThrough proc
  153.         mov     cs:Register_bypass[bx],ah
  154.  
  155.         mov     dx,388h
  156.         mov     al,bl
  157.         out     dx,al
  158.         call    waitlong
  159.         mov     dx,389h
  160.         mov     al,ah
  161.         out     dx,al
  162.         ret
  163. WriteThrough endp
  164.  
  165. empty proc
  166.         ret
  167. empty endp
  168.  
  169. general_ret:
  170.         sti
  171.         ret
  172.  
  173. TestAdlib proc
  174. ;
  175. ; Checks for adlib
  176. ; carry flag:
  177. ;         1...........no Adlib detected
  178. ;         0...........Adlib found (yeah!)
  179. ;
  180.         Adwrite 1,0
  181.         Adwrite 4,60H
  182.         Adwrite 4,80H
  183.  
  184.         mov     dx,388h
  185.         in      al,dx
  186.         and     al,11100000b
  187.         mov     bl,al
  188.  
  189.         Adwrite 2,0ffH
  190.         Adwrite 4,00100001b
  191.  
  192.         mov     cx,6
  193. t_a_1:
  194.         call    waitlong
  195.         loop    t_a_1
  196.  
  197.         mov     dx,388h
  198.         in      al,dx
  199.         and     al,11100000b
  200.         mov     bh,al
  201.  
  202.         Adwrite 4,60H
  203.         Adwrite 4,80H
  204.  
  205.         cmp     bl,0
  206.         jne     t_a_2
  207.         cmp     bh,11000000b
  208.         jne     t_a_2
  209.  
  210.         clc
  211.         ret
  212. t_a_2:
  213.         stc
  214.         mov     ax,4
  215.         ret
  216. TestAdlib endp
  217.  
  218. Init_Adlib proc
  219.         mov     bx,1
  220.         mov     cx,245
  221. I_a_1:
  222.         mov     ah,0
  223.         call    WriteThrough
  224.         inc     bx
  225.         loop    I_a_1
  226.  
  227.         mov     bx,1
  228.         mov     ah,00100000b
  229.         call    WriteThrough
  230.         mov     bx,8
  231.         mov     ah,01000000B
  232.         call    WriteThrough
  233.         mov     bx,0bdh
  234.         mov     ah,11000000B
  235.         call    WriteThrough
  236.  
  237.         lea     bx,InsTab
  238.         mov     ax,5
  239.         mov     cx,31
  240. I_a_3:
  241.         mov     cs:[bx],ax
  242.         add     bx,2
  243.         add     ax,15
  244.         loop    I_a_3
  245.  
  246.  
  247.         mov     mainvol,64
  248.  
  249.         clc
  250.         ret
  251. Init_Adlib endp
  252.  
  253. Init_Adlib_Tables proc
  254. ;
  255. ; Initialisiert Tabellen, etc.
  256. ;
  257.         mov     si,0
  258.         mov     bx,0
  259.         mov     cx,9
  260. @@l1:
  261.         mov     stopped         [si],1
  262.         mov     channel_active  [si],0
  263.         mov     channel_ins     [si],0
  264.         mov     channel_note    [si],0
  265.         mov     channel_note2   [si],0
  266.         mov     channel_vol     [si],0
  267.         mov     channel_vol2    [si],0
  268.         mov     channel_vpos    [si],0
  269.         mov     channel_vspeed  [si],0
  270.         mov     channel_vdepth  [si],0
  271.         mov     channel_eff     [bx],0
  272.         mov     channel_freq    [bx],0
  273.         mov     channel_fshift  [bx],0
  274.         mov     channel_pdest   [bx],0
  275.         mov     channel_pspeed  [bx],0
  276.         mov     channel_aspeed  [si],0
  277.         mov     channel_acurpos [si],0
  278.         mov     channel_acursp  [si],0
  279.         mov     channel_vsubt   [si],0
  280.         mov     current_speed   [si],6
  281.         mov     current_line    [si],0
  282.         mov     break_pos       [si],0
  283.         mov     pattern_break   [si],0
  284.         mov     position_jump   [si],0
  285.         inc     si
  286.         add     bx,2
  287.         jumps
  288.         loop    @@l1
  289.         nojumps
  290.         mov     mainvol,64
  291.         ret
  292. Init_Adlib_Tables endp
  293.  
  294. DefineBoth proc
  295.         add     bl,cl
  296.         lodsw
  297.         mov     ch,ah
  298.         mov     ah,al
  299.         call    Fastwrite               ; Connector
  300.         add     bl,3
  301.         mov     ah,ch
  302.         call    Fastwrite               ; Carrier
  303.         ret
  304. DefineBoth endp
  305.  
  306. CalcVol proc
  307.         sub     al,63
  308.         neg     al
  309.         mov     dl,mainvol
  310.         mul     dl
  311.         shr     ax,6
  312.         sub     al,63
  313.         neg     al
  314.         ret
  315. calcvol endp
  316.  
  317. Set_Volume proc
  318.         mov     di,bx
  319.         mov     bx,40h
  320.         add     bl,Register_map[di]     ; bl = KSL / TL offset
  321.  
  322.         mov     cx,ax
  323.  
  324.         mov     al,ch
  325.         and     al,63
  326.         mov     channel_vol2[di],al
  327.         call    calcvol
  328.         mov     ah,al
  329.         mov     al,register_bypass[bx]
  330.         and     al,11000000b
  331.         or      ah,al
  332.         call    Fastwrite
  333.  
  334. s_v_1:
  335.         add     bl,3
  336.  
  337.         mov     al,cl
  338.         and     al,63
  339.         mov     channel_vol[di],al
  340.         call    calcvol
  341.         mov     ah,al
  342.         mov     al,register_bypass[bx]
  343.         and     al,11000000b
  344.         or      ah,al
  345.         jmp     Fastwrite
  346. Set_Volume endp
  347.  
  348. calc_freq_up proc
  349.         mov     dx,cx
  350.         mov     di,cx
  351.         and     dx,0011110000000000b
  352.         and     cx,1023
  353.         add     cx,ax
  354.         cmp     cx,647
  355.         jl      @@fu_ok
  356.         mov     ax,di
  357. @@fu_2:
  358.         and     ax,0001110000000000b
  359.         cmp     ax,0001110000000000b
  360.         jne     @@next_okt
  361.         mov     cx,di
  362.         jmp     @@fu_ok
  363. @@next_okt:
  364.         sar     cx,1
  365.         add     ax,0000010000000000b
  366.         and     di,0010000000000000b
  367.         or      ax,di
  368.         mov     dx,ax
  369.         cmp     cx,647
  370.         jg      @@fu_2
  371. @@fu_ok:
  372.         or      cx,dx
  373.         ret
  374. calc_freq_up endp
  375.  
  376. calc_freq_down proc
  377.         mov     dx,cx
  378.         mov     di,cx
  379.         and     dx,0011110000000000b
  380.         and     cx,1023
  381.         sub     cx,ax
  382.         cmp     cx,343
  383.         jg      @@fd_ok
  384.         mov     ax,di
  385. @@fd_2:
  386.         and     ax,0001110000000000b
  387.         cmp     ax,0
  388.         jne     @@prev_okt
  389.         mov     cx,di
  390.         jmp     @@fd_ok
  391. @@prev_okt:
  392.         sal     cx,1
  393.         sar     ah,2
  394.         dec     ah
  395.         sal     ah,2
  396.         and     di,0010000000000000b
  397.         or      ax,di
  398.         mov     dx,ax
  399.         cmp     cx,343
  400.         jl      @@fd_2
  401. @@fd_ok:
  402.         or      cx,dx
  403.         ret
  404. calc_freq_down endp
  405.  
  406. Frequenz_up2 proc
  407.         shl     bp,1
  408.         mov     cx,cs:channel_freq[bp]
  409.         shr     bp,1
  410.         call    calc_freq_up
  411.         add     bx,0a0h
  412.         mov     ah,cl
  413.         call    Fastwrite
  414.         add     bx,10h
  415.         mov     ah,register_bypass[bx]
  416.         and     ah,32
  417.         and     ch,31
  418.         or      ah,ch
  419.         call    Fastwrite
  420.         ret
  421. Frequenz_up2 endp
  422.  
  423. Frequenz_down2 proc
  424.         shl     bp,1
  425.         mov     cx,cs:channel_freq[bp]
  426.         shr     bp,1
  427.         add     bx,0a0h
  428.         call    calc_freq_down
  429.         mov     ah,cl
  430.         call    Fastwrite
  431.         add     bx,10h
  432.         mov     ah,register_bypass[bx]
  433.         and     ah,32
  434.         and     ch,31
  435.         or      ah,ch
  436.         call    Fastwrite
  437.         ret
  438. Frequenz_down2 endp
  439.  
  440. Release_note proc
  441.         add     bx,0b0h
  442.         mov     ah,register_bypass[bx]
  443.         test    ah,32
  444.         jz      @@released
  445.         and     ah,255-32
  446.         jmp     WriteThrough
  447. @@released:
  448.         ret
  449. release_note endp
  450.  
  451. Retrig_note proc
  452.         add     bx,0b0h
  453.         mov     ah,register_bypass[bx]
  454.         test    ah,32
  455.         jnz     @@still_on
  456.         or      ah,32
  457.         call    WriteThrough
  458. @@released:
  459.         ret
  460. @@still_on:
  461.         mov     bx,bp
  462.         call    release_note
  463.         mov     bx,bp
  464.         jmp     retrig_note
  465. retrig_note endp;
  466.  
  467. Play_Note2 proc
  468.         pusha
  469.         call    release_note
  470.  
  471.  
  472.         sub     bx,10h
  473.         xor     ch,ch
  474.         mov     si,cx
  475.         shl     si,1
  476.         add     si,offset NoteTab
  477.         mov     cx,cs:[si]
  478.         mov     ah,cl
  479.         call    Fastwrite
  480.  
  481.         add     bx,10h
  482.         mov     ah,ch
  483.         call    WriteThrough
  484.  
  485.         mov     bx,bp
  486.         shl     bx,1
  487.         mov     channel_freq[bx],cx
  488.         mov     channel_fshift[bx],0
  489.  
  490.         popa
  491.         ret
  492. play_note2 endp
  493.  
  494. Set_Freq proc
  495.         add     bx,0a0h
  496.  
  497.         mov     ah,cl
  498.         call    Fastwrite
  499.  
  500.         add     bx,10h
  501.         mov     ah,register_bypass[bx]
  502.         and     ah,32
  503.         and     ch,31
  504.         or      ah,ch
  505.         call    FastWrite
  506.  
  507.         mov     bx,bp
  508.         shl     bx,1
  509.         mov     channel_freq[bx],cx
  510.         ret
  511. Set_Freq endp
  512.  
  513. Init_Instrument2 proc
  514.         pusha
  515.  
  516.         mov     bl,ch
  517.         dec     bl
  518.         xor     bh,bh
  519.         shl     bx,1
  520.         mov     si,cs:instab[bx]
  521.  
  522. ;--- spec. arpeggio init ----------------------------------
  523.  
  524.         mov     bx,si
  525.  
  526.         add     si,11
  527.         lodsb
  528.         mov     cs:channel_acurpos[bp],al
  529.         lodsb
  530.         cmp     al,0
  531.         jne     @@alok
  532.         inc     al
  533. @@alok:
  534.         mov     cs:channel_acursp[bp],0
  535.         mov     cs:channel_aspeed[bp],al
  536.  
  537. @@no_spec:
  538.         mov     si,bx
  539.  
  540. ;----------------------------------------------------------
  541.  
  542.  
  543.         mov     bx,bp
  544.  
  545.         mov     cl,bl
  546.  
  547.         mov     bx,0c0h
  548.         add     bl,cl
  549.         lodsb
  550.         mov     ah,al
  551.         mov     ch,al
  552.         call    Fastwrite
  553.  
  554.         mov     bx,bp
  555.         add     bx,offset Register_map
  556.         mov     cl,cs:[bx]
  557.  
  558.         mov     bx,20h
  559.         call    DefineBoth
  560.  
  561.         mov     bx,60h
  562.         call    DefineBoth
  563.  
  564.         mov     bx,80h
  565.         call    DefineBoth
  566.  
  567.         mov     bx,0e0h
  568.         call    DefineBoth
  569.  
  570.         mov     bx,40h
  571.         add     bl,cl
  572.  
  573.         lodsw
  574.         mov     cx,ax
  575.  
  576.         mov     di,bp
  577.         mov     al,byte ptr channel_vol2[di]
  578.         mov     ah,byte ptr channel_vol[di]
  579.         and     ax,0011111100111111b
  580.         and     cx,1100000011000000b
  581.         or      ax,cx
  582.         or      cx,ax
  583.  
  584.         and     al,63
  585.         call    calcvol
  586.         mov     ah,al
  587.         and     cl,11000000b
  588.         or      ah,cl
  589.         call    Fastwrite
  590.  
  591.         add     bl,3
  592.  
  593.         mov     al,ch
  594.         and     al,63
  595.         call    calcvol
  596.         mov     ah,al
  597.         and     ch,11000000b
  598.         or      ah,ch
  599.         call    Fastwrite
  600.  
  601.         popa
  602.         ret
  603. @@seperate_vol:
  604.         ret
  605. Init_Instrument2 endp
  606.  
  607. select_wave proc
  608.         mov     bl,register_map[bx]
  609.         xor     bh,bh
  610.         add     bx,0e0h
  611.         mov     ah,cl
  612.         dec     ah
  613.         js      @@none1
  614.         call    fastwrite
  615. @@none1:
  616.         add     bx,3
  617.         mov     ah,ch
  618.         dec     ah
  619.         js      @@none2
  620.         jmp     fastwrite
  621. @@none2:
  622.         ret
  623. select_wave endp
  624.  
  625. Mute_voice proc
  626.         push    bx
  627.         mov     dl,register_map[bx]
  628.         mov     cl,dl
  629.         add     dl,60h
  630.         mov     bl,dl
  631.         mov     di,bx
  632.         mov     ah,0ffh
  633.         call    fastwrite
  634.         mov     bx,di
  635.         add     bx,3
  636.         mov     ah,0ffh
  637.         call    fastwrite
  638.         mov     bx,di
  639.         add     bx,20h
  640.         mov     ah,0ffh
  641.         call    fastwrite
  642.         mov     bx,di
  643.         add     bx,23h
  644.         mov     ah,0ffh
  645.         call    fastwrite
  646.         pop     bx
  647.         add     bx,0b0h
  648.         mov     di,bx
  649.         mov     ah,032
  650.         call    fastwrite
  651.         mov     bl,cl
  652.         add     bx,40h
  653.         mov     ah,register_bypass[bx]
  654.         or      ah,63
  655.         call    fastwrite
  656.         mov     ah,0
  657.         mov     bx,di
  658.         jmp     fastwrite
  659. m_v:
  660.         ret
  661. Mute_voice endp
  662.  
  663. Clear_All_Voices proc
  664.         mov     cx,9
  665.         mov     bp,0
  666. c_a_v_2:
  667.         push    cx
  668.         mov     bx,bp
  669.         call    mute_voice
  670.         inc     bp
  671.         pop     cx
  672.         loop    c_a_v_2
  673.  
  674.         ret
  675. Clear_All_Voices endp
  676.  
  677. Set_Main_Volume proc
  678.         cmp     bl,64
  679.         jbe     s_m_v_ok
  680.         mov     ax,0
  681.         stc
  682.         ret
  683. s_m_v_ok:
  684.         cmp     mainvol,bl
  685.         je      s_m_v_end
  686.         mov     mainvol,bl
  687.         mov     si,0
  688.         mov     cx,9
  689. s_m_v_1:
  690.         cmp     channel_active[si],0
  691.         je      s_m_v_2
  692.  
  693.         mov     di,si
  694.         add     di,offset channel_vol2
  695.  
  696.         mov     bx,40h
  697.         add     bl,register_map[si]
  698.  
  699.         mov     al,cs:[di]
  700.         call    calcvol
  701.         mov     ah,al
  702.         mov     al,register_bypass[bx]
  703.         and     al,11000000b
  704.         or      ah,al
  705.         call    Fastwrite
  706.  
  707.         add     bl,3
  708.         add     di,9
  709.  
  710.         mov     al,cs:[di]
  711.         call    calcvol
  712.         mov     ah,al
  713.         mov     al,register_bypass[bx]
  714.         and     al,11000000b
  715.         or      ah,al
  716.         call    Fastwrite
  717.  
  718. s_m_v_2:
  719.         inc     si
  720.         loop    s_m_v_1
  721. s_m_v_end:
  722.         ret
  723. Set_Main_Volume endp
  724.  
  725. shift_helper proc
  726.         mov     bx,bp
  727.         cmp     ax,0
  728.         jl      @@down
  729.         call    calc_freq_up
  730.         jmp     @@doit
  731. @@down:
  732.         neg     ax
  733.         call    calc_freq_down
  734. @@doit:
  735.         add     bx,0a0h
  736.         mov     ah,cl
  737.         call    Fastwrite
  738.         add     bx,10h
  739.         mov     al,register_bypass[bx]
  740.         and     al,32
  741.         mov     ah,ch
  742.         and     ah,11011111b
  743.         or      ah,al
  744.         call    Fastwrite
  745.  
  746.         mov     bx,bp
  747.         shl     bx,1
  748.         mov     channel_freq[bx],cx
  749.         ret
  750. shift_helper endp
  751.  
  752. effect_arpeggio proc
  753.         mov     cl,cs:channel_note2[bp]
  754.         mov     bl,byte ptr count
  755.         xor     bh,bh
  756.         mov     bl,byte ptr arpeggio_table[bx]
  757.         cmp     bl,0
  758.         je      @@arp_found
  759.         cmp     bl,1
  760.         jne     @@arp2
  761.         shr     ah,4
  762.         add     cl,ah
  763.         jmp     @@arp_found
  764. @@arp2:
  765.         and     ah,15
  766.         add     cl,ah
  767. @@arp_found:
  768.         cmp     cl,96
  769.         jbe     @@note_ok
  770.         mov     cl,96
  771. @@note_ok:
  772.         xor     ch,ch
  773.         mov     bx,cx
  774.         shl     bx,1
  775.         mov     cx,word ptr notetab[bx]
  776.         mov     bx,bp
  777.         call    set_freq
  778.         ret
  779. effect_arpeggio endp
  780.  
  781. effect_slide_up proc
  782.         mov     bx,bp
  783.         shl     bx,1
  784.         mov     al,ah
  785.         xor     ah,ah
  786.         add     word ptr channel_fshift[bx],ax
  787.         mov     ax,word ptr channel_fshift[bx]
  788.         mov     bl,byte ptr cs:channel_note2[bp]
  789.         xor     bh,bh
  790.         shl     bx,1
  791.         mov     cx,word ptr notetab[bx]
  792.  
  793.         call    shift_helper
  794.         ret
  795. effect_slide_up endp
  796.  
  797. effect_slide_down proc
  798.         mov     bx,bp
  799.         shl     bx,1
  800.         mov     al,ah
  801.         xor     ah,ah
  802.         sub     word ptr channel_fshift[bx],ax
  803.         mov     ax,word ptr channel_fshift[bx]
  804.         mov     bl,byte ptr cs:channel_note2[bp]
  805.         xor     bh,bh
  806.         shl     bx,1
  807.         mov     cx,word ptr notetab[bx]
  808.  
  809.         call    shift_helper
  810.         ret
  811. effect_slide_down endp
  812.  
  813. effect_portamento proc
  814.         cmp     count,0
  815.         ja      @@not_first
  816.         mov     bx,bp
  817.         shl     bx,1
  818.         cmp     ah,0
  819.         je      @@no_new_speed
  820.         mov     al,ah
  821.         xor     ah,ah
  822.         mov     word ptr channel_pspeed[bx],ax
  823. @@no_new_speed:
  824.         mov     bl,byte ptr cs:channel_note[bp]
  825.         cmp     bl,0
  826.         je      @@not_first
  827.         xor     bh,bh
  828.         shl     bx,1
  829.         mov     dx,word ptr notetab[bx]
  830.         mov     bx,bp
  831.         shl     bx,1
  832.         mov     word ptr channel_pdest[bx],dx
  833. @@not_first:
  834.         jmp     execute_portamento
  835. effect_portamento endp
  836.  
  837. execute_portamento proc
  838.         mov     bx,bp
  839.         add     bx,0a0h
  840.         mov     al,byte ptr register_bypass[bx]
  841.         add     bx,10h
  842.         mov     ah,byte ptr register_bypass[bx]
  843.  
  844.         mov     bx,bp
  845.         shl     bx,1
  846.         mov     dx,word ptr channel_pdest[bx]
  847.         mov     cx,word ptr channel_pspeed[bx]
  848.         cmp     ax,dx
  849.         jumps
  850.         je      @@kill_porta
  851.         ja      @@pdown
  852. @@up:
  853.         nojumps
  854.         mov     bx,bp
  855.         mov     ax,cx
  856.         push    dx
  857.         add     bx,0b0h
  858.         mov     ch,byte ptr register_bypass[bx]
  859.         sub     bx,10h
  860.         mov     cl,byte ptr register_bypass[bx]
  861.         call    calc_freq_up
  862.         pop     dx
  863.         mov     bx,cx
  864.         mov     ax,dx
  865.         and     bx,0011100000000000b
  866.         and     ax,0011100000000000b
  867.         cmp     bx,ax
  868.         jb      @@puok
  869.         mov     bx,cx
  870.         mov     ax,dx
  871.         and     bx,0000011111111111b
  872.         and     ax,0000011111111111b
  873.         cmp     bx,ax
  874.         jb      @@puok
  875.         mov     cx,dx
  876. @@puok:
  877.         mov     bx,bp
  878.         call    set_freq
  879.         ret
  880. @@pdown:
  881.         mov     bx,bp
  882.         mov     ax,cx
  883.         push    dx
  884.         add     bx,0b0h
  885.         mov     ch,byte ptr register_bypass[bx]
  886.         sub     bx,10h
  887.         mov     cl,byte ptr register_bypass[bx]
  888.         call    calc_freq_down
  889.         pop     dx
  890.         mov     bx,cx
  891.         mov     ax,dx
  892.         and     bx,0011100000000000b
  893.         and     ax,0011100000000000b
  894.         cmp     bx,ax
  895.         ja      @@pdok
  896.         mov     bx,cx
  897.         mov     ax,dx
  898.         and     bx,0000011111111111b
  899.         and     ax,0000011111111111b
  900.         cmp     bx,ax
  901.         ja      @@pdok
  902.         mov     cx,dx
  903. @@pdok:
  904.         mov     bx,bp
  905.         call    set_freq
  906. @@kill_porta:
  907.         ret
  908. execute_portamento endp
  909.  
  910. effect_vibrato proc
  911.         cmp     count,0
  912.         ja      @@not_first
  913.         cmp     ah,0
  914.         je      @@not_first
  915.         mov     al,ah
  916.         and     al,15
  917.         shr     ah,4
  918.         mov     cs:channel_vspeed[bp],ah
  919.         mov     cs:channel_vdepth[bp],al
  920.         mov     dl,ah
  921.         jmp     do_vibrato
  922. @@not_first:
  923.         jmp     execute_vibrato
  924. effect_vibrato endp
  925.  
  926. execute_vibrato proc
  927.         mov     dl,cs:channel_vspeed[bp]
  928.         mov     al,cs:channel_vdepth[bp]
  929. do_vibrato:
  930.         mov     bl,cs:channel_vpos[bp]
  931.         xor     bh,bh
  932.         add     bl,dl
  933.         mov     cs:channel_vpos[bp],bl
  934.         mov     dh,bl
  935.         and     bx,1fh
  936.         mov     dl,byte ptr vibratotab[bx]
  937.         mul     dl
  938.         rol     ax,1
  939.         xchg    ah,al
  940.         and     ah,1
  941.         test    dh,32
  942.         jne     @@vibup
  943.         jmp     @@vibdown
  944. @@vibup:
  945.         mov     bx,bp
  946.         call    frequenz_up2
  947.         ret
  948. @@vibdown:
  949.         mov     bx,bp
  950.         call    frequenz_down2
  951.         ret
  952. execute_vibrato endp
  953.  
  954. effect_volume_slide proc
  955.         cmp     count,0
  956.         jne     @@just_vslide
  957.         mov     dl,ah
  958.         cmp     dl,16
  959.         jb      @@dlok
  960.         shr     dl,4
  961.         neg     dl
  962. @@dlok:
  963.         mov     bx,bp
  964.         shl     bx,1
  965.         mov     byte ptr channel_eff[bx+1],dl
  966.         mov     ah,dl
  967.         mov     byte ptr cs:channel_vsubt[bp],0
  968. @@just_vslide:
  969.         mov     dl,ah
  970.         mov     dh,byte ptr cs:channel_vsubt[bp]
  971.         add     dh,dl
  972.         mov     ch,dh
  973.         sar     ch,2
  974.         mov     ah,byte ptr cs:channel_vol2[bp]
  975.         mov     al,byte ptr cs:channel_vol[bp]
  976.         add     ah,ch
  977.         add     al,ch
  978.         cmp     al,0
  979.         jge     @@alok
  980.         xor     al,al
  981. @@alok:
  982.         cmp     ah,0
  983.         jge     @@ahok
  984.         xor     ah,ah
  985. @@ahok:
  986.         cmp     ah,63
  987.         jb      @@ahok2
  988.         mov     ah,63
  989. @@ahok2:
  990.         cmp     al,63
  991.         jb      @@alok2
  992.         mov     al,63
  993. @@alok2:
  994.         sal     ch,2
  995.         sub     dh,ch
  996.         mov     byte ptr cs:channel_vsubt[bp],dh
  997.         mov     bx,bp
  998.         call    set_volume
  999.         ret
  1000. effect_volume_slide endp
  1001.  
  1002. effect_portamento_volume_slide proc
  1003.         call    effect_volume_slide
  1004.         call    execute_portamento
  1005.         ret
  1006. effect_portamento_volume_slide endp
  1007.  
  1008. effect_vibrato_volume_slide proc
  1009.         call    effect_volume_slide
  1010.         call    execute_vibrato
  1011.         ret
  1012. effect_vibrato_volume_slide endp
  1013.  
  1014. effect_release_note proc
  1015.         mov     bx,bp
  1016.         call    release_note
  1017.         mov     bx,bp
  1018.         shl     bx,1
  1019.         mov     word ptr channel_eff[bx],0
  1020.         ret
  1021. effect_release_note endp
  1022.  
  1023. effect_position_jump proc
  1024.         mov     bx,segnum
  1025.         mov     position_jump[bx],1
  1026.         mov     al,ah
  1027.         xor     ah,ah
  1028.         mov     cs:new_position[bx],al
  1029.         mov     cs:break_pos[bx],0
  1030.         mov     cs:pattern_break[bx],1
  1031.         mov     bx,bp
  1032.         shl     bx,1
  1033.         mov     word ptr channel_eff[bx],0
  1034.         ret
  1035. effect_position_jump endp
  1036.  
  1037. effect_set_volume proc
  1038.         cmp     ah,63
  1039.         jb      @@ahok
  1040.         mov     ah,63
  1041. @@ahok:
  1042.         mov     al,63
  1043.         sub     al,ah
  1044.         mov     ah,al
  1045.         mov     bx,bp
  1046.         call    set_volume
  1047.         ret
  1048. effect_set_volume endp
  1049.  
  1050. effect_pattern_break proc
  1051.         mov     bx,segnum
  1052.         mov     cs:pattern_break[bx],1
  1053.         mov     bx,ax
  1054.         mov     al,ah
  1055.         shr     al,4
  1056.         mov     cl,10
  1057.         mul     cl
  1058.         and     bh,0fh
  1059.         add     al,bh
  1060.         xor     ah,ah
  1061.         mov     cs:break_pos[bx],al
  1062.         mov     bx,bp
  1063.         shl     bx,1
  1064.         mov     word ptr channel_eff[bx],0
  1065.         ret
  1066. effect_pattern_break endp
  1067.  
  1068. effect_set_speed proc
  1069.         mov     bx,segnum
  1070.         cmp     ah,0
  1071.         ja      @@ahok
  1072.         mov     ah,1
  1073. @@ahok:
  1074.         cmp     ah,31
  1075.         ja      @@high_speed
  1076.         mov     current_speed[bx],ah
  1077.         jmp     @@aout
  1078. @@high_speed:
  1079.         cmp     polling,1
  1080.         je      @@aout
  1081.         mov     bl,ah
  1082.         xor     bh,bh
  1083.         cmp     bx,50
  1084.         ja      @@bxok
  1085.         mov     bx,50
  1086. @@bxok:
  1087. ;        mov     current_bpm,bx
  1088. ;        add     bx,3
  1089.  
  1090.         cli
  1091.         mov     dx,2dh
  1092.         mov     ax,8426h
  1093.         div     bx
  1094.         push    ax
  1095.         mov     al,54
  1096.         out     43h,al
  1097.  
  1098.         pop     ax
  1099.         out     40h,al
  1100.         xchg    ah,al
  1101.         out     40h,al
  1102.         sti
  1103. @@aout:
  1104.         mov     bx,bp
  1105.         shl     bx,1
  1106.         mov     word ptr channel_eff[bx],0
  1107.         ret
  1108. effect_set_speed endp
  1109.  
  1110. spec_arpeggio proc
  1111.         pusha
  1112.         cmp     byte ptr cs:channel_acurpos[bp],0
  1113.         jumps
  1114.         je      @@no_arp
  1115.         dec     byte ptr cs:channel_acursp[bp]
  1116.         jg      @@no_arp
  1117.         nojumps
  1118.  
  1119.         mov     al,byte ptr cs:channel_acurpos[bp]
  1120.         xor     ah,ah
  1121.         mov     di,ax
  1122.         mov     al,byte ptr ds:[_acommands+di]
  1123.         cmp     al,254
  1124.         jb      @@no_verw
  1125.         cmp     al,255
  1126.         jne     @@no_end
  1127.         mov     byte ptr cs:channel_acurpos[bp],0
  1128.         jmp     @@no_arp
  1129. @@no_end:
  1130.         mov     al,byte ptr ds:[_arpeggio+di]
  1131.         mov     di,ax
  1132.         mov     byte ptr cs:channel_acurpos[bp],al
  1133.         mov     al,byte ptr ds:[_acommands+di]
  1134. @@no_verw:
  1135.  
  1136.         cmp     al,0
  1137.         je      @@no_command
  1138.         cmp     al,44
  1139.         ja      @@no_wave
  1140.         xor     ah,ah
  1141.         mov     bl,10
  1142.         div     bl
  1143.         xchg    al,ah
  1144.         mov     cx,ax
  1145.         mov     bx,bp
  1146.         call    select_wave
  1147.         jmp     @@no_command
  1148. @@no_wave:
  1149.         cmp     al,253
  1150.         jne     @@no_release
  1151.         mov     bx,bp
  1152.         call    release_note
  1153. @@no_release:
  1154.         cmp     al,252
  1155.         jne     @@no_setvol
  1156.         mov     ah,byte ptr ds:[_arpeggio+di]
  1157.         call    effect_set_volume
  1158. @@no_setvol:
  1159.         cmp     al,251
  1160.         jne     @@no_retrig_vol
  1161.         mov     ah,byte ptr ds:[_arpeggio+di]
  1162.         call    effect_set_volume
  1163.         mov     bx,bp
  1164.         call    retrig_note
  1165.         jmp     @@no_half
  1166. @@no_retrig_vol:
  1167.  
  1168. @@no_command:
  1169.         mov     al,byte ptr ds:[_arpeggio+di]
  1170.         cmp     al,100
  1171.         ja      @@abs_note_found
  1172.         mov     ah,byte ptr cs:channel_note[bp]
  1173.         add     al,ah
  1174.         jmp     @@note_check
  1175. @@abs_note_found:
  1176.         sub     al,99
  1177. @@note_check:
  1178.         cmp     al,96
  1179.         jbe     @@note_found
  1180.         mov     al,96
  1181. @@note_found:
  1182.         xor     ah,ah
  1183.         mov     byte ptr cs:channel_note2[bp],al
  1184.         mov     bx,ax
  1185.         shl     bx,1
  1186.         mov     cx,word ptr notetab[bx]
  1187.  
  1188.         mov     bx,bp
  1189.         shl     bx,1
  1190.         mov     ax,word ptr channel_fshift[bx]
  1191.  
  1192.         call    shift_helper
  1193.  
  1194. @@no_half:
  1195.         mov     al,byte ptr cs:channel_aspeed[bp]
  1196.         mov     byte ptr cs:channel_acursp[bp],al
  1197.         inc     byte ptr cs:channel_acurpos[bp]
  1198.  
  1199. @@no_arp:
  1200.         popa
  1201.         ret
  1202. spec_arpeggio endp
  1203.  
  1204. do_volume proc
  1205.         pusha
  1206.         mov     bl,al
  1207.         dec     bl
  1208.         xor     bh,bh
  1209.         shl     bx,1
  1210.         mov     si,word ptr InsTab[bx]
  1211.         add     si,9
  1212.         mov     al,[si]
  1213.         mov     ah,al
  1214.         mov     al,[si+1]
  1215.         and     ax,3F3FH
  1216.         mov     bx,bp
  1217.         call    set_volume
  1218. dov2:
  1219.         popa
  1220.         ret
  1221. do_volume endp
  1222.  
  1223. calc_work_pattern proc
  1224.         xor     ah,ah
  1225.         mov     bp,ax
  1226.         add     bp,_patternorder
  1227.         mov     al,ds:[bp]
  1228.         mov     dx,ax
  1229.         shl     dx,3
  1230.         add     ax,dx
  1231.         add     ax,_trackorder
  1232.         mov     work_pattern[bx],ax
  1233.         ret
  1234. calc_work_pattern endp
  1235.  
  1236. effect_calls    dw offset effect_arpeggio                       ; 0
  1237.                 dw offset effect_slide_up                       ; 1
  1238.                 dw offset effect_slide_down                     ; 2
  1239.                 dw offset effect_portamento                     ; 3
  1240.                 dw offset effect_vibrato                        ; 4
  1241.                 dw offset effect_portamento_volume_slide        ; 5
  1242.                 dw offset effect_vibrato_volume_slide           ; 6
  1243.                 dw offset empty                                 ; 7
  1244.                 dw offset effect_release_note                   ; 8
  1245.                 dw offset empty                                 ; 9
  1246.                 dw offset effect_volume_slide                   ; A
  1247.                 dw offset effect_position_jump                  ; B
  1248.                 dw offset effect_set_volume                     ; C
  1249.                 dw offset effect_pattern_break                  ; D
  1250.                 dw offset empty                                 ; E
  1251.                 dw offset effect_set_speed                      ; F
  1252.                 
  1253.  
  1254. _eff  db 0
  1255. _para db 0
  1256.  
  1257. play_line proc
  1258.  
  1259.         mov     cx,9
  1260.         mov     bp,0
  1261. @@l1:
  1262.         push    cx
  1263.  
  1264.         cmp     byte ptr cs:channel_active[bp],1
  1265.         je      @@play
  1266.         jmp     @@no_effect
  1267.  
  1268. @@play:
  1269.         mov     bl,cs:channel_segment[bp]
  1270.         xor     bh,bh
  1271.         mov     segnum,bx
  1272.         mov     al,s_count[bx]
  1273.         mov     count,al
  1274.         shl     bx,1
  1275.         mov     dx,cs:segments[bx]
  1276.         mov     ds,dx
  1277.         shr     bx,1
  1278.         cmp     al,0
  1279.         jumps
  1280.         jne     @@effects
  1281.         nojumps
  1282.         xor     ah,ah
  1283.         mov     al,current_line[bx]
  1284.         mov     si,ax
  1285.         shl     si,1
  1286.         add     si,ax
  1287.         shl     bx,1
  1288.         mov     bx,work_pattern[bx]
  1289.         add     bx,bp
  1290.         mov     al,[bx]
  1291.         cmp     al,0
  1292.         jumps
  1293.         je      @@no_effect
  1294.         nojumps
  1295.         dec     ax
  1296.         mov     bx,192
  1297.         mul     bx
  1298.         add     si,ax
  1299.         add     si,_trackdata
  1300.  
  1301.         cmp     count,0
  1302.         jbe     @@do_note
  1303.         jmp     @@effects
  1304. @@do_note:
  1305.         lodsb
  1306.         mov     cl,al
  1307.         lodsb
  1308.         mov     ah,al
  1309.         lodsb
  1310.  
  1311.         mov     _para,al
  1312.         mov     ch,ah
  1313.         and     ch,15
  1314.         mov     _eff,ch
  1315.         and     ah,0f0h
  1316.         shr     cl,1
  1317.         rcr     ah,4
  1318.         mov     al,ah
  1319.  
  1320.         mov     ch,al
  1321.         jcxz    @@nothing_there
  1322.         cmp     al,0
  1323.         je      @@no_ins
  1324.         mov     byte ptr cs:channel_ins[bp],al
  1325.         call    do_volume
  1326. @@no_ins:
  1327.         cmp     cl,0
  1328.         je      @@nothing_there
  1329.         mov     byte ptr cs:channel_note[bp],cl
  1330.         mov     byte ptr cs:channel_note2[bp],cl
  1331.         cmp     _eff,3
  1332.         je      @@nothing_there
  1333.         mov     ch,byte ptr cs:channel_ins[bp]
  1334.         call    init_instrument2
  1335.         mov     bx,bp
  1336.         mov     byte ptr cs:channel_vpos[bp],0
  1337.         call    play_note2
  1338.  
  1339. @@nothing_there:
  1340.         mov     al,_eff
  1341.         mov     ah,_para
  1342.         mov     bx,bp
  1343.         shl     bx,1
  1344.         mov     word ptr channel_eff[bx],ax
  1345. @@effects:
  1346.  
  1347.         call    spec_arpeggio
  1348.  
  1349.         mov     bx,bp
  1350.         shl     bx,1
  1351.         mov     ax,word ptr channel_eff[bx]
  1352.         mov     bx,ax
  1353.         cmp     bx,0
  1354.         je      @@no_effect
  1355.         xor     bh,bh
  1356.         shl     bx,1
  1357.         mov     bx,effect_calls[bx]
  1358.         call    bx
  1359.  
  1360. @@no_effect:
  1361.         inc     bp
  1362.         pop     cx
  1363.         jumps
  1364.         loop    @@l1
  1365.         nojumps
  1366.  
  1367.         mov     cx,9
  1368.         xor     bx,bx
  1369.         xor     si,si
  1370. @@l2:
  1371.         mov     ax,segments[bx]
  1372.         cmp     ax,0
  1373.         je      @@fuck_off
  1374.         cmp     stopped[si],1
  1375.         je      @@fuck_off
  1376.         mov     ds,ax
  1377.         inc     s_count[si]
  1378.         mov     al,current_speed[si]
  1379.         cmp     s_count[si],al
  1380.         jl      @@no_advance
  1381.         mov     s_count[si],0
  1382.         inc     current_line[si]
  1383.         cmp     current_line[si],64
  1384.         je      @@advance
  1385.         cmp     pattern_break[si],1
  1386.         je      @@advance
  1387.         jmp     @@no_advance
  1388. @@advance:
  1389.         inc     current_pos[si]
  1390.         mov     al,current_pos[si]
  1391.         cmp     al,ds:[_songlength]
  1392.         jb      @@norestart
  1393.         mov     al,ds:[_restart]
  1394. @@norestart:
  1395.         cmp     position_jump[si],0
  1396.         je      @@noposjump
  1397.         mov     al,new_position[si]
  1398. @@noposjump:
  1399.         mov     current_pos[si],al
  1400.         
  1401.         call    calc_work_pattern
  1402.         mov     al,break_pos[si]
  1403.         mov     current_line[si],al
  1404.         mov     break_pos[si],0
  1405.         mov     pattern_break[si],0
  1406.         mov     position_jump[si],0
  1407. @@no_advance:
  1408. @@fuck_off:
  1409.         inc     si
  1410.         add     bx,2
  1411.         jumps
  1412.         loop    @@l2
  1413.         nojumps
  1414.  
  1415.         clc
  1416.  
  1417.         ret
  1418. play_line endp
  1419.  
  1420. test_device proc
  1421.         call    testadlib
  1422.         ret
  1423. test_device endp
  1424.  
  1425. oldone_got db 0
  1426.  
  1427. init_device proc
  1428.         call    init_adlib
  1429.         call    init_adlib_tables
  1430.         cmp     oldone_got,0
  1431.         jne     @@got
  1432.         call    getold
  1433. @@got:
  1434.         mov     oldone_got,1
  1435.         clc
  1436.         ret
  1437. init_device endp
  1438.  
  1439. stop_all proc
  1440.         cli
  1441.         call    clear_all_voices
  1442.         call    init_adlib
  1443.         call    init_adlib_tables
  1444.         sti
  1445.         cmp     oldone_got,0
  1446.         je      @@not
  1447.         call    setold
  1448. @@not:
  1449.         call    reset_clock_ticks
  1450.         clc
  1451.         ret
  1452. stop_all endp
  1453.  
  1454. load_song proc
  1455. ;
  1456. ; bl = num (0..8)
  1457. ; dx = segment
  1458. ;
  1459.         xor     bh,bh
  1460.         cmp     bx,8
  1461.         ja      @@err
  1462.         mov     si,bx
  1463.         shl     si,1
  1464.         cmp     segments[si],0
  1465.         jne     @@err
  1466.         mov     ds,dx
  1467.         mov     ax,ds:[_channels]
  1468.         xor     si,si
  1469.         mov     cx,9
  1470. @@l1:
  1471.         shl     ax,1
  1472.         jnc     @@nop
  1473.         cmp     channel_active[si],0
  1474.         jne     @@err
  1475. @@nop:
  1476.         inc     si
  1477.         loop    @@l1
  1478.         mov     ax,ds:[_channels]
  1479.         xor     si,si
  1480.         mov     cx,9
  1481. @@l2:
  1482.         shl     ax,1
  1483.         jnc     @@nop2
  1484.         mov     channel_active[si],0
  1485.         mov     channel_segment[si],bl
  1486. @@nop2:
  1487.         inc     si
  1488.         loop    @@l2
  1489.         mov     stopped[bx],1
  1490.         shl     bx,1
  1491.         mov     segments[bx],dx
  1492.         mov     ax,ds:[_BPM]
  1493.         mov     current_bpm,ax
  1494. @@noerr:
  1495.         clc
  1496.         ret
  1497. @@err:
  1498.         stc
  1499.         ret
  1500. load_song endp
  1501.  
  1502. unload_song proc
  1503. ;
  1504. ; bl = num (0..8)
  1505. ;
  1506.         xor     bh,bh
  1507.         cmp     bx,8
  1508.         ja      merr
  1509.         mov     si,bx
  1510.         shl     si,1
  1511.         cmp     segments[si],0
  1512.         je      merr
  1513.         mov     dx,segments[si]
  1514.         mov     segments[si],0
  1515.         mov     ds,dx
  1516.         mov     ax,ds:[_channels]
  1517.         xor     si,si
  1518.         mov     cx,9
  1519. @@l1:
  1520.         shl     ax,1
  1521.         jnc     @@nop
  1522.         cmp     channel_active[si],0
  1523.         je      merr
  1524.         cmp     channel_segment[si],bl
  1525.         jne     merr
  1526. @@nop:
  1527.         inc     si
  1528.         loop    @@l1
  1529.         mov     ax,ds:[_channels]
  1530.         xor     si,si
  1531.         mov     cx,9
  1532. @@l2:
  1533.         shl     ax,1
  1534.         jnc     @@nop2
  1535.         mov     channel_active[si],0
  1536.         mov     channel_segment[si],0
  1537.         pusha
  1538.         mov     bx,si
  1539.         call    mute_voice
  1540.         popa
  1541. @@nop2:
  1542.         inc     si
  1543.         loop    @@l2
  1544.         mov     stopped[bx],1
  1545.         shl     bx,1
  1546.         mov     segments[bx],0
  1547. noerr:
  1548.         clc
  1549.         ret
  1550. merr:
  1551.         stc
  1552.         ret
  1553. unload_song endp
  1554.  
  1555. start_song proc
  1556. ;
  1557. ; bl = num
  1558. ;
  1559.         xor     bh,bh
  1560.         cmp     bl,8
  1561.         ja      merr
  1562.         shl     bx,1
  1563.         mov     ax,segments[bx]
  1564.         cmp     ax,0
  1565.         je      merr
  1566.         mov     ds,ax
  1567.         mov     al,0
  1568.         push    bx
  1569.         call    calc_work_pattern
  1570.         pop     bx
  1571.         shr     bx,1
  1572.         mov     current_line[bx],0
  1573.         mov     current_speed[bx],6
  1574.         mov     pattern_break[bx],0
  1575.         mov     current_pos[bx],0
  1576.         mov     s_count[bx],0
  1577.         mov     position_jump[bx],0
  1578.         mov     stopped[bx],0
  1579.         mov     ax,ds:[_channels]
  1580.         xor     si,si
  1581.         mov     cx,9
  1582. @@l2:
  1583.         shl     ax,1
  1584.         jnc     @@nop2
  1585.         mov     channel_active[si],1
  1586. @@nop2:
  1587.         inc     si
  1588.         loop    @@l2
  1589.         clc
  1590.         ret
  1591. start_song endp
  1592.  
  1593. play_independent proc
  1594.         mov     polling,0
  1595.         mov     ax,current_bpm
  1596.         mov     ah,al
  1597.         cli
  1598.         mov     bp,0
  1599.         call    effect_set_speed
  1600.         call    setnew
  1601.         sti
  1602.         ret
  1603. play_independent endp
  1604.  
  1605. service_calls dw offset test_device             ; 0
  1606.               dw offset init_device             ; 1
  1607.               dw offset load_song               ; 2
  1608.               dw offset unload_song             ; 3
  1609.               dw offset start_song              ; 4
  1610.               dw offset play_line               ; 5
  1611.               dw offset play_independent        ; 6
  1612.               dw offset set_main_volume         ; 7
  1613.               dw offset empty                   ; 8
  1614.               dw offset empty                   ; 9
  1615.               dw offset stop_all                ; 10
  1616.  
  1617. adlib proc
  1618.         push    ds
  1619.         cmp     al,10
  1620.         jg      @@finish
  1621.         xor     ah,ah
  1622.         mov     si,ax
  1623.         shl     si,1
  1624.         mov     bp,service_calls[si]
  1625.         call    bp
  1626.         pop     ds
  1627.         ret
  1628. @@finish:
  1629.         pop     ds
  1630.         stc
  1631.         ret
  1632. adlib endp
  1633.  
  1634. ;-------------------------------------------------------------------------------
  1635.  
  1636. old08_seg  dw ?
  1637. old08_offs dw ?
  1638.  
  1639. GetOld PROC
  1640.         mov     ah,35h
  1641.         mov     al,8
  1642.         int     21h
  1643.         mov     ax,es
  1644.         mov     old08_seg,ax
  1645.         mov     old08_offs,bx
  1646.         ret
  1647. GetOld ENDP
  1648.  
  1649. SetOld PROC
  1650.         mov     ax,old08_seg
  1651.         mov     ds,ax
  1652.         mov     dx,old08_offs
  1653.         mov     ah,25h
  1654.         mov     al,8
  1655.         int     21h
  1656.         ret
  1657. SetOld  ENDP
  1658.  
  1659. SetNew PROC
  1660.         push    cs
  1661.         push    cs
  1662.         pop     ds
  1663.         lea     dx,new08
  1664.         mov     ah,25h
  1665.         mov     al,8
  1666.         int     21h
  1667.         pop     ds
  1668.         ret
  1669. SetNew ENDP
  1670.  
  1671. New08 PROC
  1672.         pusha
  1673.         push    ds
  1674.         push    es
  1675.  
  1676.         call    play_line
  1677.  
  1678.         mov     al,20h
  1679.         out     20h,al
  1680.  
  1681.         pop     es
  1682.         pop     ds
  1683.         popa
  1684.         iret
  1685. New08 ENDP
  1686.  
  1687. Reset_Clock_Ticks PROC
  1688.         cli
  1689.         mov     al,54
  1690.         out     43h,al
  1691.         mov     al,0
  1692.         out     40h,al
  1693.         out     40h,al
  1694.         sti
  1695.         ret
  1696. Reset_Clock_Ticks ENDP
  1697.  
  1698.  
  1699. ;-------------------------------------------------------------------------------
  1700.  
  1701. usage db 'Usage: qdplay <filename>',13,10,'$'
  1702.  
  1703. bad_use:
  1704.         push    cs
  1705.         pop     ds
  1706.         mov     ah,9
  1707.         lea     dx,usage
  1708.         int     21h
  1709.         mov     ah,4ch
  1710.         int     21h
  1711.  
  1712. get_file proc
  1713.         mov     ah,62h
  1714.         int     21h
  1715.         mov     ds,bx
  1716.         mov     si,80h
  1717.         lodsb
  1718.         xor     ah,ah
  1719.         mov     cx,ax
  1720.         jcxz    bad_use
  1721.         dec     cx
  1722.         jcxz    bad_use
  1723.         push    cs
  1724.         pop     es
  1725.         inc     si
  1726.         lea     di,fname
  1727.         rep     movsb
  1728.         ret
  1729. get_file endp
  1730.  
  1731. vol db 64
  1732.  
  1733. start:
  1734.         call    setfree                 ; init memory..
  1735.  
  1736.         call    get_file
  1737.  
  1738.         push    cs
  1739.         pop     ds
  1740.         lea     dx,fname
  1741.         lea     di,fsong
  1742.         call    loadseg
  1743.  
  1744.         mov     al,1
  1745.         call    adlib                   ; init
  1746.  
  1747.         mov     bl,0
  1748.         push    fsong
  1749.         pop     dx
  1750.         mov     al,2
  1751.         call    adlib                   ; loadsong
  1752.  
  1753.         mov     al,4
  1754.         mov     bl,0
  1755.         call    adlib                   ; startsong
  1756.  
  1757.         mov     al,6
  1758.         call    adlib                   ; play using timer interrupt...
  1759.  
  1760. again:
  1761.         sti
  1762.  
  1763.         mov     ah,11
  1764.         int     21h
  1765.         cmp     al,0
  1766.         je      again
  1767.         mov     ah,8
  1768.         int     21h
  1769.         cmp     al,'+'
  1770.         jne     @@no_p
  1771.         cmp     vol,64
  1772.         jge     again
  1773.         inc     vol
  1774.         mov     bl,vol
  1775.         mov     al,7
  1776.         call    adlib
  1777.         jmp     again
  1778. @@no_p:
  1779.         cmp     al,'-'
  1780.         jne     @@no_m
  1781.         cmp     vol,0
  1782.         jle     again
  1783.         dec     vol
  1784.         mov     bl,vol
  1785.         call    set_main_volume                 ; change main volume
  1786.         jmp     again
  1787. @@no_m:
  1788.  
  1789.         mov     al,10
  1790.         call    adlib                           ; end of all
  1791.  
  1792. end_of_all:
  1793.  
  1794.         mov     ax,4c00H
  1795.         int     21H
  1796. end start
  1797.  
  1798.  
  1799. ;    ▄▀▀▀▀▀▀▀▀▓▀▀▀▀▀▀▀▀▓   ▓▀▀▀▀▀▀▀▀▀▓▄▄
  1800. ;   ▓ ▄█▓▀▀▀▀   ▄████▄ ▀▀█ █ ▒▓█ ▒▓█   █
  1801. ;   █  ▀▀▀▀█▄  ▐██  ██▌  ▓ █ ▓██ ▓██▀▀ █▄▄
  1802. ;   █  ▄▄▌ ██▌ ██▓  ███  ▓ █ ▓██ ▓██ ▐▄▄ ■▓
  1803. ;   █ ██▓  ███ ██▓  ███  ▓▄▓ ███ ███  ███ █
  1804. ;   █ ██▓  ███ ███▄▄███  ▄▄▄▄███ ███  ███ █
  1805. ;   █ ███  ██▓ ███  ██▓ ▐██  ██▓ ███  ██▓ █
  1806. ;   █ ███  ██▓ ███  ██▓ ███  ██▓ ███  ██▓ █
  1807. ;   ▐▌▐██▒ ██▓ ███▒ ██▓ ███▒ ██▓ ▐██▒ ██▓ █
  1808. ;    █ ▀█▓▄█▓▒ ███▓ █▓▒ ▀██▓▄█▓▒  ▀█▓▄█▓▒ █
  1809. ;    ▓■▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▓▄▄▄▄▄▄▄▄▓ v2.00 - Quick'n'Dirty Play
  1810.