home *** CD-ROM | disk | FTP | other *** search
/ Dave Lowe: Street Fighter 2 PC Disk 1 / Lowe_StreetFighter2PCDisk1.img / ROLAND.ASM < prev    next >
Encoding:
Assembly Source File  |  1992-10-09  |  12.4 KB  |  694 lines

  1. ;--------------------------------------------------------------------------------
  2. ;Roland LAPC-1 specific routines
  3. ;--------------------------------------------------------------------------------
  4. LOAD_MIDI_FILES proc near
  5.  
  6.     cmp boardflg,0
  7.     je getrol
  8.  
  9.  
  10.     ;    LOAD AD LIB FILE
  11.  
  12.     mov    al,[Asong_number]
  13.     mov    ah,0
  14.     mov    bx,ax    
  15.     shl    bx,1
  16.     mov    dx,SongNames[bx]
  17.     mov    di,offset MIDIPlayBuffer1
  18.     mov    ax,csongseg1
  19.     push    ds
  20.     call    LoadSegFile    ;get midi file
  21.     pop    ds
  22.     ret
  23.  
  24. ;   get next file  and load it
  25. getrol:
  26.  
  27.     mov    al,[Rsong_number]
  28.     mov    ah,0
  29.     mov    bx,ax        ;select next song
  30.     shl    bx,1
  31.     mov    dx,SongNames[bx]
  32.     mov    di,offset MIDIPlayBuffer1
  33.     mov    ax,csongseg1
  34.     push    ds
  35.     call    LoadSegFile    ;get midi file
  36.     pop    ds
  37.     ret
  38.  
  39. load_rfx_file:
  40.     ;mov    bx,5        ;roland fx file
  41.     ;shl    bx,1
  42.     ;mov    dx,SongNames[bx]
  43.     ;mov    di,offset fxd
  44.     ;mov    ax,fx_segment
  45.     ;push    ds
  46.     ;call    LoadSegFile    ;get midi file
  47.     ;pop    ds
  48.     ;ret
  49.  
  50.  
  51.  LOAD_MIDI_FILES endp
  52. ;***********************************************
  53.  
  54. ; makesound    
  55. ; input al = midi file to play
  56. ; sets up ax to csongseg? and bx to tempo from list
  57.  
  58.  
  59. makesound    proc near
  60.     mov    MusicPlayFlg,0
  61.     push ax
  62.     call    InstallTimer        ;install special timer routine
  63.     pop ax
  64.  
  65.  
  66.     cmp    al,1
  67.     jz    pfile1
  68.  
  69.  
  70. pfile0:
  71. ;    *****************
  72.  
  73. pfile1:
  74.     mov    ax,csongseg1   ; current file to play
  75.     mov    es,ax
  76.     mov    si,offset MIDIPlayBuffer1
  77.     mov    al,[Rsong_number]
  78.     xor     ah,ah
  79.     mov    bx,ax
  80.     mov    al,SongTempos[bx]
  81.     xor    ah,ah
  82.     call    PlayMIDIFileLAPC1
  83.     ret
  84.  
  85. makesound endp
  86. ;--------------------------------------------------------------------------------
  87. ;PlayMIDIFileLAPC1
  88. ;
  89. ;Inputs:
  90. ;
  91. ;es:si    pointer to MIDI file start
  92. ;ax    temp beats per min.
  93. ;
  94. ;plays until end of file or 
  95. ;until StopMIDIPlayLAPC1 is called
  96. ;
  97. ;--------------------------------------------------------------------------------
  98.  
  99. PlayMIDIFileLAPC1 proc near
  100.  
  101.     mov    PlaySeg,es
  102.     mov    PlayPtr,si
  103.     mov    Tempo,ax
  104.     call    SetTimerTempo
  105.     call    ReadMIDIHeader
  106.     call    SwitchLAPC1toUART
  107.     mov    RecordFlg,0
  108.     mov    DonePlay,0
  109.     mov    TimeOver,0    ;******
  110.     mov    si,PlayPtr
  111.     call    GetVarLength    ;get first delay
  112.     mov    PlayPtr,si
  113.     mov    cs:EventDelay,1    ;every time this counts to 0 RolEventTimer is called
  114.     mov    MusicPlayFlg,-1
  115.     ret
  116. PlayMIDIFileLAPC1 endp
  117.  
  118. ;*********************************************
  119.  
  120. StopMIDIPlayLAPC1 proc near
  121.  
  122.     mov    MusicPlayFlg,0    ;0= stop midi play
  123.     mov    fx_flag,0
  124.     call    RemoveTimer
  125.     call    AllLAPCNotesOff    ;make sure all notes off
  126.     call    ResetLAPC1
  127.     ret
  128. StopMIDIPlayLAPC1 endp
  129.  
  130. ;-----------------------------------------------------------------------------
  131. ;ReadMIDIHeader
  132. ;
  133. ;process MIDI file header information
  134. ;-----------------------------------------------------------------------------
  135.  
  136. ReadMIDIHeader proc near
  137.  
  138. ;read midi file header
  139.  
  140.     mov    es,PlaySeg
  141.     mov    si,PlayPtr
  142.     mov    ax,es:[si]    
  143.     mov    ax,es:[si+2]    ;MThd
  144.     mov    ax,es:[si+4]    ;length of header
  145.     mov    ax,es:[si+6]    ;length of header
  146.     add    si,8
  147.     mov    ax,es:[si]    ;format (must be 0)
  148.     mov    ax,es:[si+2]    ;no of tracks
  149.     mov    ax,es:[si+4]    ;division (96 ticks/quarter note)
  150.     add    si,6
  151.  
  152. ;read track header
  153.  
  154.     add    si,4        ;MTrk
  155.     mov    dh,es:[si]
  156.     mov    dl,es:[si+1]
  157.     mov    ch,es:[si+2]
  158.     mov    cl,es:[si+3]    ;dx:cx length
  159.     add    si,4
  160.     mov    PlayLength,cx
  161.     ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;mov    si,03ah
  162.     mov    PlayPtr,si    ;position to play from
  163.     mov    StartPtr,si
  164.     ret
  165. ReadMIDIHeader endp
  166.  
  167. ;------------------------------------------------------------------------------
  168.  
  169. ;------------------------------------------------------------------------------
  170. ;RolEventRoutine
  171. ;
  172. ;used for playing songs in UART mode
  173. ;
  174. ;handles interrupts from timer routine
  175. ;to send next MIDI data
  176. ;
  177. ;------------------------------------------------------------------------------
  178.  
  179. RolEventRoutine proc near
  180.  
  181. ;do current event
  182.  
  183. testrun:
  184.     cld
  185.     mov    es,PlaySeg
  186.     mov    si,PlayPtr
  187.  
  188.     cmp    byte ptr es:[si],080h
  189.     jb    RProcessMIDIEvent    ;using running status
  190.  
  191.     mov    al,es:[si]
  192.     inc    si
  193.  
  194.     cmp    al,0FFh
  195.     jne    RNotAMeta
  196.     mov    al,es:[si]    ;Meta event type
  197.     inc    si
  198.     call    ProcessMetaEvent
  199.     cmp    ax,0
  200.     je    RJND
  201.     jmp    RDonePlay    ;end of track
  202. RJND:    jmp    RNextDelay
  203. RNotAMeta:
  204.  
  205.     cmp    al,0F0h
  206.     jb    RNotASE
  207.     call    ProcessSysEx0
  208.     jmp    RNextDelay
  209. RNotASE:
  210.  
  211.     mov    MIDIStatus,al
  212.     call    TxLAData    ;output MIDI status byte
  213.  
  214. RProcessMIDIEvent:
  215.     mov    al,MIDIStatus
  216.     mov    bl,al
  217.     and    al,1111b    ;channel
  218.     mov    MIDIChannel,al
  219.     xor    bh,bh
  220.     mov    cl,4
  221.     shr    bx,cl        ;form index
  222.     mov    cl,MIDIDataSizes[bx]
  223.     xor    ch,ch
  224.     mov    MIDIDataSiz,cx
  225.  
  226. RSendMIDI:
  227.     mov    al,es:[si]
  228.     inc    si
  229.     call    TxLAData     ;send MIDI data
  230.     loop    RSendMIDI
  231.  
  232. RNextDelay:
  233.  
  234. ;check for end of tune
  235.  
  236.     mov    bx,si
  237.     sub    bx,StartPtr
  238.     cmp    bx,PlayLength
  239.     jae    RDonePlay
  240. play_it_again:
  241.     call    GetVarLength    ;get delay to next event
  242.     mov    PlayPtr,si
  243.     ret
  244.  
  245. RDonePlay:
  246.     ;mov ax,[loop_flag]
  247.     ;cmp ax,0
  248.     ;jne quitit
  249.  
  250.     mov    si,StartPtr
  251.     jmp    play_it_again        ;for test replay
  252.  
  253. quitit:
  254.     mov    MusicPlayFlg,0
  255.     mov    ax,1
  256.  
  257.     ret
  258. RolEventRoutine endp
  259.  
  260. ;------------------------------------------------------------------------------
  261. ;ProcessLACom
  262. ;
  263. ;deals with all requests/commands from the LAPC1
  264. ;------------------------------------------------------------------------------
  265.  
  266. ProcessLACom proc near
  267.     mov    di,offset MIDIBuffer
  268.     stosb
  269.     mov    MIDIInBytes,0        ;branch on command
  270.     cmp    al,0F0h
  271.     jb    MIDITimeByte
  272.     cmp    al,0F7h
  273.     jbe    TrackDataReq
  274.     cmp    al,0FCh
  275.     je    AllEnd
  276.     ret
  277.  
  278. MIDITimeByte:
  279.     call    RxLAData    ;record MIDI input
  280.     stosb
  281.     cmp    al,07Fh
  282.     jbe    MIDIRunning
  283.     cmp    al,0EFh
  284.     ja    MPUMark
  285.     mov    bx,ax
  286.     and    bx,0F0h
  287.     shr    bx,1
  288.     shr    bx,1
  289.     shr    bx,1
  290.     shr    bx,1
  291.     mov    cl,MIDIDataSizes[bx]
  292.     xor    ch,ch
  293.     mov    MIDIDataSiz,cx
  294. LGetEm:    cmp    cx,0
  295.     jle    LNoMore
  296.  
  297. LMMore:    inc    MIDIInBytes
  298.     call    RxLAData
  299.     stosb
  300.     loop    LMMore
  301. LNoMore:
  302.     ret
  303.  
  304. MIDIRunning:
  305.     mov    cx,MIDIDataSiz
  306.     dec    cx        ;we already have one
  307.     jmp    LGetEm
  308.  
  309. MPUMark:
  310.     ret
  311.  
  312. TrackDataReq:
  313.     cmp    MusicPlayFlg,0    ;Is it MIDI format?
  314.     jne    MidiTDR
  315.     mov    si,PlayPtr    ;play non-formatted MIDI data
  316.     mov    bx,si
  317.     sub    bx,offset RecBuffer
  318.     cmp    bx,PlayLength
  319.     jae    NonLf
  320.     lodsb
  321.     mov    cl,al    ;no of bytes
  322.     xor    ch,ch
  323.     cmp    cx,0
  324.     jle    NonLf    ;invalid
  325. WriteData:
  326.     lodsb
  327.     call    TxLAData
  328.     loop    WriteData
  329.     mov    PlayPtr,si
  330.     ret
  331.  
  332. NonLf:    SnDta    0       ;final timing byte
  333.     SnDta    0FCh    ;Data End
  334.     ret
  335.  
  336. AllEnd:    mov    DonePlay,-1    ;set semaphore
  337.     ret
  338.  
  339. MidiTDR:
  340.  
  341. ;handle track data request for MIDI format play
  342.  
  343.     mov    es,PlaySeg
  344.     mov    si,PlayPtr
  345.     mov    bx,si
  346.     sub    bx,StartPtr
  347.     cmp    bx,PlayLength    ;check for end
  348.     jae    NonLf
  349.     cmp    MusicPlayFlg,0    ;finished play?
  350.     je    NonLf
  351.     cmp    TimeOver,0
  352.     jg    LWait
  353. LACont:    
  354.     call    GetVarLength    ;get timing length
  355.     cmp    ax,240
  356.     jg    LTimeO
  357.  
  358. ;output    leading timing byte
  359.  
  360. LOutTime:
  361.     cmp    byte ptr es:[si],0FFh
  362.     je    LNotRS
  363.  
  364.     call    TxLAData
  365.  
  366. ;output MIDI event
  367.  
  368.     cmp    byte ptr es:[si],080h
  369.     jae    LNotRS
  370.     mov    cx,MIDIDataSiz    ;running status
  371.     jmp    LGotRS
  372. LNotRS:
  373.     mov    al,es:[si]    ;get status byte
  374.     inc    si
  375.  
  376.     cmp    al,0FFh
  377.     jne    LNotMeta
  378.     mov    al,es:[si]    ;Meta event type
  379.     inc    si
  380.     call    ProcessMetaEvent
  381.     mov    PlayPtr,si    ;******
  382.     cmp    ax,0
  383.     jne    NonLF        ;end of track
  384.     jmp    MidiTDR        ;must go and get more MIDI data
  385. LNotMeta:
  386.  
  387.     cmp    al,0F0h
  388.     jb    LNotSE
  389.     call    ProcessSysEx0    ;handle Sys-ex message
  390.     jmp    LDoneO
  391. LNotSE:
  392.  
  393.     push    ax
  394.     call    TxLAData    ;output MIDI status byte
  395.     pop    ax
  396.  
  397.     mov    bl,al        ;get the size of MIDI data from table
  398.     xor    bh,bh
  399.     mov    cl,4
  400.     shr    bx,cl
  401.     mov    cl,MIDIDataSizes[bx]
  402.     xor    ch,ch
  403.     mov    MIDIDataSiz,cx
  404.     cmp    cx,0
  405.     je    LDoneO
  406. LGotRS:
  407.     mov    al,es:[si]    ;output rest of MIDI event
  408.     inc    si
  409.     call    TxLAData
  410.     loop    LGotRS
  411.  
  412. LDoneO:
  413.     mov    PlayPtr,si
  414.     mov    TimeOver,0
  415.     ret
  416.  
  417. LWait:    mov    ax,TimeOver    ;come here for timing delay
  418.     cmp    ax,240
  419.     jge    LTimeO
  420.     mov    TimeOver,0    ;******
  421.     jmp    LOutTime    ;less than 240 so output
  422.  
  423. LTimeO:
  424.     mov    PlayPtr,si    ;check for timing overflow (>240)
  425.     sub    ax,240
  426.     mov    TimeOver,ax
  427.     mov    al,0F8h
  428.     call    TxLAData
  429.     ret
  430.     
  431.  
  432. GetVarLength:
  433.     xor    dx,dx        ;read a variable-length quantity
  434.     xor    ax,ax
  435.     mov    cx,7
  436.  
  437. LVLoop:    mov    al,es:[si]
  438.     inc    si
  439.     mov    bl,al
  440.     shl    dx,cl
  441.     and    al,7Fh
  442.     add    dx,ax
  443.     test    bl,80h
  444.     jne    LVLoop
  445.  
  446.     mov    ax,dx        ;output in ax
  447.     ret
  448.  
  449.  
  450. ProcessMetaEvent:
  451.     cmp    al,2Fh        ;end-of-track
  452.     je    LDoneTrk
  453.  
  454.     cmp    al,51h
  455.     je    SetTempo
  456.  
  457.     call    GetVarLength
  458.     cmp    ax,0
  459.     je    LDoneMet
  460.     mov    cx,ax
  461.     add    si,cx        ;waste data
  462. LDoneMet:
  463.     mov    ax,0
  464.     ret
  465. LDoneTrk:
  466.     mov    ax,-1
  467.     ret
  468.  
  469. SetTempo:
  470.     call    GetVarLength
  471.     cmp    ax,0
  472.     je    LDoneTmp
  473.     xor    dh,dh
  474.     mov    dl,es:[si]    ;get tempo
  475.     mov    ah,es:[si+1]
  476.     mov    al,es:[si+2]    ;tempo in dx:ax (not implemented)
  477.     add    si,3
  478. LDoneTmp:
  479.     mov    ax,0
  480.     ret
  481.  
  482. ProcessSysEx0:
  483.  
  484.     push cx
  485.     call TxLAData        ;send al = sys ex  F0 or F7
  486.  
  487.         ;si at next data pos
  488. sexloop2:
  489.     call getvarlength        ;in ax si on data pos    
  490.     mov    cx,ax
  491. sexloop:
  492.     mov    al,es:[si]    ;get MIDI sys-ex byte
  493.     cmp    al,0f7h
  494.     je    ldonese
  495.     call     txladata
  496.     inc    si        ;next byte or delay tick
  497.     loop    sexloop    
  498.     inc si            ;f7 escape code
  499.     inc si            ;variable length data position
  500.     jmp sexloop2
  501.  
  502. LDoneSE:
  503.     inc si
  504.     call TxLAData        ;terminate with f7
  505.  
  506.     pop cx
  507.     ret
  508.  
  509. ProcessLACom endp
  510.  
  511. ;------------------------------------------------------------------------------
  512. ;TxLACom
  513. ;
  514. ;send a command to the LAPC1
  515. ;------------------------------------------------------------------------------
  516.  
  517. TxLACom proc near
  518.     push    cx
  519.     push    ax
  520.     mov    cx,0
  521. WaitLA0:
  522.     mov    dx,LAStatPort
  523.     in    al,dx
  524.     test    al,LADRR
  525.     loopne    WaitLA0        ;wait until status clear
  526.     cli
  527.     pop    ax
  528.     mov    dx,LAComPort    ;output command
  529.     out    dx,al
  530. WaitLA1:
  531.     mov    cx,0
  532. WaitLA1L:
  533.     mov    dx,LAStatPort
  534.     in    al,dx
  535.     test    al,LADSR
  536.     je    GetAck
  537.     loop    WaitLA1L
  538.     jmp    LxDone        ;quit this
  539. GetAck:
  540.     mov    dx,LADataPort
  541.     in    al,dx
  542.     sti
  543.     cmp    al,0FEh        ;ack?
  544.     je    LxDone
  545.     call    ProcessLACom    ;must process command if it's there
  546.     jmp    WaitLA1
  547. LxDone:    pop    cx
  548.     ret
  549. TxLACom endp
  550.  
  551. ;------------------------------------------------------------------------------
  552. ;TxLAData
  553. ;
  554. ;send data to the LAPC1
  555. ;------------------------------------------------------------------------------
  556.  
  557. TxLAData proc near
  558.     push    cx
  559.     push    ax
  560.     mov    cx,0
  561. WaitLAD0:
  562.     mov    dx,LAStatPort    ;wait for status to clear
  563.     in    al,dx
  564.     test    al,LADRR
  565.     loopne    WaitLAD0
  566.     pop    ax
  567.     mov    dx,LADataPort    ;and output
  568.     out    dx,al
  569.     pop    cx
  570.     ret
  571. TxLAData endp
  572.  
  573. ;------------------------------------------------------------------------------
  574. ;RxLAData
  575. ;
  576. ;receive data from the LAPC1
  577. ;------------------------------------------------------------------------------
  578.  
  579. RxLAData proc near
  580.     push    cx
  581.     mov    cx,0
  582. WaitRX0:
  583.     mov    dx,LAStatPort
  584.     in    al,dx
  585.     test    al,LADSR
  586.     loopne    WaitRX0
  587.     mov    dx,LADataPort
  588.     in    al,dx        ;get it
  589.     pop    cx
  590.     ret
  591. RxLAData endp
  592.  
  593. ;-----------------------------------------------------------------------------
  594. ;SwitchLAPC1toUART
  595. ;
  596. ;put Roland in UART mode
  597. ;-you can then read and write the MIDI
  598. ;port directly
  599. ;
  600. ;-----------------------------------------------------------------------------
  601.  
  602. SwitchLAPC1toUART proc near
  603.     mov    dx,LAStatPort
  604.     in    al,dx
  605.     test    al,LADRR
  606.     jne    SwitchLAPC1toUART
  607.     cli
  608.     mov    al,03Fh        ;switch to UART
  609.     mov    dx,LAComPort
  610.     out    dx,al
  611.     sti            ;no ack
  612.     ret
  613. SwitchLAPC1toUART endp
  614.  
  615. ;-----------------------------------------------------------------------------
  616. ;ResetLAPC1
  617. ;
  618. ;resets everything on the LAPC1 to defaults
  619. ;-----------------------------------------------------------------------------
  620.  
  621. ResetLAPC1 proc near
  622.     SnCmd    0FFh
  623.     ret
  624. ResetLAPC1 endp
  625.  
  626. ;-----------------------------------------------------------------------------
  627. ; LAPC-1 synth programming
  628. ;-----------------------------------------------------------------------------
  629.  
  630. ;-----------------------------------------------------------------------------
  631. ;SendLAPCChange
  632. ;
  633. ;sends a system exclusive MIDI message to the
  634. ;LAPC1 board.
  635. ;
  636. ;inputs:
  637. ;
  638. ;si:     points to sys.ex. string (FF terminated)
  639. ;
  640. ;-----------------------------------------------------------------------------
  641.  
  642. SendLAPCChange proc near
  643.     SnCmd    0DFh        ;want to send system message
  644.     SnDta    0F0h        ;System exclusive Send DT1 header
  645.     SnDta    041h
  646.     SnDta    010h
  647.     SnDta    016h
  648.     SnDta    012h
  649.  
  650.     xor    bl,bl        ;for checksum
  651. LoopLC:    lodsb
  652.     cmp    al,0FFh
  653.     je    LCDone
  654.     add    bl,al
  655.     SnDta    al        ;send a byte
  656.     jmp    LoopLC        ;and again
  657.  
  658. LCDone:    and    bl,07Fh
  659.     mov    bh,080h
  660.     sub    bh,bl        ;checksum
  661.     SnDta    bh
  662.     SnDta    0F7h        ;end of message
  663.     ret
  664. SendLAPCChange endp
  665.  
  666. SetUpLAPCParts proc near
  667.     SnLA    Part1        ;set up all parts 1-8 timbres
  668.     SnLA    Part2
  669.     SnLA    Part3
  670.     SnLA    Part4
  671.     SnLA    Part5
  672.     SnLA    Part6
  673.     SnLA    Part7
  674.     SnLA    Part8
  675.     ret
  676. SetUpLAPCParts endp
  677.  
  678. ;turn all notes off
  679.  
  680. AllLAPCNotesOff proc near
  681.     mov    cl,0        ;Channel no.
  682. ChNoO:
  683.     mov    al,cl
  684.     or    al,0B0h
  685.     call    TxLAData    ;Channel n All notes off
  686.     SnDta    07Bh
  687.     SnDta    000h
  688.     inc    cl
  689.     cmp    cl,7
  690.     jle    ChNoO
  691.  
  692.     ret
  693. AllLAPCNotesOff endp
  694.