home *** CD-ROM | disk | FTP | other *** search
/ Dave Lowe: Intro 1 of 2 Adlib / Lowe_Intro1of2Adlib.img / DRIVERS / PCDRIV.ASM < prev    next >
Encoding:
Assembly Source File  |  1992-10-27  |  15.7 KB  |  798 lines

  1. ;**************************************************************************
  2. ;                                                                         *
  3. ;     PC DRIVER TO RUN MUSIC ON ROLAND/ADLIB and FX ON ROLAND                                      *
  4. ;                                      *
  5. ;**************************************************************************
  6.  
  7. ;  
  8. ;  note ..this driver does not run the ADLIB FX..as they do not use
  9. ;  Midi data files......see ADFX DIRECTORY on disk for the adlib fx driver
  10.  
  11.  
  12. ;        --------------------------------
  13.  
  14. ;  The variables :boardflg: and :mode_flag: must be set before calling
  15. ;  any of the following procedures
  16.  
  17. public    do_music        ;call to start music playing
  18. public    load_files        ;call to load Midi files from current dir.
  19. public  terminate        ;call to kill boards
  20. public  fx_mode_on        ;call to initiliase driver for ROLAND FX
  21.                 ;sets up the timer etc.  
  22. public    trigger_fx        ;call to start fx.(see list)with number in al
  23.  
  24. public  boardflg        ;byte variable 0 = ROLAND/1 = ADLib
  25. public  mode_flag        ;byte variable 0 = MUSIC(both boards)/1 = ROLAND FX
  26.  
  27. ;  examples....
  28. ;  if boardflg =1 and mode_flag = 0 then the driver will run MUSIC on ADLIB
  29. ;  if boardflg =0 and mode_flag = 1 then driver will run FX on ROLAND
  30. ;  if boardflg =0 and mode_flag = 0 then driver will run MUSIC on ROLAND
  31.  
  32. ;      see fx_table or included list for sound fx numbers
  33.  
  34.  
  35. ;        --------------------------------
  36.  
  37.         ;    DATA FILES
  38.  
  39.  
  40. csongseg1 segment para  'DATA'
  41. MIDIPlayBuffer1 db 58000 dup (?)
  42. csongseg1 ends
  43.  
  44.  
  45. csongseg2 segment para  'DATA'
  46. MIDIPlayBuffer2 db 10 dup (?)
  47. csongseg2 ends
  48.  
  49.  
  50.  
  51.  
  52. fx_segment    segment para  'DATA'
  53. fxd:
  54.  
  55. zb        db    20 dup (?)
  56. fx_segment    ends
  57.  
  58. ;______________________________________________________________________
  59.  
  60. dseg    segment para 'DATA'
  61.  
  62.  
  63. ;    messages used for testing /debugging etc...can be deleted
  64.  
  65. load_mess    db    'loading files...Please Wait',13,10,'$'
  66. board_mess    db    'Select which board..R/A',13,10,'$'
  67. mode_mess    db    'PINBALL DREAMS STEEL WHEELS....Music or FX ????   M/F',13,10,'$'
  68. fin_mess    db    '1 for DOS/2 to RESELECT',13,10,'$'
  69. fx_mess        db    13,10,' ********* KEYS A-Z for jingles 1 to 26 + KEYS 3-6 for jingles 27 to 30 ********',13,10,13,10,'$'
  70. roland_mess    db    13,10,' ************** PLAYING ROLAND PINBALL DREAMS LOADING MUSIC ***************',13,10,13,10,'$'
  71. adlib_mess    db    13,10,' ********************* PLAYING  ADLIB PINBALL DREAMS MUSIC *********************',13,10,13,10,'$'
  72. select_tune_mess db    13,10,' SELECT TUNES A, B or C ',13,10,'$'
  73.  
  74. ch1mess        db    '1 ','$'
  75. ch2mess        db    '2 ','$'
  76.  
  77. ;-----------------------------------------------------------------------
  78. ;  offsets into midi fx file....1= loop 0 = no loop
  79. fx_table:
  80.  
  81. ;---------------------------------------------------------------
  82. include rolvars.asm
  83. include advars.asm
  84. include nwsongs.asm
  85.  
  86. dseg    ends
  87. ;--------------------------
  88. CStack    segment    para stack 'STACK'        ;for stand alone assembly
  89.     db    128 dup(?)
  90. CStack    ends
  91. ;--------------------------
  92. cseg    segment    para public 'CODE'
  93.     assume    cs:cseg,ds:dseg
  94. ;************************************************************************
  95.  
  96.     ;    TEST CONTROL SECTION to allow stand alone testing
  97.     ;          can be deleted when not required
  98.  
  99.  
  100. Start proc near
  101.     mov    dx,ds
  102.     mov    si,2
  103.     mov    bx,[si]
  104.     mov    ax,dseg
  105.     mov    ds,ax
  106.     cld            ;default direction flag
  107.     call resetall
  108.  
  109.  
  110. ;-------------------------------
  111. board_select:
  112.     ;  SELECT WHICH BOARD TO USE
  113.  
  114.     mov    dx,offset board_mess
  115.     call    print
  116.  
  117.  
  118. GBrd:    call    GetKey        ;Roland or Adlib?
  119.     cmp    al,'a'    
  120.     jne    checkROL        ;Adlib
  121.     jmp    play_ad_board
  122. checkROL:
  123.     cmp    al,'r'
  124.     jne    GBrd        ;CHANGED
  125.  
  126.     ;    PLAY SONG ON ROLAND
  127.  
  128.     mov    BoardFlg,0
  129.     ;mov    dx,offset roland_mess
  130.     ;call     print
  131.  
  132.  
  133.     jmp    choose_mode
  134. play_ad_board:
  135.     mov    boardFlg,1
  136.     mov    mode_flag,0    ;music only on adlib
  137.     mov    dx,offset adlib_mess
  138.     call     print
  139.     jmp    adj1
  140. ;---------------------------------
  141.  
  142.     ;  CHOOSE MUSIC OR FX ON  ROLAND
  143.  
  144. ;   test wait for key loop
  145. choose_mode:
  146.  
  147.         ;    test for fx or music here
  148.  
  149. ;    mov    dx,offset mode_mess
  150. ;    call print
  151. ;    call getkey
  152.             ;choose music or fx
  153. ;    cmp    al,'m'
  154. ;    jne    check_fx
  155.     mov    dx,offset roland_mess
  156.     call print
  157.  
  158.     ;-----------------------------
  159.     mov    mode_flag,0    ;music mode
  160.     mov    dx,offset select_tune_mess
  161.     call     print
  162.     call    getkey
  163. newr:    sub    al,97    
  164.     mov [Rsong_number],al
  165.     call far ptr load_files    ; get em in
  166.     call    far ptr do_music
  167.     jmp    test_loop
  168.  
  169.  
  170. ;********************************************************
  171. ;        PLAY MUSIC ONLY ON ADLIB
  172.  
  173. adj1:    mov    mode_flag,0    ;  music mode
  174.     mov    dx,offset select_tune_mess
  175.     call print
  176.     call   getkey
  177. newa:    sub    al,82        ;15 roland files first    
  178.     mov [Asong_number],al
  179.     call far ptr load_files    ; get em in
  180.     call    far ptr do_music
  181.     jmp test_loop
  182. ;***********************************************************
  183.  
  184. check_fx:
  185.     cmp    al,'f'
  186.     jne    choose_mode    ;error
  187.     mov    mode_flag,1
  188.  
  189. set_fx_mode:
  190.     call    far ptr fx_mode_on    ;ROLAND FX MODE SET UP
  191.     mov    dx,offset fx_mess
  192.     call print
  193.  
  194. ;--------------------------------------------
  195. ;       TEST LOOP......IE SITS IN THIS LOOP WHILE RUNNING MIDI
  196.     ;  interrupts play music
  197. test_loop:
  198.  
  199.     ;  test only
  200.     ;jmp    testrun
  201.  
  202.  
  203.     mov    dx,offset fin_mess
  204.     call print
  205.     
  206. test_loop1:            ; TEST FOR KEY PRESS TO FINISH
  207.     call    CheckKey
  208.     jz    test_loop1
  209.     call    GetKey
  210.     cmp    al,'1'        ;  quit altogether
  211.     je    back_to_dos
  212.     cmp    al,'2'        ;   reset to choose mode
  213.     je    reset
  214.  
  215.  
  216. ;    must be key to trigger fx
  217.     cmp    al,127
  218.     jae    test_loop1
  219.     cmp    al,49
  220.     jbe    test_loop1
  221.  
  222.  
  223.                 ;manipulate key number
  224.     cmp al,97     
  225.     jae isletk
  226.     add al,72
  227. isletk:
  228.     sub    al,96    
  229.     call  far ptr    trigger_fx
  230.     jmp     test_loop1
  231.  
  232. ;------------------------
  233.  
  234. back_to_dos:
  235.  
  236.     call resetall
  237.     call far ptr terminate
  238.     mov    ah,4ch
  239.     int 21h
  240.     ret
  241. reset:
  242.     push ax
  243.     call resetall
  244.     call far ptr terminate
  245.     ;mov    al,[boardflg]
  246.     ;cmp     al,0
  247.     ;jne    reseta
  248.     ;pop ax
  249.     jmp start
  250. reseta:
  251.     pop ax
  252.     jmp start
  253.  
  254.  
  255. start    endp
  256. ;---------------------------------
  257. print    proc near
  258.         ;  input  dx    points to message
  259.  
  260.     push    ax
  261.     mov    ah,9
  262.     int 21h
  263.     pop     ax
  264.     ret
  265.     
  266. print    endp
  267.  
  268. ;        END OF CONTROL TEST (deletable) SECTION
  269. ;************************************************************************
  270. ;************************************************************************
  271. ;************************************************************************
  272. ;************************************************************************
  273.  
  274.     ;          ACTUAL DRIVER ROUTINES
  275.  
  276.     ;        call here to start music
  277.     ;    boardflg must be set 0= ROLAND 1 = ADLIB 
  278.  
  279.  
  280. ;----------------------------------------------
  281. ;;;;;;;DO MUSIC ROUTINE
  282.  
  283. do_music  proc far
  284.  
  285.     mov    dx,ds
  286.     mov    si,2
  287.     mov    bx,[si]
  288.     mov    ax,dseg
  289.     mov    ds,ax
  290.     cld            ;default direction flag
  291.  
  292.     mov    [tickspq],96    ;standard seq
  293.             ;   choose which music and set it running
  294.     cmp    boardFlg,0
  295.     jne    playad
  296.     call    resetall
  297.     mov    al,[Rsong_number]
  298.     xor     ah,ah
  299.     call    makesound    ;al = tune to play on ROLAND
  300.     ret 
  301. playad:
  302.     mov    al,[Asong_number]
  303.     xor     ah,ah
  304. nocorr:    call    playsad
  305.     ret
  306. do_music endp 
  307. ;*************************************
  308. load_files proc far
  309.             ;  call here to load required MIDI files
  310.             ;  The files must be in the current directory
  311.             ;  and the boardflg must be set
  312.  
  313.     mov    dx,ds
  314.     mov    si,2
  315.     mov    bx,[si]
  316.     mov    ax,dseg
  317.     mov    ds,ax
  318.     cld            ;default direction flag
  319.     call    LOAD_MIDI_FILES
  320.     ret
  321.  
  322. load_files endp
  323. ;************************************
  324. terminate proc far
  325.  
  326.             ;  call here to stop sound on both boards
  327.             ;  boardflg must be set.
  328.  
  329.     mov    dx,ds
  330.     mov    si,2
  331.     mov    bx,[si]
  332.     mov    ax,dseg
  333.     mov    ds,ax
  334.     cld            ;default direction flag
  335.     cmp boardflg,0
  336.     jne    stop_ad
  337.     mov    ch1_flag,0
  338.     mov    ch2_flag,0    ;clear fx flags
  339.     call rcc10
  340.     call rcc2
  341.     call ano2
  342.     call ano10
  343.  
  344.     call stopMusicR
  345.     ret
  346. stop_ad:
  347.     call stopmidiplayadlib
  348.     ret
  349. terminate endp
  350. ;-------------------------------------------------------
  351. fx_mode_on proc far
  352.     ;   play fx
  353.     ;   SEt UP THE TIMER AND FLAGS TO RUN THE FX DRIVER
  354.  
  355. ;-------------------------------
  356. ;;load midi fx file for ROLAND
  357.  
  358.     mov bx,4    ;5 name in list
  359.     shl    bx,1
  360.     mov    dx,SongNames[bx]
  361.     mov    di,offset fxd
  362.     mov    ax,fx_segment
  363.     push ds
  364.     call    LoadSegFile
  365.     pop ds
  366.     
  367. ;---------------------------------
  368.         ;board to reset status
  369.  
  370.     mov    dx,ds
  371.     mov    si,2
  372.     mov    bx,[si]
  373.     mov    ax,dseg
  374.     mov    ds,ax
  375.     cld            ;default direction flag
  376. ;    call    resetall        ;not implemented
  377.     mov    fx_flag,1    ;set flag for interrupt routine
  378.     mov    DonePlay,0
  379.     mov    recordflg,0
  380.     mov    timeover,0    
  381. ;    reset fx vars
  382.     mov    ch1_pattp,0
  383.     mov    ch2_pattp,0
  384.     mov    ch1_flag,0
  385.     mov    ch2_flag,0
  386.     mov    ch1_intc,0
  387.     mov    ch2_intc,0
  388.     call installTimer
  389.     mov    tickspq,96        ;ticks per quarter beat
  390.     mov    ax,120        ; tempo to give 76 hz
  391.     mov    tempo,ax
  392.     call setTimerTempo
  393.     call switchlapc1touart
  394.     call    rcc2
  395.     call    ano2
  396.     call    rcc10
  397.     
  398.     SnLA    setvol
  399.     mov    cs:eventdelay,1        ;run interrupt routine on next 50th
  400.     mov    musicPlayFlg,-1        ;to allow event routine to run
  401.     ret
  402.  
  403. fx_mode_on endp     
  404. ;*************************************************
  405. trigger_fx proc far
  406.  
  407.  
  408.     push ax            ;fx number
  409.     mov [curr_fx],ax
  410.     mov    dx,ds
  411.     mov    si,2
  412.     mov    bx,[si]
  413.     mov    ax,dseg
  414.     mov    ds,ax
  415.     cld            ;default direction flag
  416.     pop ax
  417.  
  418.             ;mov    dx,offset ch1mess
  419.             ;call print
  420.  
  421.     ;   sort fx offset from fx list
  422.     dec    al
  423.     add     al,al    ;*2    
  424.     add    al,al    ;*4    ;double word table
  425.     mov    bl,al
  426.     xor    bh,bh
  427.     ;mov    ax,fx_table[bx]
  428.  
  429.     add    ax,59        ;header
  430.     mov    [startptr],ax
  431.     push     ax        ; offset
  432.     inc     bx
  433.     inc    bx
  434.     ;mov    ax,fx_table[bx]
  435.     mov [loop_flag],ax
  436.     jmp    use2
  437.  
  438.  
  439.  
  440.     ;   use driver channel 1
  441. use1:
  442.     pop     ax
  443.     mov    ch1_pattp,ax
  444.     mov    int_flag,1    ;disable interrupt routine
  445.     mov    ch1_flag,1    ;enable channel 1
  446.     mov    ch1_intc,0    ;reset any interrupt count
  447.     mov    int_flag,0    ;enable interrupt routine
  448.     ;call    rcc10        ;reset controllers 10        
  449.     ;call    ano10
  450.     call resetall
  451.  
  452.     ret
  453. use2:
  454.     ;  always overwrite on channel 2
  455.     ;  always send all notes off mchannel 2
  456.  
  457.             ;mov    dx,offset ch2mess
  458.             ;call    print
  459. ;-----------------------
  460. ;reset all controllers  and notes
  461.  
  462.  
  463.     ;call    ano2
  464.     call    rcc2
  465.     ;call    rcc10        ;reset controllers 10        
  466.     ;call    ano10
  467.     call resetall
  468.     pop     ax
  469. ;-------------------------
  470.     ;   sort fx offset from fx list
  471.     ;    use channel 2
  472.     mov    ch2_pattp,ax
  473.     mov    int_flag,1    ;disable interrupt routine
  474.     mov    ch2_flag,1    ;enable channel 1
  475.     mov    ch2_intc,0    ;reset any interrupt count
  476.     mov    int_flag,0    ;enable interrupt routine
  477.     ret
  478.  
  479. trigger_fx endp
  480.  
  481. ;------------------------------------------------
  482.     ; controller subroutines
  483. rcc2:            ;reset cont. ch2
  484.     mov    al,0B1h
  485.     call     TXLAData
  486.     mov    al,79h
  487.     call    TXLAData
  488.     mov    al,0
  489.     call    TXLAData
  490.     ret
  491.  
  492. ano2:    ;  all notes off two
  493.     mov    al,0B1h        ;all notes off ch2
  494.     call    TxLAData
  495.     mov    al,07Bh    
  496.     call    TxLAData
  497.     ret
  498.  
  499. rcc10:                ;reset all controllers
  500.     mov    al,0B9h
  501.     call     TXLAData
  502.     mov    al,79h
  503.     call    TXLAData
  504.     mov    al,0
  505.     call    TXLAData
  506.     ret
  507.  
  508.  
  509. ano10:    ;  all notes off 10
  510.     mov    al,0B9h        ;all notes off ch10
  511.     call    TxLAData
  512.     mov    al,07Bh    
  513.     call    TxLAData
  514.     mov    al,0
  515.     call    Txladata
  516.     ret
  517.  
  518.  
  519. resetall:
  520.  
  521.     mov al,0B0h
  522. dorlooc:
  523.     push    ax
  524.     call    TxLAData
  525.     mov    al,079h    
  526.     call    TxLAData
  527.     mov    al,0
  528.     call    Txladata
  529.     pop ax
  530.     inc al
  531.     cmp al,0Bah
  532.     jne    dorlooc
  533.  
  534.  
  535.     mov al,0B0h
  536. dorloop:
  537.     push    ax
  538.     call    TxLAData
  539.     mov    al,07Bh    
  540.     call    TxLAData
  541.     mov    al,0
  542.     call    Txladata
  543.     pop ax
  544.     inc al
  545.     cmp al,0Bah
  546.     jne    dorloop
  547.     ret
  548.  
  549.  
  550. ;*************************************************
  551.  
  552. ;   THIS ROUTINE IS CALLED BY THE TIMER INTERRUPT WHEN PLAYING ROLAND FX.
  553.  
  554.  
  555. rol_fx_driver proc near
  556.  
  557.     cmp    int_flag,1    ;fx being set up/miss one
  558.     je    fin_fx_call    
  559.     
  560.     mov    ax,fx_segment
  561.     mov    es,ax
  562.  
  563. ;- - - - - - - - - - - - - - - - - - - - 
  564. ;    THIS SECTION IS CHANNEL SPECIFIC
  565.     ; test for fx playing on channel 1
  566.     
  567.     cmp    ch1_flag,0
  568.     je    ch2        ; should go next chann
  569.             ;   channel 1 playing
  570.  
  571.     mov    run1,1            ;which channel flag
  572.     mov    si,ch1_pattp
  573.     cmp    ch1_intc,0
  574.     jne    ch1_wait
  575.  
  576. ;                          check for end of current fx
  577. next_event_now1:
  578.     mov    al,es:[si]
  579.     cmp    al,255
  580.     je     ch1_off
  581.     call    process_data        ;next event ready to process
  582.     call    getvarlength
  583.     cmp    ax,0
  584.     je    next_event_now1
  585.     mov    ch1_pattp,si    ;store offset
  586.     mov    ch1_intc,ax
  587. ch1_wait:
  588.     mov    ax,ch1_intc
  589.     dec    ax
  590.     mov    ch1_intc,ax
  591. ;**********
  592. ch2:    
  593.     ; test for fx playing on channel 2
  594.     cmp    ch2_flag,0
  595.     je    fin_fx_call    
  596.             ;   channel 2 playing
  597.  
  598.     mov    run1,0        ;which channel 0 =2
  599.     mov    si,ch2_pattp
  600.     cmp    ch2_intc,0
  601.     jne    ch2_wait
  602. ;                          check for end of current fx
  603. next_event_now2:
  604.     mov    al,es:[si]
  605.     cmp    al,255
  606.     je     ch2_off
  607.     call    process_data        ;next event ready to process
  608.     call    getvarlength
  609.     cmp    ax,0
  610.     je    next_event_now2
  611.     mov    ch2_pattp,si    ;store offset
  612.     mov    ch2_intc,ax
  613. ch2_wait:
  614.     mov    ax,ch2_intc
  615.     dec    ax
  616.     mov    ch2_intc,ax
  617.  
  618. ;**********
  619. fin_fx_call:
  620.     mov    ax,1    ;  next delay 
  621.     ret
  622. ;--------------------------------------------
  623. ch1_off:
  624.     call    rcc10
  625.     mov    ch1_flag,0
  626.     jmp    ch2
  627. ch2_off:
  628.     call    rcc2
  629.     mov    ch2_flag,0
  630.     mov ax,[loop_flag]
  631.     cmp ax,1
  632.     jne fin_fx_call
  633.     mov ax,[curr_fx]
  634.     call far ptr trigger_fx
  635.     jmp    fin_fx_call
  636. ;****************************************
  637. process_data:
  638.     ;input    si with event offset pointer
  639.     ;output    ax = no of event delays to next event
  640.     ;first check for end of fx
  641.     call    send_next_event
  642.             ; now store frame delay + pointer    
  643.     ret
  644. ;----------------------------------
  645. send_next_event:
  646.         ;input si holding  current event offset
  647.     mov     al,es:[si]
  648. ;  test for new status byte
  649.     test    al,128    
  650.     jz    old_status
  651.  
  652. ;  only here if new status byte
  653.     cmp    run1,0
  654.     jne    running1
  655.     mov    csb2,al    ;store status+channel for 2
  656.     jmp running2
  657. running1:
  658.     mov    csb1,al    ;store status+channel for 1
  659. running2:
  660.     xor     ah,ah    
  661.     mov     bl,al
  662.     xor    bh,bh
  663.     mov    cl,4
  664.     shr    bx,cl
  665.     mov    cl,MIDIDataSizes[bx]    ;value -1
  666.     inc    cl
  667.     xor     ch,ch
  668.     mov     MIDIDataSiz,cx
  669.     cmp     cx,0
  670.     je    event_fin
  671.     cmp    run1,0
  672.     jne    save_len1
  673.     mov    cel2,cx    ;store event  len
  674.     jmp    output_event
  675. save_len1:
  676.     mov    cel1,cx    ;store event  len
  677.     jmp    output_event    ;new 
  678. ;-------------------------------------
  679. old_status:
  680.     cmp    run1,0
  681.     jne    get1
  682.     mov    al,csb2
  683.     mov    cx,cel2
  684.     jmp    old_event_entry
  685. get1:
  686.     mov    al,csb1
  687.     mov    cx,cel1
  688.     jmp    old_event_entry
  689. ;------------------------------------
  690. output_event:
  691.     mov     al,es:[si]    ;status from file
  692.     inc     si
  693. old_event_entry:
  694.     call TxLAData
  695.     loop    output_event
  696. event_fin:
  697.     ret
  698.  
  699. rol_fx_driver endp
  700. ;***************************************************    
  701. StopMusicR:
  702.     call    StopMIDIPlayLAPC1
  703.     ret
  704. ;play song on AdLib
  705. PlaySAd:
  706.     call    PlaySongAdLib
  707.     ret
  708. ;------------------------------Start endp
  709.  
  710. GetKey proc near
  711.     mov    ah,0    ;do DOS getkey
  712.     int    16h    ;ASCII in al
  713.     ret
  714. GetKey     endp
  715.  
  716. CheckKey proc near
  717.     mov    ah,1    ;do DOS checkkey
  718.     int    16h
  719.     ret
  720. CheckKey endp
  721.  
  722. ;--------------------------------------------------------------------------------
  723. ;LoadSegFile
  724. ;
  725. ;loads a file into a specified segment
  726. ;
  727. ;inputs:
  728. ;
  729. ;ax:    load segment
  730. ;dx:    pointer to filename
  731. ;di:    load offset
  732. ;
  733. ;--------------------------------------------------------------------------------
  734.  
  735. LoadSegFile proc near
  736.     push    ax
  737.     mov    al,0
  738.     mov    ah,3Dh            ;open file
  739.     int    21h
  740.     jc    LSFError
  741.     pop    ds
  742.     jmp    LFOpen
  743. LSFError:
  744.     pop    ax
  745.     ret
  746. LoadSegFile endp
  747.  
  748. LoadFile proc near
  749.     mov    al,0
  750.     mov    ah,3Dh
  751.     int    21h            ;open file
  752.     jnc    LFOpen
  753.     jmp    LFError
  754. LFOpen:
  755.     mov    bx,ax
  756.     mov    cx,0
  757.     mov    dx,0
  758.     mov    ax,4202h
  759.     int    21h
  760.     push    ax         ;find size
  761.     mov    cx,0
  762.     mov    dx,0
  763.     mov    ax,4200h
  764.     int    21h
  765.     pop    cx
  766.  
  767.     push    cx
  768.     mov    dx,di        ;buffer
  769.     push    di
  770.     mov    ah,3Fh
  771.     int    21h
  772.     mov    ah,3Eh
  773.     int    21h           ;close
  774.     pop    di
  775.     pop    bx
  776. LFSafe:
  777.     mov    ax,0
  778.     ret
  779. LFError:
  780.     mov    ax,-1
  781.     ret
  782.  
  783. LoadFile endp
  784.  
  785. ;-----------------------------------------------------------------------------
  786. include roland.asm
  787. ;-----------------------------------------------------------------------------
  788. include adlib.asm
  789. ;-----------------------------------------------------------------------------
  790. include adtimer.asm
  791. ;-----------------------------------------------------------------------------
  792.  
  793. EndCode:
  794.  
  795. cseg    ends
  796.  
  797.     end Start
  798.