home *** CD-ROM | disk | FTP | other *** search
- model large,pascal
-
- .DATA
- noeffect EQU dw offset checkonlyPara ; no effect
- noeffect2 EQU dw offset handlenothing ; nothing to do for this effect here ...
-
- INCLUDE GENERAL.DEF
- EXTRN ORDER : BYTE
- EXTRN CHANNEL : TCHANNEL
- EXTRN PATTERN : WORD
- EXTRN INSTRUMENTs : WORD
- EXTRN usedchannels : BYTE
- EXTRN curline : BYTE
- EXTRN curOrder : BYTE
- EXTRN curPattern : BYTE
- EXTRN curtick : BYTE
- EXTRN curspeed : BYTE
- EXTRN Userate : WORD
- EXTRN loopS3M : BYTE
- EXTRN lastorder : BYTE
- EXTRN EndOfSong : BYTE
- EXTRN gvolume : BYTE
- EXTRN amigalimits : BYTE
- EXTRN sinuswave : BYTE
- EXTRN rampwave : BYTE
- EXTRN Squarewave : BYTE
- EXTRN Insnum : WORD
- EXTRN patterndelay : BYTE
- EXTRN Ploop_on : BYTE
- EXTRN Ploop_no : BYTE
- EXTRN Ploop_to : BYTE
- EXTRN patEMShandle : WORD
- EXTRN FrameSeg : WORD
- EXTRN patlength : WORD
-
- wavetab DW offset sinuswave
- DW offset rampwave
- DW offset squarewave ; looks not like a square but anyway
- ; 'random wave' is not a table, but a call for a random number !
-
- st3periods dw 1712,1616,1524,1440,1356,1280,1208,1140,1076,1016, 960, 907
-
- ; we have to init all the effects :
- initeffects noeffect
- dw offset setspeed ; effect 'A' ok !
- dw offset jump2order ; effect 'B' ok !
- dw offset patternbreak2 ; effect 'C' ok !
- dw offset VolumeEfcts ; effect 'D' ok !
- dw offset Pitchdowns ; effect 'E' ok !
- dw offset Pitchups ; effect 'F' ok !
- dw offset Portamento ; effect 'G' ok !
- dw offset vibrato ; effect 'H' ok !
- dw offset Tremor ; effect 'I' <- shity can't get it :( ... ugly implementation
- dw offset Arpeggio ; effect 'J' ok !
- dw offset Vib_Vol ; effect 'K' ok !
- dw offset Port_Vol ; effect 'L' ok !
- noeffect
- noeffect
- noeffect
- noeffect
- dw offset Retrigg ; effect 'Q' ok !
- dw offset Tremolo ; effect 'R' ok !
- dw offset Specialsets ; effect 'S' look at special 1
- dw offset setTempo ; effect 'T' ok !
- dw offset vibrato ; effect 'U' ok ! (here equal to vibrato)
- dw offset globalvolume ; effect 'V' ok !
-
- ; Ok now some tables for multichoise effects (e.g. 'Syx' but also 'Dxy',E,F)
- ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- special1 noeffect ; S0? - nothin
- noeffect ; set filter -> not implemented (by ST3)
- noeffect ; set glissando -> not implemented (by ST3)
- noeffect ; set finetune -> not here ! look special2
- dw offset setvibwav ;OK !
- dw offset settremwav ;OK !
- noeffect ; does not exist
- noeffect ; does not exist
- noeffect ; maybe later (it's E8x - panning )
- noeffect ; does not exist
- noeffect ; stereo control not implemented
- dw offset cmdPatloop ;
- dw offset InitNotecut ;
- dw offset InitNotedelay ;
- dw offset InitPatdelay ;
- noeffect ; funkrepeat -> not implemented
-
- retrig_dif dw offset nosld ; all done ...
- dw offset slddown
- dw offset slddown
- dw offset slddown
- dw offset slddown
- dw offset slddown
- dw offset use2div3
- dw offset use1div2
- dw offset nosld
- dw offset sldup
- dw offset sldup
- dw offset sldup
- dw offset sldup
- dw offset sldup
- dw offset use3div2
- dw offset use2times
-
- ; and some effects we have to handle after reading vol/inst/note
- ; maybe refresh etc. - remember MODplayer ...
- ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- handleeffects noeffect2 ; really no effect ;)
- noeffect2
- noeffect2
- noeffect2
- dw offset Hdl_Volfx ; effect 'D' ok!
- dw offset Hdl_pitchdwn ; effect 'E' ok!
- dw offset Hdl_pitchup ; effect 'F' ok!
- dw offset Hdl_porta ; effect 'G' ok!
- dw offset Hdl_Vibrato ; effect 'H' ok!
- noeffect2
- dw offset Hdl_arpeggio ; effect 'J' ok!
- dw offset hdl_Vib_Vol ; effect 'K' ok!
- dw offset Hdl_Port_Vol ; effect 'L' ok!
- noeffect2
- noeffect2
- dw offset Hdl_setsmpofs ; effect 'O' ok!
- noeffect2
- noeffect2
- dw offset Hdl_tremolo ; effect 'R' ok!
- dw offset Hdl_Special ; effect 'S' look at special 2
- noeffect2
- dw offset Hdl_Vibrato ; effect 'U' ok! (here equal to vibrato
- noeffect2
-
- ; Ok now some tables for multichoise effects (e.g. 'Syx' but also 'Dxy',E,F)
- ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- Vol_cmd2nd noeffect2
- noeffect2
- dw offset FineVSlideDwn
- dw offset FineVSlideUp
- Pitdwn_cmd2nd noeffect2
- dw offset Finepitch_down
- dw offset XFinepitch_down
- Pitup_cmd2nd noeffect2
- dw offset Finepitch_up
- dw offset XFinepitch_up
-
- special2 noeffect2 ; S0? - nothin
- noeffect2 ; set filter -> not implemented (by ST3)
- noeffect2 ; set glissando -> not implemented (by ST3)
- dw offset Hdl_finetune
- noeffect2 ; not here -> special 1
- noeffect2 ; not here -> special 1
- noeffect2 ; does not exist
- noeffect2 ; does not exist
- noeffect2 ; not here -> special 1
- noeffect2 ; does not exist
- noeffect2 ; stereo control -> not implemented (by ST3)
- noeffect2 ; not here -> special 1
- noeffect2 ; not here -> special 1
- noeffect2 ; not here -> special 1
- dw offset Hdl_patterndly
- noeffect2 ; funkrepeat -> not implemented
-
- chnCounter db ?
- jump2flag db ?
- jump2where db ?
- breakflag db ?
- break2where db ?
- pLoop_now db ?
- gvolFlag db ?
- newgvol db ?
- ; to save portamento values :
- portaFlag db ?
- Period_old dw ?
- sStep_old dd ?
- ; a little one for arpeggio :
- arp_chg db ?
- ; save effect,parameter for patterndelay
- sav_cmd dw ?
- sav_para db ?
- ; now some variables I added after I found out those amazing things
- ; about patterndelay
- inpatterndly db ? ;<- call 'readnotes' inside a patterndelay, if then ignore all
- ;notes/inst/vol !
- curnote db ? ;<- normaly it will be a copie of es:[di], but in
- ; patterndelay =0 <- ignore note =)
- curinst db ? ; the same thing for instrument
- curVol db ? ; and for volume
-
- ENDS
-
- .CODE
- .386
-
- PUBLIC READNEWNOTES
- PUBLIC SetupNewInst
- PUBLIC SetNewNote
- EXTRN SET_TEMPO
- EXTRN EMSMAP : FAR ; <- somehow that does not work (assembler creats:
- ; "push cs" + "near call", but that's wrong !!!
-
- CalcFrequStep MACRO
- ; IN: ax = period
- ; OUT: destroys EDX,EBX
-
- and eax,0ffffh ; clear upper 16bit
- xor edx,edx
- mov dx,[Userate]
- mul edx ; EAX = Userate*Period
- mov ebx,eax
-
- xor edx,edx
- mov dx,0dah
- mov eax,77900000h ; EDX:EAX = 1712*8363*10000h
-
- div ebx
-
- ; 1712 * 8363 * 10000h
- ; EAX = ----------------------
- ; Userate * Period
- ENDM
-
- CalcPeriod macro
- local notbelow,notabove
- ; IN: AL - Note (higher 4=name,lower 4=octave)
- ; FS - Segment of instrument
- ; OUT: AX = Period
- ; DESTROYs: BX,CL
- ; calc speriod (with st3 finetune) :
- mov bl,al
- mov cl,al
- shr cl,4
- xor bh,bh
- and bl,0fh
- shl bl,1
- ; ok calculate the period
- mov ax,[st3periods+bx]
- shl ax,4 ; period(note)*16
- shr ax,cl ; period(note)*16 >> octave(note)
- mov dx,8363
- mul dx ; dx:ax = 8363*period(note)*16 >> octave(note)
- mov bx,fs:[TInstrument.c2speed]
- div bx
-
- ; 8363*(period(note)*16 shr octave(note))
- ; ax = --------------------------------------
- ; C2Speed of current Sample
-
- ; Now check borders :
- cmp ax,[channel.lower_border+si]
- jnb notbelow
- mov ax,[channel.lower_border+si]
- notbelow: cmp ax,[channel.upper_border+si]
- jna notabove
- mov ax,[channel.upper_border+si]
- notabove:
- endM
-
- CheckPara0 MACRO
- local cp
- cmp al,0
- jnz cp
- mov al,[channel.parameter+si]
- cp: mov [channel.parameter+si],al
- ENDM
-
- CheckPara0not MACRO
- local cp
- cmp al,0
- je cp
- mov [channel.parameter+si],al
- cp:
- ENDM
-
- SetupNewInst PROC NEAR
- ; IN : AL = number of new instrument
- ; SI = offset to channel
- ; DS = Dataseg
- ;
- ; DESTROYs FS,BX,AX,DX
- ;
- dec al
- mov bl,al
- xor bh,bh
- shl bx,2
- xor ah,ah
- add bx,ax
- mov ax,ds:[Instruments+2]
- add bx,ax
- mov fs,bx
- mov [channel.instrSEG+si],bx
- mov al,fs:[TInstrument.vol]
- cmp al,64
- jb volwell
- mov al,63
- volwell: mul [gvolume]
- shr ax,6
- mov [channel.SampleVol+si],al
- mov ax,fs:[TInstrument.memseg]
- mov [channel.sampleSEG+si],ax
- mov al,fs:[TInstrument.flags]
- and al,00000001b ; bit 0 - loop sample ?
- mov [channel.sLoopflag+si],al
- mov ax,fs:[TInstrument.loopbeg]
- mov [channel.sLoopstart+si],ax
- mov ax,fs:[TInstrument.loopend]
- cmp [channel.sLoopflag+si],1
- je weloop ; =:)
- mov ax,fs:[TInstrument.slength] ; <- we don't loop :( anyway ...
- weLoop: mov [channel.sLoopend+si],ax
- ; calc period borders
- mov bx,fs:[TInstrument.c2speed]
- cmp bx,0
- jne c2speedok
- ; c2speed = 0 -> don't play it !! it's wrong !
- mov [channel.InstrNo+si],0
- c2speedok: mov [channel.ssmpstart+si],0 ; reset start value
- cmp [amigalimits],1
- je takeamigalimits
- ; B-7 :
- mov ax,907 * 16 / 128 ; period(note)*16 >> 7
- mov dx,8363
- mul dx ; dx:ax = 8363*period(note)*16 >> octave(note)
- div bx
- mov [channel.lower_border+si],ax
- ; C-0 :
- mov ax,1712 * 16 ; period(note)*16 >> 0
- mov dx,8363
- mul dx ; dx:ax = 8363*period(note)*16 >> octave(note)
- cmp bx,3500
- jb c2below
- div bx
- mov [channel.upper_border+si],ax
- jmp after1
- c2below: mov bx,3500
- div bx
- mov [channel.upper_border+si],ax
- jmp after1
- takeamigalimits:
- ; first C-3 :
- mov ax,1712 * 16 / 8 ; period(note)*16 >> 3
- mov dx,8363
- mul dx ; dx:ax = 8363*period(note)*16 >> octave(note)
- div bx
- mov [channel.upper_border+si],ax
- ; then B-5 :
- mov ax,907 * 16 / 32 ; period(note)*16 >> 5
- mov dx,8363
- mul dx ; dx:ax = 8363*period(note)*16 >> octave(note)
- div bx
- mov [channel.lower_border+si],ax
- after1: mov al,[curInst]
-
- ret
- ENDP
-
- SetNewNote PROC NEAR
- ; IN: AL = note & octave
- ; SI = offset to channel
- ;
- ; DESTROYs: EAX,EBX,EDX,FS,CX
- ;
- ; clear it first - just to make sure we really set it
- mov [channel.speriod+si],0
- cmp [channel.instrNo+si],0
- je after2 ; if there's no instrumnet
- ; set pointer to instrument
- push ax
- mov ax,[channel.instrSEG+si]
- mov fs,ax
- pop ax
- cmp fs:[TInstrument.Typ],1 ; only calc if instrument does exist
- jne after2
-
- calcperiod
-
- mov [channel.speriod+si],ax
-
- ; now step calculations :
- CalcFrequStep
-
- mov [channel.sStep+si],EAX
-
- cmp [portaFlag],1
- je after2 ; it's porta, do not restart !
- ; restart instrument
- xor ebx,ebx
- mov bx,[channel.sSmpstart+si]
- shl ebx,16
- mov [channel.sCurpos+si],ebx
- mov [channel.enabled+si],1
- after2: ret
- ENDP
-
- ; put next notes into channels
- READNEWNOTES PROC NEAR
- mov [jump2flag],0
- mov [breakflag],0
- mov [gvolFlag],0
- mov [Ploop_now],0
- mov [inpatterndly],0
- cmp [patterndelay],0
- je nopatdly
- mov [inpatterndly],1
- nopatdly: mov al,[usedchannels]
- mov [chnCounter],al
- ; get next postion in current pattern
- mov al,[usedchannels]
- mov ah,al
- shl al,2
- add al,ah ; al = 5*[usedchannels]
- mov ah,[curline]
- mul ah
- ; ok that was the offset :
- mov di,ax
- ; now the segment of current pattern :
- xor bh,bh
- mov bl,[curorder]
- mov bl,[order+bx]
- cmp bl,254
- jae nextorder
- shl bx,1
- mov ax,[pattern+bx]
- or ax,ax
- jz nopatloop
- cmp ax,0C000h
- jb noEMSpattern
- push ax
- push di
- ; Set page number:
- mov ah,044h
- xor bx,bx
- mov bl,al ; bx = logical page
- xor al,al ; al = physical page
- mov dx,[patEMShandle] ; dx = handle
- int 67h
- cmp ah,0
- je noemsprob
- mov dl,0
- div dl ; <- cause a "div by 0" because EMSdriver does not work correct
- noemsprob: pop di
- pop ax
- ; change offset to part #(ah and 0fh)
- shr ax,8
- and al,3fh ; bit 13-8 = partno.
- xor ah,ah
- mov dx,[patlength]
- mul dx ; ax = partno * pattern length
- add di,ax
- mov ax,[frameSEG]
- noemspattern:mov es,ax
- ; ES:DI - pointer to current position in current pattern
- xor si,si ; extra channel offset (running through the channels)
- chnLoop: cmp [channel.channeltyp+si],2
- ja donothing ; <- for adlib channels
- mov [portaFlag],0 ; <- set Flag back
- ; ok first do read current note,inst,vol -> if in patterndelay then ignore them !
- mov [curNote],0ffh
- mov [curInst],00h
- mov [curVol] ,0ffh
- cmp [inpatterndly],1
- je ignorethem
- mov al,es:[di]
- mov [curNote],al
- mov al,es:[di+1]
- mov [curInst],al
- mov al,es:[di+2]
- mov [curVol],al
- ignorethem: ; read effects - it may change the read instr/note !
- ; ~~~~~~~~~~~~
- mov al,es:[di+3] ; read effect number
- xor ah,ah
- shl ax,1
- mov [channel.continueEf+si],0
- cmp ax,2*8 ; Vibrato ...
- je checkifcontV
- cmp ax,2*11 ; Vibrato Volefcs
- je checkifcontV
- cmp ax,2*21 ; fine Vibrato
- je checkifcontV
- ; -> no vibrato effect, so check if last row there was one ...
- ; if there was - do refresh sStep
- cmp [channel.command+si],2*8 ; was vibrato
- je Vibend
- cmp [channel.command+si],2*21 ; was fine vibrato
- je Vibend
- cmp [channel.command+si],2*11 ; was vibrato+volef
- jne noVibend
- ; refresh frequency
- vibend: push ax
- mov ax,[channel.OldPeriod+si]
- mov [channel.sPeriod+si],ax
- cmp ax,0
- je novibcalc
- CalcFrequStep
- mov [channel.sStep+si],EAX
- novibcalc: pop ax
- novibend: cmp ax,2*18 ; Tremolo ...
- je checkifcontTrm
- cmp ax,2*10 ; Arpeggio ...
- je checkifcontA
- ; - currently no arpeggio, but arpeggio was last row ?
- ; if there was - set sStep = Step0 (refresh frequ)
- cmp [channel.command+si],2*10
- jne noarpegend
- ; arpeggio ends :
- push ax
- mov eax,[channel.step0+si]
- mov [channel.sStep+si],eax
- pop ax
- noarpegend: cmp ax,2*17 ; Note retrigg
- je checkifcontRetr
- aftercontcheck:
- mov bx,[channel.command+si]
- mov [sav_cmd],bx ; to save it for pattern delay ...
- mov [channel.command+si],ax
- mov [channel.cmd2nd+si],0
- cmp al,44
- jbe noproblem
- mov [channel.command+si],0
- xor ax,ax
- noproblem: mov bx,ax
- mov al,es:[di+4] ; read effect parameter
- jmp [initeffects+bx]
- back2reality:
-
- effectdone: ; read instrument
- ; ~~~~~~~~~~~~~~~
- ; reinit instrument data but don't restart !
- mov al,[curInst]
- cmp al,00
- je no_newinstr
-
- ; ------------------ check if instrument does exist
- push ax
- dec al
- mov bl,al
- xor bh,bh
- shl bx,2
- xor ah,ah
- add bx,ax
- mov ax,ds:[Instruments+2]
- add bx,ax
- mov fs,bx
- cmp fs:[TInstrument.typ],1
- je instok
- pop ax
- xor al,al
- mov [curInst],al
- jmp no_newinstr
- instok: pop ax
-
- comment #
- cmp [channel.enabled+si],0 ; if channel is disabled then restart definitly
- je restart
- cmp [channel.InstrNo+si],al ; but if it's enabled & same instrno then don't restart
- je dontrestart
- restart: cmp [portaFlag],1 ; and if portamento then don't restart ;)
- je dontrestart
- mov bx,[channel.sSmpstart+si]
- mov [channel.sCurpos+si],bx
- dontrestart:
- #
-
- mov [channel.InstrNo+si],al
- call near ptr SetupNewInst
- no_newinstr: ; read note ...
- ; ~~~~~~~~~~~~~
- mov al,[curNote]
- cmp al,0ffh
- je no_newnote
- cmp al,0feh
- jne normal_note
- mov [channel.enabled+si],0 ; stop mixing
- jmp no_newnote
- normal_note: mov [channel.Note+si],al
- call near ptr SetNewNote
- no_newnote: ; read volume - last but not least ;)
- ; ~~~~~~~~~~~
- mov al,[curVol]
- cmp al,0ffh
- je no_vol
- cmp al,64
- jb volok
- mov al,63
- volok: mul [gvolume]
- shr ax,6
- mov [channel.SampleVol+si],al
-
- no_vol: ; ok now the effect handling after reading vol/instr/note
- mov bx,[channel.command+si]
- jmp [handleeffects+bx]
- handlenothing:
-
- donothing: add di,5 ; to next channel in pattern
- add si,size Channel ; to next channel in channel mix info
- dec [chnCounter] ; one channel done
- jnz chnLoop
- cmp [gvolFlag],0
- je nonewglobal
- mov al,[newgvol]
- mov [gvolume],al
- nonewglobal: mov al,[curspeed]
- mov [curtick],al
- cmp [breakflag],1
- je patternbreak
- cmp [jump2flag],1
- je jumporder
- cmp [Ploop_now],1
- je dopatloop
- nopatloop: inc [curline]
- cmp [curline],64
- jne only_next
- ; ok - next order ...
- mov [curline],0
- nextorder: inc [curorder]
- otherorder: mov [Ploop_to],0
- mov al,[lastorder]
- cmp [curorder],al
- ja end_reached
- doloop: xor bh,bh
- mov bl,[curorder]
- mov al,[Order+bx]
- cmp al,254
- jae nextorder
- mov [curpattern],al
- only_next: ret
-
- patternbreak:mov al,[break2where]
- mov [curline],al
- jmp nextorder
-
- jumporder: mov [curline],0
- mov al,[jump2where]
- mov [curorder],al
- jmp otherorder
-
- dopatloop: dec [Ploop_no]
- jz patloopends
- mov al,[Ploop_to]
- mov [curline],al
- jmp only_next
- patloopends: mov al,[curline]
- inc al
- mov [PLoop_to],al
- mov [Ploop_on],0
- jmp nopatloop
-
- end_reached: cmp [loopS3M],1
- jne donotloop
- mov [curorder],0
- jmp doloop
- donotloop: mov [EndOfSong],1
- jmp only_next
-
- checkifcontV: ; check if continue Vib/Vib_vol
- cmp [curNote],0feh
- jb aftercontcheck
- cmp [channel.command+si],11*2 ; command before was vibrato
- je checkok1
- cmp [channel.command+si],21*2 ; command before was fine vibrato
- je checkok1
- cmp [channel.command+si],8*2 ; command before was vibrato+volef
- jne aftercontcheck
- checkok1: mov [channel.continueEf+si],1
- jmp aftercontcheck
-
- checkifcontA: ; check if continue Arpeg
- cmp [curNote],0feh
- jb aftercontcheck
- checkifcontTrm: ; check if continue a tremolo
- checkifcontRetr: ; check if continue a note retrig
- cmp [channel.command+si],ax
- jne aftercontcheck
- mov [channel.continueEf+si],1
- jmp aftercontcheck
-
- ; Effects :
- ; ~~~~~~~~~
-
- checkonlyPara: checkPara0
- jmp back2reality
-
- setspeed: ; effect 'A'
- checkPara0not
- cmp al,0 ; speed = 0 does not exist
- je back2reality
- mov [curspeed],al
- jmp back2reality
- jump2order: ; effect 'B'
- checkPara0not
- mov [jump2flag],1
- mov [jump2where],al
- jmp back2reality
- patternbreak2: ; effect 'C'
- checkPara0not
- mov [breakflag],1
- mov ah,al
- and al,0fh
- shr ah,4
- AAD
- mov [break2where],al
- jmp back2reality
- VolumeEfcts: ; effect 'D' or jump from dual commands ...
- checkPara0
- mov ah,al
- shr ah,4
- cmp ah,0fh
- jne nofinevoldown
- cmp al,0f0h
- je volup
- ; normal fine volume down DFx
- mov [channel.cmd2nd + si],04
- jmp back2reality
- nofinevoldown: mov ah,al
- and ah,0fh
- cmp ah,0fh
- jne nofinevolup
- cmp al,0fh
- je voldown
- ; normal fine volume up DxF
- mov [channel.cmd2nd + si],06
- jmp back2reality
- nofinevolup: mov ah,al
- and ah,00fh
- jz notVslidedown
- ; normale slide down effect D0x
- voldown: mov [channel.cmd2nd + si],00
- jmp back2reality
- notVslidedown: ; normal slide up effect Dx0
- volup: mov [channel.cmd2nd + si],02
- jmp back2reality
- Pitchdowns: ; effect 'E'
- checkPara0
- cmp al,0DFh ; al is parameter
- ja extraptdowns
- mov [channel.cmd2nd + si],00
- jmp back2reality
- extraptdowns: cmp al,0EFh
- ja Finepitchdown
- ; extra fine slides
- mov [channel.cmd2nd + si],04
- jmp back2reality
- Finepitchdown: mov [channel.cmd2nd + si],02
- jmp back2reality
- Pitchups: ; effect 'F'
- checkPara0
- cmp al,0DFh ; al is parameter
- ja extraptups
- mov [channel.cmd2nd + si],00
- jmp back2reality
- extraptups: cmp al,0EFh
- ja Finepitchup
- ; extra fine slides
- mov [channel.cmd2nd + si],04
- jmp back2reality
- Finepitchup: mov [channel.cmd2nd + si],02
- jmp back2reality
- Portamento: ; effect 'G'
- checkPara0not
- cmp al,0
- je nonewPortpara
- mov [channel.PortPara+si],al
- nonewPortpara: mov [portaFlag],1
- ; check first if portamento really possible:
- cmp [channel.enabled+si],0
- je stopporta
- cmp [curNote],0feh
- jae back2reality ; <- continue portamento
- ; now save some values (we wanna slide from ...)
- mov eax,[channel.sStep+si]
- mov [sStep_old],eax
- mov ax,[channel.sPeriod+si]
- mov [Period_old],ax
- jmp back2reality
- stopporta: mov [channel.command+si],0 ;<-noeffect
- mov [portaFlag],0
- jmp back2reality
- Vibrato: ; effect 'H'
- checkpara0not
- cmp [channel.continueEf+si],1
- je norestart
- mov [channel.Tablepos+si],0
- norestart: cmp al,0
- jne newVibvalue
- mov al,[channel.VibPara+si]
- newVibValue: mov ah,al
- shr ah,4
- cmp ah,0
- jne Vibspeedok
- mov ah,[channel.VibPara+si]
- and ah,0f0h
- or al,ah
- VibspeedOk: mov [channel.VibPara+si],al
- jmp back2reality
- Tremor: ; effect 'I'
- checkPara0
- jmp back2reality
- Arpeggio: ; effect 'J'
- cmp al,0
- je uselastPara
- mov [arp_chg],1
- mov [channel.parameter+si],al
- jmp back2reality
- uselastPara: mov [arp_chg],0
- jmp back2reality
- Vib_Vol: ; effect 'K'
- cmp [channel.continueEf+si],1
- je volumeefcts
- mov [channel.Tablepos+si],0
- jmp volumeefcts
- Port_Vol: ; effect 'L'
- mov [portaFlag],1
- ; check first if portamento really possible:
- cmp [channel.enabled+si],0
- je stopporta ; <- channel plays nothing -> no porta and volfx usefull ;)
- cmp [curNote],0feh
- jae volumeefcts ; <- continue portamento
- ; now save some values (we wanna slide from ...)
- push ax
- mov eax,[channel.sStep+si]
- mov [sStep_old],eax
- mov ax,[channel.sPeriod+si]
- mov [Period_old],ax
- pop ax
- jmp volumeefcts ; <- and now volume effects
-
- Retrigg: ; effect 'Q'
- cmp al,0
- jne newretrPara
- mov al,[channel.parameter+si]
- jmp aftersetretr
- newretrPara: mov [channel.parameter+si],al
- mov ah,al
- and ah,0fh
- cmp ah,0
- je noretrigg
- dec ah
- mov [channel.ctick+si],ah
- aftersetretr: mov bl,al
- shr bl,4
- shl bl,1
- xor bh,bh
- jmp [retrig_dif+bx]
- nosld: mov [channel.cmd2nd+si],0
- jmp back2reality
- slddown: mov [channel.cmd2nd+si],2
- jmp back2reality
- use2div3: mov [channel.cmd2nd+si],4
- jmp back2reality
- use1div2: mov [channel.cmd2nd+si],6
- jmp back2reality
- sldup: mov [channel.cmd2nd+si],8
- jmp back2reality
- use3div2: mov [channel.cmd2nd+si],10
- jmp back2reality
- use2times: mov [channel.cmd2nd+si],12
- jmp back2reality
- noretrigg: mov [channel.command+si],0
- jmp back2reality
- Tremolo: ; effect 'R'
- cmp [channel.continueEf+si],1
- je noTrmrestart
- mov [channel.Tablepos+si],0
- noTrmrestart: cmp al,0
- jne newTrmvalue
- mov al,[channel.Parameter+si]
- newTrmValue: mov ah,al
- shr ah,4
- cmp ah,0
- jne Trmspeedok
- mov ah,[channel.Parameter+si]
- and ah,0f0h
- or al,ah
- TrmspeedOk: mov [channel.Parameter+si],al
- jmp back2reality
- Specialsets: ; effect 'S'
- checkPara0
- xor bh,bh
- mov bl,al
- shr bl,4
- shl bx,1
- mov [channel.cmd2nd+si],bx
- ; do effects we have to check before reading note/vol/instr
- jmp [special1+bx]
- setvibwav: ; for every channel a seperate choise !
- and al,3
- add al,al
- xor ah,ah
- mov bx,ax
- shl bx,1
- mov ax,[wavetab+bx]
- mov [channel.VibTabOfs+si],ax
- jmp back2reality
- settremwav: ; for every channel a seperate choise !
- and al,3
- add al,al
- xor ah,ah
- mov bx,ax
- shl bx,1
- mov ax,[wavetab+bx]
- mov [channel.TrmTabOfs+si],ax
- jmp back2reality
- cmdPatloop: and al,0fh
- cmp al,0
- je set2where
- cmp [Ploop_on],1
- je alreadyinside
- mov [Ploop_on],1
- inc al
- mov [Ploop_no],al
- alreadyinside: mov [Ploop_now],1
- jmp back2reality
- set2where: mov al,[curline]
- mov [Ploop_to],al
- jmp back2reality
- InitNotecut: and al,0fh
- cmp al,0
- je noCut
- ;inc al
- mov [channel.ndtick+si],al
- jmp back2reality
- noCut: mov [channel.command+si],9
- jmp back2reality
- InitNotedelay: and al,0fh
- mov [channel.ndTick+si],al
- cmp [inpatterndly],1
- je donothing
- mov al,[curNote] ; new note for later
- mov [channel.savnote+si],al
- mov al,[curInst] ; new instrument for later
- mov [channel.savInst+si],al
- mov al,[curVol] ; new volume for later
- mov [channel.savVol+si],al
- jmp donothing ; setup note/instr/vol later while mixing !
- InitPatdelay: cmp [inpatterndly],1
- je back2reality ; <- hehe we are allread in this patterndelay ...
- and al,0fh
- inc al
- mov [patterndelay],al
- mov al,[channel.parameter+si]
- mov [sav_para],al
- jmp back2reality
- setTempo: ; effect 'T'
- checkPara0not
- xor ah,ah
- push si di fs es
- push ax
- call far ptr SET_TEMPO
- pop es fs di si
- jmp back2reality
-
- globalvolume: ; effect 'V'
- checkPara0not
- mov [gvolFlag],1
- cmp al,64
- jbe gvolok
- mov al,64
- gvolok: mov [newgvol],al
- jmp back2reality
-
- ; _____________________________________
- ; Effect after reading vol/instr/note :
- ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- Hdl_Volfx: ; effect 'D'
- mov bx,[channel.cmd2nd + si]
- jmp [vol_cmd2nd+bx]
- FineVSlideDwn:mov al,[channel.Parameter+si]
- and al,0fh
- sub [channel.SampleVol+si],al
- jnc handlenothing
- mov [channel.SampleVol+si],0
- jmp handlenothing
- FineVSlideUp: mov al,[channel.Parameter+si]
- shr al,4
- add [channel.SampleVol+si],al
- cmp [channel.SampleVol+si],64
- jb handlenothing
- mov [channel.SampleVol+si],63
- jmp handlenothing
- Hdl_pitchdwn: ; effect 'E'
- mov bx,[channel.cmd2nd + si]
- jmp [pitdwn_cmd2nd+bx]
- Finepitch_down:
- ; we pitch down, but increase period ! (so check upper_border)
- mov ax,[channel.sPeriod+si]
- mov bl,[channel.Parameter+si]
- and bl,0fh
- xor bh,bh
- shl bx,2
- add ax,bx
- cmp ax,[channel.upper_border+si]
- jb ptok
- mov ax,[channel.upper_border+si]
- ptok: ; now calc new frequency step for this period
- mov [channel.sPeriod+si],ax
- CalcFrequStep
- mov ds:[channel.sStep+si],EAX
- jmp handlenothing
- XFinepitch_down:
- ; we pitch down, but increase period ! (so check upper_border)
- mov ax,[channel.sPeriod+si]
- mov bl,[channel.Parameter+si]
- and bl,0fh
- xor bh,bh
- add ax,bx
- cmp ax,[channel.upper_border+si]
- jb ptok
- mov ax,[channel.upper_border+si]
- jmp ptok
- Hdl_pitchup: ; effect 'F'
- mov bx,[channel.cmd2nd + si]
- jmp [pitup_cmd2nd+bx]
- Finepitch_up: ; we pitch up, but decrease period ! (so check lower_border)
- mov ax,[channel.sPeriod+si]
- mov bl,[channel.Parameter+si]
- and bl,0fh
- xor bh,bh
- shl bx,2
- sub ax,bx
- cmp ax,[channel.lower_border+si]
- ja ptok
- mov ax,[channel.lower_border+si]
- jmp ptok
- XFinepitch_up:; we pitch up, but decrease period ! (so check lower_border)
- mov ax,[channel.sPeriod+si]
- mov bl,[channel.Parameter+si]
- and bl,0fh
- xor bh,bh
- sub ax,bx
- cmp ax,[channel.lower_border+si]
- ja ptok
- mov ax,[channel.lower_border+si]
- jmp ptok
- Hdl_porta: ; effect 'G'
- cmp [curNote],0feh
- jae handlenothing ; <- is a portamento continue
- mov ax,[Period_Old]
- xchg ax,[channel.sPeriod+si]
- mov [channel.wantedPeri+si],ax
- mov eax,[sStep_old]
- mov [channel.sStep+si],eax
- jmp handlenothing
- Hdl_Vibrato: ; effect 'H'
- cmp [channel.continueEf+si],1
- je handlenothing ; continue this effect !
- mov ax,[channel.sPeriod+si]
- mov [channel.OldPeriod+si],ax
- jmp handlenothing
- Hdl_arpeggio: ; effect 'J'
- cmp [arp_chg],1
- je newPara
- cmp [channel.continueEf+si],1
- je handlenothing ; no new note !
- ; start arpeggio:
- mov [channel.ArpegPos+si],0
- newPara: mov al,[channel.parameter+si]
- mov ah,[channel.note+si]
- ; calc note 1:
- mov bl,ah
- mov bh,al
- shr bh,4 ; upper 4 bits for note 1
- add bl,bh
- mov bh,bl
- and bh,0f0h
- and bl,00fh
- arpt1: cmp bl,12
- jb arpok1
- sub bl,12
- add bh,10h
- jmp arpt1
- arpok1: or bh,bl
- mov [channel.note1+si],bh
- ; now note 2:
- mov bl,ah
- mov bh,al
- and bh,0fh ; lower 4 bits for note 2
- add bl,bh
- mov bh,bl
- and bh,0f0h
- and bl,00fh
- arpt2: cmp bl,12
- jb arpok2
- sub bl,12
- add bh,10h
- jmp arpt2
- arpok2: or bh,bl
- mov [channel.note2+si],bh
- ; now calc the Steps:
- mov ax,[channel.instrSEG+si]
- mov fs,ax
- mov al,[channel.Note+si]
- call near ptr calcpart
- mov [channel.Step0+si],eax
- mov al,[channel.Note1+si]
- call near ptr calcpart
- mov [channel.Step1+si],eax
- mov al,[channel.Note2+si]
- call near ptr calcpart
- mov [channel.Step2+si],eax
- jmp handlenothing
-
- calcpart: calcperiod
- cmp ax,0
- je nostep
- calcfrequStep
- retn
- nostep: xor eax,eax
- retn
-
- Hdl_Vib_Vol: cmp [channel.continueEf+si],1
- je Hdl_Volfx
- mov ax,[channel.sPeriod+si]
- mov [channel.OldPeriod+si],ax
- jmp Hdl_Volfx
-
- Hdl_Port_Vol: ; effect 'L'
- ; first handle Portamento (and then jump to volume effect handling)
- cmp [curNote],0feh
- jae Hdl_Volfx
- mov ax,[Period_Old]
- xchg ax,[channel.sPeriod+si]
- mov [channel.wantedPeri+si],ax
- mov eax,[sStep_old]
- mov [channel.sStep+si],eax
- jmp Hdl_Volfx
- Hdl_setsmpofs:; effect 'O'
- xor eax,eax
- mov ah,[channel.parameter+si]
- mov [channel.ssmpstart+si],ax
- shl eax,16
- cmp [curnote],0ffh
- je handlenothing
- mov [channel.sCurPos+si],eax
- jmp handlenothing
- Hdl_tremolo: ; effect 'R' (Tremolo)
- cmp [curInst],0
- jne savevol ; new instrument
- cmp [curVol],0ffh
- jne savevol ; new volume
- cmp [channel.continueEf+si],1
- je handlenothing ; continue this effect !
- ; save volume
- savevol: mov al,[channel.SampleVol+si]
- mov [channel.OldVolume+si],al
- jmp handlenothing
- Hdl_Special: ; effect 'S'
- mov bx,[channel.cmd2nd+si]
- jmp [special2+bx]
- Hdl_finetune: jmp handlenothing
- Hdl_patterndly: mov al,[sav_para]
- mov [channel.parameter+si],al
- mov ax,[sav_cmd]
- mov [channel.command+si],ax
- mov [channel.cmd2nd+si],0
- jmp handlenothing
-
- READNEWNOTES ENDP
-
- ENDS
-
- END