home *** CD-ROM | disk | FTP | other *** search
/ Dave Lowe: PCPandemonium Copy Sent To Programmer / Lowe_PCPandemoniumCopySentToProgrammer_1992.09.30.img / ROLAND.ASM < prev    next >
Encoding:
Assembly Source File  |  1992-09-30  |  12.4 KB  |  689 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    si,StartPtr
  247.     jmp    play_it_again        ;for test replay
  248.  
  249.     mov    MusicPlayFlg,0
  250.     mov    ax,1
  251.  
  252.     ret
  253. RolEventRoutine endp
  254.  
  255. ;------------------------------------------------------------------------------
  256. ;ProcessLACom
  257. ;
  258. ;deals with all requests/commands from the LAPC1
  259. ;------------------------------------------------------------------------------
  260.  
  261. ProcessLACom proc near
  262.     mov    di,offset MIDIBuffer
  263.     stosb
  264.     mov    MIDIInBytes,0        ;branch on command
  265.     cmp    al,0F0h
  266.     jb    MIDITimeByte
  267.     cmp    al,0F7h
  268.     jbe    TrackDataReq
  269.     cmp    al,0FCh
  270.     je    AllEnd
  271.     ret
  272.  
  273. MIDITimeByte:
  274.     call    RxLAData    ;record MIDI input
  275.     stosb
  276.     cmp    al,07Fh
  277.     jbe    MIDIRunning
  278.     cmp    al,0EFh
  279.     ja    MPUMark
  280.     mov    bx,ax
  281.     and    bx,0F0h
  282.     shr    bx,1
  283.     shr    bx,1
  284.     shr    bx,1
  285.     shr    bx,1
  286.     mov    cl,MIDIDataSizes[bx]
  287.     xor    ch,ch
  288.     mov    MIDIDataSiz,cx
  289. LGetEm:    cmp    cx,0
  290.     jle    LNoMore
  291.  
  292. LMMore:    inc    MIDIInBytes
  293.     call    RxLAData
  294.     stosb
  295.     loop    LMMore
  296. LNoMore:
  297.     ret
  298.  
  299. MIDIRunning:
  300.     mov    cx,MIDIDataSiz
  301.     dec    cx        ;we already have one
  302.     jmp    LGetEm
  303.  
  304. MPUMark:
  305.     ret
  306.  
  307. TrackDataReq:
  308.     cmp    MusicPlayFlg,0    ;Is it MIDI format?
  309.     jne    MidiTDR
  310.     mov    si,PlayPtr    ;play non-formatted MIDI data
  311.     mov    bx,si
  312.     sub    bx,offset RecBuffer
  313.     cmp    bx,PlayLength
  314.     jae    NonLf
  315.     lodsb
  316.     mov    cl,al    ;no of bytes
  317.     xor    ch,ch
  318.     cmp    cx,0
  319.     jle    NonLf    ;invalid
  320. WriteData:
  321.     lodsb
  322.     call    TxLAData
  323.     loop    WriteData
  324.     mov    PlayPtr,si
  325.     ret
  326.  
  327. NonLf:    SnDta    0       ;final timing byte
  328.     SnDta    0FCh    ;Data End
  329.     ret
  330.  
  331. AllEnd:    mov    DonePlay,-1    ;set semaphore
  332.     ret
  333.  
  334. MidiTDR:
  335.  
  336. ;handle track data request for MIDI format play
  337.  
  338.     mov    es,PlaySeg
  339.     mov    si,PlayPtr
  340.     mov    bx,si
  341.     sub    bx,StartPtr
  342.     cmp    bx,PlayLength    ;check for end
  343.     jae    NonLf
  344.     cmp    MusicPlayFlg,0    ;finished play?
  345.     je    NonLf
  346.     cmp    TimeOver,0
  347.     jg    LWait
  348. LACont:    
  349.     call    GetVarLength    ;get timing length
  350.     cmp    ax,240
  351.     jg    LTimeO
  352.  
  353. ;output    leading timing byte
  354.  
  355. LOutTime:
  356.     cmp    byte ptr es:[si],0FFh
  357.     je    LNotRS
  358.  
  359.     call    TxLAData
  360.  
  361. ;output MIDI event
  362.  
  363.     cmp    byte ptr es:[si],080h
  364.     jae    LNotRS
  365.     mov    cx,MIDIDataSiz    ;running status
  366.     jmp    LGotRS
  367. LNotRS:
  368.     mov    al,es:[si]    ;get status byte
  369.     inc    si
  370.  
  371.     cmp    al,0FFh
  372.     jne    LNotMeta
  373.     mov    al,es:[si]    ;Meta event type
  374.     inc    si
  375.     call    ProcessMetaEvent
  376.     mov    PlayPtr,si    ;******
  377.     cmp    ax,0
  378.     jne    NonLF        ;end of track
  379.     jmp    MidiTDR        ;must go and get more MIDI data
  380. LNotMeta:
  381.  
  382.     cmp    al,0F0h
  383.     jb    LNotSE
  384.     call    ProcessSysEx0    ;handle Sys-ex message
  385.     jmp    LDoneO
  386. LNotSE:
  387.  
  388.     push    ax
  389.     call    TxLAData    ;output MIDI status byte
  390.     pop    ax
  391.  
  392.     mov    bl,al        ;get the size of MIDI data from table
  393.     xor    bh,bh
  394.     mov    cl,4
  395.     shr    bx,cl
  396.     mov    cl,MIDIDataSizes[bx]
  397.     xor    ch,ch
  398.     mov    MIDIDataSiz,cx
  399.     cmp    cx,0
  400.     je    LDoneO
  401. LGotRS:
  402.     mov    al,es:[si]    ;output rest of MIDI event
  403.     inc    si
  404.     call    TxLAData
  405.     loop    LGotRS
  406.  
  407. LDoneO:
  408.     mov    PlayPtr,si
  409.     mov    TimeOver,0
  410.     ret
  411.  
  412. LWait:    mov    ax,TimeOver    ;come here for timing delay
  413.     cmp    ax,240
  414.     jge    LTimeO
  415.     mov    TimeOver,0    ;******
  416.     jmp    LOutTime    ;less than 240 so output
  417.  
  418. LTimeO:
  419.     mov    PlayPtr,si    ;check for timing overflow (>240)
  420.     sub    ax,240
  421.     mov    TimeOver,ax
  422.     mov    al,0F8h
  423.     call    TxLAData
  424.     ret
  425.     
  426.  
  427. GetVarLength:
  428.     xor    dx,dx        ;read a variable-length quantity
  429.     xor    ax,ax
  430.     mov    cx,7
  431.  
  432. LVLoop:    mov    al,es:[si]
  433.     inc    si
  434.     mov    bl,al
  435.     shl    dx,cl
  436.     and    al,7Fh
  437.     add    dx,ax
  438.     test    bl,80h
  439.     jne    LVLoop
  440.  
  441.     mov    ax,dx        ;output in ax
  442.     ret
  443.  
  444.  
  445. ProcessMetaEvent:
  446.     cmp    al,2Fh        ;end-of-track
  447.     je    LDoneTrk
  448.  
  449.     cmp    al,51h
  450.     je    SetTempo
  451.  
  452.     call    GetVarLength
  453.     cmp    ax,0
  454.     je    LDoneMet
  455.     mov    cx,ax
  456.     add    si,cx        ;waste data
  457. LDoneMet:
  458.     mov    ax,0
  459.     ret
  460. LDoneTrk:
  461.     mov    ax,-1
  462.     ret
  463.  
  464. SetTempo:
  465.     call    GetVarLength
  466.     cmp    ax,0
  467.     je    LDoneTmp
  468.     xor    dh,dh
  469.     mov    dl,es:[si]    ;get tempo
  470.     mov    ah,es:[si+1]
  471.     mov    al,es:[si+2]    ;tempo in dx:ax (not implemented)
  472.     add    si,3
  473. LDoneTmp:
  474.     mov    ax,0
  475.     ret
  476.  
  477. ProcessSysEx0:
  478.  
  479.     push cx
  480.     call TxLAData        ;send al = sys ex  F0 or F7
  481.  
  482.         ;si at next data pos
  483. sexloop2:
  484.     call getvarlength        ;in ax si on data pos    
  485.     mov    cx,ax
  486. sexloop:
  487.     mov    al,es:[si]    ;get MIDI sys-ex byte
  488.     cmp    al,0f7h
  489.     je    ldonese
  490.     call     txladata
  491.     inc    si        ;next byte or delay tick
  492.     loop    sexloop    
  493.     inc si            ;f7 escape code
  494.     inc si            ;variable length data position
  495.     jmp sexloop2
  496.  
  497. LDoneSE:
  498.     inc si
  499.     call TxLAData        ;terminate with f7
  500.  
  501.     pop cx
  502.     ret
  503.  
  504. ProcessLACom endp
  505.  
  506. ;------------------------------------------------------------------------------
  507. ;TxLACom
  508. ;
  509. ;send a command to the LAPC1
  510. ;------------------------------------------------------------------------------
  511.  
  512. TxLACom proc near
  513.     push    cx
  514.     push    ax
  515.     mov    cx,0
  516. WaitLA0:
  517.     mov    dx,LAStatPort
  518.     in    al,dx
  519.     test    al,LADRR
  520.     loopne    WaitLA0        ;wait until status clear
  521.     cli
  522.     pop    ax
  523.     mov    dx,LAComPort    ;output command
  524.     out    dx,al
  525. WaitLA1:
  526.     mov    cx,0
  527. WaitLA1L:
  528.     mov    dx,LAStatPort
  529.     in    al,dx
  530.     test    al,LADSR
  531.     je    GetAck
  532.     loop    WaitLA1L
  533.     jmp    LxDone        ;quit this
  534. GetAck:
  535.     mov    dx,LADataPort
  536.     in    al,dx
  537.     sti
  538.     cmp    al,0FEh        ;ack?
  539.     je    LxDone
  540.     call    ProcessLACom    ;must process command if it's there
  541.     jmp    WaitLA1
  542. LxDone:    pop    cx
  543.     ret
  544. TxLACom endp
  545.  
  546. ;------------------------------------------------------------------------------
  547. ;TxLAData
  548. ;
  549. ;send data to the LAPC1
  550. ;------------------------------------------------------------------------------
  551.  
  552. TxLAData proc near
  553.     push    cx
  554.     push    ax
  555.     mov    cx,0
  556. WaitLAD0:
  557.     mov    dx,LAStatPort    ;wait for status to clear
  558.     in    al,dx
  559.     test    al,LADRR
  560.     loopne    WaitLAD0
  561.     pop    ax
  562.     mov    dx,LADataPort    ;and output
  563.     out    dx,al
  564.     pop    cx
  565.     ret
  566. TxLAData endp
  567.  
  568. ;------------------------------------------------------------------------------
  569. ;RxLAData
  570. ;
  571. ;receive data from the LAPC1
  572. ;------------------------------------------------------------------------------
  573.  
  574. RxLAData proc near
  575.     push    cx
  576.     mov    cx,0
  577. WaitRX0:
  578.     mov    dx,LAStatPort
  579.     in    al,dx
  580.     test    al,LADSR
  581.     loopne    WaitRX0
  582.     mov    dx,LADataPort
  583.     in    al,dx        ;get it
  584.     pop    cx
  585.     ret
  586. RxLAData endp
  587.  
  588. ;-----------------------------------------------------------------------------
  589. ;SwitchLAPC1toUART
  590. ;
  591. ;put Roland in UART mode
  592. ;-you can then read and write the MIDI
  593. ;port directly
  594. ;
  595. ;-----------------------------------------------------------------------------
  596.  
  597. SwitchLAPC1toUART proc near
  598.     mov    dx,LAStatPort
  599.     in    al,dx
  600.     test    al,LADRR
  601.     jne    SwitchLAPC1toUART
  602.     cli
  603.     mov    al,03Fh        ;switch to UART
  604.     mov    dx,LAComPort
  605.     out    dx,al
  606.     sti            ;no ack
  607.     ret
  608. SwitchLAPC1toUART endp
  609.  
  610. ;-----------------------------------------------------------------------------
  611. ;ResetLAPC1
  612. ;
  613. ;resets everything on the LAPC1 to defaults
  614. ;-----------------------------------------------------------------------------
  615.  
  616. ResetLAPC1 proc near
  617.     SnCmd    0FFh
  618.     ret
  619. ResetLAPC1 endp
  620.  
  621. ;-----------------------------------------------------------------------------
  622. ; LAPC-1 synth programming
  623. ;-----------------------------------------------------------------------------
  624.  
  625. ;-----------------------------------------------------------------------------
  626. ;SendLAPCChange
  627. ;
  628. ;sends a system exclusive MIDI message to the
  629. ;LAPC1 board.
  630. ;
  631. ;inputs:
  632. ;
  633. ;si:     points to sys.ex. string (FF terminated)
  634. ;
  635. ;-----------------------------------------------------------------------------
  636.  
  637. SendLAPCChange proc near
  638.     SnCmd    0DFh        ;want to send system message
  639.     SnDta    0F0h        ;System exclusive Send DT1 header
  640.     SnDta    041h
  641.     SnDta    010h
  642.     SnDta    016h
  643.     SnDta    012h
  644.  
  645.     xor    bl,bl        ;for checksum
  646. LoopLC:    lodsb
  647.     cmp    al,0FFh
  648.     je    LCDone
  649.     add    bl,al
  650.     SnDta    al        ;send a byte
  651.     jmp    LoopLC        ;and again
  652.  
  653. LCDone:    and    bl,07Fh
  654.     mov    bh,080h
  655.     sub    bh,bl        ;checksum
  656.     SnDta    bh
  657.     SnDta    0F7h        ;end of message
  658.     ret
  659. SendLAPCChange endp
  660.  
  661. SetUpLAPCParts proc near
  662.     SnLA    Part1        ;set up all parts 1-8 timbres
  663.     SnLA    Part2
  664.     SnLA    Part3
  665.     SnLA    Part4
  666.     SnLA    Part5
  667.     SnLA    Part6
  668.     SnLA    Part7
  669.     SnLA    Part8
  670.     ret
  671. SetUpLAPCParts endp
  672.  
  673. ;turn all notes off
  674.  
  675. AllLAPCNotesOff proc near
  676.     mov    cl,0        ;Channel no.
  677. ChNoO:
  678.     mov    al,cl
  679.     or    al,0B0h
  680.     call    TxLAData    ;Channel n All notes off
  681.     SnDta    07Bh
  682.     SnDta    000h
  683.     inc    cl
  684.     cmp    cl,7
  685.     jle    ChNoO
  686.  
  687.     ret
  688. AllLAPCNotesOff endp
  689.