|
@@ -1,3326 +0,0 @@
|
|
|
-;----------------------------------------------------------------------------------------
|
|
|
-;pro tracker (mod) player for the spc700 (c)d4s in 2005
|
|
|
-;----------------------------------------------------------------------------------------
|
|
|
-
|
|
|
-.MEMORYMAP ; Tell WLA that the SPC has RAM at locations ;$0000-$ffff in every bank
|
|
|
-SLOTSIZE $10000 ; and that this area is $10000 bytes in size.
|
|
|
-DEFAULTSLOT 0 ; There is only a single slot in SNES, other consoles
|
|
|
-SLOT 0 $0000 ; may have more slots per bank.
|
|
|
-.ENDME
|
|
|
-
|
|
|
-.ROMBANKSIZE $10000 ; Every ROM bank is 64 KBytes in size
|
|
|
-.ROMBANKS 1
|
|
|
-;----------------------------------------------------------------------------------------
|
|
|
-.BANK 0 SLOT 0
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-.define SpcCmdUploadSong $f1 ;indicates that a song is to be uploaded
|
|
|
-.define SpcCmdUploadSongT1 $f2 ;indicates that data for transfer1 is on apu ports
|
|
|
-.define SpcCmdUploadSongT2 $f3 ;indicates that data for transfer2 is on apu ports
|
|
|
-.define SpcCmdUploadSongDone $f4 ;indicates that song upload is complete
|
|
|
-.define SpcCmdReceiveStream $f5 ;indicates that 65816 wants to stream brr data to spc
|
|
|
-.define SpcCmdSubmitStreamNumber $f7 ;indicates that 65816 wants to stream brr data to spc
|
|
|
-.define SpcCmdReceiveStreamComplete $f6 ;spc wants to end stream transmission
|
|
|
-.define SpcCmdUploadSamplePack $f8 ;indicates that a sample pack is to be uploaded. the rest of the commands are taken from normal song upload
|
|
|
-.define SpcCmdUploadSamplePackDone $f9 ;indicates that sample pack upload is complete
|
|
|
-.define SpcCmdPlaySoundEffect $fa ;play a sound effect
|
|
|
-.define SpcCmdStopSong $fb
|
|
|
-.define SpcCmdSetSongSpeed $fc ;set timer speed of mod playback routine
|
|
|
-.define SpcCmdSetSongChMask $fd ;song channel mask
|
|
|
-.define SpcCmdReportType $fe ;type of data spc should respond with
|
|
|
-.define SpcCmdSetSongVolume $ff
|
|
|
-
|
|
|
-.define SpcStreamLatency 7 ;number of frames to load before actually playing sample
|
|
|
-.define SpcStreamSampleNumber 33 ;number of dsp sample to use as streamer
|
|
|
-.define StreamerTimer0 $00 ;how long to wait before downloading next frame
|
|
|
-
|
|
|
-.define ChannelArray $0
|
|
|
-.define ExtSample $20 ;this sample is used for set sample offset effect
|
|
|
-
|
|
|
-.define Stack $ff
|
|
|
-.define ApuCodeBaseAdress $300
|
|
|
-.define SampleSource $0200 ;$ff bytes long
|
|
|
-.define StreamBuffer $fb80 ;480 bytes long
|
|
|
-.define HighestPortaPeriod $0071
|
|
|
-.define LowestPortaPeriod $0358
|
|
|
-.define EchoStartAdress $f8
|
|
|
-.define EchoDelay $01
|
|
|
-
|
|
|
-.define SongEffectsUploaded $ef ;flags that indicate whether a song or sample pack have already been uploaded.bit0=song bit1=sample pack. wla is too stupid to recognize a variable here, so we have to use a static one.
|
|
|
-;variables:
|
|
|
-;.........................................................
|
|
|
-.enum $60
|
|
|
-WaitCounter dw
|
|
|
-CurrentPatternPointerLo db
|
|
|
-CurrentPatternPointerHi db
|
|
|
-InitPatternPointerLo db
|
|
|
-InitPatternPointerHi db
|
|
|
-PortamentoDownLimitLo db
|
|
|
-PortamentoDownLimitHi db
|
|
|
-PortamentoUpLimitLo db
|
|
|
-PortamentoUpLimitHi db
|
|
|
-CurrentChDataLo db
|
|
|
-CurrentChDataHi db
|
|
|
-TempBuffer1 db
|
|
|
-TempBuffer2 db
|
|
|
-TempBuffer3 db
|
|
|
-TempBuffer4 db
|
|
|
-
|
|
|
-TempBuffer5 db
|
|
|
-TempBuffer6 db
|
|
|
-TempBuffer7 db
|
|
|
-TempBuffer8 db
|
|
|
-TempBuffer9 db
|
|
|
-TempBuffer10 db
|
|
|
-TempVol db
|
|
|
-KeyOn db
|
|
|
-CurrentChannel db
|
|
|
-CurrentVolume db
|
|
|
-PitchBufferLo db
|
|
|
-PitchBufferHi db
|
|
|
-CurrentPatternNumber db
|
|
|
-PortamentoSpeedMask db
|
|
|
-NotUsedVariable db
|
|
|
-CurrentPeriodPointer db
|
|
|
-CurrentPeriodPointerHi db
|
|
|
-
|
|
|
-PeriodTablePointerLo db
|
|
|
-PeriodTablePointerHi db
|
|
|
-SpcDataPointerLo db
|
|
|
-SpcDataPointerHi db
|
|
|
-ModFilePointerLo db
|
|
|
-ModFilePointerHi db
|
|
|
-ModFilePointer2Lo db
|
|
|
-ModFilePointer2Hi db
|
|
|
-
|
|
|
-;added variables
|
|
|
-
|
|
|
-ScratchPad1 db
|
|
|
-ScratchPad2 db
|
|
|
-ScratchPad3 db
|
|
|
-
|
|
|
-PeriodBufferLo db
|
|
|
-PeriodBufferHi db
|
|
|
-
|
|
|
-NumberOfPatterns db
|
|
|
-PatternSpeed db
|
|
|
-NextRowChFadeOuts db ;lower nibble bits0-4:channels to fade out for next row
|
|
|
-NextRowChFadeOutTime db ;patternspeed-2
|
|
|
-PortamentoLUTLo db ;table for portamento up/down
|
|
|
-PortamentoLUTHi db ;table for portamento up/down
|
|
|
-TonePortamentoLUTLo db ;table for portamento up/down
|
|
|
-TonePortamentoLUTHi db ;table for portamento up/down
|
|
|
-CurrentRowPointerLo db
|
|
|
-CurrentRowPointerHi db
|
|
|
-CurrentLoopPointerLo db
|
|
|
-CurrentLoopPointerHi db
|
|
|
-LoopCounter db
|
|
|
-PatternBreakFlag db ;if bit0 is set, break to next pattern
|
|
|
-
|
|
|
-;main volume section:
|
|
|
-MainVolL db
|
|
|
-MainVolR db
|
|
|
-EchoVolL db
|
|
|
-EchoVolR db
|
|
|
-ChannelEnable db
|
|
|
-ChannelEchoEnable db
|
|
|
-
|
|
|
-
|
|
|
-PitchTablePointerLo db
|
|
|
-PitchTablePointerHi db
|
|
|
-
|
|
|
-Channel1Array dw
|
|
|
-Channel2Array dw
|
|
|
-Channel3Array dw
|
|
|
-Channel4Array dw
|
|
|
-
|
|
|
-;apu streaming stuff
|
|
|
-StreamState db ;variable for streaming state machine
|
|
|
-StreamCurrentBuffer db ;indicates currently active stream buffer out of 8
|
|
|
-StreamVolume db
|
|
|
-
|
|
|
-ActiveSoundEffectCh db ;0-3
|
|
|
-ModPlayerTimer0 db
|
|
|
-SongChannelMask db ;mask variable for 4 song channels. default $0f
|
|
|
-SpcReportType db
|
|
|
-ModTimecode dw ;timecode for mod currently playing. reset after song upload
|
|
|
-SpecialReportCmd db
|
|
|
-SoundEffectFlipFlag db
|
|
|
-TickSampleStart db ;channel mask to start samples on the next tick. used for delay and retrigger
|
|
|
-MusicVol1 db ;mod channel 0,2 volume
|
|
|
-MusicVol2 db ;mod channel 1,3 volume
|
|
|
-.ende
|
|
|
-
|
|
|
-
|
|
|
-;channel variables
|
|
|
-.enum $00
|
|
|
-ch_instrument db ;00
|
|
|
-ch_note db ;01
|
|
|
-ch_effect db ;02
|
|
|
-ch_effect_data db ;03
|
|
|
-ch_finetune db ;04
|
|
|
-ch_current_volume db ;05
|
|
|
-ch_current_pitch_lo db ;06 this gets updated on portamento etc
|
|
|
-ch_current_pitch_hi db ;07 (not directly used in sourcecode)
|
|
|
-ch_target_pitch_lo db ;08 (not used at all in sourcecode) target pitch for tone portamento
|
|
|
-ch_target_pitch_hi db ;09 (not used at all in sourcecode)
|
|
|
-ch_tone_portamento_speed db ;0a
|
|
|
-ch_portamento_slide_dir db ;0b bit0 sets up/down
|
|
|
-ch_vibrato_command_buffer db ;0c this is a buffer for depth and speed when using vibrato continue
|
|
|
-ch_vibrato_position db ;0d
|
|
|
-ch_vibrato_tremolo_waveform db ;0e 0=sine, 1=ramp down, 2=square
|
|
|
-ch_tremolo_position db ;0f
|
|
|
-ch_tremolo_command_buffer db ;10
|
|
|
-ch_arpeggio_note_buffer db ;11
|
|
|
-ch_tick_delay db ;12
|
|
|
-ch_amiga_period_lo db ;13 this is the current amiga period
|
|
|
-ch_amiga_period_hi db ;14 (not directly used in sourcecode)
|
|
|
-ch_current_amiga_period_lo db ;15 this is the tone portamento target amiga period
|
|
|
-ch_current_amiga_period_hi db ;16 (not directly used in sourcecode)
|
|
|
-;next must be the last entry in this array:
|
|
|
-ch_current_channelmask db ;last byte in array and mask for channel
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-.ende
|
|
|
-
|
|
|
-
|
|
|
-;.........................................................
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-.ORGA (ApuCodeBaseAdress-2) ;$2FC
|
|
|
-.DW ApuCodeBaseAdress ;spcram copy offset
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-BootInit:
|
|
|
- clrp
|
|
|
- mov $f1,#$f0
|
|
|
- mov a,#$ff
|
|
|
- mov !$fff0,a
|
|
|
- mov x,#Stack ;set stack pointer (old: $cf)
|
|
|
- mov sp,x
|
|
|
- mov a,#$00
|
|
|
- mov x,a
|
|
|
- jmp !ClearVariables
|
|
|
-
|
|
|
-CopyRight:
|
|
|
- .db "matt@dforce3000.de"
|
|
|
-CopyRightEnd:
|
|
|
-
|
|
|
-ClearVariables:
|
|
|
- mov (x)+,a
|
|
|
- cmp x,#$f0
|
|
|
- bne ClearVariables
|
|
|
-
|
|
|
- mov MainVolL,#$7f
|
|
|
- mov MainVolR,#$7f
|
|
|
- mov EchoVolL,#$00
|
|
|
- mov EchoVolR,#$00
|
|
|
- mov ChannelEnable,#$0f
|
|
|
- mov ChannelEchoEnable,#$0f
|
|
|
- mov SpcReportType,#0 ;reset report type to void
|
|
|
- mov MusicVol1,#$7f ;init volume. narrow stereo, a little bit stereo separation
|
|
|
- mov MusicVol2,#$7f
|
|
|
-
|
|
|
-
|
|
|
- mov SpcDataPointerLo,#(ModFile & $00ff) ;setup mod pointer
|
|
|
- mov SpcDataPointerHi,#(ModFile >> 8)
|
|
|
-
|
|
|
- call !ClearAllChannelArray
|
|
|
- call !SetupDspRegsAndTimers ;reset dsp regs first.
|
|
|
- call !InitVariables ;set up pointers to first pattern
|
|
|
- call !UpdateVolEchoVariablesOnly
|
|
|
-
|
|
|
-
|
|
|
-MainLoop:
|
|
|
- mov a,$fd ;clear counter0
|
|
|
-MainLoop1:
|
|
|
- mov a,$fd ;wait for counter 0 to become zero
|
|
|
- beq MainLoop1 ;takes roughly 44 scanlines total
|
|
|
-
|
|
|
- call !MainWaitLoop
|
|
|
- call !SendReportData
|
|
|
-
|
|
|
- mov a,$f4 ;check if command present on port0
|
|
|
- and a,#$f0
|
|
|
- cmp a,#$f0
|
|
|
- bne MainLoop ;return to mainloop if there isn't
|
|
|
-
|
|
|
- mov a,$f4 ;get command
|
|
|
- and a,#$0f
|
|
|
- asl a
|
|
|
- mov x,a ;pointer into jump table
|
|
|
- jmp [!CommandJumpTable+x]
|
|
|
-
|
|
|
-CommandJumpTable:
|
|
|
- .dw CommandVoid ;0
|
|
|
- .dw ReceiveSong
|
|
|
- .dw CommandVoid
|
|
|
- .dw CommandVoid
|
|
|
- .dw CommandVoid
|
|
|
- .dw ReceiveStream ;5
|
|
|
- .dw CommandVoid
|
|
|
- .dw CommandVoid
|
|
|
- .dw ReceiveSamplePack
|
|
|
- .dw CommandVoid
|
|
|
- .dw PlaySoundEffect ;10
|
|
|
- .dw StopSongStream
|
|
|
- .dw SetSongSpeed
|
|
|
- .dw SetSongChannelMask
|
|
|
- .dw SetReportType
|
|
|
- .dw SetSongVolume
|
|
|
-
|
|
|
-
|
|
|
-ReceiveSong:
|
|
|
- ;timers must be reset before receiving a song, else we can't wait properly for the echo buffer to initialize
|
|
|
- call !ReceiveSongHandler
|
|
|
- call !ClearAllChannelArray
|
|
|
- call !SetupSamples ;set up sample offsets
|
|
|
- call !SetupDspRegsAndTimers ;reset dsp regs first.
|
|
|
- call !InitVariables ;set up pointers to first pattern
|
|
|
- call !UpdateVolEchoVariablesOnly
|
|
|
-;return to mainloop:
|
|
|
- bra MainLoop
|
|
|
-
|
|
|
-UpdateVolEcho:
|
|
|
- call !UpdateVolEchoHandler
|
|
|
- bra MainLoop
|
|
|
-
|
|
|
-ResetHandler:
|
|
|
-;clear apu ports:
|
|
|
- mov y,#$00
|
|
|
- mov $f4,y
|
|
|
- mov $f5,y
|
|
|
- mov $f6,y
|
|
|
- mov $f7,y
|
|
|
-;clear dsp regs:
|
|
|
- mov a,#$6c
|
|
|
- mov y,#$e0 ;reset dsp, mute on, echo off
|
|
|
- movw $f2,ya
|
|
|
- mov a,#$0c
|
|
|
- movw $f2,ya
|
|
|
- mov a,#$1c
|
|
|
- movw $f2,ya
|
|
|
- mov a,#$2c
|
|
|
- movw $f2,ya
|
|
|
- mov a,#$3c
|
|
|
- movw $f2,ya
|
|
|
- mov a,#$4c
|
|
|
- movw $f2,ya
|
|
|
- mov y,#$ff
|
|
|
- mov a,#$5c
|
|
|
- movw $f2,ya
|
|
|
- mov y,#$00
|
|
|
- mov a,#$0d
|
|
|
- movw $f2,ya
|
|
|
- mov a,#$2d
|
|
|
- movw $f2,ya
|
|
|
- mov a,#$3d
|
|
|
- movw $f2,ya
|
|
|
- mov a,#$4d
|
|
|
- movw $f2,ya
|
|
|
- mov a,#$5d
|
|
|
- movw $f2,ya
|
|
|
- mov a,#$6d
|
|
|
- movw $f2,ya
|
|
|
- mov a,#$7d
|
|
|
- movw $f2,ya
|
|
|
- mov $f1,#$f0
|
|
|
-;jump to ipl rom:
|
|
|
- jmp !$ffc0
|
|
|
- jmp !$ffc0
|
|
|
-
|
|
|
-MainWaitLoop:
|
|
|
- bbs $ef.0,MainWaitLoopSongPresent ;only process song if song has been uploaded before
|
|
|
- ret
|
|
|
-
|
|
|
-MainWaitLoopSongPresent:
|
|
|
- inc WaitCounter
|
|
|
-
|
|
|
-InnerWaitLoop:
|
|
|
- cmp WaitCounter,PatternSpeed ;old #$04 incremet WaitCounter until 4, selfmodying code changes the default speed(command setspeed0x0f) by writing to the second operand
|
|
|
- bne UpdateTickBasedEffectsOnly
|
|
|
-
|
|
|
-
|
|
|
- mov WaitCounter,#$00
|
|
|
- mov y,NextRowChFadeOuts
|
|
|
- mov a,#$5c
|
|
|
- movw $f2,ya
|
|
|
- mov a,$fe ;clear 4bit counter
|
|
|
- mov y,#2
|
|
|
-KofWaitLoop:
|
|
|
- mov a,$fe ;wait for 2mS
|
|
|
- beq KofWaitLoop
|
|
|
-;**************************************************
|
|
|
- dbnz y,KofWaitLoop
|
|
|
-
|
|
|
- call !ProcessNextRow
|
|
|
-
|
|
|
- call !PreTestRow
|
|
|
- ret
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-UpdateTickBasedEffectsOnly:
|
|
|
-
|
|
|
-
|
|
|
- movw ya,Channel1Array
|
|
|
- movw CurrentChDataLo,ya
|
|
|
- mov CurrentChannel,#$00
|
|
|
- call !CheckForTickBasedEffects
|
|
|
- movw ya,Channel2Array
|
|
|
- movw CurrentChDataLo,ya
|
|
|
- mov CurrentChannel,#$10
|
|
|
- call !CheckForTickBasedEffects
|
|
|
- movw ya,Channel3Array
|
|
|
- movw CurrentChDataLo,ya
|
|
|
- mov CurrentChannel,#$20
|
|
|
- call !CheckForTickBasedEffects
|
|
|
-
|
|
|
- movw ya,Channel4Array
|
|
|
- movw CurrentChDataLo,ya
|
|
|
- mov CurrentChannel,#$30
|
|
|
- call !CheckForTickBasedEffects
|
|
|
-
|
|
|
- mov a,TickSampleStart
|
|
|
- beq UpdateTickBasedEffectsOnlyNoRetrigger
|
|
|
-
|
|
|
- mov $f2,#$4c
|
|
|
- mov $f3,a ;retrigger recently started samples
|
|
|
-
|
|
|
- mov TickSampleStart,#0
|
|
|
-UpdateTickBasedEffectsOnlyNoRetrigger:
|
|
|
-
|
|
|
- ret
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-ProcessNextRow:
|
|
|
- movw ya,CurrentPatternPointerLo ;mark beginning of current row
|
|
|
- movw CurrentRowPointerLo,ya
|
|
|
-
|
|
|
- incw ModTimecode
|
|
|
- mov KeyOn,#$00 ;clear key on
|
|
|
- movw ya,Channel1Array
|
|
|
- movw CurrentChDataLo,ya
|
|
|
- mov CurrentChannel,#$00
|
|
|
- call !GetDataFromPattern
|
|
|
- call !SetVolume
|
|
|
- movw ya,Channel2Array
|
|
|
- movw CurrentChDataLo,ya
|
|
|
- mov CurrentChannel,#$10
|
|
|
- call !GetDataFromPattern
|
|
|
- call !SetVolume
|
|
|
- movw ya,Channel3Array
|
|
|
- movw CurrentChDataLo,ya
|
|
|
- mov CurrentChannel,#$20
|
|
|
- call !GetDataFromPattern
|
|
|
- call !SetVolume
|
|
|
- movw ya,Channel4Array
|
|
|
- movw CurrentChDataLo,ya
|
|
|
- mov CurrentChannel,#$30
|
|
|
- call !GetDataFromPattern
|
|
|
- call !SetVolume
|
|
|
-
|
|
|
- call !KeyOnKeyOff
|
|
|
- call !PatternLoopJumper
|
|
|
- jmp !GetDataFromPatternCheckPatternPosition
|
|
|
-
|
|
|
-
|
|
|
-GetDataFromPatternEntryIsVoid:
|
|
|
- incw CurrentPatternPointerLo
|
|
|
- mov y,#ch_instrument
|
|
|
- mov a,#$ff ;store $ff in all 4 channel input buffers
|
|
|
- mov [CurrentChDataLo]+y,a
|
|
|
- inc y
|
|
|
- mov [CurrentChDataLo]+y,a
|
|
|
- inc y
|
|
|
- mov [CurrentChDataLo]+y,a
|
|
|
- inc y
|
|
|
- mov [CurrentChDataLo]+y,a
|
|
|
- ret
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-GetDataFromPattern:
|
|
|
- mov y,#ch_instrument
|
|
|
- mov a,[CurrentChDataLo]+y ;get last rows instrument, pitch and effects
|
|
|
- mov TempBuffer1,a
|
|
|
- inc y
|
|
|
- mov a,[CurrentChDataLo]+y
|
|
|
- mov TempBuffer2,a
|
|
|
- inc y
|
|
|
- mov a,[CurrentChDataLo]+y
|
|
|
- mov TempBuffer5,a
|
|
|
- inc y
|
|
|
- mov a,[CurrentChDataLo]+y
|
|
|
- mov TempBuffer6,a
|
|
|
- or TempBuffer1,TempBuffer2
|
|
|
- or TempBuffer1,TempBuffer5
|
|
|
- or TempBuffer1,TempBuffer6 ;check if a note was present
|
|
|
- mov a,TempBuffer1
|
|
|
- bne GetDataFromPatternEntryContainsNewData
|
|
|
- call !GetPitchFromBufferAndSet
|
|
|
-
|
|
|
-GetDataFromPatternEntryContainsNewData:
|
|
|
- mov y,#$00
|
|
|
- mov a,[CurrentPatternPointerLo]+y
|
|
|
- cmp a,#$ff ;compare if channel entry is $ff(skip)
|
|
|
- beq GetDataFromPatternEntryIsVoid
|
|
|
-
|
|
|
-;there is a new note to trigger, copy data from pattern to current channel data buffer:
|
|
|
-
|
|
|
- mov [CurrentChDataLo]+y,a ;copy instrument
|
|
|
- inc y
|
|
|
- mov a,[CurrentPatternPointerLo]+y ;copy note
|
|
|
- mov [CurrentChDataLo]+y,a
|
|
|
- inc y
|
|
|
- mov a,[CurrentPatternPointerLo]+y ;copy effect
|
|
|
- mov [CurrentChDataLo]+y,a
|
|
|
- inc y
|
|
|
- mov a,[CurrentPatternPointerLo]+y ;copy effect data
|
|
|
- mov [CurrentChDataLo]+y,a
|
|
|
- incw CurrentPatternPointerLo
|
|
|
- incw CurrentPatternPointerLo
|
|
|
- incw CurrentPatternPointerLo
|
|
|
- incw CurrentPatternPointerLo
|
|
|
-
|
|
|
-
|
|
|
- mov y,#ch_effect
|
|
|
- mov a,[CurrentChDataLo]+y
|
|
|
- and a,#$0f
|
|
|
- mov TempBuffer1,a
|
|
|
- mov y,#ch_effect_data
|
|
|
- mov a,[CurrentChDataLo]+y
|
|
|
- and a,#$f0
|
|
|
- or a,TempBuffer1
|
|
|
- cmp a,#$de ;delay sample effect present? if yes, don't trigger sample
|
|
|
- beq DontSetNewSample
|
|
|
-
|
|
|
- call !SetNewSample
|
|
|
-
|
|
|
-DontSetNewSample:
|
|
|
- ret
|
|
|
-
|
|
|
-SetNewSample:
|
|
|
- mov y,#ch_instrument ;a non-present instrument is indicated by $00
|
|
|
- mov a,[CurrentChDataLo]+y
|
|
|
- beq GetDataFromPatternInstrumentIsVoid
|
|
|
-
|
|
|
-;trigger new instrument, fetch sample data for current instrument
|
|
|
- dec a ;multiply instrument number with 8 to get pointer into sample array
|
|
|
- mov y,#$08
|
|
|
- mul ya
|
|
|
- addw ya,ModFilePointer2Lo
|
|
|
- movw TempBuffer1,ya ;tempbuffer1 is now pointer to current sample entry
|
|
|
- mov y,#$02 ;get sample finetune
|
|
|
- mov a,[TempBuffer1]+y
|
|
|
- mov y,#ch_finetune ;save to current channel finetune
|
|
|
- mov [CurrentChDataLo]+y,a
|
|
|
- mov y,#$03 ;get sample volume
|
|
|
- mov a,[TempBuffer1]+y
|
|
|
- mov CurrentVolume,a ;save to current volume and current channel volume
|
|
|
- mov y,#ch_current_volume
|
|
|
- mov [CurrentChDataLo]+y,a
|
|
|
-
|
|
|
-GetDataFromPatternInstrumentIsVoid:
|
|
|
- mov y,#ch_note
|
|
|
- mov a,[CurrentChDataLo]+y
|
|
|
- cmp a,#$ff ;a non-present note is indicated by $ff
|
|
|
- beq GetDataFromPatternPeriodIsVoid
|
|
|
-
|
|
|
- mov y,#ch_effect ;check if effect command is $ff
|
|
|
- mov a,[CurrentChDataLo]+y
|
|
|
- cmp a,#$ff
|
|
|
- beq GetDataFromPatternCalculateNewPeriod ;if it is, directly calculate new period (why?)
|
|
|
-
|
|
|
- and a,#$0f ;merge effect command and data to test for finetune command
|
|
|
- mov TempBuffer1,a
|
|
|
- inc y
|
|
|
- mov a,[CurrentChDataLo]+y
|
|
|
- and a,#$f0
|
|
|
- or a,TempBuffer1
|
|
|
- xcn a
|
|
|
-
|
|
|
- cmp a,#$e5 ;finetune
|
|
|
- beq FinetuneStep
|
|
|
-
|
|
|
- mov y,#ch_effect
|
|
|
- mov a,[CurrentChDataLo]+y ;get current effect
|
|
|
- and a,#$0f
|
|
|
- cmp a,#$03 ;check if effect is tone portamento
|
|
|
- beq GetDataFromPatternPortamento
|
|
|
-
|
|
|
- cmp a,#$05 ;check if effect is tone portamento and volslide
|
|
|
- beq GetDataFromPatternPortamento
|
|
|
- bra GetDataFromPatternCalculateNewPeriod
|
|
|
-
|
|
|
-FinetuneStep:
|
|
|
- call !Finetune
|
|
|
- bra GetDataFromPatternCalculateNewPeriod
|
|
|
-
|
|
|
-GetDataFromPatternPortamento:
|
|
|
- call !TonePortamento
|
|
|
-
|
|
|
- jmp !GetDataFromPatternCheckEffects
|
|
|
-
|
|
|
-
|
|
|
-GetDataFromPatternPeriodIsVoid:
|
|
|
- jmp !GetDataFromPatternCheckEffects
|
|
|
-
|
|
|
-GetDataFromPatternCalculateNewPeriod:
|
|
|
- mov y,#ch_note
|
|
|
- mov a,[CurrentChDataLo]+y
|
|
|
- mov y,#ch_arpeggio_note_buffer
|
|
|
- mov [CurrentChDataLo]+y,a
|
|
|
- mov y,a ;put period in y
|
|
|
- push y
|
|
|
- mov y,#ch_finetune
|
|
|
- mov a,[CurrentChDataLo]+y ;calculate finetune
|
|
|
- mov y,#$48
|
|
|
- mul ya
|
|
|
- addw ya,PeriodTablePointerLo
|
|
|
- movw CurrentPeriodPointer,ya
|
|
|
-
|
|
|
- pop y ;get corresponding value in 14bit period table
|
|
|
- mov a,[CurrentPeriodPointer]+y ;get current period
|
|
|
- mov TempBuffer1,a
|
|
|
- mov PeriodBufferLo,a
|
|
|
- inc y
|
|
|
- mov a,[CurrentPeriodPointer]+y
|
|
|
- mov TempBuffer2,a
|
|
|
- mov PeriodBufferHi,a
|
|
|
-
|
|
|
-;fetch pitch from pitch table. input: period
|
|
|
- mov y,TempBuffer2
|
|
|
- mov a,TempBuffer1
|
|
|
- addw ya,TempBuffer1 ;multiply by 2
|
|
|
- addw ya,PitchTablePointerLo ;add table offset
|
|
|
- movw TempBuffer1,ya ;move adress to pointer
|
|
|
- mov y,#0
|
|
|
-
|
|
|
- mov a,[TempBuffer1]+y ;get lo pitch byte
|
|
|
- mov PitchBufferLo,a ;save new pitch
|
|
|
- inc y
|
|
|
- mov a,[TempBuffer1]+y
|
|
|
- mov PitchBufferHi,a
|
|
|
-;fetch pitch end
|
|
|
-
|
|
|
- mov y,#ch_current_pitch_lo ;save new pitch to array
|
|
|
- mov a,PitchBufferLo
|
|
|
- mov [CurrentChDataLo]+y,a
|
|
|
- inc y
|
|
|
- mov a,PitchBufferHi
|
|
|
- mov [CurrentChDataLo]+y,a
|
|
|
-
|
|
|
- mov y,#ch_amiga_period_lo ;save new period to array
|
|
|
- mov a,PeriodBufferLo
|
|
|
- mov [CurrentChDataLo]+y,a
|
|
|
- inc y
|
|
|
- mov a,PeriodBufferHi
|
|
|
- mov [CurrentChDataLo]+y,a
|
|
|
- mov y,#ch_vibrato_tremolo_waveform ;check vibrato waveform
|
|
|
- mov a,[CurrentChDataLo]+y
|
|
|
- cmp a,#$04
|
|
|
- bne VibratoRetrigger
|
|
|
-
|
|
|
- mov y,#ch_vibrato_position ;reset vibrato position
|
|
|
- mov a,#$00
|
|
|
- mov [CurrentChDataLo]+y,a
|
|
|
-
|
|
|
-VibratoRetrigger:
|
|
|
- mov y,#ch_vibrato_tremolo_waveform
|
|
|
- mov a,[CurrentChDataLo]+y
|
|
|
- cmp a,#$40
|
|
|
- bne VibratoNoWaveformReset
|
|
|
-
|
|
|
- mov y,#ch_tremolo_position
|
|
|
- mov a,#$00
|
|
|
- mov [CurrentChDataLo]+y,a
|
|
|
-
|
|
|
-VibratoNoWaveformReset:
|
|
|
- mov a,CurrentChannel
|
|
|
- or a,#$02
|
|
|
- mov x,a
|
|
|
- mov y,#ch_current_pitch_lo
|
|
|
- mov a,[CurrentChDataLo]+y
|
|
|
- mov $f2,x ;set pitch height(hi), dsp reg $x2
|
|
|
- mov $f3,a
|
|
|
- inc y
|
|
|
- inc x
|
|
|
- mov a,[CurrentChDataLo]+y
|
|
|
-
|
|
|
- mov $f2,x ;set pitch height(lo), dsp reg $x3
|
|
|
- mov $f3,a
|
|
|
- inc x
|
|
|
-
|
|
|
- mov y,#ch_instrument ;set source sample number
|
|
|
- mov a,[CurrentChDataLo]+y
|
|
|
- beq DontUpdateSourceSampleNumber
|
|
|
- mov $f2,x
|
|
|
- mov $f3,a
|
|
|
- inc x
|
|
|
- mov $f2,x ;disable adsr, enable gain
|
|
|
- mov $f3,#$00 ;old #$0c
|
|
|
- inc x
|
|
|
-
|
|
|
- mov $f2,x ;clear adsr2
|
|
|
- mov $f3,#$00
|
|
|
- inc x
|
|
|
- inc x
|
|
|
- mov y,#ch_current_channelmask
|
|
|
- mov a,[CurrentChDataLo]+y ;trigger note
|
|
|
- or a,KeyOn ;set note in key on var
|
|
|
- mov KeyOn,a
|
|
|
-DontUpdateSourceSampleNumber:
|
|
|
- jmp !GetDataFromPatternCheckEffects
|
|
|
-
|
|
|
-GetPitchFromBufferAndSet:
|
|
|
- mov a,CurrentChannel
|
|
|
- or a,#$02
|
|
|
- mov x,a
|
|
|
- mov y,#ch_current_pitch_lo
|
|
|
- mov a,[CurrentChDataLo]+y
|
|
|
- mov $f2,x
|
|
|
- mov $f3,a
|
|
|
- inc x
|
|
|
- inc y
|
|
|
- mov a,[CurrentChDataLo]+y
|
|
|
- mov $f2,x
|
|
|
- mov $f3,a
|
|
|
- ret
|
|
|
-
|
|
|
-
|
|
|
-CheckForTickBasedEffects:
|
|
|
-;check if note cutoff is due
|
|
|
-
|
|
|
- mov y,#ch_effect
|
|
|
- mov a,[CurrentChDataLo]+y
|
|
|
- cmp a,#$ff
|
|
|
- beq GetPitchFromBufferAndSet
|
|
|
-;check for special effects:
|
|
|
- and a,#$0f
|
|
|
- asl a
|
|
|
- mov x,a ;use effect command as pointer into jump table
|
|
|
- jmp [!TickBasedEffectJumpTable+x]
|
|
|
-
|
|
|
-TickBasedEffectJumpTable:
|
|
|
- .dw TickBasedArpeggio
|
|
|
- .dw TickBasedPortamentoUp
|
|
|
- .dw TickBasedPortamentoDown
|
|
|
- .dw TickBasedTonePortamento
|
|
|
- .dw TickBasedVibrato
|
|
|
- .dw TickBasedVolslidePorta
|
|
|
- .dw VolslideVibrato
|
|
|
- .dw TickBasedTremolo
|
|
|
- .dw TickBasedVoid
|
|
|
- .dw TickBasedVoid
|
|
|
- .dw TickbasedVolslide
|
|
|
- .dw TickBasedVoid
|
|
|
- .dw TickBasedVoid
|
|
|
- .dw TickBasedVoid
|
|
|
- .dw TickBasedExEffects
|
|
|
- .dw TickBasedVoid
|
|
|
-
|
|
|
-
|
|
|
-TickBasedVoid:
|
|
|
- ret
|
|
|
-
|
|
|
-TickBasedExEffects:
|
|
|
- mov y,#ch_effect_data
|
|
|
- mov a,[CurrentChDataLo]+y ;get ex-effect subtype
|
|
|
- and a,#$f0
|
|
|
- lsr a
|
|
|
- lsr a
|
|
|
- lsr a
|
|
|
- mov x,a ;use effect command as pointer into jump table
|
|
|
- jmp [!TickBasedExEffectJumpTable+x]
|
|
|
-
|
|
|
-TickBasedExEffectJumpTable:
|
|
|
- .dw TickBasedExVoid
|
|
|
- .dw TickBasedExVoid
|
|
|
- .dw TickBasedExVoid
|
|
|
- .dw TickBasedExVoid
|
|
|
- .dw TickBasedExVoid
|
|
|
- .dw TickBasedExVoid
|
|
|
- .dw TickBasedExVoid
|
|
|
- .dw TickBasedExVoid
|
|
|
- .dw TickBasedExVoid
|
|
|
- .dw TickBasedExEffectNoteRetrigger
|
|
|
- .dw TickBasedExVoid
|
|
|
- .dw TickBasedExVoid
|
|
|
- .dw TickBasedExEffectNoteCutOff
|
|
|
- .dw TickBasedExEffectNoteDelay
|
|
|
- .dw TickBasedExVoid
|
|
|
- .dw TickBasedExVoid
|
|
|
-
|
|
|
-TickBasedExVoid:
|
|
|
- ret
|
|
|
-
|
|
|
-;check for special effects commands
|
|
|
-GetDataFromPatternCheckEffects:
|
|
|
- mov y,#ch_effect
|
|
|
- mov a,[CurrentChDataLo]+y
|
|
|
- cmp a,#$ff ;no effect present?
|
|
|
- beq GetPitchFromBufferAndSetLong
|
|
|
-
|
|
|
- and a,#$0f
|
|
|
-
|
|
|
- asl a
|
|
|
- mov x,a ;use effect command as pointer into jump table
|
|
|
- jmp [!NormalEffectJumpTable+x]
|
|
|
-
|
|
|
-NormalEffectJumpTable:
|
|
|
- .dw GetPitchFromBufferAndSet
|
|
|
- .dw GetPitchFromBufferAndSet
|
|
|
- .dw GetPitchFromBufferAndSet
|
|
|
- .dw GetPitchFromBufferAndSet
|
|
|
- .dw GetPitchFromBufferAndSet
|
|
|
- .dw GetPitchFromBufferAndSet
|
|
|
- .dw GetPitchFromBufferAndSet
|
|
|
- .dw GetPitchFromBufferAndSet
|
|
|
- .dw GetPitchFromBufferAndSet
|
|
|
- .dw SetSampleOffset
|
|
|
- .dw GetPitchFromBufferAndSet
|
|
|
- .dw PositionJump
|
|
|
- .dw EffectSetVolume
|
|
|
- .dw PatternBreak
|
|
|
- .dw GetDataFromPatternCheckExEffects
|
|
|
- .dw SetSpeed0x0F
|
|
|
-
|
|
|
-GetPitchFromBufferAndSetLong:
|
|
|
- jmp !GetPitchFromBufferAndSet
|
|
|
-
|
|
|
-;these are the special $Ex effects
|
|
|
-GetDataFromPatternCheckExEffects:
|
|
|
-
|
|
|
- mov y,#ch_effect_data
|
|
|
- mov a,[CurrentChDataLo]+y
|
|
|
- and a,#$f0
|
|
|
- mov y,a ;save a
|
|
|
- xcn a
|
|
|
- asl a
|
|
|
- mov x,a ;pointer into jump table
|
|
|
-
|
|
|
- jmp [!ExEffectJumpTable+x]
|
|
|
-
|
|
|
-ExEffectJumpTable:
|
|
|
- .dw ExEffectSpecialReportCmd
|
|
|
- .dw FinePortamentoUp
|
|
|
- .dw FinePortamentoDown
|
|
|
- .dw ExEffectVoid
|
|
|
- .dw SetVibratoWaveform
|
|
|
- .dw Finetune
|
|
|
- .dw PatternLoop
|
|
|
- .dw ExEffectVoid
|
|
|
- .dw ExEffectVoid
|
|
|
- .dw EffectNoteRetrigger
|
|
|
- .dw FineVolSlideUp
|
|
|
- .dw FineVolSlideDown
|
|
|
- .dw EffectNoteCutOff
|
|
|
- .dw EffectNoteDelay
|
|
|
- .dw ExEffectVoid
|
|
|
- .dw ExEffectVoid
|
|
|
-
|
|
|
-
|
|
|
-ExEffectVoid:
|
|
|
- ret
|
|
|
-
|
|
|
-
|
|
|
-TickBasedArpeggio:
|
|
|
- mov y,#ch_finetune ;calculate finetune
|
|
|
- mov a,[CurrentChDataLo]+y
|
|
|
- mov y,#$48
|
|
|
- mul ya
|
|
|
- addw ya,PeriodTablePointerLo
|
|
|
- movw CurrentPeriodPointer,ya
|
|
|
-
|
|
|
- mov y,#ch_current_pitch_lo
|
|
|
- mov a,[CurrentChDataLo]+y ;save current pitch to buffer
|
|
|
- mov PitchBufferLo,a
|
|
|
- inc y
|
|
|
- mov a,[CurrentChDataLo]+y
|
|
|
- mov PitchBufferHi,a
|
|
|
- jmp !ArpeggioToneSelector
|
|
|
-
|
|
|
-TickBasedVolslidePorta:
|
|
|
- call !TonePortamentoContinue
|
|
|
- jmp !TickbasedVolslide
|
|
|
-VolslideVibrato:
|
|
|
- call !ContinueVibrato
|
|
|
- jmp !TickbasedVolslide
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-ArpeggioToneSelector:
|
|
|
- mov a,WaitCounter ;get waitcounter
|
|
|
- mov y,#0 ;clear y
|
|
|
- mov x,#3 ;put 3 into x
|
|
|
- div ya,x ;divide waitcounter by three
|
|
|
-
|
|
|
- mov TempBuffer1,y ;put remainder(can take values 0-2) into TempBuffer1
|
|
|
-
|
|
|
- cmp TempBuffer1,#$01
|
|
|
- beq ArpeggioTone1
|
|
|
-
|
|
|
- cmp TempBuffer1,#$02
|
|
|
- beq ArpeggioTone2
|
|
|
-
|
|
|
- cmp TempBuffer1,#$00
|
|
|
- beq ArpeggioTone3
|
|
|
-
|
|
|
-
|
|
|
- ret
|
|
|
-
|
|
|
-ArpeggioTone1:
|
|
|
- mov y,#ch_effect_data
|
|
|
- mov a,[CurrentChDataLo]+y
|
|
|
- xcn a
|
|
|
- and a,#$0f
|
|
|
- bra ArpeggioCommit
|
|
|
-
|
|
|
-ArpeggioTone2:
|
|
|
- mov y,#ch_effect_data
|
|
|
- mov a,[CurrentChDataLo]+y
|
|
|
- and a,#$0f
|
|
|
- bra ArpeggioCommit
|
|
|
-
|
|
|
-ArpeggioTone3:
|
|
|
- mov y,#ch_current_pitch_lo ;use current tone as pitch, unchanged
|
|
|
- mov a,[CurrentChDataLo]+y
|
|
|
- mov TempBuffer1,a
|
|
|
- inc y
|
|
|
- mov a,[CurrentChDataLo]+y
|
|
|
- mov TempBuffer2,a
|
|
|
- bra ArpeggioSetPitch
|
|
|
-
|
|
|
-ArpeggioCommit:
|
|
|
- asl a
|
|
|
- mov TempBuffer1,a
|
|
|
- mov y,#ch_arpeggio_note_buffer
|
|
|
- mov a,[CurrentChDataLo]+y
|
|
|
- clrc
|
|
|
- adc a,TempBuffer1
|
|
|
- mov y,a
|
|
|
-
|
|
|
- mov a,[CurrentPeriodPointer]+y ;get current period
|
|
|
- mov ScratchPad1,a
|
|
|
- inc y
|
|
|
- mov a,[CurrentPeriodPointer]+y
|
|
|
- mov ScratchPad2,a
|
|
|
-
|
|
|
- mov y,ScratchPad2
|
|
|
- mov a,ScratchPad1
|
|
|
- addw ya,ScratchPad1 ;multiply by 2
|
|
|
- addw ya,PitchTablePointerLo ;add table offset
|
|
|
- movw ScratchPad1,ya ;move adress to pointer
|
|
|
- mov y,#0
|
|
|
-
|
|
|
- mov a,[ScratchPad1]+y ;get lo pitch byte
|
|
|
- mov TempBuffer1,a ;save new pitch
|
|
|
- inc y
|
|
|
- mov a,[ScratchPad1]+y
|
|
|
- mov TempBuffer2,a
|
|
|
-
|
|
|
-
|
|
|
-ArpeggioSetPitch:
|
|
|
- mov a,CurrentChannel
|
|
|
- or a,#$02
|
|
|
- mov $f2,a
|
|
|
- mov $f3,TempBuffer1
|
|
|
- inc a
|
|
|
- mov $f2,a
|
|
|
- mov $f3,TempBuffer2
|
|
|
- ret
|
|
|
-
|
|
|
-FinePortamentoUp:
|
|
|
- cmp WaitCounter,#$00
|
|
|
- bne PortamentoExit
|
|
|
-
|
|
|
- mov PortamentoSpeedMask,#$0f ;portamento up, but only with lower nibble of effect value
|
|
|
-
|
|
|
-TickBasedPortamentoUp:
|
|
|
- mov a, #(HighestPortaPeriod & $00ff)
|
|
|
- mov y, #(HighestPortaPeriod >> 8)
|
|
|
- movw TempBuffer5,ya ;put highest slideable period into buffer
|
|
|
-
|
|
|
- mov y,#ch_amiga_period_lo ;get current period
|
|
|
- mov a,[CurrentChDataLo]+y
|
|
|
- mov TempBuffer1,a ;and save it to temp buffer
|
|
|
- inc y
|
|
|
- mov a,[CurrentChDataLo]+y
|
|
|
- mov TempBuffer2,a
|
|
|
-
|
|
|
- mov y,#ch_effect_data
|
|
|
- mov a,[CurrentChDataLo]+y ;get current effect value
|
|
|
- and a,PortamentoSpeedMask ;and with mask depeding on normal or finetune portamento
|
|
|
- mov y,#$00 ;inverse clear y
|
|
|
- movw TempBuffer3,ya ;put ya into tempbuffer3
|
|
|
- movw ya,TempBuffer1 ;get current period
|
|
|
- subw ya,TempBuffer3 ;substract portamento speed
|
|
|
-
|
|
|
- cmpw ya,TempBuffer5 ;if negative, we've slided too high
|
|
|
- bpl PortaUpNoLimit
|
|
|
-
|
|
|
- movw ya,TempBuffer5 ;use limit value if we've slided too high
|
|
|
-
|
|
|
-PortaUpNoLimit:
|
|
|
- movw TempBuffer1,ya ;put new pitch to buffer
|
|
|
-
|
|
|
- mov y,#ch_amiga_period_lo ;save back current period
|
|
|
- mov a,TempBuffer1
|
|
|
- mov [CurrentChDataLo]+y,a
|
|
|
- inc y
|
|
|
- mov a,TempBuffer2
|
|
|
- mov [CurrentChDataLo]+y,a
|
|
|
-
|
|
|
- mov y,TempBuffer2 ;get current period
|
|
|
- mov a,TempBuffer1
|
|
|
- addw ya,TempBuffer1 ;multiply by 2
|
|
|
- addw ya,PitchTablePointerLo ;add table offset
|
|
|
- movw TempBuffer3,ya ;move adress to pointer
|
|
|
- mov y,#0
|
|
|
-
|
|
|
- mov a,[TempBuffer3]+y ;get lo pitch byte
|
|
|
- mov TempBuffer1,a ;save new pitch
|
|
|
- inc y
|
|
|
- mov a,[TempBuffer3]+y
|
|
|
- mov TempBuffer2,a
|
|
|
-
|
|
|
-
|
|
|
- mov y,#ch_current_pitch_lo ;save new pitch to current pitch and update pitch register
|
|
|
- mov a,TempBuffer1
|
|
|
- mov [CurrentChDataLo]+y,a
|
|
|
- inc y
|
|
|
- mov a,TempBuffer2
|
|
|
- mov [CurrentChDataLo]+y,a
|
|
|
- mov a,CurrentChannel
|
|
|
- or a,#$02
|
|
|
- mov $f2,a
|
|
|
- mov $f3,TempBuffer1
|
|
|
- inc a
|
|
|
- mov $f2,a
|
|
|
- mov $f3,TempBuffer2
|
|
|
-
|
|
|
-PortamentoExit:
|
|
|
- mov PortamentoSpeedMask,#$ff
|
|
|
- ret
|
|
|
-
|
|
|
-FinePortamentoDown:
|
|
|
- cmp WaitCounter,#$00
|
|
|
- bne PortamentoExit
|
|
|
-
|
|
|
- mov PortamentoSpeedMask,#$0f
|
|
|
-
|
|
|
-TickBasedPortamentoDown:
|
|
|
-
|
|
|
- mov a, #(LowestPortaPeriod & $00ff)
|
|
|
- mov y, #(LowestPortaPeriod >> 8)
|
|
|
- movw TempBuffer5,ya ;put lowest slideable period into buffer
|
|
|
-
|
|
|
- mov y,#ch_amiga_period_lo ;get current period
|
|
|
- mov a,[CurrentChDataLo]+y
|
|
|
- mov TempBuffer1,a ;and save it to temp buffer
|
|
|
- inc y
|
|
|
- mov a,[CurrentChDataLo]+y
|
|
|
- mov TempBuffer2,a
|
|
|
-
|
|
|
- mov y,#ch_effect_data
|
|
|
- mov a,[CurrentChDataLo]+y ;get current effect value
|
|
|
- and a,PortamentoSpeedMask ;and with mask depeding on normal or finetune portamento
|
|
|
- mov y,#$00 ;inverse clear y
|
|
|
- addw ya,TempBuffer1 ;add portamento speed
|
|
|
-
|
|
|
- cmpw ya,TempBuffer5 ;if positive, we've slided too high
|
|
|
- bmi PortaDownNoLimit
|
|
|
-
|
|
|
- movw ya,TempBuffer5 ;use limit value if we've slided too high
|
|
|
-
|
|
|
-PortaDownNoLimit:
|
|
|
- movw TempBuffer1,ya ;put new pitch to buffer
|
|
|
-
|
|
|
- mov y,#ch_amiga_period_lo ;save back current period
|
|
|
- mov a,TempBuffer1
|
|
|
- mov [CurrentChDataLo]+y,a
|
|
|
- inc y
|
|
|
- mov a,TempBuffer2
|
|
|
- mov [CurrentChDataLo]+y,a
|
|
|
-
|
|
|
- mov y,TempBuffer2 ;get current period
|
|
|
- mov a,TempBuffer1
|
|
|
- addw ya,TempBuffer1 ;multiply by 2
|
|
|
- addw ya,PitchTablePointerLo ;add table offset
|
|
|
- movw TempBuffer3,ya ;move adress to pointer
|
|
|
- mov y,#0
|
|
|
-
|
|
|
- mov a,[TempBuffer3]+y ;get lo pitch byte
|
|
|
- mov TempBuffer1,a ;save new pitch
|
|
|
- inc y
|
|
|
- mov a,[TempBuffer3]+y
|
|
|
- mov TempBuffer2,a
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- mov y,#ch_current_pitch_lo
|
|
|
- mov a,TempBuffer1
|
|
|
- mov [CurrentChDataLo]+y,a
|
|
|
- inc y
|
|
|
- mov a,TempBuffer2
|
|
|
- mov [CurrentChDataLo]+y,a
|
|
|
- mov a,CurrentChannel
|
|
|
- or a,#$02
|
|
|
- mov $f2,a
|
|
|
- mov $f3,TempBuffer1
|
|
|
- inc a
|
|
|
- mov $f2,a
|
|
|
- mov $f3,TempBuffer2
|
|
|
- ret
|
|
|
-
|
|
|
-TonePortamento:
|
|
|
- mov y,#ch_note ;get note
|
|
|
- mov a,[CurrentChDataLo]+y
|
|
|
- mov y,a ;put period in y
|
|
|
- push y
|
|
|
- mov y,#ch_finetune
|
|
|
- mov a,[CurrentChDataLo]+y ;calculate finetune
|
|
|
- mov y,#$48
|
|
|
- mul ya
|
|
|
- addw ya,PeriodTablePointerLo
|
|
|
- movw CurrentPeriodPointer,ya
|
|
|
-
|
|
|
- pop y ;get corresponding value in 14bit period table
|
|
|
- mov a,[CurrentPeriodPointer]+y ;get current period
|
|
|
- mov PeriodBufferLo,a
|
|
|
- inc y
|
|
|
- mov a,[CurrentPeriodPointer]+y
|
|
|
- mov PeriodBufferHi,a
|
|
|
-
|
|
|
- mov y,#ch_current_amiga_period_lo ;this is our target period to slide to
|
|
|
- mov a,PeriodBufferLo
|
|
|
- mov [CurrentChDataLo]+y,a
|
|
|
- inc y
|
|
|
- mov a,PeriodBufferHi
|
|
|
- mov [CurrentChDataLo]+y,a
|
|
|
-
|
|
|
- mov y,#ch_amiga_period_lo ;get current actual period
|
|
|
- mov a,[CurrentChDataLo]+y
|
|
|
- mov TempBuffer1,a
|
|
|
- inc y
|
|
|
- mov a,[CurrentChDataLo]+y
|
|
|
- mov TempBuffer2,a
|
|
|
-
|
|
|
-
|
|
|
- mov y,#ch_portamento_slide_dir
|
|
|
- mov a,#$00
|
|
|
- mov [CurrentChDataLo]+y,a
|
|
|
- movw ya,PeriodBufferLo
|
|
|
- cmpw ya,TempBuffer1
|
|
|
- beq TonePortamentoEqual ;check if already at target period
|
|
|
-
|
|
|
- bmi TonePortamentoExit ;if plus, the target period is higher(tone is lower) than the current period. slide value must be added in that case
|
|
|
-
|
|
|
- mov y,#ch_portamento_slide_dir ;invert sliding direction
|
|
|
- mov a,#$01
|
|
|
- mov [CurrentChDataLo]+y,a
|
|
|
-
|
|
|
-TonePortamentoExit:
|
|
|
- ret
|
|
|
-
|
|
|
-TonePortamentoEqual:
|
|
|
- mov y,#ch_current_amiga_period_lo
|
|
|
- mov a,#$00
|
|
|
- mov [CurrentChDataLo]+y,a
|
|
|
- inc y
|
|
|
- mov [CurrentChDataLo]+y,a
|
|
|
- ret
|
|
|
-
|
|
|
-TickBasedTonePortamento:
|
|
|
- mov y,#ch_effect_data
|
|
|
- mov a,[CurrentChDataLo]+y ;get effect data (tone portamento speed value)
|
|
|
- beq TonePortamentoContinue ;if zero, continue and dont alter period
|
|
|
-
|
|
|
- mov y,#ch_tone_portamento_speed ;save speed
|
|
|
- mov [CurrentChDataLo]+y,a
|
|
|
- mov y,#ch_effect_data ;clear effect data
|
|
|
- mov a,#$00
|
|
|
- mov [CurrentChDataLo]+y,a
|
|
|
-
|
|
|
-TonePortamentoContinue:
|
|
|
- mov y,#ch_current_amiga_period_lo ;get target period, put into tempbuffer1
|
|
|
- mov a,[CurrentChDataLo]+y
|
|
|
- mov TempBuffer1,a
|
|
|
- inc y
|
|
|
- mov a,[CurrentChDataLo]+y
|
|
|
- mov TempBuffer2,a
|
|
|
-
|
|
|
-
|
|
|
- movw ya,TempBuffer1 ;exit if target period is zero (set before if target period has already been reached
|
|
|
- beq TonePortamentoExit
|
|
|
- mov y,#ch_tone_portamento_speed
|
|
|
- mov a,[CurrentChDataLo]+y ;get current speed value (tone portamento speed)
|
|
|
- mov y,#$00 ;clear y
|
|
|
- movw TempBuffer3,ya ;put slide amount into tempbuffer3
|
|
|
-
|
|
|
- mov y,#ch_portamento_slide_dir
|
|
|
- mov a,[CurrentChDataLo]+y
|
|
|
- bne TonePortaSlideDown ;check whether to slide up or down
|
|
|
-
|
|
|
- mov y,#ch_amiga_period_lo ;get current period, put into TempBuffer5
|
|
|
- mov a,[CurrentChDataLo]+y
|
|
|
- mov TempBuffer5,a
|
|
|
- inc y
|
|
|
- mov a,[CurrentChDataLo]+y
|
|
|
- mov TempBuffer6,a
|
|
|
-
|
|
|
- movw ya,TempBuffer5 ;get current period
|
|
|
- subw ya,TempBuffer3 ;substract slidespeed
|
|
|
- cmpw ya,TempBuffer1 ;check for overflow
|
|
|
- bpl TonePortaSlideDone
|
|
|
-
|
|
|
- mov y,#ch_current_amiga_period_lo ;if overflow occured, clear tone porta target period
|
|
|
- mov a,#$00
|
|
|
- mov [CurrentChDataLo]+y,a
|
|
|
- inc y
|
|
|
- mov [CurrentChDataLo]+y,a
|
|
|
- movw ya,TempBuffer1 ;and load target period instead
|
|
|
- bra TonePortaSlideDone
|
|
|
-
|
|
|
-TonePortaSlideDown:
|
|
|
- mov y,#ch_amiga_period_lo ;get current period, put into TempBuffer5
|
|
|
- mov a,[CurrentChDataLo]+y
|
|
|
- mov TempBuffer5,a
|
|
|
- inc y
|
|
|
- mov a,[CurrentChDataLo]+y
|
|
|
- mov TempBuffer6,a
|
|
|
-
|
|
|
- movw ya,TempBuffer5 ;get current period
|
|
|
- addw ya,TempBuffer3 ;substract slidespeed
|
|
|
- cmpw ya,TempBuffer1 ;check for overflow
|
|
|
- bmi TonePortaSlideDone
|
|
|
-
|
|
|
- mov y,#ch_current_amiga_period_lo ;if overflow occured, clear tone porta target period
|
|
|
- mov a,#$00
|
|
|
- mov [CurrentChDataLo]+y,a
|
|
|
- inc y
|
|
|
- mov [CurrentChDataLo]+y,a
|
|
|
- movw ya,TempBuffer1 ;and load target period instead
|
|
|
-; bra TonePortaSlideDone
|
|
|
-
|
|
|
-TonePortaSlideDone:
|
|
|
- movw TempBuffer1,ya ;save newly calculated period to current period buffer
|
|
|
-
|
|
|
- mov y,#ch_amiga_period_lo ;save to current period buffer
|
|
|
- mov a,TempBuffer1
|
|
|
- mov [CurrentChDataLo]+y,a
|
|
|
- inc y
|
|
|
- mov a,TempBuffer2
|
|
|
- mov [CurrentChDataLo]+y,a
|
|
|
-
|
|
|
-;fetch pitch from pitch table. input: period
|
|
|
- movw ya,TempBuffer1
|
|
|
- addw ya,TempBuffer1 ;multiply by 2
|
|
|
- addw ya,PitchTablePointerLo ;add table offset
|
|
|
- movw TempBuffer1,ya ;move adress to pointer
|
|
|
- mov y,#0
|
|
|
-
|
|
|
- mov a,[TempBuffer1]+y ;get lo pitch byte
|
|
|
- mov TempBuffer5,a ;save new pitch
|
|
|
- inc y
|
|
|
- mov a,[TempBuffer1]+y
|
|
|
- mov TempBuffer6,a
|
|
|
-
|
|
|
-
|
|
|
- mov y,#ch_current_pitch_lo ;save to current pitch buffer
|
|
|
- mov a,TempBuffer5
|
|
|
- mov [CurrentChDataLo]+y,a
|
|
|
- inc y
|
|
|
- mov a,TempBuffer6
|
|
|
- mov [CurrentChDataLo]+y,a
|
|
|
- mov a,CurrentChannel
|
|
|
- or a,#$02
|
|
|
- mov $f2,a ;write to dsp
|
|
|
- mov $f3,TempBuffer5
|
|
|
- inc a
|
|
|
- mov $f2,a
|
|
|
- mov $f3,TempBuffer6
|
|
|
- ret
|
|
|
-
|
|
|
-TickBasedVibrato:
|
|
|
- mov y,#ch_effect_data
|
|
|
- mov a,[CurrentChDataLo]+y ;if speed & depth are zero, continue vibrato without updating em.
|
|
|
- beq ContinueVibrato
|
|
|
-
|
|
|
- mov TempBuffer1,a
|
|
|
- mov y,#ch_vibrato_command_buffer ;get vibrato speed & depth buffer
|
|
|
- mov a,[CurrentChDataLo]+y
|
|
|
- mov TempBuffer2,a
|
|
|
- and TempBuffer1,#$0f
|
|
|
- beq VibratoSkipDepthUpdate ;dont update depth if its zero
|
|
|
-
|
|
|
- and TempBuffer2,#$f0 ;update buffer
|
|
|
- or TempBuffer2,TempBuffer1
|
|
|
-
|
|
|
-VibratoSkipDepthUpdate:
|
|
|
- mov y,#ch_effect_data
|
|
|
- mov a,[CurrentChDataLo]+y ;get vibrato speed
|
|
|
- mov TempBuffer1,a
|
|
|
- and TempBuffer1,#$f0
|
|
|
- beq VibratoSkipSpeedUpdate ;dont upgrade speed if its zero
|
|
|
-
|
|
|
- and TempBuffer2,#$0f ;update buffer
|
|
|
- or TempBuffer2,TempBuffer1
|
|
|
-
|
|
|
-VibratoSkipSpeedUpdate:
|
|
|
- mov y,#ch_vibrato_command_buffer
|
|
|
- mov a,TempBuffer2 ;save back updated vibrato speed & depth
|
|
|
- mov [CurrentChDataLo]+y,a
|
|
|
-
|
|
|
-ContinueVibrato:
|
|
|
- mov y,#ch_vibrato_position
|
|
|
- mov a,[CurrentChDataLo]+y
|
|
|
- mov TempBuffer2,a ;get current vibrato position, this is our pointer into the vibrato table
|
|
|
- lsr TempBuffer2
|
|
|
- lsr TempBuffer2
|
|
|
- and TempBuffer2,#$1f ;divide by 4 and limit
|
|
|
- mov y,#ch_vibrato_tremolo_waveform
|
|
|
- mov a,[CurrentChDataLo]+y
|
|
|
- and a,#$03 ;select current waveform
|
|
|
- mov TempBuffer3,a
|
|
|
- beq VibratoSelectSine
|
|
|
-
|
|
|
- asl TempBuffer2 ;multiply table pointer with 8
|
|
|
- asl TempBuffer2
|
|
|
- asl TempBuffer2
|
|
|
- cmp a,#$01
|
|
|
- beq VibratoSelectRampDown
|
|
|
-
|
|
|
- mov TempBuffer3,#$ff ;this is square vibrato
|
|
|
- bra VibratoSelectSet
|
|
|
-
|
|
|
-VibratoSelectRampDown:
|
|
|
- mov y,#ch_vibrato_position
|
|
|
- mov a,[CurrentChDataLo]+y ;get current vibrato position
|
|
|
- bpl VibratoSet
|
|
|
-
|
|
|
- mov TempBuffer3,#$ff
|
|
|
- setc
|
|
|
- sbc TempBuffer3,TempBuffer2
|
|
|
- bra VibratoSelectSet
|
|
|
-
|
|
|
-VibratoSet:
|
|
|
- mov TempBuffer3,TempBuffer2
|
|
|
- bra VibratoSelectSet
|
|
|
-
|
|
|
-VibratoSelectSine:
|
|
|
- mov x,TempBuffer2
|
|
|
- mov a,!VibratoTable+x ;access vibrato table
|
|
|
- mov TempBuffer3,a
|
|
|
-
|
|
|
-VibratoSelectSet:
|
|
|
- mov y,#ch_vibrato_command_buffer
|
|
|
- mov a,[CurrentChDataLo]+y
|
|
|
- and a,#$0f ;get current vibrato depth
|
|
|
- mov y,TempBuffer3
|
|
|
- mul ya ;multiply with selected vibrato position
|
|
|
- movw TempBuffer5,ya
|
|
|
- mov y,#$07
|
|
|
-
|
|
|
-VibratoDivLoop:
|
|
|
- lsr TempBuffer6 ;divide by 128
|
|
|
- ror TempBuffer5
|
|
|
- dbnz y,VibratoDivLoop
|
|
|
-
|
|
|
- mov y,#ch_amiga_period_lo ;get current period
|
|
|
- mov a,[CurrentChDataLo]+y
|
|
|
- mov PitchBufferLo,a
|
|
|
- inc y
|
|
|
- mov a,[CurrentChDataLo]+y
|
|
|
- mov PitchBufferHi,a
|
|
|
- mov y,#ch_vibrato_position
|
|
|
- mov a,[CurrentChDataLo]+y ;get vibrato position
|
|
|
- bmi VibratoPosNegative
|
|
|
-
|
|
|
-
|
|
|
- movw ya,PitchBufferLo
|
|
|
- subw ya,TempBuffer5
|
|
|
- bra VibratoUpdatePitch
|
|
|
-
|
|
|
-VibratoPosNegative:
|
|
|
- movw ya,PitchBufferLo
|
|
|
- addw ya,TempBuffer5
|
|
|
-
|
|
|
-VibratoUpdatePitch:
|
|
|
- movw PitchBufferLo,ya ;this is our new period
|
|
|
- addw ya,PitchBufferLo ;multiply by 2
|
|
|
- addw ya,PitchTablePointerLo ;add table offset
|
|
|
- movw ScratchPad1,ya ;move adress to pointer
|
|
|
- mov y,#0
|
|
|
-
|
|
|
- mov a,[ScratchPad1]+y ;get lo pitch byte
|
|
|
- mov PitchBufferLo,a ;save new pitch
|
|
|
- inc y
|
|
|
- mov a,[ScratchPad1]+y
|
|
|
- mov PitchBufferHi,a
|
|
|
-
|
|
|
-
|
|
|
- mov a,CurrentChannel ;write pitch to dsp
|
|
|
- or a,#$02
|
|
|
- mov $f2,a
|
|
|
- mov $f3,PitchBufferLo
|
|
|
- inc a
|
|
|
- mov $f2,a
|
|
|
- mov $f3,PitchBufferHi
|
|
|
-
|
|
|
-
|
|
|
- mov y,#ch_vibrato_command_buffer
|
|
|
- mov a,[CurrentChDataLo]+y
|
|
|
- lsr a
|
|
|
- lsr a
|
|
|
- and a,#$3c
|
|
|
- mov TempBuffer1,a
|
|
|
- mov y,#ch_vibrato_position
|
|
|
- mov a,[CurrentChDataLo]+y
|
|
|
- clrc
|
|
|
- adc a,TempBuffer1
|
|
|
- mov [CurrentChDataLo]+y,a
|
|
|
- ret
|
|
|
-
|
|
|
-TickBasedTremolo:
|
|
|
- mov y,#ch_effect_data
|
|
|
- mov a,[CurrentChDataLo]+y
|
|
|
- beq TremoloContinue
|
|
|
-
|
|
|
-
|
|
|
- mov TempBuffer1,a
|
|
|
- mov y,#ch_tremolo_command_buffer
|
|
|
- mov a,[CurrentChDataLo]+y
|
|
|
- mov TempBuffer2,a
|
|
|
- and TempBuffer1,#$0f
|
|
|
- beq TremoloNoNewSpeed
|
|
|
-
|
|
|
- and TempBuffer2,#$f0
|
|
|
- or TempBuffer2,TempBuffer1
|
|
|
-
|
|
|
-TremoloNoNewSpeed:
|
|
|
- mov y,#ch_effect_data
|
|
|
- mov a,[CurrentChDataLo]+y
|
|
|
- mov TempBuffer1,a
|
|
|
- and TempBuffer1,#$f0
|
|
|
- beq TremoloNoNewDepth
|
|
|
-
|
|
|
- and TempBuffer2,#$0f
|
|
|
- or TempBuffer2,TempBuffer1
|
|
|
-
|
|
|
-TremoloNoNewDepth:
|
|
|
- mov y,#ch_tremolo_command_buffer
|
|
|
- mov a,TempBuffer2
|
|
|
- mov [CurrentChDataLo]+y,a
|
|
|
-
|
|
|
-TremoloContinue:
|
|
|
- mov y,#ch_tremolo_position
|
|
|
- mov a,[CurrentChDataLo]+y
|
|
|
- mov TempBuffer2,a
|
|
|
- lsr TempBuffer2
|
|
|
- lsr TempBuffer2
|
|
|
- and TempBuffer2,#$1f
|
|
|
- mov y,#ch_vibrato_tremolo_waveform
|
|
|
- mov a,[CurrentChDataLo]+y
|
|
|
- mov TempBuffer3,a
|
|
|
- lsr TempBuffer3
|
|
|
- lsr TempBuffer3
|
|
|
- lsr TempBuffer3
|
|
|
- lsr TempBuffer3
|
|
|
- and TempBuffer3,#$03
|
|
|
- beq TremolWavSel
|
|
|
-
|
|
|
-
|
|
|
- asl TempBuffer2
|
|
|
- asl TempBuffer2
|
|
|
- asl TempBuffer2
|
|
|
- asl TempBuffer2
|
|
|
- cmp TempBuffer3,#$01
|
|
|
- beq TremolWavSel2
|
|
|
-
|
|
|
- mov TempBuffer3,#$ff
|
|
|
- bra TremoloCommit
|
|
|
-
|
|
|
-TremolWavSel2:
|
|
|
- mov y,#ch_vibrato_position
|
|
|
- mov a,[CurrentChDataLo]+y
|
|
|
- bpl TremoloCommit2
|
|
|
-
|
|
|
- mov TempBuffer3,#$ff
|
|
|
- setc
|
|
|
- sbc TempBuffer3,TempBuffer2
|
|
|
- bra TremoloCommit
|
|
|
-
|
|
|
-TremoloCommit2:
|
|
|
- mov TempBuffer3,TempBuffer2
|
|
|
- bra TremoloCommit
|
|
|
-
|
|
|
-TremolWavSel:
|
|
|
- mov x,TempBuffer2
|
|
|
- mov a,!VibratoTable+x ;access table #2
|
|
|
- mov TempBuffer3,a
|
|
|
-
|
|
|
-TremoloCommit:
|
|
|
- mov y,#ch_tremolo_command_buffer
|
|
|
- mov a,[CurrentChDataLo]+y
|
|
|
- and a,#$0f
|
|
|
- mov y,TempBuffer3
|
|
|
- mul ya
|
|
|
- movw TempBuffer5,ya
|
|
|
- mov y,#$06
|
|
|
-
|
|
|
-TremolDivLoop:
|
|
|
- lsr TempBuffer6
|
|
|
- ror TempBuffer5
|
|
|
- dbnz y,TremolDivLoop
|
|
|
-
|
|
|
- mov y,#ch_current_volume
|
|
|
- mov a,[CurrentChDataLo]+y
|
|
|
- mov TempBuffer1,a
|
|
|
- mov y,#ch_tremolo_position
|
|
|
- mov a,[CurrentChDataLo]+y
|
|
|
- bmi TremolPosNeg
|
|
|
-
|
|
|
- clrc
|
|
|
- adc TempBuffer1,TempBuffer5
|
|
|
- bra TremolPosPos
|
|
|
-
|
|
|
-TremolPosNeg:
|
|
|
- setc
|
|
|
- sbc TempBuffer1,TempBuffer5
|
|
|
-
|
|
|
-TremolPosPos:
|
|
|
- bpl TremolPosRes
|
|
|
-
|
|
|
- mov TempBuffer1,#$00
|
|
|
-
|
|
|
-TremolPosRes:
|
|
|
- cmp TempBuffer1,#$40
|
|
|
- bmi TremolPosRes2
|
|
|
-
|
|
|
- mov TempBuffer1,#$40
|
|
|
-
|
|
|
-TremolPosRes2:
|
|
|
- mov a,CurrentChannel
|
|
|
- or a,#$00
|
|
|
- mov $f2,a
|
|
|
- mov $f3,TempBuffer1
|
|
|
- inc a
|
|
|
- mov $f2,a
|
|
|
- mov $f3,TempBuffer1
|
|
|
- mov y,#ch_tremolo_command_buffer
|
|
|
- mov a,[CurrentChDataLo]+y
|
|
|
- lsr a
|
|
|
- lsr a
|
|
|
- and a,#$3c
|
|
|
- mov TempBuffer1,a
|
|
|
- mov y,#ch_tremolo_position
|
|
|
- mov a,[CurrentChDataLo]+y
|
|
|
- clrc
|
|
|
- adc a,TempBuffer1
|
|
|
- mov [CurrentChDataLo]+y,a
|
|
|
- ret
|
|
|
-
|
|
|
-TickbasedVolslide:
|
|
|
- mov y,#ch_effect_data
|
|
|
- mov a,[CurrentChDataLo]+y
|
|
|
- xcn a
|
|
|
- and a,#$0f
|
|
|
- beq TickbasedVolSlideDown
|
|
|
-
|
|
|
- mov TempBuffer1,a
|
|
|
-
|
|
|
-VolSlideUp:
|
|
|
- mov y,#ch_current_volume
|
|
|
- mov a,[CurrentChDataLo]+y
|
|
|
- adc a,TempBuffer1
|
|
|
- cmp a,#$40
|
|
|
- bmi VolSlideUpNoWaveformReset
|
|
|
-
|
|
|
- mov a,#$40
|
|
|
-
|
|
|
-VolSlideUpNoWaveformReset:
|
|
|
- mov [CurrentChDataLo]+y,a
|
|
|
- mov CurrentVolume,a
|
|
|
-
|
|
|
- call !SetVolumeVibrato
|
|
|
-
|
|
|
- ret
|
|
|
-
|
|
|
-TickbasedVolSlideDown:
|
|
|
- mov y,#ch_effect_data
|
|
|
- mov a,[CurrentChDataLo]+y
|
|
|
- and a,#$0f
|
|
|
- mov TempBuffer1,a
|
|
|
-
|
|
|
-VolSlideDown:
|
|
|
- mov y,#ch_current_volume
|
|
|
- mov a,[CurrentChDataLo]+y
|
|
|
- sbc a,TempBuffer1
|
|
|
- bpl VolSlideDownNoReset
|
|
|
-
|
|
|
- mov a,#$00
|
|
|
-
|
|
|
-VolSlideDownNoReset:
|
|
|
- mov [CurrentChDataLo]+y,a
|
|
|
- mov CurrentVolume,a
|
|
|
- call !SetVolumeVibrato
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- ret
|
|
|
-
|
|
|
-SetSpeed0x0F:
|
|
|
- mov y,#ch_effect_data
|
|
|
- mov a,[CurrentChDataLo]+y
|
|
|
- mov PatternSpeed,a ;self-modifying code
|
|
|
- dec a
|
|
|
- mov NextRowChFadeOutTime,a
|
|
|
- ret
|
|
|
-
|
|
|
-SetSampleOffset:
|
|
|
- mov y,#ch_effect_data
|
|
|
- mov a,[CurrentChDataLo]+y
|
|
|
- mov x,a
|
|
|
- mov a,#0
|
|
|
- mov y,#0
|
|
|
- mov TempBuffer3,#$90 ;512/16*9=288, $120
|
|
|
- mov TempBuffer4,#$00
|
|
|
-
|
|
|
-SetSampleOffsetCalcLoop:
|
|
|
- cmp x,#0
|
|
|
- beq SetSampleOffsetCalcLoopDone
|
|
|
-
|
|
|
- addw ya,TempBuffer3
|
|
|
- dec x
|
|
|
- bra SetSampleOffsetCalcLoop
|
|
|
-
|
|
|
-SetSampleOffsetCalcLoopDone:
|
|
|
- movw TempBuffer1,ya
|
|
|
-
|
|
|
- mov y,#ch_instrument
|
|
|
- mov a,[CurrentChDataLo]+y
|
|
|
- asl a
|
|
|
- asl a
|
|
|
- mov x,a
|
|
|
- mov a,!SampleSource+x ;create a new sample (#3f) that plays with the modified start position
|
|
|
- mov TempBuffer5,a
|
|
|
- mov !(SampleSource+(ExtSample*4)),a
|
|
|
- mov a,!(SampleSource+1)+x
|
|
|
- mov TempBuffer6,a
|
|
|
- mov !(SampleSource+1+(ExtSample*4)),a
|
|
|
- mov a,!(SampleSource+2)+x
|
|
|
- mov !(SampleSource+2+(ExtSample*4)),a
|
|
|
- mov a,!(SampleSource+3)+x
|
|
|
- mov !(SampleSource+3+(ExtSample*4)),a
|
|
|
- movw ya,TempBuffer5
|
|
|
- addw ya,TempBuffer1
|
|
|
- movw TempBuffer5,ya
|
|
|
- mov a,TempBuffer5
|
|
|
- mov !(SampleSource+(ExtSample*4)),a
|
|
|
- mov a,TempBuffer6
|
|
|
- mov !(SampleSource+1+(ExtSample*4)),a
|
|
|
- mov a,CurrentChannel
|
|
|
- or a,#$04
|
|
|
- mov $f2,a
|
|
|
- mov $f3,#ExtSample
|
|
|
- ret
|
|
|
-
|
|
|
-PositionJump:
|
|
|
- mov y,#ch_effect_data
|
|
|
- mov a,[CurrentChDataLo]+y
|
|
|
- mov CurrentPatternNumber,a
|
|
|
- mov x,a
|
|
|
- mov a,!(ModFile+$fa)+x
|
|
|
- asl a
|
|
|
- mov x,a
|
|
|
- mov a,!(ModFile+$17a)+x
|
|
|
- mov y,a
|
|
|
- mov a,!(ModFile+$17b)+x
|
|
|
- addw ya,InitPatternPointerLo
|
|
|
- movw CurrentPatternPointerLo,ya
|
|
|
- pop a ;need to purge the stack a bit first
|
|
|
- pop a ;else, it would overflow slowly when using the pattern break command constantly
|
|
|
- pop a
|
|
|
- pop a
|
|
|
- pop a
|
|
|
- pop a
|
|
|
-
|
|
|
- jmp !MainLoop
|
|
|
-
|
|
|
-
|
|
|
-;set channel volume:
|
|
|
-EffectSetVolume:
|
|
|
- mov y,#ch_effect_data
|
|
|
- mov a,[CurrentChDataLo]+y
|
|
|
-
|
|
|
-
|
|
|
- mov y,#ch_current_volume
|
|
|
- mov [CurrentChDataLo]+y,a
|
|
|
-
|
|
|
- mov CurrentVolume,a
|
|
|
- call !SetVolume
|
|
|
- ret
|
|
|
-
|
|
|
-PatternBreak:
|
|
|
- mov y,#ch_effect_data
|
|
|
- mov a,[CurrentChDataLo]+y ;get break row.
|
|
|
- bne PatternBreakZero ;only breaks to row #0 of next pattern are supported. else dont do anything
|
|
|
-
|
|
|
- mov PatternBreakFlag,#1 ;set break flag. the actual break gets executed after the current row has been completely processed
|
|
|
-PatternBreakZero:
|
|
|
- ret
|
|
|
-
|
|
|
-
|
|
|
-ExEffectSpecialReportCmd:
|
|
|
- inc SpecialReportCmd ;increase special cmd counter.
|
|
|
- ret
|
|
|
-
|
|
|
-SetVibratoWaveform:
|
|
|
- mov y,#ch_effect_data
|
|
|
- mov a,[CurrentChDataLo]+y
|
|
|
- and a,#$0f
|
|
|
- mov TempBuffer1,a
|
|
|
- mov y,#ch_vibrato_tremolo_waveform ;update vibrato waveform
|
|
|
- mov a,[CurrentChDataLo]+y
|
|
|
- and a,#$f0
|
|
|
- or a,TempBuffer1
|
|
|
- mov [CurrentChDataLo]+y,a
|
|
|
- ret
|
|
|
-
|
|
|
-Finetune:
|
|
|
- mov y,#ch_effect_data
|
|
|
- mov a,[CurrentChDataLo]+y
|
|
|
- and a,#$0f
|
|
|
- mov y,#ch_finetune ;whats written to chdata $04 here?
|
|
|
- mov [CurrentChDataLo]+y,a
|
|
|
- ret
|
|
|
-
|
|
|
-FineVolSlideUp:
|
|
|
- mov a,WaitCounter
|
|
|
- bne FineVolSlideUpCancel
|
|
|
-
|
|
|
- mov y,#ch_effect_data
|
|
|
- mov a,[CurrentChDataLo]+y
|
|
|
- and a,#$0f
|
|
|
- mov TempBuffer1,a
|
|
|
- jmp !VolSlideUp
|
|
|
-
|
|
|
-FineVolSlideUpCancel:
|
|
|
- ret
|
|
|
-
|
|
|
-FineVolSlideDown:
|
|
|
- mov a,WaitCounter
|
|
|
- bne FineVolSlideDownCancel
|
|
|
-
|
|
|
- mov y,#ch_effect_data
|
|
|
- mov a,[CurrentChDataLo]+y
|
|
|
- and a,#$0f
|
|
|
- mov TempBuffer1,a
|
|
|
- jmp !VolSlideDown
|
|
|
-
|
|
|
-FineVolSlideDownCancel:
|
|
|
- ret
|
|
|
-
|
|
|
-InitVariables:
|
|
|
- mov WaitCounter,#$00
|
|
|
- mov a,#$06
|
|
|
- mov PatternSpeed,a ;self-modifying code
|
|
|
- dec a
|
|
|
- mov NextRowChFadeOutTime,a
|
|
|
- mov LoopCounter,#0
|
|
|
- mov CurrentPatternNumber,#$00
|
|
|
- mov PortamentoSpeedMask,#$ff
|
|
|
- mov a,!(ModFile+$f8) ;$13d3
|
|
|
- mov NumberOfPatterns,a
|
|
|
- mov TempBuffer1,#$fc ;initial relative adress of pattern tables
|
|
|
- mov TempBuffer2,#$01
|
|
|
- movw ya,ModFilePointerLo
|
|
|
- movw ModFilePointer2Lo,ya
|
|
|
- addw ya,TempBuffer1
|
|
|
- movw CurrentPatternPointerLo,ya
|
|
|
- movw InitPatternPointerLo,ya
|
|
|
- movw CurrentLoopPointerLo,ya
|
|
|
- mov a,!(ModFile+$fa) ;load initial pattern.
|
|
|
- asl a
|
|
|
- mov x,a
|
|
|
- mov a,!(ModFile+$17a)+x ;get pointer to pattern
|
|
|
- mov y,a
|
|
|
- mov a,!(ModFile+$17b)+x
|
|
|
- addw ya,InitPatternPointerLo
|
|
|
- movw CurrentPatternPointerLo,ya
|
|
|
-
|
|
|
- mov a,#(PeriodTable & $00ff) ;set pointer to amiga period table
|
|
|
- mov PeriodTablePointerLo,a
|
|
|
- mov a,#(PeriodTable >> 8)
|
|
|
- mov PeriodTablePointerHi,a
|
|
|
-
|
|
|
- mov a,#(PitchTable & $00ff) ;set pointer to snes pitch table
|
|
|
- mov PitchTablePointerLo,a
|
|
|
- mov a,#(PitchTable >> 8)
|
|
|
- mov PitchTablePointerHi,a
|
|
|
- mov PatternBreakFlag,#0
|
|
|
-
|
|
|
- mov SpecialReportCmd,#0
|
|
|
-
|
|
|
- ret
|
|
|
-
|
|
|
-PortamentoDownLimit:
|
|
|
- .dw $01e3
|
|
|
-
|
|
|
-;set reset some dsp registers:
|
|
|
-SetupDspRegsAndTimers:
|
|
|
- mov $f1,#$00 ;stop timers
|
|
|
- mov a,$fd ;clear 4bit counters
|
|
|
- mov a,$fe ;clear 4bit counters
|
|
|
- mov a,$ff ;clear 4bit counters
|
|
|
- mov SongChannelMask,#$0f ;enable all 4 mod channels
|
|
|
- mov ModPlayerTimer0,#$a0
|
|
|
- mov $fa,ModPlayerTimer0 ;20 milliSeconds on timer 0
|
|
|
- mov $fb,#$10 ;2 milliSeconds on timer 1
|
|
|
-
|
|
|
- nop
|
|
|
- nop
|
|
|
- mov $f1,#$03 ;start timer(s)
|
|
|
-
|
|
|
- mov a,#$00 ;clear all dsp regs
|
|
|
- mov x,a
|
|
|
-
|
|
|
-DspRegClearLoop:
|
|
|
- cmp x,#$6c
|
|
|
- bne DspRegClearLoopEchoSkip
|
|
|
-
|
|
|
- mov $f2,x ;disable echo
|
|
|
- mov $f3,#$20
|
|
|
- inc x
|
|
|
-
|
|
|
-DspRegClearLoopEchoSkip:
|
|
|
- mov $f2,x
|
|
|
- mov $f3,a
|
|
|
- inc x
|
|
|
- bpl DspRegClearLoop
|
|
|
-
|
|
|
- mov $f2,#$5d ;setup dsp regs
|
|
|
- mov $f3,#(SampleSource >> 8) ;this is the sample info loaction (dir)
|
|
|
- mov $f2,#$6c
|
|
|
- mov $f3,#$20
|
|
|
- mov $f2,#$0c ;set master volume
|
|
|
- mov $f3,MainVolL
|
|
|
- mov $f2,#$1c
|
|
|
- mov $f3,MainVolR
|
|
|
- mov $f2,#$3d
|
|
|
- mov $f3,#$00
|
|
|
- mov $f2,#$7c
|
|
|
- mov $f3,a
|
|
|
-;setup echo stuff:
|
|
|
-
|
|
|
-;set filter:
|
|
|
- mov $f2,#$0f ;fir
|
|
|
- mov $f3,#$30
|
|
|
- mov $f2,#$1f ;fir
|
|
|
- mov $f3,#$00
|
|
|
- mov $f2,#$2f ;fir
|
|
|
- mov $f3,#$00
|
|
|
- mov $f2,#$3f ;fir
|
|
|
- mov $f3,#$00
|
|
|
- mov $f2,#$4f ;fir
|
|
|
- mov $f3,#$00
|
|
|
- mov $f2,#$5f ;fir
|
|
|
- mov $f3,#$00
|
|
|
- mov $f2,#$6f ;fir
|
|
|
- mov $f3,#$20
|
|
|
- mov $f2,#$7f ;fir
|
|
|
- mov $f3,#$30
|
|
|
-
|
|
|
-
|
|
|
-;setup adsr on channels 1-4:
|
|
|
- mov a,CurrentChannel
|
|
|
- push a
|
|
|
- mov CurrentChannel,#$00 ;channel 1
|
|
|
- call !SetupAdsr
|
|
|
- mov CurrentChannel,#$10 ;channel 2
|
|
|
- call !SetupAdsr
|
|
|
- mov CurrentChannel,#$20 ;channel 3
|
|
|
- call !SetupAdsr
|
|
|
- mov CurrentChannel,#$30 ;channel 4
|
|
|
- call !SetupAdsr
|
|
|
-
|
|
|
- pop a
|
|
|
-
|
|
|
-
|
|
|
- ret
|
|
|
-
|
|
|
-SetupAdsr:
|
|
|
- mov a,#$05 ;dsp reg $x5 (adsr1)
|
|
|
- or a,CurrentChannel ;or with channel number
|
|
|
- mov x,a
|
|
|
-
|
|
|
- mov $f2,x ;set adsr 1 (winter gold example: $dc) new value: $cb (slower attack an decay)
|
|
|
- mov $f3,#$0e ;old #$0c
|
|
|
- inc x
|
|
|
- mov $f2,x ;set adsr 2 (winter gold example: $2d) new value: $36 (longer release)
|
|
|
- mov $f3,#$2d ;old #$2d
|
|
|
- inc x
|
|
|
-
|
|
|
- mov a,x
|
|
|
- and a,#$f0 ;only get channel, not register
|
|
|
- mov x,a
|
|
|
- mov a,#$40
|
|
|
- ret
|
|
|
-
|
|
|
-
|
|
|
-SetupSamples:
|
|
|
- mov x,#$00
|
|
|
- mov y,#$00
|
|
|
-
|
|
|
-SetupSamplesLoop:
|
|
|
- inc y
|
|
|
- mov a,[ModFilePointerLo]+y ;get sample relative adress low
|
|
|
- dec y
|
|
|
- clrc
|
|
|
- adc a,ModFilePointerLo ;add modfile position
|
|
|
- mov !(SampleSource+4)+x,a ;store in dsp sample area
|
|
|
- mov a,[ModFilePointerLo]+y ;get sample relative adress hi
|
|
|
- adc a,ModFilePointerHi ;add modfile position, with carry from previous add
|
|
|
- mov !(SampleSource+5)+x,a ;store in dsp sample area
|
|
|
- inc y
|
|
|
- inc y
|
|
|
- inc y
|
|
|
- inc y
|
|
|
-;repeat the same with loop adress:
|
|
|
- inc y
|
|
|
- mov a,[ModFilePointerLo]+y ;get sample relative adress low
|
|
|
- dec y
|
|
|
- clrc
|
|
|
- adc a,ModFilePointerLo ;add modfile position
|
|
|
- mov !(SampleSource+6)+x,a ;store in dsp sample area
|
|
|
- mov a,[ModFilePointerLo]+y ;get sample relative adress hi
|
|
|
- adc a,ModFilePointerHi ;add modfile position, with carry from previous add
|
|
|
- mov !(SampleSource+7)+x,a ;store in dsp sample area
|
|
|
- inc y
|
|
|
- inc y
|
|
|
- inc y
|
|
|
- inc y
|
|
|
- inc x
|
|
|
- inc x
|
|
|
- inc x
|
|
|
- inc x
|
|
|
- cmp x,#$7c
|
|
|
- bne SetupSamplesLoop
|
|
|
-
|
|
|
- ret
|
|
|
-
|
|
|
-;old:
|
|
|
- clrc
|
|
|
- mov a,!(ModFile+1)+x ;get sample location $12dc
|
|
|
- adc a,#(ModFile & $00ff) ;add #$12db
|
|
|
- mov !(SampleSource+4)+y,a ;store in dsp sample area
|
|
|
- mov a,!ModFile+x
|
|
|
- adc a,#(ModFile >> 8)
|
|
|
- mov !(SampleSource+5)+y,a
|
|
|
- inc x
|
|
|
- inc x
|
|
|
- inc x
|
|
|
- inc x
|
|
|
- clrc
|
|
|
- mov a,!(ModFile+1)+x
|
|
|
- adc a,#(ModFile & $00ff)
|
|
|
- mov !(SampleSource+6)+y,a
|
|
|
- mov a,!ModFile+x
|
|
|
- adc a,#(ModFile >> 8)
|
|
|
- mov !(SampleSource+7)+y,a
|
|
|
- inc x
|
|
|
- inc x
|
|
|
- inc x
|
|
|
- inc x
|
|
|
- inc y
|
|
|
- inc y
|
|
|
- inc y
|
|
|
- inc y
|
|
|
- cmp y,#$7c
|
|
|
- bne SetupSamplesLoop
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- ret
|
|
|
-
|
|
|
-;setup stream sample adress, sample #33
|
|
|
-
|
|
|
-SetupStreamSampleAdress:
|
|
|
- mov a,#SpcStreamSampleNumber ;get number of sample to use
|
|
|
- asl a ;multiply by 4
|
|
|
- asl a
|
|
|
- mov y,a ;pointer into sample source table
|
|
|
-
|
|
|
- mov a,#(StreamBuffer & $00ff) ;get 1st stream buffer adress
|
|
|
- mov !(SampleSource)+y,a ;store in dsp sample area
|
|
|
- mov !(SampleSource+2)+y,a
|
|
|
- mov a,#(StreamBuffer >> 8)
|
|
|
- mov !(SampleSource+1)+y,a
|
|
|
- mov !(SampleSource+3)+y,a
|
|
|
- ret
|
|
|
-
|
|
|
-KeyOnKeyOff:
|
|
|
- mov y,#0
|
|
|
- mov a,#$5c
|
|
|
- movw $f2,ya
|
|
|
- mov $f2,#$4c
|
|
|
- mov a,KeyOn
|
|
|
- and a,SongChannelMask
|
|
|
- mov $f3,a
|
|
|
- ret
|
|
|
-
|
|
|
-CutOffChannelGain:
|
|
|
- mov a,#$07 ;select GAIN dsp reg
|
|
|
- or a,CurrentChannel ;
|
|
|
- mov $f2,a ;set gain (winter gold example: $3d)
|
|
|
- mov $f3,#%10011111 ;decrease volume, 8mS ;old #%10111111
|
|
|
- mov y,#ch_current_volume
|
|
|
- mov a,#0 ;clear volume
|
|
|
- mov [CurrentChDataLo]+y,a
|
|
|
- ret ;return
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-SetVolumeVibrato:
|
|
|
-;set channel mod volume
|
|
|
- mov a,#$07 ;select GAIN dsp reg
|
|
|
- or a,CurrentChannel ;
|
|
|
- mov $f2,a ;set gain
|
|
|
- mov a,CurrentVolume
|
|
|
- and a,#$7f ;set direct gain mode
|
|
|
- mov $f3,a
|
|
|
-
|
|
|
-;set channel global volume
|
|
|
- mov a,CurrentChannel ;check active channel
|
|
|
- cmp a,#0
|
|
|
- beq SetVolumeLeftCh
|
|
|
- cmp a,#$20
|
|
|
- beq SetVolumeLeftCh
|
|
|
-
|
|
|
- mov y,MusicVol1
|
|
|
- movw $f2,ya
|
|
|
- inc a
|
|
|
- mov y,MusicVol2
|
|
|
- movw $f2,ya
|
|
|
- ret
|
|
|
-
|
|
|
-
|
|
|
-SetVolume:
|
|
|
-;set channel mod volume
|
|
|
- mov a,#$07 ;select GAIN dsp reg
|
|
|
- or a,CurrentChannel ;
|
|
|
- mov $f2,a ;set gain
|
|
|
- mov y,#ch_current_volume
|
|
|
- mov a,[CurrentChDataLo]+y
|
|
|
- and a,#$7f ;set direct gain mode
|
|
|
- mov $f3,a
|
|
|
-
|
|
|
-;set channel global volume
|
|
|
- mov a,CurrentChannel ;check active channel
|
|
|
- cmp a,#0
|
|
|
- beq SetVolumeLeftCh
|
|
|
- cmp a,#$20
|
|
|
- beq SetVolumeLeftCh
|
|
|
-
|
|
|
- mov y,MusicVol1
|
|
|
- movw $f2,ya
|
|
|
- inc a
|
|
|
- mov y,MusicVol2
|
|
|
- movw $f2,ya
|
|
|
- ret
|
|
|
-
|
|
|
-
|
|
|
-SetVolumeLeftCh:
|
|
|
- mov y,MusicVol2
|
|
|
- movw $f2,ya
|
|
|
- inc a
|
|
|
- mov y,MusicVol1
|
|
|
- movw $f2,ya
|
|
|
- ret
|
|
|
-
|
|
|
- mov a,CurrentChannel ;save current volume
|
|
|
- mov $f2,a
|
|
|
- mov a,$f3
|
|
|
- mov TempVol,a
|
|
|
-
|
|
|
-SetVolumeLoop:
|
|
|
- cmp CurrentVolume,TempVol ;check if bigger or smaller
|
|
|
- beq SetVolumeExit
|
|
|
- bmi SetVolumeDec ;branch if old value is bigger than new
|
|
|
-
|
|
|
- inc TempVol
|
|
|
- mov a,CurrentChannel ;check active channel
|
|
|
- mov y,TempVol
|
|
|
- movw $f2,ya
|
|
|
- inc a
|
|
|
- movw $f2,ya
|
|
|
-
|
|
|
- bra SetVolumeLoop
|
|
|
-
|
|
|
-SetVolumeDec:
|
|
|
- dec TempVol
|
|
|
- mov a,CurrentChannel ;check active channel
|
|
|
- mov y,TempVol
|
|
|
- movw $f2,ya
|
|
|
- inc a
|
|
|
- movw $f2,ya
|
|
|
- bra SetVolumeLoop
|
|
|
-
|
|
|
-
|
|
|
-SetVolumeExit:
|
|
|
-
|
|
|
- ret
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-PreTestRow:
|
|
|
- mov y,#$00
|
|
|
- mov NextRowChFadeOuts,#$00
|
|
|
- mov CurrentChannel,#$01
|
|
|
- call !PreTestChannel
|
|
|
- mov CurrentChannel,#$02
|
|
|
- call !PreTestChannel
|
|
|
- mov CurrentChannel,#$04
|
|
|
- call !PreTestChannel
|
|
|
- mov CurrentChannel,#$08
|
|
|
- jmp !PreTestChannel
|
|
|
-
|
|
|
-
|
|
|
-PreTestChannel:
|
|
|
- mov a,[CurrentPatternPointerLo]+y
|
|
|
- cmp a,#$00
|
|
|
- beq PreTestChannelIsEffectOnly
|
|
|
- cmp a,#$ff ;compare if channel entry is $ff(skip)
|
|
|
- beq PreTestChannelIsVoid
|
|
|
-
|
|
|
- inc y ;check if a period is present
|
|
|
- mov a,[CurrentPatternPointerLo]+y
|
|
|
- cmp a,#$ff
|
|
|
- beq PreTestChannelIsEffectOnly2
|
|
|
-
|
|
|
- inc y
|
|
|
- mov a,[CurrentPatternPointerLo]+y
|
|
|
- cmp a,#3 ;check if tone portamento (which doesnt actually play a new note, so the old one must not be muted)
|
|
|
- beq PreTestChannelIsEffectOnly3
|
|
|
-
|
|
|
- and a,#$0f
|
|
|
- mov TempBuffer1,a
|
|
|
- inc y
|
|
|
- mov a,[CurrentPatternPointerLo]+y
|
|
|
- dec y
|
|
|
- and a,#$f0
|
|
|
- or a,TempBuffer1
|
|
|
- cmp a,#$de ;delay sample effect present? if yes, don't trigger sample
|
|
|
- beq PreTestChannelIsEffectOnly3
|
|
|
-
|
|
|
- mov a,NextRowChFadeOuts
|
|
|
- or a,CurrentChannel ;if theres a note in the next row on this channel, set flag to fade it out before the next row gets processed
|
|
|
- mov NextRowChFadeOuts,a
|
|
|
- bra PreTestChannelIsEffectOnly3
|
|
|
-
|
|
|
-PreTestChannelIsEffectOnly:
|
|
|
- inc y ;if theres a note, the pattern data entry is 4 bytes long
|
|
|
-PreTestChannelIsEffectOnly2:
|
|
|
- inc y
|
|
|
-PreTestChannelIsEffectOnly3:
|
|
|
- inc y
|
|
|
-
|
|
|
-PreTestChannelIsVoid:
|
|
|
- inc y
|
|
|
- ret
|
|
|
-
|
|
|
-
|
|
|
-PatternLoop:
|
|
|
-;get effect value
|
|
|
- mov y,#ch_effect_data
|
|
|
- mov a,[CurrentChDataLo]+y ;get current effect value
|
|
|
- and a,#$0f ;and $0f
|
|
|
- bne PatternLoopDontSetLoopPoint
|
|
|
-
|
|
|
-;effect value is 0, set loop point:
|
|
|
- movw ya,CurrentRowPointerLo
|
|
|
- movw CurrentLoopPointerLo,ya
|
|
|
- ret
|
|
|
-
|
|
|
-;effect value is not 0, check if we are in an active loop
|
|
|
-PatternLoopDontSetLoopPoint:
|
|
|
- mov a,LoopCounter ;check if loop is in progress, must be reset by loop jumper after loop repeat has been finished.
|
|
|
- and a,#$20
|
|
|
- bne PatternLoopDontSetLoopPointButLoop
|
|
|
-;we arent in a loop, set loop count:
|
|
|
- mov y,#ch_effect_data
|
|
|
- mov a,[CurrentChDataLo]+y ;get current effect value
|
|
|
- and a,#$0f ;and $0f
|
|
|
- or a,#$30 ;set "in loop"-flag and "do jump"-flag
|
|
|
- mov LoopCounter,a
|
|
|
- ret
|
|
|
-
|
|
|
-PatternLoopDontSetLoopPointButLoop:
|
|
|
-;we are in a loop, just jump:
|
|
|
- mov a,LoopCounter
|
|
|
- and a,#$0f
|
|
|
- dec a
|
|
|
- mov LoopCounter,a
|
|
|
- beq PatternLoopFinished
|
|
|
-
|
|
|
-;do another loop jump
|
|
|
- or LoopCounter,#$30
|
|
|
-
|
|
|
-PatternLoopFinished:
|
|
|
- ret
|
|
|
-
|
|
|
-
|
|
|
-PatternLoopJumper:
|
|
|
- mov a,LoopCounter
|
|
|
- and a,#%00010000
|
|
|
- beq PatternLoopJumperNoJump
|
|
|
-
|
|
|
- movw ya,CurrentLoopPointerLo
|
|
|
- movw CurrentPatternPointerLo,ya
|
|
|
- mov a,LoopCounter
|
|
|
- and a,#%11101111
|
|
|
- mov LoopCounter,a
|
|
|
-
|
|
|
-PatternLoopJumperNoJump:
|
|
|
- ret
|
|
|
-
|
|
|
-EffectNoteRetrigger:
|
|
|
-EffectNoteDelay:
|
|
|
-EffectNoteCutOff:
|
|
|
- mov y,#ch_effect_data
|
|
|
- mov a,[CurrentChDataLo]+y ;get current effect value
|
|
|
- and a,#$0f ;and $0f
|
|
|
- beq EffectNoteCutOffImmediately
|
|
|
-
|
|
|
- dec a
|
|
|
-
|
|
|
-EffectNoteCutOffImmediately:
|
|
|
- mov y,#ch_tick_delay
|
|
|
- mov [CurrentChDataLo]+y,a ;write to buffer
|
|
|
- ret
|
|
|
-
|
|
|
-TickBasedExEffectNoteCutOff:
|
|
|
- mov y,#ch_tick_delay
|
|
|
- mov a,[CurrentChDataLo]+y
|
|
|
- and a,#$0f
|
|
|
- bne CheckForTickBasedEffectsNoteCutOffDec
|
|
|
-
|
|
|
-
|
|
|
- mov [CurrentChDataLo]+y,a
|
|
|
- call !CutOffChannelGain
|
|
|
-
|
|
|
- mov y,#ch_current_channelmask
|
|
|
- mov a,[CurrentChDataLo]+y ;disable channel in keyon reg
|
|
|
- eor a,#$ff
|
|
|
- mov ScratchPad1,a
|
|
|
- and KeyOn,ScratchPad1
|
|
|
-
|
|
|
- mov CurrentVolume,#$00
|
|
|
- call !SetVolume
|
|
|
-
|
|
|
- mov y,#ch_effect_data ;clear effect data so this routine isnt triggered on successive ticks of this frame
|
|
|
- mov a,#0
|
|
|
- mov [CurrentChDataLo]+y,a
|
|
|
-
|
|
|
- ret
|
|
|
-
|
|
|
-
|
|
|
-CheckForTickBasedEffectsNoteCutOffDec:
|
|
|
- dec a
|
|
|
- mov [CurrentChDataLo]+y,a
|
|
|
-
|
|
|
-;CheckForTickBasedEffectsNoNoteCutOff:
|
|
|
- ret
|
|
|
-
|
|
|
-TickBasedExEffectNoteRetrigger:
|
|
|
-TickBasedExEffectNoteDelay:
|
|
|
- mov y,#ch_tick_delay
|
|
|
- mov a,[CurrentChDataLo]+y
|
|
|
- and a,#$0f
|
|
|
- bne CheckForTickBasedEffectsNoteDelayDec
|
|
|
-
|
|
|
- call !SetNewSample
|
|
|
-
|
|
|
- mov y,#ch_current_channelmask
|
|
|
- mov a,[CurrentChDataLo]+y ;enable channel in keyon reg
|
|
|
- or a,TickSampleStart
|
|
|
- mov TickSampleStart,a
|
|
|
-
|
|
|
- mov y,#ch_effect_data ;clear effect data so this routine isnt triggered on successive ticks of this frame
|
|
|
- mov a,#0
|
|
|
- mov [CurrentChDataLo]+y,a
|
|
|
- ret
|
|
|
-
|
|
|
-CheckForTickBasedEffectsNoteDelayDec:
|
|
|
- dec a
|
|
|
- mov [CurrentChDataLo]+y,a
|
|
|
- ret
|
|
|
-
|
|
|
-SetEchoAndVolume:
|
|
|
- mov $f2,#$2c ;echo volume l
|
|
|
- mov $f3,#$00 ;0d
|
|
|
- mov $f2,#$3c ;echo volume r
|
|
|
- mov $f3,#$00 ;0d
|
|
|
- mov $f2,#$4d ;echo channel enable
|
|
|
- mov $f3,#$00 ;ff
|
|
|
- ret
|
|
|
-
|
|
|
-ReceiveSongHandler:
|
|
|
- mov $f2,#$0c
|
|
|
- mov $f3,#$00
|
|
|
- mov $f2,#$1c
|
|
|
- mov $f3,#$00
|
|
|
- mov $f2,#$2c
|
|
|
- mov $f3,#$00
|
|
|
- mov $f2,#$3c
|
|
|
- mov $f3,#$00
|
|
|
- mov $f2,#$6c ;disable echo
|
|
|
- mov $f3,#$20
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- mov a,#SpcCmdUploadSong ;set "upload song command received"-flag so cpu knows we're ready
|
|
|
- mov $f4,a
|
|
|
- mov a,#$00 ;clear remaining ports
|
|
|
- mov $f5,a
|
|
|
- mov $f6,a
|
|
|
- mov $f7,a
|
|
|
-
|
|
|
- mov SpcDataPointerLo,#(ModFile & $00ff) ;setup mod pointer
|
|
|
- mov SpcDataPointerHi,#(ModFile >> 8)
|
|
|
- mov ModFilePointerLo,#(ModFile & $00ff) ;setup mod pointer
|
|
|
- mov ModFilePointerHi,#(ModFile >> 8)
|
|
|
-
|
|
|
- mov y,#$00 ;clear mod pointer counter(actually, this counter always stays 0,just needed for indirect write)
|
|
|
-
|
|
|
-ReceiveSongWaitLoop2: ;wait for first transfer
|
|
|
- cmp $f4,#SpcCmdUploadSongDone
|
|
|
- beq ReceiveSongComplete ;check if upload complete
|
|
|
-
|
|
|
- cmp $f4,#SpcCmdUploadSongT1 ;check if data for transfer 1 is stable and on ports
|
|
|
- bne ReceiveSongWaitLoop2
|
|
|
-
|
|
|
- mov a,$f5 ;get byte
|
|
|
- mov [SpcDataPointerLo]+y,a
|
|
|
- incw SpcDataPointerLo ;increment counter, word
|
|
|
- mov a,$f6 ;get byte
|
|
|
- mov [SpcDataPointerLo]+y,a
|
|
|
- incw SpcDataPointerLo ;increment counter, word
|
|
|
- mov a,$f7 ;get byte
|
|
|
- mov [SpcDataPointerLo]+y,a
|
|
|
- incw SpcDataPointerLo ;increment counter, word
|
|
|
-
|
|
|
- mov $f4,#SpcCmdUploadSongT1
|
|
|
-
|
|
|
-ReceiveSongWaitLoop3: ;wait for second transfer
|
|
|
- cmp $f4,#SpcCmdUploadSongT2
|
|
|
- bne ReceiveSongWaitLoop3
|
|
|
-
|
|
|
- mov a,$f5 ;get byte
|
|
|
- mov [SpcDataPointerLo]+y,a
|
|
|
- incw SpcDataPointerLo ;increment counter, word
|
|
|
- mov a,$f6 ;get byte
|
|
|
- mov [SpcDataPointerLo]+y,a
|
|
|
- incw SpcDataPointerLo ;increment counter, word
|
|
|
- mov a,$f7 ;get byte
|
|
|
- mov [SpcDataPointerLo]+y,a
|
|
|
- incw SpcDataPointerLo ;increment counter, word
|
|
|
-
|
|
|
- mov $f4,#SpcCmdUploadSongT2
|
|
|
- bra ReceiveSongWaitLoop2
|
|
|
-
|
|
|
-ReceiveSongComplete:
|
|
|
- mov a,#$00 ;clear apu ports so that cpu knows were ready
|
|
|
- mov $f4,a
|
|
|
- mov $f5,a
|
|
|
- mov $f6,a
|
|
|
- mov $f7,a
|
|
|
-
|
|
|
- mov ModTimecode,#0 ;clear Timecode
|
|
|
- mov ModTimecode+1,#0
|
|
|
-
|
|
|
- mov SongEffectsUploaded,#%00000001 ;set "song uploaded" flag, clear "sample pack uploaded" flag
|
|
|
- ret
|
|
|
-
|
|
|
-ReceiveSamplePack:
|
|
|
- mov a,#SpcCmdUploadSamplePack ;set "upload song command received"-flag so cpu knows we're ready
|
|
|
- mov $f4,a
|
|
|
- mov a,#$00 ;clear remaining ports
|
|
|
- mov $f5,a
|
|
|
- mov $f6,a
|
|
|
- mov $f7,a
|
|
|
-
|
|
|
- mov $f2,#$5c ;key off all channels
|
|
|
- mov $f3,#%11111111
|
|
|
-
|
|
|
- movw ya,SpcDataPointerLo ;save offset
|
|
|
- movw TempBuffer1,ya
|
|
|
-
|
|
|
- mov y,#$00 ;clear mod pointer counter(actually, this counter always stays 0,just needed for indirect write)
|
|
|
-
|
|
|
-ReceiveSamplePackWaitLoop2: ;wait for first transfer
|
|
|
- cmp $f4,#SpcCmdUploadSamplePackDone
|
|
|
- beq ReceiveSamplePackComplete ;check if upload complete
|
|
|
-
|
|
|
- cmp $f4,#SpcCmdUploadSongT1 ;check if data for transfer 1 is stable and on ports
|
|
|
- bne ReceiveSamplePackWaitLoop2
|
|
|
-
|
|
|
- mov a,$f5 ;get byte
|
|
|
- mov [SpcDataPointerLo]+y,a
|
|
|
- incw SpcDataPointerLo ;increment counter, word
|
|
|
- mov a,$f6 ;get byte
|
|
|
- mov [SpcDataPointerLo]+y,a
|
|
|
- incw SpcDataPointerLo ;increment counter, word
|
|
|
- mov a,$f7 ;get byte
|
|
|
- mov [SpcDataPointerLo]+y,a
|
|
|
- incw SpcDataPointerLo ;increment counter, word
|
|
|
-
|
|
|
- mov $f4,#SpcCmdUploadSongT1
|
|
|
-
|
|
|
-ReceiveSamplePackWaitLoop3: ;wait for second transfer
|
|
|
- cmp $f4,#SpcCmdUploadSongT2
|
|
|
- bne ReceiveSamplePackWaitLoop3
|
|
|
-
|
|
|
- mov a,$f5 ;get byte
|
|
|
- mov [SpcDataPointerLo]+y,a
|
|
|
- incw SpcDataPointerLo ;increment counter, word
|
|
|
- mov a,$f6 ;get byte
|
|
|
- mov [SpcDataPointerLo]+y,a
|
|
|
- incw SpcDataPointerLo ;increment counter, word
|
|
|
- mov a,$f7 ;get byte
|
|
|
- mov [SpcDataPointerLo]+y,a
|
|
|
- incw SpcDataPointerLo ;increment counter, word
|
|
|
-
|
|
|
- mov $f4,#SpcCmdUploadSongT2
|
|
|
- bra ReceiveSamplePackWaitLoop2
|
|
|
-
|
|
|
-ReceiveSamplePackComplete:
|
|
|
- mov a,#$00 ;clear apu ports so that cpu knows were ready
|
|
|
- mov $f4,a
|
|
|
- mov $f5,a
|
|
|
- mov $f6,a
|
|
|
- mov $f7,a
|
|
|
- movw ya,TempBuffer1 ;restore saved pointer
|
|
|
- movw SpcDataPointerLo,ya
|
|
|
-
|
|
|
- or SongEffectsUploaded,#%00000010 ;set "sample pack uploaded" flag
|
|
|
- call !SetupEffectSamples
|
|
|
-;return to mainloop:
|
|
|
- jmp !MainLoop
|
|
|
-
|
|
|
-
|
|
|
-SetupEffectSamples:
|
|
|
- mov x,#34*4 ;start copying to 34th dsp sample
|
|
|
- mov y,#$00
|
|
|
- mov a,[SpcDataPointerLo]+y ;get number of sample in pack
|
|
|
- and a,#$1f ;maximum number of samples 31
|
|
|
- mov TempBuffer1,a ;this is our number of samples to process
|
|
|
- inc y ;advance to first byte pointer
|
|
|
-
|
|
|
-SetupEffectSamplesLoop:
|
|
|
-
|
|
|
-;sample adress:
|
|
|
- mov a,[SpcDataPointerLo]+y ;get sample relative adress low
|
|
|
- inc y
|
|
|
- clrc
|
|
|
- adc a,SpcDataPointerLo ;add modfile position
|
|
|
- mov !(SampleSource+0)+x,a ;store in dsp sample area
|
|
|
- mov a,[SpcDataPointerLo]+y ;get sample relative adress hi
|
|
|
- adc a,SpcDataPointerHi ;add modfile position, with carry from previous add
|
|
|
- dec y
|
|
|
- mov !(SampleSource+1)+x,a ;store in dsp sample area
|
|
|
- inc y
|
|
|
- inc y
|
|
|
-;sample loop adress:
|
|
|
- mov a,[SpcDataPointerLo]+y ;get sample relative adress low
|
|
|
- inc y
|
|
|
- clrc
|
|
|
- adc a,SpcDataPointerLo ;add modfile position
|
|
|
- mov !(SampleSource+2)+x,a ;store in dsp sample area
|
|
|
-
|
|
|
-
|
|
|
- mov a,[SpcDataPointerLo]+y ;get sample relative adress hi
|
|
|
- adc a,SpcDataPointerHi ;add modfile position, with carry from previous add
|
|
|
- dec y
|
|
|
- mov !(SampleSource+3)+x,a ;store in dsp sample area
|
|
|
-
|
|
|
- mov a,y ;increment source pointer by 15 (entry is 16 bytes long)
|
|
|
- clrc
|
|
|
- adc a,#14
|
|
|
- mov y,a
|
|
|
-
|
|
|
- inc x
|
|
|
- inc x
|
|
|
- inc x
|
|
|
- inc x
|
|
|
- dbnz TempBuffer1,SetupEffectSamplesLoop
|
|
|
-
|
|
|
- ret
|
|
|
-
|
|
|
-PlaySoundEffectAbort:
|
|
|
- jmp !MainLoop
|
|
|
-
|
|
|
-PlaySoundEffect:
|
|
|
- movw ya,$f4 ;save all 4 ports to variables
|
|
|
- movw TempBuffer1,ya ;tempbuffer1:command,tb2:se number,tb3-4:volume/pitch
|
|
|
- movw ya,$f6
|
|
|
- movw TempBuffer3,ya
|
|
|
-
|
|
|
- mov $f4,#SpcCmdPlaySoundEffect ;echo command received
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- bbc $ef.1,PlaySoundEffectAbort ;only process song if song has been uploaded before
|
|
|
-
|
|
|
- mov a,TempBuffer4
|
|
|
- and a,#$80 ;get flip flag
|
|
|
- eor a,SoundEffectFlipFlag
|
|
|
- bne PlaySoundEffectAbort ;only play effect if this flag has changed as expected
|
|
|
-
|
|
|
- eor SoundEffectFlipFlag,#$80 ;toggle flag for next soundeffect
|
|
|
-
|
|
|
- mov y,#0
|
|
|
- mov a,[SpcDataPointerLo]+y ;get number of samples in pack
|
|
|
- mov TempBuffer5,a
|
|
|
- mov a,TempBuffer2
|
|
|
-
|
|
|
- cmp a,TempBuffer5
|
|
|
- bcs PlaySoundEffectAbort ;return if sound effect to play is bigger than number of samples in pack
|
|
|
-
|
|
|
-
|
|
|
- mov a,ActiveSoundEffectCh
|
|
|
- inc a ;goto next channel
|
|
|
- and a,#3 ;maximum number of channels is 3
|
|
|
- mov ActiveSoundEffectCh,a ;save back
|
|
|
- mov x,a
|
|
|
- mov a,!SoundEffectChannelDspRegLUT+x ;get channel value for dsp access
|
|
|
- mov TempBuffer5,a
|
|
|
-
|
|
|
- mov a,!SoundEffectChannelKofLUT+x ;get channel key off bit
|
|
|
- mov TempBuffer6,a
|
|
|
- mov $f2,#$5c ;key off current channel
|
|
|
- mov $f3,a
|
|
|
-
|
|
|
-
|
|
|
-;wait 8ms for key off to finish
|
|
|
- mov a,$fe ;clear 4bit counter
|
|
|
- mov y,#4
|
|
|
-KofWaitLoop2:
|
|
|
- mov a,$fe ;wait for 2mS
|
|
|
- beq KofWaitLoop2
|
|
|
- dbnz y,KofWaitLoop2
|
|
|
-
|
|
|
- mov x,TempBuffer5 ;get pointer to dsp channel register set
|
|
|
-
|
|
|
- mov a,TempBuffer2 ;get sample number
|
|
|
- asl a ;multiply by 16
|
|
|
- asl a
|
|
|
- asl a
|
|
|
- asl a
|
|
|
- inc a ;increment because first byte in sample pack is number of samples
|
|
|
- mov y,a
|
|
|
-
|
|
|
- inc y
|
|
|
- inc y
|
|
|
- inc y
|
|
|
- inc y
|
|
|
-
|
|
|
- mov a,TempBuffer4 ;get 65816 command volume
|
|
|
- and a,#$7f ;mask off flip flag
|
|
|
- beq PlaySoundEffectDefaultVol
|
|
|
-
|
|
|
-;play SE with custom volume
|
|
|
- and a,#%0001111 ;get volume
|
|
|
- mov TempBuffer7,a
|
|
|
- clrc
|
|
|
- asl a
|
|
|
- asl a
|
|
|
- asl a
|
|
|
- and TempBuffer7,#%00001111 ;add lower bits to get maximum range
|
|
|
- or a,TempBuffer7
|
|
|
- mov TempBuffer7,a
|
|
|
-
|
|
|
- call !SoundEffectCalcPanL
|
|
|
-
|
|
|
- mov $f2,x
|
|
|
- mov $f3,a
|
|
|
- inc y
|
|
|
- inc x
|
|
|
- call !SoundEffectCalcPanR
|
|
|
- mov $f2,x
|
|
|
- mov $f3,a
|
|
|
- bra PlaySoundEffectCustomVol
|
|
|
-
|
|
|
-PlaySoundEffectDefaultVol:
|
|
|
- mov a,[SpcDataPointerLo]+y ;get volume l
|
|
|
-
|
|
|
- mov $f2,x
|
|
|
- mov $f3,a
|
|
|
- inc y
|
|
|
- inc x
|
|
|
- mov a,[SpcDataPointerLo]+y ;get volume r
|
|
|
-
|
|
|
- mov $f2,x
|
|
|
- mov $f3,a
|
|
|
-
|
|
|
-PlaySoundEffectCustomVol:
|
|
|
- inc y
|
|
|
- inc x
|
|
|
-
|
|
|
- mov a,TempBuffer3 ;get 65816 command pitch
|
|
|
- beq PlaySoundEffectDefaultPitch
|
|
|
-
|
|
|
-;play custom pitch. same as mod pitch numbers. valid pitch numbers: 0-59
|
|
|
- push y
|
|
|
-;**************************************************
|
|
|
- asl a ;asl because each period is 2 bytes long
|
|
|
- mov y,a ;get period number
|
|
|
- mov a,[PeriodTablePointerLo]+y ;get current period
|
|
|
- mov TempBuffer7,a
|
|
|
- inc y
|
|
|
- mov a,[PeriodTablePointerLo]+y
|
|
|
- mov TempBuffer8,a
|
|
|
-
|
|
|
-
|
|
|
-;fetch pitch from pitch table. input: period
|
|
|
- mov y,TempBuffer8
|
|
|
- mov a,TempBuffer7
|
|
|
- addw ya,TempBuffer7 ;multiply by 2
|
|
|
- addw ya,PitchTablePointerLo ;add table offset
|
|
|
- movw TempBuffer7,ya ;move adress to pointer
|
|
|
- mov y,#0
|
|
|
-
|
|
|
- mov a,[TempBuffer7]+y ;get lo pitch byte
|
|
|
- mov PitchBufferLo,a ;save new pitch
|
|
|
- inc y
|
|
|
- mov a,[TempBuffer7]+y
|
|
|
- mov PitchBufferHi,a
|
|
|
- pop y
|
|
|
- mov a,PitchBufferLo ;get pitch lo
|
|
|
- mov $f2,x
|
|
|
- mov $f3,a
|
|
|
- inc y
|
|
|
- inc x
|
|
|
- mov a,PitchBufferHi ;get pitch hi
|
|
|
- mov $f2,x
|
|
|
- mov $f3,a
|
|
|
- bra PlaySoundEffectCustomPitch
|
|
|
-
|
|
|
-;**********************************************+
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-PlaySoundEffectDefaultPitch:
|
|
|
- mov a,[SpcDataPointerLo]+y ;get pitch lo
|
|
|
-
|
|
|
- mov $f2,x
|
|
|
- mov $f3,a
|
|
|
- inc y
|
|
|
- inc x
|
|
|
- mov a,[SpcDataPointerLo]+y ;get pitch hi
|
|
|
-
|
|
|
- mov $f2,x
|
|
|
- mov $f3,a
|
|
|
-
|
|
|
-PlaySoundEffectCustomPitch:
|
|
|
- inc x
|
|
|
-
|
|
|
- mov a,TempBuffer2 ;get sound effect to play
|
|
|
- clrc
|
|
|
- adc a,#34 ;add 34 (sound effects start at dsp sample 34)
|
|
|
-
|
|
|
- mov $f2,x
|
|
|
- mov $f3,a
|
|
|
-
|
|
|
- inc y
|
|
|
- inc x
|
|
|
- mov a,[SpcDataPointerLo]+y ;get adsr lo
|
|
|
-
|
|
|
- mov $f2,x
|
|
|
- mov $f3,a
|
|
|
-
|
|
|
- inc y
|
|
|
- inc x
|
|
|
- mov a,[SpcDataPointerLo]+y ;get adsr hi
|
|
|
-
|
|
|
- mov $f2,x
|
|
|
- mov $f3,a
|
|
|
-
|
|
|
- inc y
|
|
|
- inc x
|
|
|
- mov a,[SpcDataPointerLo]+y ;get gain
|
|
|
-
|
|
|
- mov $f2,x
|
|
|
- mov $f3,a
|
|
|
-
|
|
|
- mov $f2,#$5c ;reset key off in case it's still active.(shouldn't, though)
|
|
|
- mov $f3,#%00000000
|
|
|
-
|
|
|
- mov $f2,#$4c ;key on channel
|
|
|
- mov $f3,TempBuffer6
|
|
|
-
|
|
|
- jmp !MainLoop
|
|
|
-
|
|
|
-;in: TempBuffer4:volume&pan command
|
|
|
-; TempBuffer7:total channel volume
|
|
|
-;out: a,8bit: panned channel volume
|
|
|
-;uses: TempBuffer8
|
|
|
-
|
|
|
-SoundEffectCalcPanL:
|
|
|
- mov a,TempBuffer4 ;get pan bits
|
|
|
- xcn a ;swap nibbles
|
|
|
- ;put pan bits into lower 4 bits. we're skipping lsr a, asl a here because the pointers in the LUT are words.
|
|
|
- and a,#%00000111 ;mask off rest
|
|
|
- push x
|
|
|
- asl a
|
|
|
- mov x,a ;use as pointer
|
|
|
- mov a,TempBuffer7
|
|
|
- jmp [!PlaySoundEffectLVolLUT+x]
|
|
|
-
|
|
|
-
|
|
|
-PlaySoundEffectLVolLUT:
|
|
|
- .dw PlaySoundEffectVolTBL
|
|
|
- .dw PlaySoundEffectVolTBL+1
|
|
|
- .dw PlaySoundEffectVolTBL+2
|
|
|
- .dw PlaySoundEffectVolTBL+3
|
|
|
- .dw PlaySoundEffectVolTBL+4
|
|
|
- .dw PlaySoundEffectVolTBL+5
|
|
|
- .dw PlaySoundEffectVolTBL+6
|
|
|
- .dw PlaySoundEffectVolTBL+7
|
|
|
-
|
|
|
-
|
|
|
-SoundEffectCalcPanR:
|
|
|
- mov a,TempBuffer4 ;get pan bits
|
|
|
- xcn a ;swap nibbles
|
|
|
- ;put pan bits into lower 4 bits. we're skipping lsr a, asl a here because the pointers in the LUT are words.
|
|
|
- and a,#%00000111 ;mask off rest
|
|
|
- push x
|
|
|
- asl a
|
|
|
- mov x,a ;use as pointer
|
|
|
- mov a,TempBuffer7
|
|
|
- jmp [!PlaySoundEffectRVolLUT+x]
|
|
|
-
|
|
|
-
|
|
|
-PlaySoundEffectRVolLUT:
|
|
|
- .dw PlaySoundEffectVolTBL+7
|
|
|
- .dw PlaySoundEffectVolTBL+6
|
|
|
- .dw PlaySoundEffectVolTBL+5
|
|
|
- .dw PlaySoundEffectVolTBL+4
|
|
|
- .dw PlaySoundEffectVolTBL+3
|
|
|
- .dw PlaySoundEffectVolTBL+2
|
|
|
- .dw PlaySoundEffectVolTBL+1
|
|
|
- .dw PlaySoundEffectVolTBL
|
|
|
-
|
|
|
-PlaySoundEffectVolTBL:
|
|
|
- lsr a
|
|
|
- lsr a
|
|
|
- lsr a
|
|
|
- lsr a
|
|
|
- lsr a
|
|
|
- lsr a
|
|
|
- lsr a
|
|
|
- nop
|
|
|
- mov TempBuffer8,a ;save
|
|
|
- mov a,TempBuffer7
|
|
|
- setc
|
|
|
- sbc a,TempBuffer8 ;substract calculated pan value
|
|
|
- pop x
|
|
|
- ret
|
|
|
-
|
|
|
-ReceiveStream:
|
|
|
- mov $f2,#$5c ;key off channels 0-3
|
|
|
- mov $f3,#%00001111
|
|
|
-
|
|
|
- mov StreamState,#0 ;reset transfer state machine
|
|
|
- mov StreamCurrentBuffer,#0 ;reset to first buffer
|
|
|
-
|
|
|
- call !SetupStreamSampleAdress
|
|
|
- movw ya,$f5
|
|
|
- movw TempBuffer1,ya ;get total number of samples to transfer
|
|
|
- mov a,#0
|
|
|
- mov y,a
|
|
|
- movw TempBuffer3,ya ;clear current frame counter
|
|
|
- movw $f5,ya ;tell 65816 current frame to transfer
|
|
|
- mov $f4,#SpcCmdReceiveStream
|
|
|
-
|
|
|
-ReceiveStreamWaitLoop1:
|
|
|
- cmp $f4,#SpcCmdSubmitStreamNumber
|
|
|
- bne ReceiveStreamWaitLoop1
|
|
|
-
|
|
|
-
|
|
|
-;wait for desired frame
|
|
|
- movw ya,$f5
|
|
|
- cmpw ya,TempBuffer3
|
|
|
- bne ReceiveStreamRequestFrame
|
|
|
-
|
|
|
- mov a,$f7
|
|
|
- mov StreamVolume,a
|
|
|
- beq ReceiveStreamExit ;exit streaming if volume is 0
|
|
|
-;enter receive state machine
|
|
|
- mov a,StreamState
|
|
|
- asl a
|
|
|
- mov x,a ;pointer into jump table
|
|
|
- jmp [!StreamJumpTable+x]
|
|
|
-
|
|
|
-ReceiveStreamWaitLoop2:
|
|
|
- cmp $f4,#SpcCmdSubmitStreamNumber ;wait for port0 data to change. Don't know if this works out as desired, but
|
|
|
- beq ReceiveStreamWaitLoop2
|
|
|
-
|
|
|
-
|
|
|
-ReceiveStreamTransferLoop: ;66 cycles per scanline. this loop must be exactly 66 bytes long while looping.
|
|
|
-;26 cycles ;59 cycles per scanline left for actual transfer
|
|
|
-
|
|
|
- movw ya,$f4
|
|
|
- push a ;save data on stack cause that's the fastest way possible
|
|
|
- push y
|
|
|
- movw ya,$f6
|
|
|
- push a
|
|
|
- push y
|
|
|
-
|
|
|
-;waste 33 cyles:
|
|
|
-;******************************
|
|
|
- mov a,TempBuffer1 ;real snes/bsnes need a total of 33 cycles here
|
|
|
- mov a,TempBuffer1
|
|
|
- mov a,TempBuffer1
|
|
|
- mov a,TempBuffer1
|
|
|
- mov a,TempBuffer1
|
|
|
- mov a,TempBuffer1
|
|
|
- mov a,TempBuffer1
|
|
|
- mov a,TempBuffer1
|
|
|
- mov a,TempBuffer1
|
|
|
- mov a,TempBuffer1
|
|
|
- mov a,TempBuffer1
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-;7 cycles when looping back
|
|
|
- dbnz TempBuffer5,ReceiveStreamTransferLoop
|
|
|
-
|
|
|
- mov a,#36
|
|
|
- mov TempBuffer5,a
|
|
|
-
|
|
|
- mov y,#144-1 ;set counter to last byte in buffer(reverse copy because of stack)
|
|
|
-
|
|
|
-ReceiveStreamSaveLoop:
|
|
|
- pop a ;dummy loop to fix stack
|
|
|
- mov [TempBuffer7]+y,a ;7 -move to buffer
|
|
|
- dec y
|
|
|
- pop a ;dummy loop to fix stack
|
|
|
- mov [TempBuffer7]+y,a ;7 -move to buffer
|
|
|
- dec y
|
|
|
- pop a ;dummy loop to fix stack
|
|
|
- mov [TempBuffer7]+y,a ;7 -move to buffer
|
|
|
- dec y
|
|
|
- pop a ;dummy loop to fix stack
|
|
|
- mov [TempBuffer7]+y,a ;7 -move to buffer
|
|
|
- dec y
|
|
|
- dbnz TempBuffer5,ReceiveStreamSaveLoop
|
|
|
-
|
|
|
- cmp StreamCurrentBuffer,#SpcStreamLatency
|
|
|
- bne SpcStreamDontSetEndBit
|
|
|
-
|
|
|
-
|
|
|
- mov y,#144-9 ;set pointer to last samples header
|
|
|
- mov a,[TempBuffer7]+y ;get header byte
|
|
|
- or a,#%00000011 ;set loop & end bits
|
|
|
-
|
|
|
- mov [TempBuffer7]+y,a ;save back header byte
|
|
|
-
|
|
|
-SpcStreamDontSetEndBit:
|
|
|
- incw TempBuffer3 ;request next frame
|
|
|
- inc StreamCurrentBuffer
|
|
|
- and StreamCurrentBuffer,#7 ;maximum number of buffers: 8
|
|
|
-StreamTimerWait: ;wait for 16 brr samples to play / ca. 2 frames to pass, then continue downloading stream
|
|
|
- mov a,$fd
|
|
|
- beq StreamTimerWait
|
|
|
-
|
|
|
-ReceiveStreamRequestFrame:
|
|
|
- movw ya,TempBuffer3
|
|
|
- movw $f5,ya ;tell 65816 which frame to transfer
|
|
|
-
|
|
|
- movw ya,TempBuffer1 ;check if done transfering
|
|
|
- cmpw ya,TempBuffer3
|
|
|
- bne ReceiveStreamWaitLoop1
|
|
|
-
|
|
|
-ReceiveStreamExit:
|
|
|
- mov $f2,#$5c ;key off channels 0-3
|
|
|
- mov $f3,#%00000001
|
|
|
- mov $f4,#SpcCmdReceiveStreamComplete ;tell 65816 we're done
|
|
|
-
|
|
|
-;StreamWaitSampleEnd:
|
|
|
- mov $f1,#$00 ;stop timer
|
|
|
- nop
|
|
|
- nop
|
|
|
- mov $fa,ModPlayerTimer0 ;reset timer, return to modplayer
|
|
|
-
|
|
|
- nop
|
|
|
- nop
|
|
|
- mov $f1,#$03 ;start timer
|
|
|
-
|
|
|
- jmp !MainLoop ;return
|
|
|
-
|
|
|
-
|
|
|
-StreamJumpTable:
|
|
|
- .dw InitStream ;fill buffer, then start playing sample
|
|
|
- .dw StreamContinue ;fill buffer according to timer
|
|
|
-
|
|
|
-StreamContinue:
|
|
|
-;setup current stream buffer
|
|
|
- mov TempBuffer7,#(StreamBuffer & $00ff) ;pointer to first stream buffer
|
|
|
- mov TempBuffer8,#(StreamBuffer >> 8)
|
|
|
- mov a,StreamCurrentBuffer
|
|
|
-
|
|
|
- mov y,#144
|
|
|
- mul ya
|
|
|
- addw ya,TempBuffer7
|
|
|
- movw TempBuffer7,ya ;pointer to current stream buffer in TempBuffer7,8
|
|
|
-
|
|
|
- mov a,#$00
|
|
|
- mov y,StreamVolume ;update volume
|
|
|
- movw $f2,ya
|
|
|
- inc a
|
|
|
- movw $f2,ya
|
|
|
-
|
|
|
-
|
|
|
- mov y,#0 ;clear target copy counter
|
|
|
-
|
|
|
- mov a,#36 ;amount of scanlines to copy
|
|
|
- mov TempBuffer5,a
|
|
|
-
|
|
|
- jmp !ReceiveStreamWaitLoop2
|
|
|
-
|
|
|
-InitStream:
|
|
|
-;receive stream here:
|
|
|
-
|
|
|
-;setup current stream buffer
|
|
|
- mov TempBuffer7,#(StreamBuffer & $00ff) ;pointer to first stream buffer
|
|
|
- mov TempBuffer8,#(StreamBuffer >> 8)
|
|
|
- mov a,StreamCurrentBuffer
|
|
|
- and a,#7 ;maximum number of buffers: 8
|
|
|
- mov y,#144
|
|
|
- mul ya
|
|
|
- addw ya,TempBuffer7
|
|
|
- movw TempBuffer7,ya ;pointer to current stream buffer in TempBuffer7,8
|
|
|
-
|
|
|
-
|
|
|
- mov y,#0 ;clear target copy counter
|
|
|
-
|
|
|
- mov a,#36 ;amount of scanlines to copy
|
|
|
- mov TempBuffer5,a
|
|
|
-
|
|
|
-
|
|
|
- cmp StreamCurrentBuffer,#SpcStreamLatency
|
|
|
- bne SpcStreamDontStartSample
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-;setup sample dsp regs on channel 1:
|
|
|
-;wide stereo effect
|
|
|
- mov a,#$00
|
|
|
- mov y,StreamVolume ;volume
|
|
|
- movw $f2,ya
|
|
|
- inc a
|
|
|
- movw $f2,ya
|
|
|
- inc a
|
|
|
- mov y,#$00 ;pitch lo
|
|
|
- movw $f2,ya
|
|
|
- inc a
|
|
|
- mov y,#$04 ;pitch hi
|
|
|
- movw $f2,ya
|
|
|
- inc a
|
|
|
- mov y,#SpcStreamSampleNumber ;sample number
|
|
|
- movw $f2,ya
|
|
|
- inc a
|
|
|
- mov y,#0 ;adsr1 (use gain instead)
|
|
|
- movw $f2,ya
|
|
|
- inc a
|
|
|
- movw $f2,ya ;adsr2
|
|
|
- inc a
|
|
|
- mov y,#$7f ;volume
|
|
|
- movw $f2,ya
|
|
|
-
|
|
|
- mov $f2,#$5c ;reset key off in case it's still active.(shouldn't, though)
|
|
|
- mov $f3,#%00000000
|
|
|
-
|
|
|
- mov $f2,#$4c ;key on channel 1
|
|
|
- mov $f3,#%00000001
|
|
|
-
|
|
|
- mov $f1,#$00 ;stop timer
|
|
|
- nop
|
|
|
- nop
|
|
|
- mov $fa,#StreamerTimer0 ;32 milliSeconds on timer 0
|
|
|
- nop
|
|
|
- nop
|
|
|
- mov $f1,#$03 ;start timer
|
|
|
- inc StreamState ;goto next state
|
|
|
-
|
|
|
-SpcStreamDontStartSample:
|
|
|
- jmp !ReceiveStreamWaitLoop2
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-UpdateVolEchoHandler:
|
|
|
- mov ModFilePointerLo,#(MainVolL & $00ff) ;setup mod pointer
|
|
|
- mov ModFilePointerHi,#(MainVolL >> 8)
|
|
|
-
|
|
|
- mov y,#$00 ;clear mod pointer counter(actually, this counter always stays 0,just needed for indirect write)
|
|
|
- mov $f4,#$01
|
|
|
-
|
|
|
-
|
|
|
-UpdateVolEchoWaitLoop1:
|
|
|
- cmp $f4,#$00 ;check if another data download is due
|
|
|
- bne UpdateVolEchoWaitLoop1
|
|
|
-
|
|
|
- mov a,$f5 ;get byte
|
|
|
- mov [ModFilePointerLo]+y,a
|
|
|
- incw ModFilePointerLo ;increment counter, word
|
|
|
- mov a,$f6 ;get byte
|
|
|
- mov [ModFilePointerLo]+y,a
|
|
|
- incw ModFilePointerLo ;increment counter, word
|
|
|
- mov a,$f7 ;get byte
|
|
|
- mov [ModFilePointerLo]+y,a
|
|
|
- incw ModFilePointerLo ;increment counter, word
|
|
|
-
|
|
|
- mov $f4,#$00
|
|
|
-
|
|
|
-UpdateVolEchoWaitLoop2:
|
|
|
- cmp $f4,#$01 ;check if another data download is due
|
|
|
- bne UpdateVolEchoWaitLoop2
|
|
|
-
|
|
|
- mov a,$f5 ;get byte
|
|
|
- mov [ModFilePointerLo]+y,a
|
|
|
- incw ModFilePointerLo ;increment counter, word
|
|
|
- mov a,$f6 ;get byte
|
|
|
- mov [ModFilePointerLo]+y,a
|
|
|
- incw ModFilePointerLo ;increment counter, word
|
|
|
- mov a,$f7 ;get byte
|
|
|
- mov [ModFilePointerLo]+y,a
|
|
|
- incw ModFilePointerLo ;increment counter, word
|
|
|
-
|
|
|
- mov a,#$00 ;clear apu ports so that cpu knows were ready
|
|
|
- mov $f4,a
|
|
|
- mov $f5,a
|
|
|
- mov $f6,a
|
|
|
- mov $f7,a
|
|
|
-UpdateVolEchoVariablesOnly:
|
|
|
-
|
|
|
- mov $f2,#$6d ;echo start adress
|
|
|
- mov $f3,#EchoStartAdress ;80
|
|
|
- mov $f2,#$7d ;echo delay
|
|
|
- mov $f3,#EchoDelay ;06
|
|
|
- mov $f2,#$0d ;echo feedback
|
|
|
- mov $f3,#$04 ;04
|
|
|
-
|
|
|
-
|
|
|
- mov $f2,#$0c
|
|
|
- mov $f3,MainVolL
|
|
|
- mov $f2,#$1c
|
|
|
- mov $f3,MainVolR
|
|
|
- mov $f2,#$2c
|
|
|
- mov $f3,EchoVolL
|
|
|
- mov $f2,#$3c
|
|
|
- mov $f3,EchoVolR
|
|
|
- mov $f2,#$4d
|
|
|
- mov $f3,ChannelEchoEnable
|
|
|
-
|
|
|
-
|
|
|
- ret
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-;set key on/key off here:
|
|
|
-GetDataFromPatternCheckPatternPosition:
|
|
|
-;***********************************************
|
|
|
-;check if pattern break is due
|
|
|
- mov a, PatternBreakFlag ;check if pattern break flag is set
|
|
|
- beq CheckPatternBreakExit
|
|
|
-
|
|
|
- inc CurrentPatternNumber ;increment current pattern
|
|
|
- mov x,CurrentPatternNumber ;check if we overflow
|
|
|
- cmp x,NumberOfPatterns
|
|
|
- bne PatternBreakNoOverflow
|
|
|
-
|
|
|
- mov CurrentPatternNumber,#$00 ;reset to pattern #0 if overflow occured
|
|
|
- mov x,CurrentPatternNumber
|
|
|
-
|
|
|
-PatternBreakNoOverflow:
|
|
|
- mov a,!(ModFile+$fa)+x ;get id number of next pattern
|
|
|
- asl a
|
|
|
- mov x,a
|
|
|
- mov a,!(ModFile+$17a)+x ;get word-pointer to that table
|
|
|
- mov y,a
|
|
|
- mov a,!(ModFile+$17b)+x
|
|
|
- addw ya,InitPatternPointerLo
|
|
|
- movw CurrentPatternPointerLo,ya ;update current pattern pointer
|
|
|
-
|
|
|
- mov PatternBreakFlag,#0 ;clear pattern break flag and exit
|
|
|
- pop a ;need to purge the stack a bit first
|
|
|
- pop a ;else, it would overflow slowly when using the pattern break command constantly
|
|
|
- pop a
|
|
|
- pop a
|
|
|
- jmp !MainLoop
|
|
|
-
|
|
|
-CheckPatternBreakExit:
|
|
|
-
|
|
|
-;check if at end of current pattern
|
|
|
- mov x,CurrentPatternNumber
|
|
|
- mov a,!(ModFile+$fa)+x ;load pattern number
|
|
|
- inc a
|
|
|
- asl a ;multiply, use as pointer into patterntable pointertable list
|
|
|
- mov x,a
|
|
|
- mov a,!(ModFile+$17a)+x ;$1455+x ;(ModFile+$17a) ;$17a
|
|
|
- mov TempBuffer2,a
|
|
|
- mov a,!(ModFile+$17b)+x ;$1456+x ;17b
|
|
|
- mov TempBuffer1,a
|
|
|
- movw ya,CurrentPatternPointerLo
|
|
|
- subw ya,InitPatternPointerLo
|
|
|
- cmpw ya,TempBuffer1
|
|
|
- bpl CheckPatternPositionPatternEnd
|
|
|
-
|
|
|
- ret
|
|
|
-
|
|
|
-CheckPatternPositionPatternEnd:
|
|
|
- inc CurrentPatternNumber ;increment position in current pattern
|
|
|
- mov a,CurrentPatternNumber
|
|
|
- cmp a,NumberOfPatterns ;check if at end of pattern
|
|
|
- beq CheckPatternPositionReset
|
|
|
-
|
|
|
- mov x,a
|
|
|
- mov a,!(ModFile+$fa)+x
|
|
|
- asl a
|
|
|
- mov x,a
|
|
|
- mov a,!(ModFile+$17a)+x
|
|
|
- mov y,a
|
|
|
- mov a,!(ModFile+$17b)+x
|
|
|
- addw ya,InitPatternPointerLo
|
|
|
- movw CurrentPatternPointerLo,ya
|
|
|
- movw CurrentLoopPointerLo,ya
|
|
|
- ret
|
|
|
-
|
|
|
-CheckPatternPositionReset: ;wrap to pattern 0
|
|
|
- mov $f6,#$50
|
|
|
- mov CurrentPatternNumber,#$00
|
|
|
- mov x,CurrentPatternNumber
|
|
|
- mov a,!(ModFile+$fa)+x
|
|
|
- asl a
|
|
|
- mov x,a
|
|
|
- mov a,!(ModFile+$17a)+x
|
|
|
- mov y,a
|
|
|
- mov a,!(ModFile+$17b)+x
|
|
|
- addw ya,InitPatternPointerLo
|
|
|
- movw CurrentPatternPointerLo,ya
|
|
|
- ret
|
|
|
-
|
|
|
-
|
|
|
-ClearAllChannelArray:
|
|
|
- mov a,#(ChannelArray & $ff) ;get pointer to first channel array
|
|
|
- mov y,#(ChannelArray >> 8)
|
|
|
- movw TempBuffer1,ya
|
|
|
- movw Channel1Array,ya
|
|
|
- mov a,#1
|
|
|
- call !ClearChannelArray
|
|
|
-
|
|
|
- movw Channel2Array,ya
|
|
|
- mov a,#2
|
|
|
- call !ClearChannelArray
|
|
|
-
|
|
|
- movw Channel3Array,ya
|
|
|
- mov a,#4
|
|
|
- call !ClearChannelArray
|
|
|
-
|
|
|
- movw Channel4Array,ya
|
|
|
- mov a,#8
|
|
|
- call !ClearChannelArray
|
|
|
- ret
|
|
|
-
|
|
|
-
|
|
|
-ClearChannelArray:
|
|
|
- mov y,#ch_current_channelmask ;number of bytes to copy
|
|
|
- mov [TempBuffer1]+y,a ;put channel mask into array pointer + channel mask value
|
|
|
- decw TempBuffer1
|
|
|
- mov a,#0
|
|
|
-ClearChannelArrayLoop:
|
|
|
- mov [TempBuffer1]+y,a ;clear array
|
|
|
- dbnz y,ClearChannelArrayLoop
|
|
|
-
|
|
|
- incw TempBuffer1
|
|
|
- mov a,#ch_current_channelmask+1 ;get amount of bytes per array and add to current adress
|
|
|
- mov y,#0
|
|
|
- addw ya,TempBuffer1
|
|
|
- movw TempBuffer1,ya ;save adress of next array
|
|
|
- ret
|
|
|
-
|
|
|
-CommandVoid:
|
|
|
- jmp !MainLoop
|
|
|
-
|
|
|
-SetSongChannelMask:
|
|
|
- mov SongChannelMask,$f5 ;get new channel mask
|
|
|
- mov $f2,#$5c
|
|
|
- mov a,SongChannelMask
|
|
|
- eor a,#$0f ;invert, switch off masked channels immediately
|
|
|
- mov $f3,a ;key off
|
|
|
- mov $f4,#SpcCmdSetSongChMask ;ack
|
|
|
- jmp !MainLoop ;return
|
|
|
-
|
|
|
-
|
|
|
-SetSongSpeed:
|
|
|
- mov ModPlayerTimer0,$f5 ;get new speed
|
|
|
-
|
|
|
- mov $f1,#$00
|
|
|
- nop
|
|
|
- nop
|
|
|
- mov $fa,ModPlayerTimer0 ;20 milliSeconds on timer 0
|
|
|
- mov $fb,#$10 ;2 milliSeconds on timer 1
|
|
|
- nop
|
|
|
- nop
|
|
|
- mov $f1,#$03 ;start timer(s)
|
|
|
- mov $f4,#SpcCmdSetSongSpeed ;ack
|
|
|
- jmp !MainLoop ;return
|
|
|
-
|
|
|
-
|
|
|
-StopSongStream:
|
|
|
- and SongEffectsUploaded,#%11111110 ;clear "song uploaded" flag
|
|
|
- mov $f2,#$5c ;reset key off in case it's still active.(shouldn't, though)
|
|
|
- mov $f3,#%00001111 ;key off all mod/stream channels
|
|
|
- mov $f4,#SpcCmdStopSong ;ack command
|
|
|
- jmp !MainLoop ;return
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-SetReportType:
|
|
|
- mov SpcReportType,$f5 ;get new report type
|
|
|
- mov $f4,#SpcCmdReportType ;ack
|
|
|
- jmp !MainLoop
|
|
|
-
|
|
|
-SetSongVolume:
|
|
|
- mov MusicVol1,$f5 ;get new volume, mod channel 0,1
|
|
|
- mov MusicVol2,$f6 ;get new volume, mod channel 0,1
|
|
|
- mov $f4,#SpcCmdSetSongVolume ;ack
|
|
|
- jmp !MainLoop
|
|
|
-
|
|
|
-SendReportData:
|
|
|
- mov a,SpcReportType ;get report type
|
|
|
- and a,#$07
|
|
|
- asl a
|
|
|
- mov x,a ;pointer into jump table
|
|
|
-
|
|
|
- jmp [!ReportJumpTable+x]
|
|
|
-
|
|
|
-ReportJumpTable:
|
|
|
- .dw ReportVoid
|
|
|
- .dw ReportTimecode
|
|
|
- .dw ReportChannelLevels
|
|
|
- .dw ReportSpecialCmd
|
|
|
- .dw ReportVoid
|
|
|
- .dw ReportVoid
|
|
|
- .dw ReportVoid
|
|
|
- .dw ReportVoid
|
|
|
-
|
|
|
-ReportVoid:
|
|
|
- mov a,#0
|
|
|
- mov $f5,a ;clear report data
|
|
|
- mov $f6,a
|
|
|
- mov $f7,a
|
|
|
- ret
|
|
|
-
|
|
|
-
|
|
|
-ReportTimecode:
|
|
|
- mov $f5,#0 ;clear report byte first
|
|
|
- movw ya,ModTimecode
|
|
|
- movw $f6,ya
|
|
|
- mov a,SpcReportType
|
|
|
- or a,#$e0
|
|
|
- mov $f5,a ;return report type
|
|
|
- ret
|
|
|
-
|
|
|
-
|
|
|
-;report current sample levels of all 4 mod channels as 4bit nibbles unsigned.
|
|
|
-ReportChannelLevels:
|
|
|
- mov $f2,#$09
|
|
|
- mov a,$f3 ;get current wave height ch0
|
|
|
- lsr a
|
|
|
- lsr a
|
|
|
- lsr a
|
|
|
- and a,#$0f
|
|
|
- mov TempBuffer1,a
|
|
|
-
|
|
|
- mov $f2,#$19
|
|
|
- mov a,$f3 ;get current wave height ch1
|
|
|
- asl a
|
|
|
- and a,#$f0
|
|
|
- or a,TempBuffer1
|
|
|
- mov TempBuffer1,a
|
|
|
-
|
|
|
- mov $f2,#$29
|
|
|
- mov a,$f3 ;get current wave height ch2
|
|
|
- lsr a
|
|
|
- lsr a
|
|
|
- lsr a
|
|
|
- and a,#$0f
|
|
|
- mov TempBuffer1+1,a
|
|
|
-
|
|
|
- mov $f2,#$39
|
|
|
- mov a,$f3 ;get current wave height ch3
|
|
|
- asl a
|
|
|
- and a,#$f0
|
|
|
- or a,TempBuffer1+1
|
|
|
- mov TempBuffer1+1,a
|
|
|
-
|
|
|
- movw ya,TempBuffer1
|
|
|
-
|
|
|
- mov $f5,#0 ;clear report byte first
|
|
|
- movw $f6,ya ;write data to ports
|
|
|
- mov a,SpcReportType
|
|
|
- or a,#$e0
|
|
|
- mov $f5,a ;return report type
|
|
|
- ret
|
|
|
-
|
|
|
-ReportSpecialCmd:
|
|
|
- mov $f5,#0 ;clear report byte first
|
|
|
- mov a,SpecialReportCmd
|
|
|
- mov $f6,a
|
|
|
- mov a,SpcReportType
|
|
|
- or a,#$e0
|
|
|
- mov $f5,a ;return report type
|
|
|
- ret
|
|
|
-
|
|
|
-
|
|
|
-SoundEffectChannelDspRegLUT:
|
|
|
- .db $40
|
|
|
- .db $50
|
|
|
- .db $60
|
|
|
- .db $70
|
|
|
-
|
|
|
-SoundEffectChannelKofLUT:
|
|
|
- .db $10
|
|
|
- .db $20
|
|
|
- .db $40
|
|
|
- .db $80
|
|
|
-
|
|
|
-VibratoTable:
|
|
|
- .incbin "data/apu/vibratotable.tbl"
|
|
|
-
|
|
|
-PeriodTable:
|
|
|
- .include "data/apu/amigaperiodtable.tbl"
|
|
|
-
|
|
|
-PitchTable:
|
|
|
- .include "data/apu/pitchtable_new.tbl"
|
|
|
- .incbin "data/apu/pitchtable2.tbl"
|
|
|
-ModFile:
|