home *** CD-ROM | disk | FTP | other *** search
- ;--------------------------------------------------------------------------------
- ;Roland LAPC-1 specific routines
- ;--------------------------------------------------------------------------------
- LOAD_MIDI_FILES proc near
-
- cmp boardflg,0
- je getrol
-
-
- ; LOAD AD LIB FILE
-
- mov al,[Asong_number]
- mov ah,0
- mov bx,ax
- shl bx,1
- mov dx,SongNames[bx]
- mov di,offset MIDIPlayBuffer1
- mov ax,csongseg1
- push ds
- call LoadSegFile ;get midi file
- pop ds
- ret
-
- ; get next file and load it
- getrol:
-
- mov al,[Rsong_number]
- mov ah,0
- mov bx,ax ;select next song
- shl bx,1
- mov dx,SongNames[bx]
- mov di,offset MIDIPlayBuffer1
- mov ax,csongseg1
- push ds
- call LoadSegFile ;get midi file
- pop ds
- ret
-
- load_rfx_file:
- ;mov bx,5 ;roland fx file
- ;shl bx,1
- ;mov dx,SongNames[bx]
- ;mov di,offset fxd
- ;mov ax,fx_segment
- ;push ds
- ;call LoadSegFile ;get midi file
- ;pop ds
- ;ret
-
-
- LOAD_MIDI_FILES endp
- ;***********************************************
-
- ; makesound
- ; input al = midi file to play
- ; sets up ax to csongseg? and bx to tempo from list
-
-
- makesound proc near
- mov MusicPlayFlg,0
- push ax
- call InstallTimer ;install special timer routine
- pop ax
-
-
- cmp al,1
- jz pfile1
-
-
- pfile0:
- ; *****************
-
- pfile1:
- mov ax,csongseg1 ; current file to play
- mov es,ax
- mov si,offset MIDIPlayBuffer1
- mov al,[Rsong_number]
- xor ah,ah
- mov bx,ax
- mov al,SongTempos[bx]
- xor ah,ah
- call PlayMIDIFileLAPC1
- ret
-
- makesound endp
- ;--------------------------------------------------------------------------------
- ;PlayMIDIFileLAPC1
- ;
- ;Inputs:
- ;
- ;es:si pointer to MIDI file start
- ;ax temp beats per min.
- ;
- ;plays until end of file or
- ;until StopMIDIPlayLAPC1 is called
- ;
- ;--------------------------------------------------------------------------------
-
- PlayMIDIFileLAPC1 proc near
-
- mov PlaySeg,es
- mov PlayPtr,si
- mov Tempo,ax
- call SetTimerTempo
- call ReadMIDIHeader
- call SwitchLAPC1toUART
- mov RecordFlg,0
- mov DonePlay,0
- mov TimeOver,0 ;******
- mov si,PlayPtr
- call GetVarLength ;get first delay
- mov PlayPtr,si
- mov cs:EventDelay,1 ;every time this counts to 0 RolEventTimer is called
- mov MusicPlayFlg,-1
- ret
- PlayMIDIFileLAPC1 endp
-
- ;*********************************************
-
- StopMIDIPlayLAPC1 proc near
-
- mov MusicPlayFlg,0 ;0= stop midi play
- mov fx_flag,0
- call RemoveTimer
- call AllLAPCNotesOff ;make sure all notes off
- call ResetLAPC1
- ret
- StopMIDIPlayLAPC1 endp
-
- ;-----------------------------------------------------------------------------
- ;ReadMIDIHeader
- ;
- ;process MIDI file header information
- ;-----------------------------------------------------------------------------
-
- ReadMIDIHeader proc near
-
- ;read midi file header
-
- mov es,PlaySeg
- mov si,PlayPtr
- mov ax,es:[si]
- mov ax,es:[si+2] ;MThd
- mov ax,es:[si+4] ;length of header
- mov ax,es:[si+6] ;length of header
- add si,8
- mov ax,es:[si] ;format (must be 0)
- mov ax,es:[si+2] ;no of tracks
- mov ax,es:[si+4] ;division (96 ticks/quarter note)
- add si,6
-
- ;read track header
-
- add si,4 ;MTrk
- mov dh,es:[si]
- mov dl,es:[si+1]
- mov ch,es:[si+2]
- mov cl,es:[si+3] ;dx:cx length
- add si,4
- mov PlayLength,cx
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;mov si,03ah
- mov PlayPtr,si ;position to play from
- mov StartPtr,si
- ret
- ReadMIDIHeader endp
-
- ;------------------------------------------------------------------------------
-
- ;------------------------------------------------------------------------------
- ;RolEventRoutine
- ;
- ;used for playing songs in UART mode
- ;
- ;handles interrupts from timer routine
- ;to send next MIDI data
- ;
- ;------------------------------------------------------------------------------
-
- RolEventRoutine proc near
-
- ;do current event
-
- testrun:
- cld
- mov es,PlaySeg
- mov si,PlayPtr
-
- cmp byte ptr es:[si],080h
- jb RProcessMIDIEvent ;using running status
-
- mov al,es:[si]
- inc si
-
- cmp al,0FFh
- jne RNotAMeta
- mov al,es:[si] ;Meta event type
- inc si
- call ProcessMetaEvent
- cmp ax,0
- je RJND
- jmp RDonePlay ;end of track
- RJND: jmp RNextDelay
- RNotAMeta:
-
- cmp al,0F0h
- jb RNotASE
- call ProcessSysEx0
- jmp RNextDelay
- RNotASE:
-
- mov MIDIStatus,al
- call TxLAData ;output MIDI status byte
-
- RProcessMIDIEvent:
- mov al,MIDIStatus
- mov bl,al
- and al,1111b ;channel
- mov MIDIChannel,al
- xor bh,bh
- mov cl,4
- shr bx,cl ;form index
- mov cl,MIDIDataSizes[bx]
- xor ch,ch
- mov MIDIDataSiz,cx
-
- RSendMIDI:
- mov al,es:[si]
- inc si
- call TxLAData ;send MIDI data
- loop RSendMIDI
-
- RNextDelay:
-
- ;check for end of tune
-
- mov bx,si
- sub bx,StartPtr
- cmp bx,PlayLength
- jae RDonePlay
- play_it_again:
- call GetVarLength ;get delay to next event
- mov PlayPtr,si
- ret
-
- RDonePlay:
- ;mov ax,[loop_flag]
- ;cmp ax,0
- ;jne quitit
-
- mov si,StartPtr
- jmp play_it_again ;for test replay
-
- quitit:
- mov MusicPlayFlg,0
- mov ax,1
-
- ret
- RolEventRoutine endp
-
- ;------------------------------------------------------------------------------
- ;ProcessLACom
- ;
- ;deals with all requests/commands from the LAPC1
- ;------------------------------------------------------------------------------
-
- ProcessLACom proc near
- mov di,offset MIDIBuffer
- stosb
- mov MIDIInBytes,0 ;branch on command
- cmp al,0F0h
- jb MIDITimeByte
- cmp al,0F7h
- jbe TrackDataReq
- cmp al,0FCh
- je AllEnd
- ret
-
- MIDITimeByte:
- call RxLAData ;record MIDI input
- stosb
- cmp al,07Fh
- jbe MIDIRunning
- cmp al,0EFh
- ja MPUMark
- mov bx,ax
- and bx,0F0h
- shr bx,1
- shr bx,1
- shr bx,1
- shr bx,1
- mov cl,MIDIDataSizes[bx]
- xor ch,ch
- mov MIDIDataSiz,cx
- LGetEm: cmp cx,0
- jle LNoMore
-
- LMMore: inc MIDIInBytes
- call RxLAData
- stosb
- loop LMMore
- LNoMore:
- ret
-
- MIDIRunning:
- mov cx,MIDIDataSiz
- dec cx ;we already have one
- jmp LGetEm
-
- MPUMark:
- ret
-
- TrackDataReq:
- cmp MusicPlayFlg,0 ;Is it MIDI format?
- jne MidiTDR
- mov si,PlayPtr ;play non-formatted MIDI data
- mov bx,si
- sub bx,offset RecBuffer
- cmp bx,PlayLength
- jae NonLf
- lodsb
- mov cl,al ;no of bytes
- xor ch,ch
- cmp cx,0
- jle NonLf ;invalid
- WriteData:
- lodsb
- call TxLAData
- loop WriteData
- mov PlayPtr,si
- ret
-
- NonLf: SnDta 0 ;final timing byte
- SnDta 0FCh ;Data End
- ret
-
- AllEnd: mov DonePlay,-1 ;set semaphore
- ret
-
- MidiTDR:
-
- ;handle track data request for MIDI format play
-
- mov es,PlaySeg
- mov si,PlayPtr
- mov bx,si
- sub bx,StartPtr
- cmp bx,PlayLength ;check for end
- jae NonLf
- cmp MusicPlayFlg,0 ;finished play?
- je NonLf
- cmp TimeOver,0
- jg LWait
- LACont:
- call GetVarLength ;get timing length
- cmp ax,240
- jg LTimeO
-
- ;output leading timing byte
-
- LOutTime:
- cmp byte ptr es:[si],0FFh
- je LNotRS
-
- call TxLAData
-
- ;output MIDI event
-
- cmp byte ptr es:[si],080h
- jae LNotRS
- mov cx,MIDIDataSiz ;running status
- jmp LGotRS
- LNotRS:
- mov al,es:[si] ;get status byte
- inc si
-
- cmp al,0FFh
- jne LNotMeta
- mov al,es:[si] ;Meta event type
- inc si
- call ProcessMetaEvent
- mov PlayPtr,si ;******
- cmp ax,0
- jne NonLF ;end of track
- jmp MidiTDR ;must go and get more MIDI data
- LNotMeta:
-
- cmp al,0F0h
- jb LNotSE
- call ProcessSysEx0 ;handle Sys-ex message
- jmp LDoneO
- LNotSE:
-
- push ax
- call TxLAData ;output MIDI status byte
- pop ax
-
- mov bl,al ;get the size of MIDI data from table
- xor bh,bh
- mov cl,4
- shr bx,cl
- mov cl,MIDIDataSizes[bx]
- xor ch,ch
- mov MIDIDataSiz,cx
- cmp cx,0
- je LDoneO
- LGotRS:
- mov al,es:[si] ;output rest of MIDI event
- inc si
- call TxLAData
- loop LGotRS
-
- LDoneO:
- mov PlayPtr,si
- mov TimeOver,0
- ret
-
- LWait: mov ax,TimeOver ;come here for timing delay
- cmp ax,240
- jge LTimeO
- mov TimeOver,0 ;******
- jmp LOutTime ;less than 240 so output
-
- LTimeO:
- mov PlayPtr,si ;check for timing overflow (>240)
- sub ax,240
- mov TimeOver,ax
- mov al,0F8h
- call TxLAData
- ret
-
-
- GetVarLength:
- xor dx,dx ;read a variable-length quantity
- xor ax,ax
- mov cx,7
-
- LVLoop: mov al,es:[si]
- inc si
- mov bl,al
- shl dx,cl
- and al,7Fh
- add dx,ax
- test bl,80h
- jne LVLoop
-
- mov ax,dx ;output in ax
- ret
-
-
- ProcessMetaEvent:
- cmp al,2Fh ;end-of-track
- je LDoneTrk
-
- cmp al,51h
- je SetTempo
-
- call GetVarLength
- cmp ax,0
- je LDoneMet
- mov cx,ax
- add si,cx ;waste data
- LDoneMet:
- mov ax,0
- ret
- LDoneTrk:
- mov ax,-1
- ret
-
- SetTempo:
- call GetVarLength
- cmp ax,0
- je LDoneTmp
- xor dh,dh
- mov dl,es:[si] ;get tempo
- mov ah,es:[si+1]
- mov al,es:[si+2] ;tempo in dx:ax (not implemented)
- add si,3
- LDoneTmp:
- mov ax,0
- ret
-
- ProcessSysEx0:
-
- push cx
- call TxLAData ;send al = sys ex F0 or F7
-
- ;si at next data pos
- sexloop2:
- call getvarlength ;in ax si on data pos
- mov cx,ax
- sexloop:
- mov al,es:[si] ;get MIDI sys-ex byte
- cmp al,0f7h
- je ldonese
- call txladata
- inc si ;next byte or delay tick
- loop sexloop
- inc si ;f7 escape code
- inc si ;variable length data position
- jmp sexloop2
-
- LDoneSE:
- inc si
- call TxLAData ;terminate with f7
-
- pop cx
- ret
-
- ProcessLACom endp
-
- ;------------------------------------------------------------------------------
- ;TxLACom
- ;
- ;send a command to the LAPC1
- ;------------------------------------------------------------------------------
-
- TxLACom proc near
- push cx
- push ax
- mov cx,0
- WaitLA0:
- mov dx,LAStatPort
- in al,dx
- test al,LADRR
- loopne WaitLA0 ;wait until status clear
- cli
- pop ax
- mov dx,LAComPort ;output command
- out dx,al
- WaitLA1:
- mov cx,0
- WaitLA1L:
- mov dx,LAStatPort
- in al,dx
- test al,LADSR
- je GetAck
- loop WaitLA1L
- jmp LxDone ;quit this
- GetAck:
- mov dx,LADataPort
- in al,dx
- sti
- cmp al,0FEh ;ack?
- je LxDone
- call ProcessLACom ;must process command if it's there
- jmp WaitLA1
- LxDone: pop cx
- ret
- TxLACom endp
-
- ;------------------------------------------------------------------------------
- ;TxLAData
- ;
- ;send data to the LAPC1
- ;------------------------------------------------------------------------------
-
- TxLAData proc near
- push cx
- push ax
- mov cx,0
- WaitLAD0:
- mov dx,LAStatPort ;wait for status to clear
- in al,dx
- test al,LADRR
- loopne WaitLAD0
- pop ax
- mov dx,LADataPort ;and output
- out dx,al
- pop cx
- ret
- TxLAData endp
-
- ;------------------------------------------------------------------------------
- ;RxLAData
- ;
- ;receive data from the LAPC1
- ;------------------------------------------------------------------------------
-
- RxLAData proc near
- push cx
- mov cx,0
- WaitRX0:
- mov dx,LAStatPort
- in al,dx
- test al,LADSR
- loopne WaitRX0
- mov dx,LADataPort
- in al,dx ;get it
- pop cx
- ret
- RxLAData endp
-
- ;-----------------------------------------------------------------------------
- ;SwitchLAPC1toUART
- ;
- ;put Roland in UART mode
- ;-you can then read and write the MIDI
- ;port directly
- ;
- ;-----------------------------------------------------------------------------
-
- SwitchLAPC1toUART proc near
- mov dx,LAStatPort
- in al,dx
- test al,LADRR
- jne SwitchLAPC1toUART
- cli
- mov al,03Fh ;switch to UART
- mov dx,LAComPort
- out dx,al
- sti ;no ack
- ret
- SwitchLAPC1toUART endp
-
- ;-----------------------------------------------------------------------------
- ;ResetLAPC1
- ;
- ;resets everything on the LAPC1 to defaults
- ;-----------------------------------------------------------------------------
-
- ResetLAPC1 proc near
- SnCmd 0FFh
- ret
- ResetLAPC1 endp
-
- ;-----------------------------------------------------------------------------
- ; LAPC-1 synth programming
- ;-----------------------------------------------------------------------------
-
- ;-----------------------------------------------------------------------------
- ;SendLAPCChange
- ;
- ;sends a system exclusive MIDI message to the
- ;LAPC1 board.
- ;
- ;inputs:
- ;
- ;si: points to sys.ex. string (FF terminated)
- ;
- ;-----------------------------------------------------------------------------
-
- SendLAPCChange proc near
- SnCmd 0DFh ;want to send system message
- SnDta 0F0h ;System exclusive Send DT1 header
- SnDta 041h
- SnDta 010h
- SnDta 016h
- SnDta 012h
-
- xor bl,bl ;for checksum
- LoopLC: lodsb
- cmp al,0FFh
- je LCDone
- add bl,al
- SnDta al ;send a byte
- jmp LoopLC ;and again
-
- LCDone: and bl,07Fh
- mov bh,080h
- sub bh,bl ;checksum
- SnDta bh
- SnDta 0F7h ;end of message
- ret
- SendLAPCChange endp
-
- SetUpLAPCParts proc near
- SnLA Part1 ;set up all parts 1-8 timbres
- SnLA Part2
- SnLA Part3
- SnLA Part4
- SnLA Part5
- SnLA Part6
- SnLA Part7
- SnLA Part8
- ret
- SetUpLAPCParts endp
-
- ;turn all notes off
-
- AllLAPCNotesOff proc near
- mov cl,0 ;Channel no.
- ChNoO:
- mov al,cl
- or al,0B0h
- call TxLAData ;Channel n All notes off
- SnDta 07Bh
- SnDta 000h
- inc cl
- cmp cl,7
- jle ChNoO
-
- ret
- AllLAPCNotesOff endp