home *** CD-ROM | disk | FTP | other *** search
- page 60,132
- title Adlib Sound Effects Driver
-
- ;******************************** fxdrive.asm *******************************
- ;* *
- ;* Ad Lib Sound Effects Driver *
- ;* Copyright 1990, Ad Lib Inc. *
- ;* *
- ;****************************************************************************
-
-
- DEBUG equ 0 ;debug conditional assembly
- NOCOUNT equ 0 ;interrupt counter conditional assembly
-
- ;****************************************************************************
- _TEXT segment byte public 'code'
-
- assume CS:_TEXT
- assume DS:_TEXT
-
- extrn MasterTable:byte,_PatchTable:byte
- extrn _motortable:byte
-
- public _NoWrites
-
- ;----------------------------------------------------------------------------
- ;function pointer table (for indirect function calls if used)
- public functable
- functable dw _Init_Sound_ISR
- dw _Terminate_Sound_ISR
- dw _Sound_ISR
- dw _sendsnd
- dw _speak
- dw _sstatus
- dw _vstatus
- dw _getaddr
- dw _setmotor
- dw _abortsample
- dw _switchsoundtable
- tablelen equ ($-functable)/4
- ;----------------------------------------------------------------------------
- include fxdrive.inc
- include pbend.inc
-
- MaxWrites dw 0
- _NoWrites dw 0
-
- installedur db 0 ;ddt 6/9/90
-
- ;sound system global variables
- Old8255 db 0 ;timer 2 control
- Mask8255 db 0 ;timer 2 control
- curchannel db 0 ;current channel being parsed
- do_sound db 0 ;run sound system flag
- DrumMask db 0
- globalTempo db 0 ;global music tempo
- motorflag db 0 ;motor active flag
- motordur db 01 ;current motor duration count
- motordcnt db 01 ;count timer for motor duration
- NoiseIndex dw 0ffffh
- seed dw 1234h ;for random number
- state db 0 ;register shadow for motor
- ShadowBD db 0 ;shadow of am/vib/drum reg
- YamOff db 0 ;chip operator offset
- Kickshadow db 0 ;shadow of kick attenuation
- Snareshadow db 0 ;shadow of snare attenuation
- Hihatshadow db 0 ;shadow of hihat attenuation
- Tomshadow db 0 ;shadow of tom attenuation
- Rideshadow db 0 ;shadow of ride attenuation
-
- KickMaster db 0 ;shadow of kick attenuation
- SnareMaster db 0 ;shadow of snare attenuation
- HihatMaster db 0 ;shadow of hihat attenuation
- TomMaster db 0 ;shadow of tom attenuation
- RideMaster db 0 ;shadow of ride attenuation
-
- KickAttn db 0 ;shadow of kick attenuation
- SnareAttn db 0 ;shadow of snare attenuation
- HihatAttn db 0 ;shadow of hihat attenuation
- TomAttn db 0 ;shadow of tom attenuation
- RideAttn db 0 ;shadow of ride attenuation
-
- notesync db 0 ;for sync start of channel
- notecntr db 0 ;for sync start of channel
- presync db 0ffh ;for sync start of channel
- syncbyte db 0 ;for sync start of channel
- synchi db 0 ;for sync start of channel
-
- DurTablePtr dw ?
- PitchTablePtr dw ?
- SoundTablePtr dw ?
-
- ;old interrupt vectors
- OldIntOFF dw 0 ;from sound sys
- OldIntSEG dw 0
- OldIntOFF2 dw 0 ;from speech int
- OldIntSEG2 dw 0
-
- ;interrupt vars
- SoundSysTick db 12 ;interrupt divider
- TimerTick db 48 ;another interrupt divider
- TickOffset dw 0 ;pointer to external time base
- TickSeg dw 0 ;other half of pointer
-
- ;variables for speech interrupt
- evenodd db 0
- lastsample db 0
- dlength dw 0
- doffset dw 0
- dsegment dw 0
- dbaseaddr dw 0
- SampleFlag db 0
-
- buffhead dw ? ;for sound code queue
- bufftail dw ? ;for sound code queue
- buff db 16 dup(?) ;sound code queue
-
- spram1 db SPRAMLEN dup(?) ;sound processor ram
- spram2 db SPRAMLEN dup(?)
- spram3 db SPRAMLEN dup(?)
- spram4 db SPRAMLEN dup(?)
- spram5 db SPRAMLEN dup(?)
- spram6 db SPRAMLEN dup(?)
- spram7 db SPRAMLEN dup(?)
- spram8 db SPRAMLEN dup(?)
- spram9 db SPRAMLEN dup(?)
- spram10 db SPRAMLEN dup(?)
-
- schnlPtr dw spram1 ;sound channel pointers
- dw spram2
- dw spram3
- dw spram4
- dw spram5
- dw spram6
- dw spram7
- dw spram8
- dw spram9
- dw spram10
-
- OPOFFSETS db 000h
- OP2 db 001h
- OP3 db 002h
- OP4 db 008h
- OP5 db 009h
- OP6 db 00ah
- OP7 db 010h
- OP8 db 011h
- OP9 db 012h
-
- FreqTable dw 0269h/2 ;c
- dw 028eh/2 ;c#
- dw 02b5h/2 ;d
- dw 02deh/2 ;d#
- dw 0309h/2 ;e
- dw 0338h/2 ;f
- dw 0369h/2 ;f#
- dw 039ch/2 ;g
- dw 03d3h/2 ;g#
- dw 040eh/2 ;a
- dw 044bh/2 ;a#
- dw 048dh/2 ;b
-
- ;----------------------------------------------------------------------------
- ;sound system interrupt service routine
- ;no ins, no outs restores everything used on exit
-
- _newint proc
- public _newint
-
- push ax ;these few pushes to allow more reg variables
- push bx
- push dx
- push ds
-
- mov ax,cs ;segment overrides cost two clocks per
- mov ds,ax ;assume ds:code recquires this
-
- cmp motorflag,0 ;motor active ?
- je no_motor
-
- dec motordcnt ;decrement the count
- jnz no_motor ;not zero do nothing
-
- mov bx,offset spram1 ;get offset of spram
- mov al,[bx+Block] ;get block of channel 0 in al
- mov ah,al ;save al
- and al,01fh ;and of gate state
- xor state,0ffh ;toggle state
- mov ah,state
- and ah,020h ;isolate gate state
- or al,ah
- mov [bx+Block],al ;save it back
- mov bl,al
-
- mov dx,ADLIBREGS ;card address for regs
- mov al,0b0h ;key on/off channel 0
- out dx,al
- call Wait33
- mov al,bl
- inc dx
- out dx,al
- call Wait34
-
- mov al,motordur ;reset count
- mov motordcnt,al
-
- no_motor:
- dec SoundSysTick ;dec tick counter
- jnz ni2 ;if zero run sound system
- mov SoundSysTick,12 ;restore counter
- call _Sound_ISR ;service sound every 4th tick
-
- if NOCOUNT
- push ds ;game time base counter
- lds bx,dword ptr tickoffset
- add word ptr [bx],1
- adc word ptr [bx+2],0
- pop ds
- endif
-
- ni2:
- dec TimerTick ;dec tick counter
- jnz ni4 ;if zero service timer interrupt
- mov TimerTick,48 ;restore counter (every 48th tick)
- pop ds ;restore regs b4
- pop dx
- pop bx ;jumping to timer interrupt
- pop ax
- jmp dword ptr cs:[oldintOFF] ;jump to old interrupt
-
- ni4:
- mov al,20h ;reset interrupt controller
- out 20h,al
-
- pop ds
- pop dx
- pop bx
- pop ax
- iret
-
- _newint endp
- ;----------------------------------------------------------------------------
- ;specch driver interrupt service routine
- ;speech variables must be setup before this can be used
- ;speak routine does all of the setup
-
- _newint2 proc
- public _newint2
-
-
-
- push ax ;(15)
- push dx ;(15)
- push ds ;(10)
- push si ;(10)
-
- cmp cs:SampleFlag,0
- je stop_sample
-
- lds si,dword ptr cs:doffset ;(16+8) pointer to data
- cld ;(2) set direction flag
- lodsb
-
- mov ah,cs:lastsample
- test cs:evenodd,1 ; even/odd count ??
- je do_dpcm
-
- shr al, 1 ; left sampl:
- shr al, 1
- shr al, 1
- shr al, 1
- inc si ; increment sampl ptr
-
- do_dpcm:
- dec si
- and al, 0FH
- test al, 8 ; test dpcm sign bit
- jne dpcm_negative
-
- add ah, al ; dpcm positive:
- jmp short do_out
-
- dpcm_negative:
- and al, 7
- sub ah, al
-
- do_out:
- mov al, ah
- mov cs:lastsample,ah
- mov dx,ADLIBDATA
- out dx,al
- dec cs:evenodd ; sampl count --
-
- mov cs:doffset,si ;(9+8) save pointer
- mov ax,si ;(8)
- sub ax,cs:dbaseaddr ;(9)
- cmp ax,cs:dlength ;(9)
- jb eoi ;(16)
-
- stop_sample:
- ;**** deinstall interrupt
- mov al,36h ;reset timer for 871 Hz operation
- out TIMERCONTROL,al
- mov al,055h ;low byte of divisor for 871Hz
- out TIMERDATA0,al
- mov al,05h ;high byte of divisor
- out TIMERDATA0,al
-
-
- mov cs:doffset,0
-
- mov si,8*4
- xor ax,ax
- mov ds,ax
-
- mov dx,cs:oldintOFF2 ;point interrupt vector
- mov ax,cs:oldintSEG2 ;back where it belongs
-
- mov [si],dx
- mov [si+2],ax
-
- mov cs:do_sound,0
-
- eoi:
- mov al,20h ;(4) reset interrupt controller
- out 20h,al ;(10)
-
- pop si ;(10)
- pop ds ;(10)
- pop dx ;(15)
- pop ax ;(15)
- iret ;(24)
-
- _newint2 endp
- ;----------------------------------------------------------------------------
- ;initialize sound sytem, install sound interrupt etc.
- ;nothing in, nothing out
- ;since this is assumed to be called from c registers are NOT preserved
- ;except ds,es,si and di
-
- _Init_Sound_ISR proc far
- public _Init_Sound_ISR
-
- push ds
- push es
- push si
- push di
-
- if NOCOUNT
- mov cs:tickoffset,ax ;save location for jim's timer ticks
- mov ax,ds
- mov cs:tickseg,ax
- endif
-
- mov ax,cs ;set ds
- mov ds,ax
-
- xor bx,bx
- mov bx,[bx+offset MasterTable] ;get address of zero'th sound table
- mov SoundTablePtr,bx ;put it in the pointer
-
- IF DEBUG
- mov MaxWrites,0
- mov _NoWrites,0
- ENDIF
-
- ; in al,P8255 ;get original config
- ; mov Old8255,al ;save original config
-
- ; and al,NOT (HWGATE2BIT+HWSPKRBIT)
-
- ; out P8255,al
- ; mov Mask8255,al ;save it
-
- cli ;clear interrupts
- mov ax,3508h ;dos function number
- int 21h ;dos get int vector
- mov oldintSEG,es ;save segment
- mov oldintOFF,bx ;save offset
-
- mov dx,offset _newint ;offset of new int handler in dx
- mov ax,2508h ;dos function number
- int 21h ;dos set interrupt vector
-
- call _initsnd ;initialize sound variables
-
- mov al,36h ;set timer mode
- out TIMERCONTROL,al ;send it
- jmp short it1 ;8253 is a bit slow
- it1:
- mov al,055h ;low byte of divisor for 871Hz
- out TIMERDATA0,al
- jmp short it1a
- it1a:
- mov al,005h ;high byte of divisor
- out TIMERDATA0,al
-
- in al,061h
- and al,0feh
- out 061h,al
-
- mov bufftail,0 ;initialize sound code queue pointers
- mov buffhead,0
-
- sti
- pop di
- pop si
- pop es
- pop ds
-
- ret
- _Init_Sound_ISR endp
- ;----------------------------------------------------------------------------
- ;un-install sound sytem, un-install sound interrupt, shut off sound chip
- ;nothing in, if debug is non-zero function returns number of writes
- ;to sound chip in ax
- ;since this is assumed to be called from c registers are NOT preserved
- ;except ds,es,si and di
-
- _Terminate_Sound_ISR proc far
- public _Terminate_Sound_ISR
-
- push ds
-
- mov ax,cs ;set ds
- mov ds,ax ;to cs
-
- push ds
- cli ;shut off interrupts
- mov dx,oldintOFF ;point interrupt vector
- mov ax,oldintSEG ;back where it belongs
- mov ds,ax ;dos set interrupt vector
- mov ax,2508h
- int 21h
- sti
- pop ds
-
- call _initsnd ;clear sound stuff
-
- mov al,36h ;reset timer for 18.2 Hz operation
- out TIMERCONTROL,al
- jmp short rt1
- rt1:
- mov al,0
- out TIMERDATA0,al
- jmp short rt1a
- rt1a:
- out TIMERDATA0,al
- IF DEBUG
- mov ax,MaxWrites
- ENDIF
-
- pop ds
- ret
- _Terminate_Sound_ISR endp
- ;----------------------------------------------------------------------------
- ;sound int called by newint calls runsnd
- ;this is really here so you can single step thrrough
- ;the sound system with a debugger it could be removed
-
- _Sound_ISR proc near
- public _Sound_ISR
-
- push cx
- push dx
- push di
- push si
-
- push ds
- mov ax,cs ;segment overides cost two clocks per
- mov ds,ax ;assume ds:code recquires this
- IF DEBUG
- mov _NoWrites,0
- ENDIF
-
- call startsound ;start any sounds in queue
- call runsnd ;run sound system
- call syncgen ;run sync generator
- pop ds
-
- pop si
- pop di
- pop dx
- pop cx
- ret
-
- _Sound_ISR endp
- ;----------------------------------------------------------------------------
- ;send sound code to sound system
- ;stack has the sound code
-
- _sendsnd proc far
- public _sendsnd
-
- push bp
- mov bp,sp
- push ds
-
- mov bx,cs ;set ds to cs this is
- mov ds,bx
-
- mov bx,buffhead ;current place in buffer
- mov ax,word ptr [bp+6] ;get sound code
- mov [bx+offset buff],ax ;store in buff
- inc bx ;next place
- and bx,000fh ;a circular queue
- mov buffhead,bx ;save it back
-
- pop ds
- mov sp,bp
- pop bp
- ret
- _sendsnd endp
- ;----------------------------------------------------------------------------
- ;called as a part of runsnd
- ;actually starts the queued sound codes
-
- startsound proc near
- public startsound
-
- ;di points to sound ram
- ;si points to sound string
- push ds
- push si
- push di
-
- mov bx,cs ;set ds to cs this is
- mov ds,bx ;a "com" file
-
- nextcode:
- mov bx,bufftail
- cmp bx,buffhead ;head=tail means no codes
- jnz start_sound_not_done
- jmp short start_sound_done
-
- start_sound_not_done:
- mov bx,[bx+offset buff]
- sub bh,bh
- shl bx,1 ;offset into table x2
- add bx,SoundTablePtr
- mov si,[bx]
-
- mov bx,cs:[si] ;channel number from string
- cmp bl,0
- jne not_channel_zero
- mov motorflag,0
-
- not_channel_zero:
- mov al,bh ;al<-priority
- mov cl,bl ;cl has channel
- sub bh,bh ;bh<-0
- shl bx,1
- mov di,[bx+offset SchnlPtr]
-
- cmp al,[di+Priority] ;priority not higher or = ?
- jl nextcode2
-
- call ClearSpram
- mov [di+Priority],al ;this is the new priority
- inc si ;skip over channel and
- inc si ;priority bytes
- mov [di+StrPointer],si ;ptr to first data in string
- mov byte ptr [di+Tempo],0ffh ;reset tempo
- mov byte ptr [di+TempoCount],0ffh ;reset tempo
- mov byte ptr [di+Duration],01h ;assure use of first op-code
- mov do_sound,01
-
- cmp bl,18
- je nextcode2 ;not in the conductor channel
- call clearenv
-
- nextcode2:
- inc bufftail
- and bufftail,000fh
- jmp nextcode
-
- start_sound_done:
- pop di
- pop si
- pop ds
- ret
- startsound endp
- ;----------------------------------------------------------------------------
- ;sets the motor freq motor freq is on the stack
-
- _setmotor proc far
- public _setmotor
-
- push bp
- mov bp,sp
- push ds
- push si
- push di
-
- mov ax,word ptr [bp+6]
-
- mov bx,cs ;set ds to cs this is
- mov ds,bx ;a "com" file
-
- mov NoiseIndex,ax
- and ax,07fffh ;and off high bit
- mov bx,ax ;bx has index into noise table
- mov si,DurTablePtr
- mov al,[bx+si]
- mov motordur,al
- mov si,PitchTablePtr
- mov al,[bx+si]
- mov ah,0a0h
- call outadlib
-
- pop di
- pop si
- pop ds
- mov sp,bp
- pop bp
- ret
- _setmotor endp
- ;----------------------------------------------------------------------------
- ;stop playing a sample
-
- _abortsample proc far
- public _abortsample
-
- push bp
- mov bp,sp
- push ds
- push si
- push di
-
- mov ax,word ptr [bp+6]
-
- mov bx,cs ;set ds to cs this is
- mov ds,bx ;a "com" file
-
- mov SampleFlag,al
-
- pop di
- pop si
- pop ds
- mov sp,bp
- pop bp
- ret
- _abortsample endp
- ;----------------------------------------------------------------------------
- ;switch to a different sound table
- ;the sound table number is on the stack
-
- _switchsoundtable proc far
- public _switchsoundtable
-
- push bp
- mov bp,sp
- push ds
-
-
- mov bx,cs ;set ds to cs this is
- mov ds,bx ;a "com" file
-
- mov bx,word ptr [bp+6]
- shl bx,1
- mov bx,[bx+offset MasterTable] ;get address of zero'th sound table
- mov SoundTablePtr,bx ;put it in the pointer
- mov ax,SoundTablePtr
-
- pop ds
- mov sp,bp
- pop bp
- ret
-
- _switchsoundtable endp
- ;----------------------------------------------------------------------------
- ;return the address of the sound table or patchtable
- ;return values are in ax
- ;values passed are on the stack
-
- _getaddr proc far ;pass back segment and offset of sound table
- public _getaddr
-
- push bp
- mov bp,sp
-
- cmp word ptr [bp+6],0 ;pass back segment
- jne getaddr1
- mov ax,cs
- jmp short getaddrout
-
- getaddr1:
- cmp word ptr [bp+6],1 ;pass offset of soundtable
- jne getaddr2
- mov ax,cs:SoundTablePtr
- jmp short getaddrout
-
- getaddr2:
- cmp word ptr [bp+6],2 ;pass offset of envelope table
- jne getaddr3
- mov ax,cs:SoundTablePtr
-
- getaddr3:
- cmp word ptr [bp+6],3 ;pass address of patchtable
- jne getaddr4
- mov ax,offset _Patchtable
-
- getaddr4:
- cmp word ptr [bp+6],4 ;pass address of motortable
- jne getaddrout
- mov ax,offset _MotorTable
-
- getaddrout:
-
- mov sp,bp
- pop bp
- ret
-
- _getaddr endp
- ;----------------------------------------------------------------------------
- ;initialize sound system variables
-
- _initsnd proc near
- public _initsnd
-
- mov do_sound,0 ;disable sound interrupts
- mov seed,01234h ;initialize for random numbers
-
- mov ax,0120h ;initialize chip test register to 0
- call outadlib
- mov ax,0800h ;initialize chip to music mode
- call outadlib
- mov ax,0bd00h ;initialize chip to no rhythm
- call outadlib
-
- mov motorflag,0 ;no motor
-
- mov cx,10 ;clear out 9 channels
- mov bh,0
- clear_spram:
- mov bl,cl
- dec bl
-
- cmp bl,9 ;skip conducotr channel
- je no_conductor
-
- mov ah,[offset OPOFFSETS+bx] ;get opcode offsets
- add ah,040h ;total level reg
- mov al,03fh ;max attenuation
- call outadlib ;shut it down
- mov ah,[offset OPOFFSETS+bx] ;get opcode offsets
- add ah,043h ;total level reg
- mov al,03fh ;max attenuation
- call outadlib ;shut it down
-
- no_conductor:
- shl bl,1
- mov di,[bx+offset schnlPtr] ;di now has pointer to spram
- call ClearSpram
- loop clear_spram
-
- ret
-
- _initsnd endp
- ;----------------------------------------------------------------------------
- ;main processing loop of sound system
- ;*** si points to next byte in sound string
- ;*** di points to appropriate sound ram block
-
- runsnd proc near
-
- cmp do_sound,0
- jne go_ahead
- ret
-
- go_ahead:
- mov curchannel,9
-
- channellup: ;RunSound loop
- mov bl,curchannel
- mov bh,0
- shl bl,1
- mov di,[bx+offset schnlPtr] ;di now has pointer to sound ram
- mov al,[di+Duration] ;check for duration = 0
- or al,al
- jnz short still_active
- jmp not_active
-
- still_active:
- mov bx,offset OPOFFSETS ;get offset into chip
- add bl,curchannel
- mov al,byte ptr [bx]
- mov YamOff,al ;YamOff<-operator offset
-
- cmp byte ptr [di+autotempo],0
- je no_auto_tempo
- mov al,globaltempo
- mov [di+Tempo],al
-
- no_auto_tempo:
- mov al,[di+TempoCount]
- add al,[di+Tempo]
- mov [di+TempoCount],al
- jc short oktempo
- jmp do_process
-
- oktempo:
- dec byte ptr [di+duration] ;channel active dec duration
- jz parse ;no time left
- mov al,[di+duration]
- cmp al,[di+PercentDuration]
- jne check_gate
- call noteoff
-
- check_gate:
- cmp al,[di+GateThreshold]
- jne nottime
- cmp curchannel,9
- je nottime
- call NoteOff
- nottime:
- jmp short do_process ;still time left
-
- parse:
- mov si,[di+StrPointer] ;si<-current operand
- parse_op:
- lodsw
- or al,al
- jns note
- jmp short op_code
-
- note:
- call SetFreq ;set frequency
- call NoteOn ;trigger note
- call installDuration ;set up duration
-
- ;*** check velocity stuff
- cmp word ptr [di+Op1Velocity],0 ;is velocity turned on
- je checkop2
- jne short velocityon
-
- checkop2:
- cmp word ptr [di+Op2Velocity],0 ;is velocity turned on
- je chkNotedur
-
- velocityon:
- GETNEXTOP
- mov [di+Velocity],al
- call CombineOp2
-
- mov dx,ADLIBREGS ;card address for regs
- mov ah,YamOff ;get current channel
- add ah,043h
- call outadlib
-
- call CombineOp1
- mov dx,ADLIBREGS ;card address for regs
- mov ah,YamOff ;get current channel
- add ah,040h
- call outadlib
- chkNotedur:
- mov al,installedur
- or al,al
- je parse_op
- mov [di+StrPointer],si ;for next time
- jmp short do_process
-
- op_code:
- and al,07Fh ;get rid of 128 byte offset
- cmp al,MAXRTN ;good opcode?
- jle good_rtn ;go ahead
- jmp EOS ;End activity in channel if bad opcode
-
- good_rtn:
- mov bl,al
- sub bh,bh
- shl bl,1 ;times 2
- mov bx,[bx+offset opcode_tbl] ;now bx points to appropriate routine
- jmp bx ;dispatch operand to sound routine
-
- do_process:
- call [di+PVector1]
- call [di+PVector2]
-
- not_active:
- dec curchannel
- js runsndout
- jmp channellup
-
- runsndout:
- ret
-
- runsnd endp
- ;----------------------------------------------------------------------------
-
- ;**** opcodes ****
- SetLoop:
- ;80,number of loops
- mov [di+lupcounter],ah ;save loop counter in ram contrl block
- jmp parse_op ;go back and parse some more
-
- TestLoop:
- ;81,label
- dec byte ptr [di+lupcounter] ;save loop counter in ram control block
- jnz branch ;not zero branch to label
- inc si ;point past label address
- jmp parse_op
-
- StartVoice:
- ;82,sndtableindex
- push si
- push di
- push bx
-
- mov bl,ah
- cmp bl,MAXSOUND2 ;max valid sound code
- jb snd_code_ok2
- jmp short sendsndExit2 ;restore registers b4 leaving
- snd_code_ok2:
- sub bh,bh
- shl bx,1 ;offset into table x2
- add bx,SoundTablePtr
- mov si,[bx] ;si has sound string offset
-
- mov bx,cs:[si] ;channel number from string
- mov al,bh ;al<-priority
- mov cl,bl ;bl = channel number
- sub bh,bh ;bh<-0
- shl bx,1
- mov di,[bx+offset schnlPtr] ;of appropriate channel
-
- cmp al,[di+priority] ;priority not higher or = ?
- jl sendsndExit2 ;return
-
- call ClearSpram
- mov [di+Priority],al ;this is the new priority
- inc si ;skip over channel and
- inc si ;priority bytes
- mov [di+StrPointer],si ;ptr to first data in string
- mov byte ptr [di+Tempo],0ffh ;reset tempo
- mov byte ptr [di+TempoCount],0ffh ;reset tempo
- mov byte ptr [di+Duration],01h ;assure use of first op-code
- mov do_sound,01
-
- call clearenv
-
- sendsndexit2:
- pop bx
- pop di
- pop si
- jmp parse_op
-
- SetGateThreshold:
- ;83,value
- mov [di+GateThreshold],ah ;assure use of first op-code
- jmp parse_op
-
- Branch:
- ;84,label
- mov cl,ah
- GETNEXTOP
- xchg ah,al
- mov al,cl
- mov si,ax
- jmp parse_op
-
- CallString:
- ;85,label
- dec si
- mov bl,[di+StackPointer] ;grab stack pointer
- mov bh,0
- shl bl,1 ;double for word access
- mov ax,si ;get current address
- inc ax ;jump over subroutine
- inc ax ;address
- mov [di+Stack0+bx],ax ;save as return address
- inc byte ptr [di+StackPointer] ;bump up stack pointer
- lodsw
- mov si,ax ;start at this address
- jmp parse_op
-
- StringReturn:
- ;86
- dec si
- dec byte ptr [di+StackPointer] ;point to retrun address
- mov bl,[di+StackPointer] ;grab stack pointer
- mov bh,0
- shl bl,1 ;double for word access
- mov ax,[di+Stack0+bx] ;get return address
- mov si,ax ;current address
- jmp parse_op
-
- OctaveOffset:
- ;87,octave offset
- mov [di+OctaveOfst],ah ;save octave offset in sound ram
- jmp parse_op
-
- EOS: ;end of string
- ;88
- mov byte ptr [di+priority],0
- mov word ptr [di+StrPointer],0
- cmp curchannel,9
- je not_conductor ;no hardware atatched to channel 9
- call NoteOff
-
- not_conductor:
- jmp not_active
-
- Rest:
- ;89,rest length
- call installDuration
- mov [di+StrPointer],si ;for next time
- cmp curchannel,9
- je not_conductor2
- call NoteOff
-
- not_conductor2:
- mov al,installedur
- or al,al
- je parse_opj4
- jmp do_process ;not_active
- parse_opj4:
- jmp parse_op
-
- SetoplReg:
- ;8a,register,value
- GETNEXTOP ;ah has address al has value
- call outadlib
- jmp parse_op
-
- newNote:
- ;8b,note,length
- xchg ah,al
- call SetFreq ;set frequency
- GETNEXTOP
- xchg ah,al
- call installDuration
- mov [di+StrPointer],si ;for next time
- mov al,installedur
- or al,al
- je parse_opj3
- jmp do_process ;not_active
- parse_opj3:
- jmp parse_op
-
- NoteOffset:
- ;8c,offset
- mov [di+NoteOfst],ah
- jmp parse_op
-
- TableModOP:
- ;8d,pre8,len8,operator8,tblbase16
- mov [di+TpTmr],ah ;
- mov [di+TpPre],ah ;
- GETNEXTOP ;al<-length of table-1
- mov [di+tmlen],al ;
- mov [di+tmoff],al ;
- GETNEXTOP ;al<-chip Operator Offset
- mov [di+TpOp],al ;
- lodsw
- mov [di+tmbase],ax
- mov [di+PVector2],offset TblMod ;set vector address
- jmp parse_op
-
- StopParse:
- ;8e,channel
- mov al,curchannel
- push ax
- push di
-
- mov bl,ah ;get addressing to different
- mov bh,0 ;sound control block
- shl bl,1
- mov di,[bx+offset schnlPtr] ;di now has pointer to spram
-
- mov byte ptr [di+Duration],0 ;stop channel parsing
- mov byte ptr [di+priority],0
- mov word ptr [di+StrPointer],0
-
- pop di ;restore
- pop ax
- mov curchannel,al
- jmp parse_op
-
- StuffPatch:
- ;90,patchindex
- push si
- mov cl,YamOff
-
- sub bx,bx
- mov bl,ah
- shl bx,1 ;for patches > 127 ddt 3/18
- mov si,[bx+offset _Patchtable]
- call writepatch
- pop si
- jmp parse_op ;go back and parse some more
-
- PitchDelta:
- ;91,pre,hidelt,lodelt
- mov [di+Pdeltpre],ah ;save it (0 means pdelt off)
- GETNEXTOP ;get high byte of delta
- xchg ah,al ;put'em in there places
- GETNEXTOP ;get low byte of delta
- mov [di+Pdelt],ax ;save it
- mov [di+PVector1],offset DoPitchDelta ;set vector address
- mov [di+Pdeltcount],byte ptr 0ffh
- jmp parse_op
-
- ClearPitchDelta:
- ;92
- dec si
- mov [di+PVector1],offset NullVector ;set vector address
- mov word ptr [di+Pdelt],0 ;save it
- jmp parse_op
-
- FracPitch:
- ;93,byte
- mov [di+FracPitchLow],ah ;save it
- jmp parse_op
-
- Vibrato:
- ;95,prescaler,shift,count,delay
- mov [di+Vibpre],ah ;save it (0 means vib off)
- GETNEXTOP ;get shift count
- mov [di+Vibshift],al ;save it
- GETNEXTOP ;get excursion count value
- mov [di+VibNewCount],al ;save it
- inc byte ptr [di+VibNewCount] ;make up for first time decrement
- shl al,1 ;half vibcount
- mov [di+Vibcount],al ;save it
- GETNEXTOP ;get delay
- mov [di+Vibdelay],al ;save it
- mov [di+PVector1],offset DoVibrato
- jmp parse_op
-
- SetPriority:
- ;9a,priority
- mov [di+priority],ah
- jmp parse_op
-
- InitSync:
- ;9c,sync value
- shr ah,1
- mov notesync,ah
- mov notecntr,ah
- mov presync,0ffh
- mov ah,0
- mov syncbyte,ah
- mov synchi,ah
- jmp parse_op
-
- WaitSync:
- ;9d
- mov al,synchi
- or al,al
- jne lookingforhilo
-
- and ah,syncbyte
- jne notsyncedyet
- inc synchi
- jmp short notsyncedyet
-
- lookingforhilo:
- and ah,syncbyte
- je notsyncedyet
- mov synchi,0
- jmp parse_op
-
- notsyncedyet:
- dec si
- dec si
- mov byte ptr [di+Duration],1
- mov [di+StrPointer],si ;save string pointer
- jmp not_active ;parse next channel
-
- start_channel:
- jmp parse_op
-
- SetAccentAttn:
- ;9e,attenuation
- mov [di+accentattn],ah ;save it
- call CombineAttn ;combine and stuff now
- jmp parse_op
-
- Stay:
- ;a0,duration
- call installDuration
- mov [di+StrPointer],si ;for next time
- mov al,installedur
- or al,al
- je parse_opj2
- jmp do_process ;not_active
- parse_opj2:
- jmp parse_op
-
- ReTrigger:
- ;a1,duration
- call installDuration
- call NoteOn
- mov [di+StrPointer],si ;for next time
- mov al,installedur
- or al,al
- je parse_opj1
- jmp do_process
- parse_opj1:
- jmp parse_op
-
- NotePercent:
- ;a4,percent
- and ah,007h
- mov [di+NotePercentVal],ah ;save it
- jmp parse_op
-
- SetMusicTempo:
- ;a6,globalTempo
- mov globalTempo,ah
- jmp parse_op
-
- KillVector2:
- ;a7
- dec si
- mov [di+PVector2],offset NullVector ;set process vector
- jmp parse_op
-
- SetTempo:
- ;a9,tempo
- mov [di+Tempo],ah ;save tempo in global variable
- jmp parse_op
-
- SetChannelAttn:
- ;ab,attn
- mov [di+channelattn],ah ;save it
- jmp parse_op
-
- SetsysAttn:
- ;ac,channel,attn
- mov al,curchannel
- push ax
- push di
-
- GETNEXTOP ;get attenuation
- mov curchannel,ah ;reset cureent channel temporarily
- mov bl,ah ;get addressing to different
- mov bh,0 ;sound control block
- shl bl,1
- mov di,[bx+offset schnlPtr] ;di now has pointer to spram
- mov [di+sysAttn],al ;save it
- call CombineAttn ;combine and stuff now
-
- pop di ;restore
- pop ax
- mov curchannel,al
- jmp parse_op
-
- SetsysAttnDelta:
- ;ad,channel,delta
- mov al,curchannel
- push ax
- push di
-
- mov curchannel,ah ;reset curent channel temporarily
- sub bx,bx
- mov bl,ah ;get addressing to different
- GETNEXTOP ;al<-attenuation
- shl bl,1
- mov di,[bx+offset schnlPtr] ;di now has pointer to spram
- add al,byte ptr [di+sysAttn] ;add delta to current attenuation
- mov [di+sysAttn],al ;save it
- call CombineAttn ;combine and stuff now
-
- pop di ;restore
- pop ax
- mov curchannel,al
- jmp parse_op
-
- SetAmDepth:
- ;ae,depth
- and ah,01
- mov cl,7
- shl ah,cl
- mov bl,ShadowBD
- and bl,07fh
- or bl,ah
- mov ShadowBD,bl
- mov ah,0bdh
- mov al,bl
- call outadlib
- jmp parse_op
-
- SetVibDepth:
- ;af,depth
- and ah,01
- mov cl,6
- shl ah,cl
- mov bl,ShadowBD
- and bl,0bfh
- or bl,ah
- mov ShadowBD,bl
- mov ah,0bdh
- mov al,bl
- call outadlib
- jmp parse_op
-
- SetSignedAttn:
- ;b0,signedAccentDelta
- add ah,[di+AccentAttn]
- mov [di+AccentAttn],ah ;save it
- call CombineAttn ;combine and stuff now
- jmp parse_op
-
- KillChannel:
- ;b3,channel
- mov al,curchannel
- push ax
- push di
-
- cmp ah,0
- jne not_motor_channel
- mov motorflag,0
-
- not_motor_channel:
- mov curchannel,ah
- mov bl,ah ;get addressing to different
- mov bh,0 ;sound control block
- shl bl,1
- mov di,[bx+offset schnlPtr] ;di now has pointer to spram
-
- mov byte ptr [di+Duration],0 ;stop channel parsing
- mov byte ptr [di+priority],0
- mov word ptr [di+StrPointer],0
-
- mov byte ptr [di+sysAttn],0 ;clear system atten when channel is killed
- cmp curchannel,9 ;are we in conductor channel?
- je short KillDone
-
- mov bl,ah ;get offset into chip
- xor bh,bh
- mov cl,[bx+offset OPOFFSETS]
-
- mov ah,0c0h ;fb/alg register
- add ah,curchannel ;proper slot
- mov al,0 ;set for stack
- call outadlib
-
- mov ah,043h
- add ah,cl ;total level/carrier
- mov al,03fh ;max attenuation
- call outadlib
-
- mov ah,083h
- add ah,cl ;sustain release
- mov al,0ffh ;min release time
- call outadlib
-
- mov ah,0b0h ;kon block
- add ah,curchannel
- mov al,0 ;key off
- call outadlib
-
- KillDone:
- pop di ;restore
- pop ax
- mov curchannel,al
- jmp parse_op
-
- RandomPitch:
- ;b5,wordmask
- GETNEXTOP
- mov bx,ax
- call Random ;ax<-16 pseudo-random number
- and ax,bx ;ax<-anded offset
- mov cl,byte ptr[di+block] ;cl<-gate/block/hiFreq
- mov bh,cl ;bh<-gate/block/hiFreq
- and cl,020h ;cl<-isolated gate information
- mov bl,[di+FreqLow]
- and bh,01FH ;bh<-isolated block/HiFreq
- add bx,ax ;bx<-+=Randomed frequency
- or bh,cl ;bh<-|=gate infomation
-
- mov ah,0a0h ;al<-chip Frequency Low base
- add ah,curchannel
- mov al,bl
- call outadlib
-
- mov ah,0b0h ;al<-chip Frequency Low base
- add ah,curchannel
- mov al,bh
- call outadlib
- jmp parse_op
-
- KillVector1:
- ;b6
- dec si
- mov [di+PVector1],offset NullVector ;set process vector
- jmp parse_op
-
- SetPitchBend:
- ;b9
- mov [di+BendValue],ah
- mov al,[di+noteval]
- push ax
- mov ch,al ;note in ch
-
- and ch,0f0h ;and off note value
- mov bl,[di+OctaveOfst] ;get octave offset
- add ch,bl ;add em'
-
- and al,0fh ;get rid of octave info
- mov bl,[di+NoteOfst] ;get note offset
- add al,bl ;add note offset
-
- cmp al,0ch ;did it wrap to next octave?
- jge upanoctave2
- cmp al,0
- jge sameoctave2
- add al,0ch
- sub ch,10h ;add one octave
- jmp short sameoctave2
-
- upanoctave2:
- sub al,0ch
- add ch,10h ;add one octave
-
- sameoctave2:
- mov bl,al
- mov bh,0
- shl bl,1
- mov ax,[bx+offset FreqTable] ;get freq
- sub dx,dx
- mov dl,byte ptr [di+FracPitchLow]
- add ax,dx ;ax<-+=8 bits of Pitch Offset
- shr ch,1
- shr ch,1
- and ch,01ch
- or ch,ah ;combine high two bits of freq
- mov cl,al
-
- cmp byte ptr [di+BendValue],0 ;bend value in ah
- jl bend_down
-
- xor bh,bh
- mov bl,[di+noteval] ;bl gets note
- and bl,0fh
- inc bl
- inc bl
- shl bx,1 ;double for table index
- push si
- mov si,[bx+offset pbendtable] ;index into table
-
- xor bh,bh
- mov bl,[di+BendValue] ;bend value in ah
- mov al,[si+bx] ;get bend value
- pop si
- xor ah,ah ;clear ah
- add cx,ax ;combine bend and em
- jmp short stuff_bend
-
- bend_down:
- xor bh,bh
- mov bl,[di+noteval] ;bl gets note
- and bl,0fh
- shl bx,1 ;double for table index
- push si
- mov si,[bx+offset pbendtable] ;index into table
-
- xor bh,bh
- mov bl,[di+BendValue] ;bend value in ah
- xor bl,0ffh
- inc bl
- mov al,[si+bx] ;get bend value
- pop si
- xor ah,ah ;clear ah
- sub cx,ax ;combine bend and em
- jmp short stuff_bend
-
- stuff_bend:
- mov ah,0a0h
- mov al,[di+Block]
- and al,020h ;isolate trigger state
- or ch,al ;combine trigger and freq info
- mov [di+Block],ch ;ch has block / freq high
- mov [di+FreqLow],cl ;cl has freqlow
-
- mov ah,0a0h ;base of frequency low reg
- add ah,curchannel ;add channel offset
- mov al,cl
- call outadlib
-
- mov ah,0b0h ;base of frequency high/block reg
- add ah,curchannel ;add channel offset
- mov al,ch ;freq high block data
- call outadlib
- pop ax
- jmp parse_op
-
- getmusicTempo:
- ;ba
- dec si
- mov al,globalTempo
- mov byte ptr [di+Tempo],al
- jmp parse_op
-
- SNOP:
- ;bb
- dec si
- jmp parse_op
-
- RandomDuration:
- ;bc,andmask
- mov [di+RndDurMask],ah
- jmp parse_op
-
- tempodelta:
- ;bd,signedtempo
- ;if signedtempo is + and result overflows tempo<-0xff
- ;if signedtempo is - and result underflows tempo<-1
-
- or ah,ah
- js tgoindown
- add ah,[di+tempo] ;tempo+=tempodelta
- jnc tempodeltaok ;if no overflow stuff
- mov ah,0ffh ;else limit to 0xff
- jmp short tempodeltaok
- tgoindown:
- add ah,[di+tempo]
- cmp ah,[di+tempo]
- jb tempodeltaok
- mov ah,1
- tempodeltaok:
- mov [di+tempo],ah
- jmp parse_op
-
- MotorOn:
- ;bf,flag,table number
- mov motorflag,ah
- GETNEXTOP
- push si
- sub bh,bh
- mov bl,al ;al has table index
- shl bx,1
- mov bx,[bx+offset _motortable] ;bx hasoffset of duration table
- mov DurTablePtr,bx
-
- inc al
- sub bh,bh
- mov bl,al
- shl bx,1
- mov bx,[bx+offset _motortable] ;bx has offset to pitch table
- mov PitchTablePtr,bx
-
- cmp ah,2
- jne check1
-
- mov bx,0 ;reset motor freq
- mov NoiseIndex,bx ;saved index to zero
- mov si,DurTablePtr
- mov al,[bx+si]
- mov motordur,al ;set duration
-
- mov si,PitchTablePtr
- mov al,[bx+si]
- mov ah,0a0h
- call outadlib ;set frequency
- pop si
- jmp parse_op
-
- check1:
- pop si
- jmp parse_op
-
- MotorOff:
- ;c0
- dec si
- mov motorflag,0
- jmp parse_op
-
- DrumSetup:
- ;c1,patch1,patch2,patch3,freq1 h,freq1 l,freq2 h,freq2 l,freq3 h,freq3 l
- mov al,curchannel ;save current channel
- push ax
- mov al,YamOff ;save current ofset intoe chip
- push ax
- push si
-
- mov curchannel,6
- mov bx,offset OPOFFSETS ;get offset into chip
- add bl,6
- mov al,byte ptr [bx]
- mov YamOff,al ;YamOff<-operator offset
- mov dx,ADLIBREGS
- mov cl,YamOff
- sub bx,bx
- mov bl,ah
- shl bx,1
- mov si,[bx+offset _Patchtable]
- mov al,[si+6]
- mov KickShadow,al
- call writepatch ;first patch kick drum
-
- pop si
- GETNEXTOP ;second patch index
- push si
- mov curchannel,7
- mov bx,offset OPOFFSETS ;get offset into chip
- add bl,7
- mov ah,byte ptr [bx]
- mov YamOff,ah ;YamOff<-operator offset
- mov dx,ADLIBREGS
- mov cl,YamOff
- sub bx,bx
- mov bl,al
- shl bx,1
- mov si,[bx+offset _Patchtable]
- mov al,[si+5]
- mov HihatShadow,al
- mov al,[si+6]
- mov SnareShadow,al
- call writepatch ;second patch snare and hihat
-
- pop si
- GETNEXTOP ;third patch index
- push si
- mov curchannel,8
- mov bx,offset OPOFFSETS ;get offset into chip
- add bl,8
- mov ah,byte ptr [bx]
- mov YamOff,ah ;YamOff<-operator offset
- mov dx,ADLIBREGS
- mov cl,YamOff
- sub bx,bx
- mov bl,al
- shl bx,1
- mov si,[bx+offset _Patchtable]
- mov al,[si+5]
- mov TomShadow,al
- mov al,[si+6]
- mov RideShadow,al
- call writepatch ;third patch tom and ride
-
- pop si
-
- GETNEXTOP ;get freq 1 high
- and al,02fh ;and off kon
- mov spram7+BLOCK,al
- mov ah,0b6h
- call outadlib
-
- GETNEXTOP ;get freq 1 low
- mov ah,0a6h
- call outadlib
-
- GETNEXTOP ;get freq 2 high
- and al,02fh ;and off kon
- mov spram8+BLOCK,al
- mov ah,0b7h
- call outadlib
-
- GETNEXTOP ;get freq 2 low
- mov ah,0a7h
- call outadlib
-
- GETNEXTOP ;get freq 3 high
- and al,02fh ;and off kon
- mov spram9+BLOCK,al
- mov ah,0b8h
- call outadlib
-
- GETNEXTOP ;get freq 3 low
- mov ah,0a8h
- call outadlib
-
- mov drummask,020h
-
- pop ax ;restore chip offset
- mov YamOff,al
- pop ax ;restore current channel
- mov curchannel,al
- jmp parse_op
-
- DoDrum:
- ;c2,mask,duration trigger drum
- ;0x01-hihat 0x02-ride 0x04-tom 0x08-snare 0x10-bass drum
-
- mov dx,ADLIBREGS
- mov al,0bdh
- out dx,al
- call Wait33
- inc dx
- xchg ah,al
- push ax
- and al,01fh
- xor al,0ffh ;invert mask
- and al,drummask
- or al,020h ;drum mode bit
- out dx,al ;send to card
- call Wait34
-
- pop ax
- or al,DrumMask
- mov DrumMask,al
- or al,ShadowBD ;now turn'em on
- or al,020h ;drum mode bit
-
- out dx,al ;send to card
- call Wait34
- jmp parse_op
-
- DrumOff:
- ;c3 no args turn off drum mode
- dec si
- mov al,ShadowBD
- mov DrumMask,0
- and al,0c0h
- mov ah,0bdh
- call outadlib
- jmp parse_op
-
- DrumAttn:
- ;c4,mask,attn
- GETNEXTOP
- mov bx,ax ;save operands (ax needed for outadlib)
-
- test ah,001h ;check hihat
- jz check_ride
- mov HihatAttn,al
- xor ah,ah
- add al,HihatShadow
- add al,HihatMaster
- add al,HihatAttn
- call CheckWrap
- mov ah,051h
- call outadlib
-
- check_ride:
- mov ax,bx
- test ah,002h ;check ride
- jz check_tom
- mov RideAttn,al
- xor ah,ah
- add al,RideShadow
- add al,RideMaster
- add al,RideAttn
- call CheckWrap
- mov ah,055h
- call outadlib
-
- check_tom:
- mov ax,bx
- test ah,004h ;check tom
- jz check_snare
- mov TomAttn,al
- xor ah,ah
- add al,TomShadow
- add al,TomMaster
- add al,TomAttn
- call CheckWrap
- mov ah,052h
- call outadlib
-
- check_snare:
- mov ax,bx
- test ah,008h ;check snare
- jz check_kick
- mov SnareAttn,al
- xor ah,ah
- add al,SnareShadow
- add al,SnareMaster
- add al,SnareAttn
- call CheckWrap
- mov ah,054h
- call outadlib
-
- check_kick:
- mov ax,bx
- test ah,010h ;check kick
- jz drum_attn_done
- mov KickAttn,al
- xor ah,ah
- add al,KickShadow
- add al,KickMaster
- add al,KickAttn
- call CheckWrap
- mov ah,053h
- call outadlib
-
- drum_attn_done:
- jmp parse_op
-
- DrumFade:
- ;c5,mask,attn amount
- GETNEXTOP
- mov bx,ax ;save operands (ax needed for outadlib)
-
- test ah,001h ;check hihat
- jz check_ride2
- xor ah,ah
- add al,HihatShadow
- add al,HihatMaster
- add al,HihatAttn
- call checkwrap
- mov HihatMaster,al
- mov ah,051h
- call outadlib
-
- check_ride2:
- mov ax,bx
- test ah,002h ;check ride
- jz check_tom2
- xor ah,ah
- add al,RideShadow
- add al,RideMaster
- add al,RideAttn
- call checkwrap
- mov RideMaster,al
- mov ah,055h
- call outadlib
-
- check_tom2:
- mov ax,bx
- test ah,004h ;check tom
- jz check_snare2
- xor ah,ah
- add al,TomShadow
- add al,TomMaster
- add al,TomAttn
- call checkwrap
- mov TomMaster,al
- mov ah,052h
- call outadlib
-
- check_snare2:
- mov ax,bx
- test ah,008h ;check snare
- jz check_kick2
- xor ah,ah
- add al,SnareShadow
- add al,SnareMaster
- add al,SnareAttn
- call checkwrap
- mov SnareMaster,al
- mov ah,054h
- call outadlib
-
- check_kick2:
- mov ax,bx
- test ah,010h ;check kick
- jz drum_attn_done2
- xor ah,ah
- add al,KickShadow
- add al,KickMaster
- add al,KickAttn
- call checkwrap
- mov KickMaster,al
- mov ah,053h
- call outadlib
-
- drum_attn_done2:
- jmp parse_op
-
- DrumMasterAttn:
- ;c6,mask,attn amount
- GETNEXTOP
- mov bx,ax ;save operands (ax needed for outadlib)
-
- test ah,001h ;check hihat
- jz check_ride3
- mov HihatMaster,al
- xor ah,ah
- add al,HihatShadow
- add al,HihatAttn
- call checkwrap
- mov ah,051h
- call outadlib
-
- check_ride3:
- mov ax,bx
- test ah,002h ;check ride
- jz check_tom3
- mov RideMaster,al
- xor ah,ah
- add al,RideShadow
- add al,RideAttn
- call checkwrap
- mov ah,055h
- call outadlib
-
- check_tom3:
- mov ax,bx
- test ah,004h ;check tom
- jz check_snare3
- mov TomMaster,al
- xor ah,ah
- add al,TomShadow
- add al,TomAttn
- call checkwrap
- mov ah,052h
- call outadlib
-
- check_snare3:
- mov ax,bx
- test ah,008h ;check snare
- jz check_kick3
- mov SnareMaster,al
- xor ah,ah
- add al,SnareShadow
- add al,SnareAttn
- call checkwrap
- mov ah,054h
- call outadlib
-
- check_kick3:
- mov ax,bx
- test ah,010h ;check kick
- jz drum_attn_done3
- mov KickMaster,al
- xor ah,ah
- add al,KickShadow
- add al,KickAttn
- call checkwrap
- mov ah,053h
- call outadlib
-
- drum_attn_done3:
- jmp parse_op
-
- SetAutoTempo:
- ;c8,flag zero off no-zero on
- mov [di+autotempo],ah ;store flag value
- jmp parse_op
-
- SetVelocity:
- ;c9,op 1 shift count, op 2 shift count
- mov [di+Op1Velocity],ah ;save it
- GETNEXTOP ;get op2 vel shift
- mov [di+Op2Velocity],al ;save it
- jmp parse_op
-
- ;----------------------------------------------------------------------------
- ;set frequency of sound chip to a note
- ;note value is in al
-
- SetFreq proc ;al has note update hardware/shadow
- public SetFreq
-
- push ax
- mov [di+noteval],al
- mov ch,al ;note in ch
-
- and ch,0f0h ;and off note value
- mov bl,[di+OctaveOfst] ;get octave offset
- add ch,bl ;add em'
-
- and al,0fh ;get rid of octave info
- mov bl,[di+NoteOfst] ;get note offset
- add al,bl ;add note offset
-
- cmp al,0ch ;did it wrap to next octave?
- jge upanoctave
- cmp al,0
- jge sameoctave
- add al,0ch
- sub ch,10h ;add one octave
- jmp short sameoctave
-
- upanoctave:
- sub al,0ch
- add ch,10h ;add one octave
-
- sameoctave:
- mov bl,al
- mov bh,0
- shl bl,1
- mov ax,[bx+offset FreqTable] ;get freq
- sub dx,dx
- mov dl,byte ptr [di+FracPitchLow]
- add ax,dx ;ax<-+=8 bits of Pitch Offset
- shr ch,1
- shr ch,1
- and ch,01ch
- or ch,ah ;combine high two bits of freq
- mov cl,al
-
-
- cmp byte ptr [di+BendValue],0 ;bend value in ah
- je no_pitchbend
- jl bend_down2
-
- xor bh,bh
- mov bl,[di+noteval] ;bl gets note
- and bl,0fh
- inc bl
- inc bl
- shl bx,1 ;double for table index
- push si
- mov si,[bx+offset pbendtable] ;index into table
-
- xor bh,bh
- mov bl,[di+BendValue] ;bend value in ah
- mov al,[si+bx] ;get bend value
- pop si
- xor ah,ah ;clear ah
- add cx,ax ;combine bend and em
- jmp short no_pitchbend
-
- bend_down2:
- xor bh,bh
- mov bl,[di+noteval] ;bl gets note
- and bl,0fh
- shl bx,1 ;double for table index
- push si
- mov si,[bx+offset pbendtable] ;index into table
-
- xor bh,bh
- mov bl,[di+BendValue] ;bend value in ah
- xor bl,0ffh
- inc bl
- mov al,[si+bx] ;get bend value
- pop si
- xor ah,ah ;clear ah
- sub cx,ax ;combine bend and em
-
- no_pitchbend:
- mov ah,0a0h
- mov al,[di+Block]
- and al,020h ;isolate trigger state
- or ch,al ;combine trigger and freq info
- mov [di+Block],ch ;ch has block / freq high
- mov [di+FreqLow],cl ;cl has freqlow
-
- mov ah,0a0h ;base of frequency low reg
- add ah,curchannel ;add channel offset
- mov al,cl
- call outadlib
-
- mov ah,0b0h ;base of frequency high/block reg
- add ah,curchannel ;add channel offset
- mov al,ch ;freq high block data
- call outadlib
- pop ax
- ret
-
- SetFreq endp
- ;----------------------------------------------------------------------------
- ;trigger note on
-
- NoteOn proc ;trigger chip note on
- public NoteOn
- push ax
- mov ah,0b0h ;sustain / release
- add ah,curchannel ;curchannel is offset into regs
-
- mov al,[di+Block]
- or al,020h ;set bit to one
- mov [di+Block],al ;update block shadow
- call outadlib
-
- mov cl,[di+VibShift] ;vibrato stuff
- mov al,9
- sub al,cl
- mov cl,al
- mov ax,[di+FreqLow]
- and ax,03ffh
- shr ax,cl
- mov ah,0
- mov [di+VibStep],ax
-
- mov cl,[di+VibDelay] ;vibrato stuff
- mov [di+VibDelayCount],cl ;vibrato stuff
- pop ax
- ret
-
- NoteOn endp
- ;----------------------------------------------------------------------------
- ;turn note off (start release segment)
-
- NoteOff proc ;trigger chip note off
- public NoteOff
-
- cmp drummask,0 ;5/30/90
- je no_drumsNO ;5/30/90
- cmp curchannel,6 ;5/30/90
- jl no_drumsNO ;5/30/90
- ret
- no_drumsNO:
- cmp curchannel,9
- je noteoffexit
- mov ah,0b0h ;sustain / release
- add ah,curchannel
- mov al,[di+Block]
- and al,0dfh ;set bit to zero
- mov [di+Block],al ;update block shadow
- call outadlib
-
- noteoffexit:
- ret
-
- NoteOff endp
- ;----------------------------------------------------------------------------
- ;note duration processing
- ;ah has duration
-
- InstallDuration proc
- mov installedur,ah
- cmp byte ptr [di+RndDurMask],0
- mov bl,ah
- je short noRandomDur
- call Random
- and al,[di+RndDurMask]
- add bl,al
- mov [di+Duration],bl ;save duration in ram control block
- ret
-
- noRandomDur:
- cmp byte ptr [di+NotePercentVal],0
- je no_note_percent
- mov bl,ah
- shr ah,1 ;divide by 2 (50%)
- shr ah,1 ;divide by 4 (25%)
- shr ah,1 ;divide by 8 (12.5%)
- mov cl,[di+NotePercentVal]
- xor ch,ch
- xor al,al
-
- note_percent:
- add al,ah
- loop note_percent
- mov [di+PercentDuration],al
-
- no_note_percent:
- mov [di+Duration],bl ;save duration in ram control block
- ret
-
- InstallDuration endp
- ;----------------------------------------------------------------------------
- ;set up speech stuff
- ;double word pointer and length are passed on the stack
-
- _speak proc far ;speak(pointer,dlength);
- public _speak
-
- push bp
- mov bp,sp
- push es
- push ds
- push si
-
- ; make sure counter-0 of timer is dividing by 65536:
- mov al,36h ;reset timer for 18.2 Hz operation
- out TIMERCONTROL,al
- xor ax, ax
- out TIMER0, al ; low byte
- out TIMER0, al ; high byte
-
- ; set some parameters of voice-0:
- mov ax, 02021H ; am= 0, vib= 0, eg-type= 1, ksr= 0, multi= 1
- call OutAdlib
- mov ax, 060f0H ; attack rate == MAX, decay rate = MIN
- call OutAdlib
- mov ax, 080f0H ; sustain level = MAX, release rate = MIN
- call OutAdlib
- mov ax, 0C001H ; feed-back= 0, connection = 1 (additive)
- call OutAdlib
- mov ax, 0E000H ; wave-select = 0 (sinus)
- call OutAdlib
- mov ax, 0433fH ; voice-0, slot-1 = MAX attenuation
- call OutAdlib
-
- ; make sure that voice-0 is off:
- mov ax, 0B000H ; voice 0, f_num = 256
- call OutAdlib
- mov ax, 0A000H ; voice 0, f_num = 256
- call OutAdlib
-
- ; start note-on on voice-0 with freq. of 250 Hz:
- mov ax, 0A000H+(F_NUM AND 0ffH) ; set 250 Hz
- call OutAdlib
- mov ax, 0B000H+20H+(YAMBLOCK SHL 2)+(F_NUM SHR 8)
- call OutAdlib
- cli ; disable interrupt for timing section:
-
- ; Time 1/4 of period using the timer-0 of the system. The timer frequency
- ; is 1193180 Hz.
- mov al, 00H ; latch counter-0
- out TIMERCONTROL, al
- in al, TIMER0 ; low byte
- mov bl, al
- in al, TIMER0 ; high byte
- mov bh, al ; count in BX
-
- ; wait until timer-2 down by DELAY_COUNT:
- lp3: mov al, 00H ; latch counter-0
- out TIMERCONTROL, al
- in al, TIMER0 ; low byte
- mov cl, al
- in al, TIMER0 ; high byte
- mov ch, al ; assemble 16 bits word in DX
- neg cx
- add cx, bx ; start - end
- cmp cx, DELAY_COUNT
- jb lp3
-
- ; time-out...
- ; block frequency of voice-0:
- mov ax, 0B000H+20H ; set high bits of f_num and block to 0
- call OutAdlib
- mov ax, 0A000H ; set f_num to 0
- call OutAdlib
-
- sti
-
- ;**** set up addressing for interrupt routine
- lds si,Dword ptr [bp+6] ;get segment and offset into si/ds
- mov ax,si ;put offset into si
- mov cs:doffset,ax ;save in code segment
- mov cs:dbaseaddr,ax ;save in code segment
- mov ax,ds ;segment into ax
- mov cs:dsegment,ax ;save segment address
- mov cx,[bp+10] ;load cx with number of samples
- mov cs:dlength,cx ;save dlength
-
- mov cs:lastsample,08h ;initialize for interrupt
- mov cs:evenodd,0 ;initialize for interrupt
-
- mov ax,cs ;set ds
- mov ds,ax ;to cs
-
- mov Sampleflag,1
- mov dx,ADLIBREGS
- mov al, 40H ;output to tl channel 0
- out dx, al
- call Wait33
- mov al,00h
- inc dx
- out dx,al
- call Wait34
-
- ;**** install interrupt routine
- cli ;clear interrupts
- mov ax,3508h ;dos function number
- int 21h ;dos get int vector
- mov oldintSEG2,es ;save segment
- mov oldintOFF2,bx ;save offset
-
- mov dx,offset _newint2 ;offset of new int handler in dx
- mov ax,2508h ;dos function number
- int 21h ;dos set interrupt vector
-
- ;**** set interrupt rate
- mov al,36h ;set timer mode
- out TIMERCONTROL,al ;send it
- call wait33
- mov al,LOWBYTEDIVISOR ;low byte of divisor for 16kHz
- out TIMERDATA0,al
- call wait33
- mov al,HIGHBYTEDIVISOR ;high byte of divisor
- out TIMERDATA0,al
-
- sti ;enable interrupts
-
- pop si
- pop ds
- pop es
- mov bp,sp
- pop bp
- ret
- _speak endp
- ;----------------------------------------------------------------------------
- ;send data to sound chip
- ;ah-sound chip register
- ;al-sound chip data
-
- OutAdlib proc near
-
- mov dx,ADLIBREGS ;card address for regs
- xchg al,ah ;write chip register
- out dx,al
- call Wait33
- inc dx ;card address for data
- xchg al,ah ;send data to register
- out dx,al ;send to card
- call Wait34
-
- ret
- OutAdlib endp
- ;----------------------------------------------------------------------------
- ;check for attenuation register overflows
- ;ax has attenuation value
-
- CheckWrap proc near
-
- cmp ax,0
- jl lessthanzero
- cmp ax,03fh
- jg greaterthan3f
- ret
-
- lessthanzero:
- mov al,0
- ret
-
- greaterthan3f:
- mov al,03fh
- ret
-
- CheckWrap endp
- ;----------------------------------------------------------------------------
- ;generate synchronization data for syncwait
-
- syncgen proc near
-
- mov al,presync ;generate music tempo ticks
- add al,globalTempo
- mov presync,al
- jc syncoverflow
- ret
-
- syncoverflow:
- dec notecntr ;16th note frequency
- je syncnow
- ret
-
- syncnow:
- mov al,notesync ;established 16th/2
- mov notecntr,al
- inc syncbyte
- ret
-
- syncgen endp
- ;----------------------------------------------------------------------------
- ;return status of speech in ax
-
- _vstatus proc far
- public _vstatus
-
- mov ax,cs:doffset
- ret
- _vstatus endp
- ;----------------------------------------------------------------------------
- ;return status of a channel in ax
- ;stack has channel to check
-
- _sstatus proc far
- public _sstatus
- push bp
- mov bp,sp
-
- push ds
- push di
-
- mov ax,cs
- mov ds,ax
-
- mov bx,word ptr [bp+6] ;get sound code
- sub bh,bh ;bh<-0
- shl bx,1
- mov di,[bx+offset SchnlPtr]
- mov al,[di+Duration] ;put duration in al
- xor ah,ah ;return duration
-
- pop di
- pop ds
-
- mov sp,bp
- pop bp
-
- ret
- _sstatus endp
- ;----------------------------------------------------------------------------
- ;delay for sound chip writes
-
- Wait34 proc near
-
- IF DEBUG
- push dx
- inc _NoWrites
- mov dx,_NoWrites
- cmp dx,MaxWrites
- jl notmax
- mov MaxWrites,dx
-
- notmax:
- pop dx
- ENDIF
-
- push ax
- push cx
- push dx
-
- mov dx,0388h
- mov cx,23
-
- waitlup1:
- in al,dx
- loop waitlup1
-
- pop dx
- pop cx
- pop ax
- ret
-
- Wait34 endp
- ;----------------------------------------------------------------------------
- ;delay for sound chip writes
-
- Wait33 proc near
-
- push ax
- push cx
- push dx
-
- mov dx,0388h
- mov cx,4
-
- waitlup2:
- in al,dx
- loop waitlup2
-
- pop dx
- pop cx
- pop ax
- ret
-
- Wait33 endp
- ;----------------------------------------------------------------------------
- ;combine all levels of attenuation and check for overflows
-
- CombineAttn proc ;combine all attenuation and stuff em
- public CombineAttn
-
- call CombineOp2
- mov bx,offset OPOFFSETS ;get offset into chip
- add bl,curchannel
- mov cl,[bx] ;cl has slot offset
-
- mov ah,cl ;get current channel
- add ah,043h
- call outadlib
-
- cmp byte ptr [di+Algorithm],0
- je attncombinedone
-
- call CombineOp1
- mov bx,offset OPOFFSETS ;get offset into chip
- add bl,curchannel
- mov cl,[bx] ;cl has slot offset
-
- mov ah,cl ;get current channel
- add ah,040h
- call outadlib
-
- attncombinedone:
- ret
-
- CombineAttn endp
- ;----------------------------------------------------------------------------
- ;combine all attenuation and return it in al
-
- CombineOp2 proc
-
- mov al,[di+PatchAttn2]
- and al,03fh ;and off ksl
- add al,[di+AccentAttn] ;add accent attenuation
- add al,[di+sysAttn] ;add system attenuation
- add al,[di+ChannelAttn] ;add channel attenuation
-
- cmp byte ptr [di+Op2Velocity],0 ;any velocity ?
- je novelocity2
- mov cl,[di+Op2Velocity]
- inc cl
- xor bh,bh
- mov bl,[di+Velocity]
- shl bx,cl
- sub al,bh
-
- novelocity2:
- cmp al,03fh ;check for wrap on top
- jna checkalg ;ok check if not stack
- cmp al,0 ;did it wrap below zero
- jl wrapbottom ;yes set to zero
- mov al,03fh ;no set to max
- jmp short checkalg
-
- wrapbottom:
- mov al,0
-
- checkalg:
- mov bl,[di+PatchAttn2] ;save ksl and attn in shadow
- and bl,0c0h ;and off attn
- or al,bl ;combine attn and ksl
- ret
-
- CombineOp2 endp
- ;----------------------------------------------------------------------------
- ;combine all attenuation and return it in al
-
- CombineOp1 proc
-
- mov al,[di+PatchAttn1]
- and al,03fh ;and off ksl
- cmp byte ptr [di+Algorithm],0 ;only add this stuff if alg 1
- je no_attn
- add al,[di+AccentAttn] ;add accent attenuation
- add al,[di+sysAttn] ;add system attenuation
- add al,[di+ChannelAttn] ;add channel attenuation
-
- no_attn:
- cmp byte ptr [di+Op1Velocity],0 ;any velocity ?
- je novelocity
- mov cl,[di+Op1Velocity]
- inc cl
- xor bh,bh
- mov bl,[di+Velocity]
- shl bx,cl
- sub al,bh
-
- novelocity:
- cmp al,03fh ;check for wrap on top
- jna stuffit
- cmp al,0 ;did it wrap below zero
- jl wrapbottom2 ;yes set to zero
- mov al,03fh ;no set to max
- jmp short stuffit
- wrapbottom2:
- mov al,0
- stuffit:
- mov bl,[di+PatchAttn1] ;save ksl and attn in shadow
- and bl,0c0h ;and off attn
- or al,bl ;combine attn and ksl
- ret
- CombineOp1 endp
-
- ;----------------------------------------------------------------------------
- ;clear sound process ram
- ;di is assumed to be set for current channel
-
- ClearSpram proc near
-
- push es
- push ax
- push cx
-
- mov cx,ds
- mov es,cx
- mov cx,SPRAMLEN-3
-
- sub ax,ax
- push di
- add di,3 ;do not initialize the first 3 bytes
- shr cx,1
- repnz stosw
- adc cx,cx
- repnz stosb
- pop di
-
- mov byte ptr [di+Tempo],0ffh ;max tempo
- mov byte ptr [di+Priority],000h ;reset priority
- mov [di+PVector1],offset NullVector ;set process vector
- mov [di+PVector2],offset NullVector ;set process vector
- mov byte ptr [di+GateThreshold],1 ;default for gate threshold
-
- pop cx
- pop ax
- pop es
-
- ret
-
- ClearSpram endp
- ;----------------------------------------------------------------------------
- ;write a patch to sound chip
- ;si should be set to point at patch data
-
- writepatch proc near
-
- mov ah,020h ;am/vib/eg/ksr/multi (miscmult)
- add ah,cl
- lodsb
- call outadlib
- mov ah,023h ;am/vib/eg/ksr/multi (miscmult)
- add ah,cl
- lodsb
- call outadlib
-
- mov ah,0c0h ;Feedback/algorithm
- add ah,curchannel
- lodsb ;si has patch source data
- call outadlib
- and al,01h ;and off feedback
- mov [di+Algorithm],al ;save in shadow
-
- mov ah,0e0h ;wavesel
- add ah,cl
- lodsb ;si has patch source data
- call outadlib
-
- mov ah,0e3h ;wavesel
- add ah,cl
- lodsb ;si has patch source data
- call outadlib
-
- mov ah,040h ;ksl/attenuation
- add ah,cl
- lodsb
- mov [di+PatchAttn1],al ;save ksl and attn in shadow
- call CombineOp1
- call outadlib
-
- mov ah,043h ;ksl/attenuation
- add ah,cl
- lodsb
- mov [di+PatchAttn2],al ;save ksl and attn in shadow
- call CombineOp2
- call outadlib
-
- mov ah,060h ;attack/decay
- add ah,cl
- lodsb ;si has patch source data
- call outadlib
-
- mov ah,063h ;attack/decay
- add ah,cl
- lodsb ;si has patch source data
- call outadlib
-
- mov ah,080h ;sustain/release
- add ah,cl
- lodsb ;si has patch source data
- call outadlib
- mov ah,083h ;sustain/release
- add ah,cl
- lodsb ;si has patch source data
- call outadlib
- ret
-
- writepatch endp
- ;----------------------------------------------------------------------------
- ;clear a currently running sound chip envelope
- ;cl has channel to clear
-
-
- clearenv proc
-
- cmp drummask,0
- je no_drums
- cmp cl,6
- jl no_drums
- ret
-
- no_drums:
- mov bx,offset OPOFFSETS ;get offset into chip
- mov ch,cl
- add bl,cl
- mov cl,byte ptr [bx]
-
- mov ah,060h ;modulator attack decay
- add ah,cl
- mov al,0ffh
- call outadlib
-
- mov ah,063h ;carrier attack decay
- add ah,cl
- mov al,0ffh
- call outadlib
-
- mov ah,080h ;modulator sustain release
- add ah,cl
- mov al,0ffh
- call outadlib
-
- mov ah,083h ;carrier sustain release
- add ah,cl
- mov al,0ffh
- call outadlib
-
- mov ah,0b0h ;gate up
- add ah,ch
- mov al,000h
- call outadlib
-
- mov al,020h ;gate down
- call outadlib
-
- ret
- clearenv endp
- ;----------------------------------------------------------------------------
-
- ;***** process vector routines
- ;process vectors routines that are executed on a channel basis
- ;whenever they are turned on. They are executed at the interrupt
- ;rate of the sound system and are independent of tempo
-
- ;null return for process vectors
- NullVector:
- ret
-
- ;vibrato processing
- DoVibrato:
- cmp byte ptr [di+Vibdelaycount],0 ;check for
- jz okdovib
- dec byte ptr [di+Vibdelaycount]
- ret
-
- okdovib:
- mov cl,[di+Vibprecount] ;look for prescaler overfllow
- add cl,[di+Vibpre]
- mov [di+Vibprecount],cl
- jc dovib
- ret
-
- dovib:
- mov bx,[di+Vibstep]
- dec byte ptr [di+VibNewCount]
- jnz cont
- xor bx,0ffffh ;shift sign
- inc bx ;finish off two's complement
- mov [di+Vibstep],bx ;save neg
- mov al,[di+Vibcount]
- mov [di+VibNewCount],al
-
- cont:
- mov ax,[di+FreqLow]
- and ax,03ffh
- add ax,bx
- mov [di+FreqLow],al
- mov al,[di+Block]
- and al,0fch
- or al,ah
- mov [di+Block],al
-
- mov ah,0a0h ;base of frequency low reg
- add ah,curchannel ;add channel offset
- mov al,[di+FreqLow]
- call outadlib
-
- mov ah,0b0h ;base of frequency high/block reg
- add ah,curchannel ;add channel offset
- mov al,[di+Block] ;freq high block data
- call outadlib
- ret
-
- TblMod:
- mov al,[di+TpTmr]
- add al,[di+TpPre]
- mov [di+TpTmr],al
- jc doTblMod
- ret
- doTblMod:
- dec byte ptr [di+tmoff]
- jns TMpout
- mov al,[di+tmlen]
- mov [di+tmoff],al
-
- TMpout:
- mov ah,[di+TpOp] ;al<-chip Hardware parameter base
- add ah,Yamoff ;adjust for this operator
- mov al,[di+tmoff] ;al<-index of Modulation data
- mov bx,[di+tmbase] ;bx<-base address of Modulation table
- xlat ;al<-modulation data for chip
- call outadlib
- ret
-
- ;pitch delta processing
- DoPitchDelta:
- mov cl,[di+Pdeltcount] ;check for prescaler overflow
- add cl,[di+Pdeltpre]
- mov [di+Pdeltcount],cl
- jc okdodelta
- ret
-
- okdodelta:
- mov bl,[di+FreqLow] ;get low byte of freq
- mov bh,[di+Block] ;high byte and block
- and bh,03h ;clear out block
- mov dl,[di+Block]
- mov dh,dl
- and dl,01ch ;block only
- and dh,020h ;trigger only
-
- mov cx,[di+Pdelt] ;check for delta up or down
- or cx,cx
- jl pitchdown
-
- add bx,cx ;add increment to freq
- cmp bx,02deh ;highest note in current octave
- jl pitchupdate ;still ok
-
- shr bx,1 ;it wrapped divide by two
- push bx
- and bx,03ffh
- jne pdeltok2
-
- pop bx
- inc bx ;dont let freq become zero
-
- pdeltok2:
- pop bx
-
- add dl,04h ;bump it up
- and dl,01ch ;wrap properly
- jmp short pitchupdate ;still ok
-
- pitchdown:
- add bx,cx ;add increment to freq
- cmp bx,0184h ;check if it went past lowest freq
- jg pitchupdate ;if greater its ok
-
- shl bx,1 ;it wrapped multiply by two
- push bx
- and bx,03ffh
- jne pdeltok
-
- pop bx
- dec bx ;dont let freq become zero
-
- pdeltok:
- pop bx
- sub dl,04h ;bump it up
- and dl,01ch ;wrap properly
-
- pitchupdate:
- and bx,03ffh ;only ten freq bits
- mov cx,dx ;put block and trigger state in cx
- mov ah,0a0h ;base of frequency low reg
- add ah,curchannel ;add channel offset
- mov al,bl
- call outadlib
- mov [di+FreqLow],al
-
- mov ah,0b0h ;base of frequency high/block reg
- add ah,curchannel ;add channel offset
- or bh,cl ;combine freq high and block
- or bh,ch ;combine freq high and trigger state
- mov al,bh
- call outadlib
- mov [di+Block],al
- ret
-
- Random:
- mov ax,seed
- add ax,9248h
- ror ax,1
- ror ax,1
- ror ax,1
- mov seed,ax
- ret
-
-
-
- ;----------------------------------------------------------------------------
- ;this is the opcode jump table
- opcode_tbl:
- dw SetLoop ;80,no. of loops set loop counter
- dw TestLoop ;81,labell test loop counter and branch if not zero
- dw StartVoice ;82,string number start a voice in some channel
- dw SetGateThreshold ;83
- dw Branch ;84,label string branch
- dw CallString ;85,label subroutine jump
- dw StringReturn ;86 subroutine return
- dw OctaveOffset ;87,no. of octaves octave transpose
- dw EOS ;88 end of string
- dw Rest ;89,duration rest
- dw SetOplReg ;8a,register,value write directly to opl reg
- dw NewNote ;8b,notevalue,notelength new note no trigger
- dw NoteOffset ;8c,note offset set note offset
- dw TableModOP ;8d,pre8,len8,operator8,tblbase16
- dw StopParse ;8e,channel
- dw EOS ;8f
- dw StuffPatch ;90,patch number install patch
- dw PitchDelta ;91,high,low
- dw ClearPitchDelta ;92 clear pitch delta
- dw FracPitch ;93,lsb pitch offset
- dw EOS ;94
- dw Vibrato ;95,prescaler,shift,count,delay
- dw EOS ;96
- dw EOS ;97
- dw EOS ;98
- dw EOS ;99
- dw SetPriority ;9a,priority set priority in current channel
- dw EOS ;9b
- dw InitSync ;9c,sync mask set string start sync
- dw WaitSync ;9d wait for sync
- dw SetAccentAttn ;9e,attenuation set attenuation
- dw EOS ;9f
- dw Stay ;a0,duration do nothing for duration
- dw Retrigger ;a1,duration retrigger current note
- dw EOS ;a2
- dw EOS ;a3
- dw NotePercent ;a4,percent set note percent
- dw EOS ;a5
- dw SetMusicTempo ;a6,tempo set global tempo
- dw KillVector2 ;a7 kill vector 2
- dw EOS ;a8
- dw SetTempo ;a9,tempo set local tempo
- dw EOS ;aa
- dw SetChannelAttn ;ab,attn set channel attn
- dw SetsysAttn ;ac,channel,attn set attn in channel other than current
- dw SetsysAttnDelta ;ad,channel,delta set delta amount in other than current channel
- dw SetAmDepth ;ae,depth
- dw SetVibDepth ;af,depth
- dw SetSignedAttn ;b0,attn signed attn value
- dw EOS ;b1
- dw EOS ;b2
- dw KillChannel ;b3,channel number
- dw EOS ;b4
- dw RandomPitch ;b5,16 bit and mask add random amount to pitch
- dw KillVector1 ;b6 stop vector 1
- dw EOS ;b7
- dw EOS ;b8 set up pitch bend vector
- dw SetPitchBend ;b9,value set pitch bend value
- dw getmusicTempo ;ba install global tempo in local
- dw SNop ;bb nop
- dw RandomDuration ;bc,8 bit and mask
- dw tempodelta ;bd,signedtempo add to local tempo
- dw EOS ;be
- dw MotorOn ;bf,flag,table number
- dw MotorOff ;c0, ;set motor flag
- dw DrumSetup ;c1,patch1,patch2,patch3,freq1,freq2,freq3
- dw DoDrum ;c2,drum mask trigger drum(s)
- dw DrumOff ;c3 turn off drum mode
- dw DrumAttn ;c4,mask,attn
- dw DrumFade ;c5,mask,attn
- dw DrumMasterAttn ;c6,mask,attn
- dw EOS ;c7
- dw SetAutoTempo ;c8,flag
- dw SetVelocity ;c9,shift op1,shift op2 set velocity shift counts for op1 and op2
-
- ;****************************************************************************
- _TEXT ends
-
- end
-