home *** CD-ROM | disk | FTP | other *** search
- ;--------------------------------------------------------------------------------
- ;
- ;AdLib specific routines
- ;--------------------------------------------------------------------------------
-
- ;--------------------------------------------------------------------------------
- ;PlaySongAdLib
- ;
- ;plays a song from the list
- ;after setting up all voices
- ;
- ;Inputs:
- ;
- ;ax: Song No.
- ;
- ;--------------------------------------------------------------------------------
-
- PlaySongAdLib proc near
- sub al,15 ;seventeen roland files in front
- mov currentSong,ax
- mov bx,ax
- shl bx,1
-
- ;transfer song parameters
- ;to AdLib driver
- mov ax,ds
- mov es,ax
-
- mov si,SongAdNVoices[bx]
- mov di,offset ChanNVoices
- mov cx,8
- rep movsb
-
- mov si,SongAdCVoices[bx]
- mov di,offset ChanVoices
- mov cx,8*4
- rep movsb
-
- mov si,SongAdPatches[bx]
- mov di,offset SongV0
- mov cx,8
- rep movsb
-
- mov si,SongAdTransp[bx]
- mov di,offset AdTransposes
- mov cx,9
- rep movsb
-
- shr bx,1
- mov al,SongAdPercs[bx]
- mov Percussion,al
-
- ;initialise AdLib
-
- call InitAdLib
- call WriteGlobals
- call InitAllVoices
-
- ;Set up voices for this song
-
- mov si,offset SongV0
- call SetUpSongVoices
-
- mov MusicPlayFlg,0
- call InstallTimer
-
-
- mov ax,csongseg1
- mov es,ax
- mov si,offset MIDIPlayBuffer1
- mov bx,CurrentSong
- mov al,SongTempos[bx]
- xor ah,ah
- call PlayMIDIFileAdLib
-
- ret
- PlaySongAdLib endp
-
- ;--------------------------------------------------------------------------------
- ;routines for playing MIDI files on AdLib
- ;--------------------------------------------------------------------------------
-
- ;--------------------------------------------------------------------------------
- ;PlayMIDIFileAdLib
- ;
- ;Inputs:
- ;
- ;es:si pointer to MIDI file start
- ;ax temp beats per min.
- ;
- ;plays until end of file or
- ;until StopMIDIPlayAdLib is called
- ;
- ;--------------------------------------------------------------------------------
-
- PlayMIDIFileAdLib proc near
- mov PlaySeg,es
- mov PlayPtr,si
-
- mov Tempo,ax
- call SetTimerTempo
-
- call ReadMIDIHeader ;get all header info
-
- mov si,PlayPtr
- call GetVarLength ;get first delay
- mov ax,10
- mov PlayPtr,si
-
- mov cs:EventDelay,1
- mov MusicPlayFlg,-1
-
- ret
- PlayMIDIFileAdLib endp
-
- StopMIDIPlayAdLib proc near
- mov MusicPlayFlg,0
- call RemoveTimer
- call AllNotesOff
- call InitAdLib
- ret
- StopMIDIPlayAdLib endp
-
- SetTimerTempo proc near
- mul TicksPQ ;ticks per min.
- mov bx,60
- div bx ;ticks per second
- mov bx,ax
- mov ax,13089 ;1192737Hz basic freq.
- mov dx,18
- div bx
- or ax,1
- call TimerRate ;set up interrupt rate
- ret
- SetTimerTempo endp
-
- ;--------------------------------------------------------------------------------
- ;EventRoutine:
- ;
- ;This routine is called after (EventDelay) interrupts
- ;
- ;returns:
- ;
- ;ax: new EventDelay
- ;
- ;--------------------------------------------------------------------------------
-
- EventRoutine proc near
- cmp MusicPlayFlg,0
- jne DoEvents
- mov ax,1 ;not playing yet
- ret
- DoEvents:
- cmp BoardFlg,0
- jne ContEvents ;play music on ADLIB BOARD
- ;
- ; must be music or fx on ROLAND
- ;
- cmp fx_flag,0
- je rol_music
- jmp rol_fx_driver
- rol_music:
- jmp RolEventRoutine ;play music on ROLAND BOARD
- ContEvents:
-
- ;do current event
-
- cld
- mov es,PlaySeg
- mov si,PlayPtr
-
- cmp byte ptr es:[si],080h
- jb ProcessMIDIEvent ;using running status
-
- mov al,es:[si]
- inc si
-
- cmp al,0FFh
- jne NotAMeta
- mov al,es:[si] ;Meta event type
- inc si
- call ProcessMetaEvent
- cmp ax,0
- je JND
- jmp DoneAMPlay ;end of track
- JND: jmp NextDelay
- NotAMeta:
-
- cmp al,0F0h
- jb NotASE
- call ProcessSysEx0
- jmp NextDelay
- NotASE:
-
- mov MIDIStatus,al
-
- ProcessMIDIEvent:
- 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
-
- ;handle different midi events
-
- cmp bx,8h ;note off
- jne NMidi8
-
- mov bl,MidiChannel
- xor bh,bh
-
- cmp Percussion,0
- je NoOffPerc
- cmp bx,9
- jne NoOffPerc
- jmp NMidiE ;no note off for percussion voices
- NoOffPerc:
-
- ;find which voice carries the note to turn off
-
- mov cl,ChanNVoices[bx]
- xor ch,ch
-
- shl bx,1
- shl bx,1
- shl bx,1 ;index into ChanVoices
-
- cmp cx,0
- jne VAllocd
- jmp NMidiE ;no voices allocated
- VAllocd:
- cmp cx,1
- je NoOChoice
- PolyNOL:
- mov dl,ChanVoices[bx]
- xor dh,dh
- mov di,dx
- mov dl,VoiceNotes[di]
- cmp dl,es:[si] ;is it this note?
- je GotOffVoice ;yes it is
- inc bx
- loop PolyNOL ;keep trying
- GotOffVoice:
- mov ax,di ;this voice
-
- UseNoteOff:
- mov bl,es:[si]
- mov cl,es:[si+1]
- call NoteOff
- jmp NMidiE
- NoOChoice:
- mov al,ChanVoices[bx] ;the only one
- jmp UseNoteOff
-
- NMidi8:
- cmp bx,9h ;note on
- je HNoteOn
- jmp NMidi9
- HNoteOn:
-
- ;handle polyphony
- ;- scan available voices
- ;- if none free use earliest played
-
- mov bl,MidiChannel
- xor bh,bh
-
- mov di,bx
- shl di,1
- inc MIDIChanCount[di]
-
- cmp Percussion,0
- je NoPercMidi
- cmp bx,9 ;midi channel 10 is percussion channel
- je HandlePerc
- NoPercMidi:
- mov cl,ChanNVoices[bx]
- xor ch,ch
-
- shl bx,1
- shl bx,1
- shl bx,1 ;index into ChanVoices
-
- cmp cx,0
- jne VNAllocd
- jmp NMidiE ;no voices allocated
- VNAllocd:
- cmp cx,1
- je NoPChoice
- mov bp,0FFFFh ;this will contain earliest voice
- xor ax,ax ;voice to use
- PolyVL:
- mov dl,ChanVoices[bx] ;is this voice free?
- xor dh,dh
- mov di,dx
- shl di,1
- mov dx,VoiceStatus[di]
- cmp dx,0
- je GotVoice ;yes, it's free
- cmp dx,bp
- jae NotEarlV
- mov bp,dx ;this is earlier
- mov ax,di
- NotEarlV:
- inc bx
- loop PolyVL ;keep trying
- shr ax,1
- jmp UseVoice ;use earliest
-
- GotVoice:
- mov ax,di
- shr ax,1
- UseVoice:
- ; mov bx,ax
- ; xor bh,bh
- ; mov bl,AdTransposes[bx] ;use transpose
- mov bl,es:[si]
- mov cl,es:[si+1]
- push ax
- push bx
- push cx
- call NoteOff
- pop cx
- pop bx
- pop ax
- call NoteOn
- jmp NMidiE
-
- NoPChoice:
- mov al,ChanVoices[bx] ;the only one
- jmp UseVoice
-
- HandlePerc:
- ;deal with percussion sounds
- mov bl,es:[si] ;note no.
- sub bl,35 ;form index
- mov al,DrumSounds[bx]
- mov bl,24
- jmp UseVoice
-
- NMidi9:
- cmp bx,0Ah ;note aftertouch
- jne NMidiA
- jmp NMidiE
- NMidiA:
- cmp bx,0Bh ;control change
- jne NMidiB
- jmp NMidiE
- NMidiB:
- cmp bx,0Ch ;program change
- jne NMidiC
- jmp NMidiE
- NMidiC:
- cmp bx,0Dh ;chan. aftertouch
- jne NMidiD
- jmp NMidiE
- NMidiD:
- cmp bx,0Eh ;pitch wheel
- jne NMidiE
- jmp NMidiE
- NMidiE:
-
- add si,MIDIDataSiz
-
- NextDelay:
-
- ;check for end of tune
-
- mov bx,si
- sub bx,StartPtr
- cmp bx,PlayLength
- jae DoneAMPlay
- play_aagain:
- call GetVarLength ;get delay to next event
- mov PlayPtr,si
- ret
-
- DoneAMPlay:
- mov si,startptr
- jmp play_aagain
-
-
- mov MusicPlayFlg,0
- mov ax,1
- ret
-
- EventRoutine endp
-
- ;--------------------------------------------------------------------------------
- ;routines for playing notes on AdLib
- ;--------------------------------------------------------------------------------
-
- ;--------------------------------------------------------------------------------
- ;NoteOn
- ;
- ;inputs:
- ;
- ;al: voice 0-8 in melodic 0-10 in percussion mode
- ;bl: pitch 0-127 midi notes: 60 is Middle C (48 is AdLib mid C)
- ;cl: volume 0-127
- ;--------------------------------------------------------------------------------
-
- NoteOn proc near
- push si
- push es
- xor ah,ah
- xor bh,bh
- mov si,ax
- mov VoiceVolumes[si],cl
- mov VoiceNotes[si],bl
- add bl,AdTransposes[si]
- shl si,1
- mov dx,PlayPtr
- mov VoiceStatus[si],dx ;flag it on
-
- sub bx,12 ;adlib pitch = midi pitch-12
- jge NoteOK
- xor bx,bx
- NoteOK:
- mov cx,2000h
- cmp Percussion,0
- jne PercNoteOn
- NormNoteOn:
- mov dx,1 ;note on
- call WriteAdLibFreq
- pop es
- pop si
- ret
-
- ;deal with percussion voices
-
- PercNoteOn:
- cmp ax,5
- jle NormNoteOn ;not a perc
- push ax
-
- cmp ax,BD ;change bass drum freq.
- je BFreq
-
- cmp ax,TC ;can't change TC and HH freq
- je WrBits
- cmp ax,HH
- je WrBits
- cmp ax,SD ;influenced by TOM
- je WrBits
-
- push ax
- push bx
- push cx
- mov ax,SD
- add bx,7 ;pitch SD = pitch TOM+7
- mov dx,0
- call WriteAdLibFreq
- pop cx
- pop bx
- pop ax
-
- BFreq:
- mov dx,0 ;must be 0 for percussion
- call WriteAdLibFreq
-
- WrBits: pop bx
- sub bx,6 ;get offset
- mov al,PerckeyOns[bx] ;bit to set
- or PercBits,al
- call WriteAmVibPerc ;set perc bit
- pop es
- pop si
- ret
- NoteOn endp
-
- ;--------------------------------------------------------------------------------
- ;NoteOff
- ;
- ;inputs:
- ;
- ;ax: voice 0-8 in melodic 0-10 in percussion mode
- ;bl: pitch 0-127 midi notes: 60 is Middle C (48 is AdLib mid C)
- ;cl: volume 0-127
- ;--------------------------------------------------------------------------------
-
- NoteOff proc near
- push si
- push es
- xor ah,ah
- xor bh,bh
- mov si,ax
- mov VoiceVolumes[si],cl
- mov VoiceNotes[si],bl
- add bl,AdTransposes[si]
- shl si,1
- mov VoiceStatus[si],0 ;flag it off
-
- sub bx,12 ;adlib pitch = midi pitch-12
- jge NoteOKO
- xor bx,bx
- NoteOKO:
- mov cx,2000h
- xor dx,dx ;voice off
- cmp Percussion,0
- jne PercNoteOff
- NormNoteOff:
- call WriteAdLibFreq
- pop es
- pop si
- ret
- PercNoteOff:
- cmp ax,5
- jle NormNoteOff ;not a perc
- mov bx,ax
- sub bx,6 ;get offset
- mov al,PerckeyOns[bx] ;bit to clear
- not al
- and PercBits,al
- call WriteAmVibPerc ;clear perc bit
- pop es
- pop si
- ret
- NoteOff endp
-
- ;--------------------------------------------------------------------------------
- ;AllNotesOff
- ;
- ;turns off all voices
- ;
- ;--------------------------------------------------------------------------------
-
- AllNotesOff proc near
- mov bp,8
- xor ax,ax
- cmp Percussion,0
- je NoteOLp
- mov bp,10
- NoteOLp:
- push ax
- push bp
- call NoteOff
- pop bp
- pop ax
- inc ax
- cmp ax,bp
- jle NoteOLp
- ret
- AllNotesOff endp
-
- ;--------------------------------------------------------------------------------
- ;routines for setting parameters in AdLib
- ;--------------------------------------------------------------------------------
-
- ;--------------------------------------------------------------------------------
- ;
- ;InitAdLib:
- ;
- ;clear all AdLib registers
- ;
- ;--------------------------------------------------------------------------------
-
- InitAdLib proc near
- mov ax,1
- IAdLp: push ax
- call AdLibWrite ;clear all reg.s
- pop ax
- inc al
- cmp al,0F5h
- jle IAdLp
-
- mov al,4
- mov ah,60h ;reset Timer-1 & 2
- call AdLibWrite
- mov al,4
- mov ah,80h ;reset Timer-1 & 2
- call AdLibWrite
-
- mov al,1
- mov ah,00100000b ;enable wave-select
- call AdLibWrite
-
- ret
- InitAdLib endp
-
- ;--------------------------------------------------------------------------------
- ;
- ;InitAllVoices:
- ;
- ;set up all slots to default
- ;
- ;--------------------------------------------------------------------------------
-
- InitAllVoices proc near
- mov si,offset pianoOpr0
- mov di,offset pianoOpr1
- mov ax,0
-
- mov bp,8 ;last voice
- cmp Percussion,0
- je LoopIS
- mov bp,5 ;last voice
-
- LoopIS: push ax
- push bp
- call WriteVoice ;set up voices 0-8
- pop bp
- pop ax
- inc ax
- cmp ax,bp
- jle LoopIS
-
- cmp Percussion,0
- je QuitIS
- SetUpPerc:
- mov si,offset bdOpr0 ;set up percussion voices
- mov di,offset bdOpr1
- mov ax,6
- call WriteVoice
- mov si,offset sdOpr
- mov ax,7
- call WriteVoice
- mov si,offset tomOpr
- mov ax,8
- call WriteVoice
- mov si,offset cymbOpr
- mov ax,9
- call WriteVoice
- mov si,offset hhOpr
- mov ax,10
- call WriteVoice
- QuitIS:
- ret
- InitAllVoices endp
-
- ;--------------------------------------------------------------------------------
- ;SetUpSongVoices
- ;
- ;set up all voices for a song
- ;
- ;si: array of patch no.s for voices
- ;
- ;--------------------------------------------------------------------------------
-
- SetUpSongVoices proc near
- mov ax,0
-
- mov bp,8 ;last voice
- cmp Percussion,0
- je LoopSV
- mov bp,5 ;last voice
-
- LoopSV: push ax
- push bp
- push si
- mov bl,[si] ;patch
- xor bh,bh
- shl bx,1
- mov si,AdLibPatches[bx]
- mov di,si
- add di,14 ;operator 1
- call WriteVoice
- pop si
- pop bp
- pop ax
-
- inc si
- inc ax
- cmp ax,bp
- jle LoopSV
-
- cmp Percussion,0
- je NoSPerc
- call SetUpPerc
- NoSPerc:
- ret
-
- SetUpSongVoices endp
-
- ;--------------------------------------------------------------------------------
- ;WriteVoice:
- ;
- ;sets up a voice for a patch
- ;
- ;ax: voice
- ;si: patch operator0
- ;di: patch operator1
- ;
- ;--------------------------------------------------------------------------------
-
- WriteVoice proc near
- push si
- mov bx,offset VoiceSlots
- cmp Percussion,0
- je VNPerc
- mov bx,offset VoiceSlotsPerc ;for percussion mode
- VNPerc:
- mov dx,ax ;voice
- shl ax,1
- add bx,ax
- mov al,[bx] ;first slot (modulator)
- push bx
- push dx
- push di
- mov bx,dx ;voice
- call WriteSlot
- pop di
- pop dx
- pop bx
-
- cmp byte ptr [bx+1],0 ;no second slot (carrier) if <0
- jl NoWriS
-
- push bx
- push dx
- push di
- call WriteFeedFM ;only once per voice
- pop di
- pop dx
- pop bx
-
- mov si,di ;operator1
- mov al,[bx+1] ;second slot (carrier)
- mov bx,dx ;voice
- call WriteSlot
-
- NoWriS:
- pop si
- ret
- WriteVoice endp
-
- ;--------------------------------------------------------------------------------
- ;WriteSlot:
- ;
- ;sets the AdLib up for:
- ;
- ;ax: slot
- ;bx: voice
- ;si: operator
- ;
- ;--------------------------------------------------------------------------------
-
- WriteSlot proc near
- mov Voice,bl
- mov bx,ax
- xor bh,bh
- mov bl,SlotOffsets[bx] ;offset within chip
-
- ;make sure all params within range
-
- and byte ptr KSL[si],3
- and byte ptr MULTI[si],15
- and byte ptr FB[si],7
- and byte ptr AR[si],15
- and byte ptr SL[si],15
- and byte ptr EG[si],1
- and byte ptr DR[si],15
- and byte ptr RR[si],15
- and byte ptr TL[si],63
- and byte ptr AM[si],1
- and byte ptr VIB[si],1
- and byte ptr KSR[si],1
- and byte ptr C[si],1
- and byte ptr WS[si],3
-
- ;set Ksl,Level
-
- mov ah,KSL[si]
- mov cl,6
- shl ah,cl
- mov al,TL[si]
- or ah,al
- mov al,40h
- add al,bl
- call AdLibWrite
-
- ;set Attack,Decay
-
- mov ah,AR[si]
- mov cl,4
- shl ah,cl
- or ah,DR[si]
- mov al,60h
- add al,bl
- call AdLibWrite
-
- ;set Sustain,Release
-
- mov ah,SL[si]
- mov cl,4
- shl ah,cl
- or ah,RR[si]
- mov al,80h
- add al,bl
- call AdLibWrite
-
- ;AM, VIB, EG-TYP (Sustaining), KSR, MULTI
-
- mov ah,AM[si]
- mov cl,7
- shl ah,cl
- mov al,VIB[si]
- mov cl,6
- shl al,cl
- or ah,al
- mov al,EG[si]
- mov cl,5
- shl al,cl
- or ah,al
- mov al,KSR[si]
- mov cl,4
- shl al,cl
- or ah,al
- or ah,MULTI[si]
- mov al,20h
- add al,bl
- call AdLibWrite
-
- ;Wave Select
-
- mov ah,WS[si]
- mov al,0E0h
- add al,bl
- call AdLibWrite
-
- ret
- WriteSlot endp
-
-
- ;set Feedback,Fm
- ;-only once per voice
-
- WriteFeedFM proc near
- mov ah,FB[si]
- shl ah,1
- mov al,C[si]
- xor al,1
- or ah,al
- ; or ah,C[si]
- mov al,0C0h
- add al,Voice
- call AdLibWrite
- ret
- WriteFeedFM endp
-
- ;-------------------------------------------------------------------------------
- ;WriteGlobals:
- ;
- ;sets up AdLib global parameters
- ;
- ;WriteAmVibPerc:
- ;
- ;sets the values: amplitude depth,vibrato depth,percussion and percussion keyons
- ;
- ;-------------------------------------------------------------------------------
-
- WriteGlobals proc near
- call WriteAmVibPerc
- mov ah,NoteSel
- mov cl,6
- shl ah,cl
- mov al,08h
- call AdLibWrite
- ret
- WriteGlobals endp
-
- WriteAmVibPerc proc near
- mov ah,AmDepth
- mov cl,7
- shl ah,cl
- mov al,VibDepth
- mov cl,6
- shl al,cl
- or ah,al
- mov al,Percussion
- mov cl,5
- shl al,cl
- or ah,al
- or ah,PercBits
- mov al,0BDh
- call AdLibWrite
- ret
- WriteAmVibPerc endp
-
- ;------------------------------------------------------------
- ;WriteAdLibFreq
- ;
- ;set a voice's frequency
- ;
- ;inputs:
- ; ax: voice (0-8)
- ; bx: note (0-95)
- ; cx: pitchbend (0-4000h, 2000h no bend)
- ; dx: keyOn (0 disable 1 enable)
- ;
- ;sets volume to VoiceVolumes[voice] if keyOn=1
- ;
- ;------------------------------------------------------------
-
- WriteAdLibFreq proc near
- mov Voice,al
- mov Note,bl
- mov PitchBend,cx
-
- mov ax,cx
-
- mov cl,5
- shl dl,cl ;shift KON to correct location
- mov keyOn,dl
-
- push ax
- cmp dl,0
- je NoVV ;not if keyon=0
- ;set voice volume
- jmp NoVV
-
- mov bx,offset VoiceSlots
- cmp Percussion,0
- je NoVVPerc
- mov bx,offset VoiceSlotsPerc
- cmp Voice,6
- jle NoVVPerc
- dec bx ;for single op. percussion
- NoVVPerc:
- mov al,Voice
- xor ah,ah
- shl ax,1
- add bx,ax
- mov bl,[bx+1] ;carrier slot
- xor bh,bh
- mov al,SlotOffsets[bx]
- mov bl,Voice
- mov ah,VoiceVolumes[bx]
- shr ah,1 ;0-63 volume
- shr ah,1 ;0-31
- shr ah,1 ;0-15
- neg ah
- add ah,15 ;attenuation
- add al,40h
- call AdLibWrite
-
- NoVV: pop ax
-
- sub ax,2000h ;convert pitch bend to signed no.
- je NoMul ;no mul if =0
-
- sar ax,1 ;scale to 0-255
- sar ax,1
- sar ax,1
- sar ax,1
- sar ax,1
-
- imul PitchBendRange ;* by pitch bend range
-
- NoMul: add ah,Note ;add on note no.
-
- add ax,8 ;round to nearest 1/16
-
- sar ax,1 ;scale to 4 bit fix point
- sar ax,1
- sar ax,1
- sar ax,1
-
- jge Not0 ;<0?
-
- xor ax,ax ;=0
- jmp Not95
-
- Not0: cmp ax,(96*16)-1 ;note <=95?
- jl Not95
-
- mov ax,(96*16)-1 ;=95
- Not95:
- mov di,ax ;get half-tone value within 1 octave
- shr di,1 ;use integer part of note MOD 12
- shr di,1
- shr di,1
- shr di,1
- mov dx,di
- mov bl,MOD12Tab[di]
- xor bh,bh
- mov di,bx
-
- shl di,1 ;get offset in frequency table
- shl di,1
- shl di,1
- shl di,1
- shl di,1
-
- shl ax,1
- and ax,31
- add di,ax ;add in fractional part (lower 4 bits)
-
- mov ax,FNumTable[di] ;get frequency
-
- mov di,dx ;get octave number
- mov bl,DIV12Tab[di] ;DIV 12
- dec bl
-
- or ax,ax ;if high bit set must inc octave
- jge NoIncO
- inc bl
- NoIncO:
- or bl,bl ;check for <0
- jge BlokOK
- inc bl
- sar ax,1 ;must /2
- BlokOK:
-
- ;finally write frequency info to AdLib
-
- push bx ;save block
- push ax ;save freq value
- mov ah,al
- mov al,FNUM_LOW
- add al,Voice
- call AdLibWrite
- pop ax
- pop bx
-
- mov al,ah ;set up for register
- and al,3
- shl bl,1
- shl bl,1
- add al,bl
- add al,keyOn
- mov ah,al
- mov al,KEYON_BLOCK_FNUM
- add al,Voice
- call AdLibWrite
- ret
-
- WriteAdLibFreq endp
-
- ;------------------------------------------------------------
- ;AdLibWrite
- ;
- ;write to AdLib board
- ;
- ;input: al - Register No.
- ; ah - Data
- ;
- ;delays an appropriate amount of
- ;time for AdLib hardware to catch up:
- ;
- ; 3.3 æsec after a register select write
- ; 23.0 æsec after a data write
- ;
- ;------------------------------------------------------------
-
- AdLibWrite proc near
-
- mov dx,ADLIB_ADDR ;AdLib output port
- out dx,al
- ;at least 12 cycles delay (3.3 æsec at 3.6 Mhz)
- in al,dx
- in al,dx
- in al,dx
- in al,dx
- in al,dx
- in al,dx
-
- inc dx ;data reg
- mov al,ah
- out dx,al
- dec dx
- ;84 cycles delay (23 æsec at 3.6 Mhz)
- in al,dx
- in al,dx
- in al,dx
- in al,dx
- in al,dx
- in al,dx
- in al,dx
- in al,dx
- in al,dx
- in al,dx
-
- in al,dx
- in al,dx
- in al,dx
- in al,dx
- in al,dx
- in al,dx
- in al,dx
- in al,dx
- in al,dx
- in al,dx
-
- in al,dx
- in al,dx
- in al,dx
- in al,dx
- in al,dx
- in al,dx
- in al,dx
- in al,dx
- in al,dx
- in al,dx
-
- in al,dx
- in al,dx
- in al,dx
- in al,dx
- in al,dx
-
- ret
-
- AdLibWrite endp
-