***************************************************************** * >> Protracker 3.00B playroutine << * * Written by Tom "Outland" Bech and Ivar "Heatseeker" J. Olsen. * * Based upon Protracker 1.1A playroutine written by Lars Hamre. * * VBlank version. Not optimised in any way. * ***************************************************************** * Call pt_InitMusic before start. Then call pt_PlayMusic at VB. * * To stop the music, call pt_StopMusic. * * Please note that in this version, all SetTempo commands are * * ignored. This assembly language program has been tested with * * the Devpac 3.0, AsmOne 1.2, MCAsm 1.5 and a68k assemblers and * * may have to be modified for other assemblers. * ***************************************************************** ; FileFormat offsets sd_songname EQU 0 ;songname offset sd_sampleinfo EQU 20 ;first sample starts here sd_numofpatt EQU 950 ;number of patterns are stored here sd_pattpos EQU 952 ;pattern positions table is here sd_mahokakt EQU 1080 ;"M.K." :) sd_patterndata EQU 1084 ;first pattern starts at this position ; Song offsets. W/L/B means word/longword/byte length. n_note EQU 0 ;W n_cmd EQU 2 ;W n_cmdlo EQU 3 ;low B of cmd n_start EQU 4 ;L n_length EQU 8 ;W n_loopstart EQU 10 ;L n_replen EQU 14 ;W n_period EQU 16 ;W n_finetune EQU 18 ;B n_volume EQU 19 ;B n_dmabit EQU 20 ;W n_toneportdirec EQU 22 ;B n_toneportspeed EQU 23 ;B n_wantedperiod EQU 24 ;W n_vibratocmd EQU 26 ;B n_vibratopos EQU 27 ;B n_tremolocmd EQU 28 ;B n_tremolopos EQU 29 ;B n_wavecontrol EQU 30 ;B n_glissfunk EQU 31 ;B n_sampleoffset EQU 32 ;B n_pattpos EQU 33 ;B n_loopcount EQU 34 ;B n_funkoffset EQU 35 ;B n_wavestart EQU 36 ;L n_reallength EQU 40 ;W n_trigger EQU 42 ;B n_samplenum EQU 43 ;B pt_InitMusic MOVEM.L D0-D3/A0-A2,-(SP) LEA pt_data,a0 MOVE.L A0,pt_SongDataPtr LEA sd_pattpos(A0),A1 MOVEQ #128-1,D0 MOVEQ #0,D1 MOVEQ #0,D2 moveq #$1e,d3 pt_lop2 MOVE.B (A1)+,D1 CMP.B D2,D1 BLE.B pt_lop MOVE.L D1,D2 pt_lop DBRA D0,pt_lop2 ADDQ.W #1,d2 ASL.L #8,D2 ASL.L #2,D2 LEA 4(A1,D2.L),A2 LEA pt_SampleStarts(PC),A1 ADD.W #2*20+2,A0 ;find first sample length MOVEQ #31-1,D0 pt_lop3 MOVE.L A2,(A1)+ MOVEQ #0,D1 MOVE.W (A0),D1 ASL.L #1,D1 ADD.L D1,A2 ADD.L D3,A0 DBRA D0,pt_lop3 MOVE.B #6,pt_Speed ;default speed OR.B #2,$BFE001 MOVEQ #0,D0 LEA $DFF000,A0 MOVE.W D0,$A8(A0) MOVE.W D0,$B8(A0) MOVE.W D0,$C8(A0) MOVE.W D0,$D8(A0) CLR.B pt_SongPos CLR.B pt_Counter CLR.B pt_PattPos MOVEM.L (SP)+,D0-D3/A0-A2 RTS pt_StopMusic MOVEM.L D0/A0,-(SP) MOVEQ #0,D0 LEA $DFF000,A0 MOVE.W D0,$A8(A0) MOVE.W D0,$B8(A0) MOVE.W D0,$C8(A0) MOVE.W D0,$D8(A0) MOVE.W #$000F,$DFF096 ;stop AudioDMA activity MOVEM.L (SP)+,D0/A0 RTS pt_PlayMusic MOVEM.L D0-D7/A0-A6,-(SP) MOVE.L pt_SongDataPtr(PC),A0 ADDQ.L #1,pt_Counter MOVE.L pt_Counter(PC),D0 CMP.L pt_CurrSpeed(PC),D0 BLO.B pt_NoNewNote CLR.L pt_Counter TST.B pt_PattDelayTime2 BEQ.B pt_GetNewNote BSR.B pt_NoNewAllChannels BRA.W pt_dskip pt_NoNewNote BSR.B pt_NoNewAllChannels BRA.W pt_NoNewPositionYet pt_NoNewAllChannels LEA pt_audchan1temp(PC),A6 LEA $DFF0A0,A5 BSR.W pt_CheckEffects LEA pt_audchan2temp(PC),A6 LEA $DFF0B0,A5 BSR.W pt_CheckEffects LEA pt_audchan3temp(PC),A6 LEA $DFF0C0,A5 BSR.W pt_CheckEffects LEA pt_audchan4temp(PC),A6 LEA $DFF0D0,A5 BRA.W pt_CheckEffects pt_GetNewNote LEA 12(A0),A3 LEA sd_pattpos(A0),A2 LEA sd_patterndata(A0),A0 MOVEQ #0,D1 MOVE.L pt_SongPosition(PC),D0 MOVE.B 0(a2,D0.W),D1 ASL.L #8,D1 ;*1024 ASL.L #2,D1 ADD.L pt_PatternPosition(PC),D1 MOVE.L D1,pt_PatternPtr CLR.W pt_DMACONtemp LEA $DFF0A0,A5 LEA pt_audchan1temp(PC),A6 MOVEQ #1,D2 BSR.W pt_PlayVoice MOVEQ #0,D0 MOVE.B n_volume(A6),D0 MOVE.W D0,8(A5) LEA $DFF0B0,A5 LEA pt_audchan2temp(PC),A6 MOVEQ #2,D2 BSR.B pt_PlayVoice MOVEQ #0,D0 MOVE.B n_volume(A6),D0 MOVE.W D0,8(A5) LEA $DFF0C0,A5 LEA pt_audchan3temp(PC),A6 MOVEQ #3,D2 BSR.B pt_PlayVoice MOVEQ #0,D0 MOVE.B n_volume(A6),D0 MOVE.W D0,8(A5) LEA $DFF0D0,A5 LEA pt_audchan4temp(PC),A6 MOVEQ #4,D2 BSR.B pt_PlayVoice MOVEQ #0,D0 MOVE.B n_volume(A6),D0 MOVE.W D0,8(A5) BRA.W pt_SetDMA pt_CheckMetronome CMP.B pt_MetroChannel,D2 BNE.W pt_Return MOVE.B pt_MetroSpeed,D2 BEQ.W pt_Return MOVE.L pt_PatternPosition,D3 LSR.L #4,D3 DIVU D2,D3 SWAP D3 TST.W D3 BNE.W pt_Return AND.L #$00000FFF,(A6) OR.L #$10D6F000,(A6) ;Play sample $1F at period $0D6 (214) RTS pt_PlayVoice TST.L (A6) BNE.B pt_plvskip BSR.W pt_PerNop pt_plvskip MOVE.L 0(a0,D1.L),(A6) ;Read one track from pattern BSR.B pt_CheckMetronome ADDQ.L #4,D1 MOVEQ #0,D2 MOVE.B n_cmd(A6),D2 ;Get lower 4 bits of instrument AND.B #$F0,D2 LSR.B #4,D2 MOVE.B (A6),D0 ;Get higher 4 bits of instrument AND.B #$F0,D0 OR.B D0,D2 TST.B D2 BEQ.B pt_SetRegisters ;Instrument was zero MOVEQ #0,D3 LEA pt_SampleStarts(PC),A1 MOVE D2,D4 MOVE.B D2,n_samplenum(A6) SUBQ.L #1,D2 LSL.L #2,D2 MULU #30,D4 MOVE.L 0(a1,D2.L),n_start(A6) MOVE.W 0(a3,D4.L),n_length(A6) MOVE.W 0(a3,D4.L),n_reallength(A6) MOVE.B 2(A3,D4.L),n_finetune(A6) MOVE.B 3(A3,D4.L),n_volume(A6) MOVE.W 4(A3,D4.L),D3 ;Get repeat TST.W D3 BEQ.B pt_NoLoop MOVE.L n_start(A6),D2 ;Get start ASL.W #1,D3 ADD.L D3,D2 ;Add repeat MOVE.L D2,n_loopstart(A6) MOVE.L D2,n_wavestart(A6) MOVE.W 4(A3,D4.L),D0 ;Get repeat ADD.W 6(A3,D4.L),D0 ;Add replen MOVE.W D0,n_length(A6) MOVE.W 6(A3,D4.L),n_replen(A6) ;Save replen BRA.B pt_SetRegisters pt_NoLoop MOVE.L n_start(A6),D2 ADD.L D3,D2 MOVE.L D2,n_loopstart(A6) MOVE.L D2,n_wavestart(A6) MOVE.W 6(A3,D4.L),n_replen(A6) ;Save replen pt_SetRegisters MOVE.W (A6),D0 AND.W #$0FFF,D0 BEQ.W pt_CheckMoreEffects ;If no note -> MOVE.W 2(A6),D0 AND.W #$0FF0,D0 CMP.W #$0E50,D0 ;finetune? BEQ.B pt_DoSetFineTune MOVE.B 2(A6),D0 AND.B #$0F,D0 CMP.B #3,D0 ;TonePortamento? BEQ.B pt_ChkTonePorta CMP.B #5,D0 ;TonePortamento + VolSlide? BEQ.B pt_ChkTonePorta CMP.B #9,D0 ;Sample Offset? BNE.B pt_SetPeriod BSR.W pt_CheckMoreEffects BRA.B pt_SetPeriod pt_DoSetFineTune BSR.W pt_SetFineTune BRA.B pt_SetPeriod pt_ChkTonePorta BSR.W pt_SetTonePorta BRA.W pt_CheckMoreEffects pt_SetPeriod MOVEM.L D0-D1/A0-A1,-(SP) MOVE.W (A6),D1 AND.W #$0FFF,D1 LEA pt_PeriodTable(PC),A1 MOVEQ #0,D0 MOVEQ #$24,D7 pt_ftuloop CMP.W 0(a1,D0.W),D1 BHS.B pt_ftufound ADDQ.L #2,D0 DBRA D7,pt_ftuloop pt_ftufound MOVEQ #0,D1 MOVE.B n_finetune(A6),D1 MULU #37*2,D1 ADD.L D1,A1 MOVE.W 0(a1,D0.W),n_period(A6) MOVEM.L (SP)+,D0-D1/A0-A1 MOVE.W 2(A6),D0 AND.W #$0FF0,D0 CMP.W #$0ED0,D0 BEQ.W pt_CheckMoreEffects MOVE.W n_dmabit(A6),$DFF096 BTST #2,n_wavecontrol(A6) BNE.B pt_vibnoc CLR.B n_vibratopos(A6) pt_vibnoc BTST #6,n_wavecontrol(A6) BNE.B pt_trenoc CLR.B n_tremolopos(A6) pt_trenoc MOVE.W n_length(A6),4(A5) ;Set length MOVE.L n_start(A6),(A5) ;Set start BNE.B pt_sdmaskp CLR.L n_loopstart(A6) MOVEQ #1,D0 MOVE.W D0,4(A5) MOVE.W D0,n_replen(A6) pt_sdmaskp MOVE.W n_period(A6),D0 MOVE.W D0,6(A5) ;Set period ST n_trigger(A6) MOVE.W n_dmabit(A6),D0 OR.W D0,pt_DMACONtemp BRA.W pt_CheckMoreEffects pt_SetDMA move.b pt_timeout,$bfe701 ;TimerB HI move.b pt_timeout+1,$bfe601 ;TimerB LO move.b #%000011001,$bfef01 ;set commandbits: OneShot & CLK & Start pt_timerwait1 btst #0,$bfef01 ;timeout on timerB? (ICR TimerB) bne.s pt_timerwait1 ;nope... MOVE.W pt_DMACONtemp,D0 AND.W pt_ActiveChannels,D0 ;mask out inactive channels OR.W #$8000,D0 MOVE.W D0,$DFF096 move.b pt_timeout,$bfe701 ;TimerB HI move.b pt_timeout+1,$bfe601 ;TimerB LO move.b #%000011001,$bfef01 ;set commandbits: OneShot & CLK & Start pt_timerwait2 btst #0,$bfef01 ;timeout on timerB? (ICR TimerB) bne.s pt_timerwait2 ;nope... LEA $DFF000,A5 LEA pt_audchan4temp(PC),A6 MOVE.L n_loopstart(A6),$D0(A5) MOVE.W n_replen(A6),$D4(A5) LEA pt_audchan3temp(PC),A6 MOVE.L n_loopstart(A6),$C0(A5) MOVE.W n_replen(A6),$C4(A5) LEA pt_audchan2temp(PC),A6 MOVE.L n_loopstart(A6),$B0(A5) MOVE.W n_replen(A6),$B4(A5) LEA pt_audchan1temp(PC),A6 MOVE.L n_loopstart(A6),$A0(A5) MOVE.W n_replen(A6),$A4(A5) pt_dskip ADD.L #16,pt_PatternPosition MOVE.B pt_PattDelayTime,D0 BEQ.B pt_dskpc MOVE.B D0,pt_PattDelayTime2 CLR.B pt_PattDelayTime pt_dskpc TST.B pt_PattDelayTime2 BEQ.B pt_dskpa SUBQ.B #1,pt_PattDelayTime2 BEQ.B pt_dskpa SUB.L #16,pt_PatternPosition pt_dskpa TST.B pt_PBreakFlag BEQ.B pt_nnpysk SF pt_PBreakFlag MOVEQ #0,D0 MOVE.B pt_PBreakPosition(PC),D0 LSL.W #4,D0 MOVE.L D0,pt_PatternPosition CLR.B pt_PBreakPosition pt_nnpysk CMP.L #1024,pt_PatternPosition BNE.B pt_NoNewPositionYet pt_NextPosition MOVEQ #0,D0 MOVE.B pt_PBreakPosition(PC),D0 LSL.W #4,D0 MOVE.L D0,pt_PatternPosition CLR.B pt_PBreakPosition CLR.B pt_PosJumpAssert ADDQ.L #1,pt_SongPosition AND.L #$7F,pt_SongPosition MOVE.L pt_SongPosition(PC),D1 MOVE.L pt_SongDataPtr(PC),A0 CMP.B sd_numofpatt(A0),D1 BLO.B pt_NoNewPositionYet CLR.L pt_SongPosition pt_NoNewPositionYet TST.B pt_PosJumpAssert BNE.B pt_NextPosition MOVEM.L (SP)+,D0-D7/A0-A6 RTS pt_CheckEffects BSR.B pt_chkefx2 MOVEQ #0,D0 MOVE.B n_volume(A6),D0 MOVE.W D0,8(A5) RTS pt_chkefx2 BSR.W pt_UpdateFunk MOVE.W n_cmd(A6),D0 AND.W #$0FFF,D0 BEQ.B pt_Return MOVE.B n_cmd(A6),D0 AND.B #$0F,D0 TST.B D0 BEQ.B pt_Arpeggio CMP.B #1,D0 BEQ.W pt_PortaUp CMP.B #2,D0 BEQ.W pt_PortaDown CMP.B #3,D0 BEQ.W pt_TonePortamento CMP.B #4,D0 BEQ.W pt_Vibrato CMP.B #5,D0 BEQ.W pt_TonePlusVolSlide CMP.B #6,D0 BEQ.W pt_VibratoPlusVolSlide CMP.B #$E,D0 BEQ.W pt_ECommands pt_SetBack MOVE.W n_period(A6),6(A5) CMP.B #7,D0 BEQ.W pt_Tremolo CMP.B #$A,D0 BEQ.W pt_VolumeSlide pt_Return RTS pt_PerNop MOVE.W n_period(A6),6(A5) RTS pt_Arpeggio MOVEQ #0,D0 MOVE.L pt_Counter(PC),D0 DIVS #3,D0 SWAP D0 CMP.W #1,D0 BEQ.B pt_Arpeggio1 CMP.W #2,D0 BEQ.B pt_Arpeggio2 pt_Arpeggio0 MOVE.W n_period(A6),D2 BRA.B pt_ArpeggioSet pt_Arpeggio1 MOVEQ #0,D0 MOVE.B n_cmdlo(A6),D0 LSR.B #4,D0 BRA.B pt_ArpeggioFind pt_Arpeggio2 MOVEQ #0,D0 MOVE.B n_cmdlo(A6),D0 AND.B #15,D0 pt_ArpeggioFind ASL.W #1,D0 MOVEQ #0,D1 MOVE.B n_finetune(A6),D1 MULU #37*2,D1 LEA pt_PeriodTable(PC),A0 ADD.L D1,A0 MOVEQ #0,D1 MOVE.W n_period(A6),D1 MOVEQ #$24,D7 pt_arploop MOVE.W 0(a0,D0.W),D2 CMP.W (A0),D1 BHS.B pt_ArpeggioSet ADDQ.L #2,A0 DBRA D7,pt_arploop RTS pt_ArpeggioSet MOVE.W D2,6(A5) RTS pt_FinePortaUp TST.L pt_Counter BNE.B pt_Return MOVE.B #$0F,pt_LowMask pt_PortaUp MOVEQ #0,D0 MOVE.B n_cmdlo(A6),D0 AND.B pt_LowMask,D0 MOVE.B #$FF,pt_LowMask SUB.W D0,n_period(A6) MOVE.W n_period(A6),D0 AND.W #$0FFF,D0 CMP.W #$0071,D0 BPL.B pt_PortaUskip AND.W #$F000,n_period(A6) OR.W #$0071,n_period(A6) pt_PortaUskip MOVE.W n_period(A6),D0 AND.W #$0FFF,D0 MOVE.W D0,6(A5) RTS pt_FinePortaDown TST.L pt_Counter BNE.W pt_Return MOVE.B #$0F,pt_LowMask pt_PortaDown CLR.W D0 MOVE.B n_cmdlo(A6),D0 AND.B pt_LowMask,D0 MOVE.B #$FF,pt_LowMask ADD.W D0,n_period(A6) MOVE.W n_period(A6),D0 AND.W #$0FFF,D0 CMP.W #$0358,D0 BMI.B pt_Portadskip AND.W #$F000,n_period(A6) OR.W #$0358,n_period(A6) pt_Portadskip MOVE.W n_period(A6),D0 AND.W #$0FFF,D0 MOVE.W D0,6(A5) RTS pt_SetTonePorta MOVE.L A0,-(SP) MOVE.W (A6),D2 AND.W #$0FFF,D2 MOVEQ #0,D0 MOVE.B n_finetune(A6),D0 MULU #37*2,D0 LEA pt_PeriodTable(PC),A0 ADD.L D0,A0 MOVEQ #0,D0 pt_StpLoop CMP.W 0(a0,D0.W),D2 BHS.B pt_StpFound ADDQ.W #2,D0 CMP.W #37*2,D0 BLO.B pt_StpLoop MOVEQ #35*2,D0 pt_StpFound MOVE.B n_finetune(A6),D2 AND.B #8,D2 BEQ.B pt_StpGoss TST.W D0 BEQ.B pt_StpGoss SUBQ.W #2,D0 pt_StpGoss MOVE.W 0(a0,D0.W),D2 MOVE.L (SP)+,A0 MOVE.W D2,n_wantedperiod(A6) MOVE.W n_period(A6),D0 CLR.B n_toneportdirec(A6) CMP.W D0,D2 BEQ.B pt_ClearTonePorta BGE.W pt_Return MOVE.B #1,n_toneportdirec(A6) RTS pt_ClearTonePorta CLR.W n_wantedperiod(A6) RTS pt_TonePortamento MOVE.B n_cmdlo(A6),D0 BEQ.B pt_TonePortNoChange MOVE.B D0,n_toneportspeed(A6) CLR.B n_cmdlo(A6) pt_TonePortNoChange TST.W n_wantedperiod(A6) BEQ.W pt_Return MOVEQ #0,D0 MOVE.B n_toneportspeed(A6),D0 TST.B n_toneportdirec(A6) BNE.B pt_TonePortaUp pt_TonePortaDown ADD.W D0,n_period(A6) MOVE.W n_wantedperiod(A6),D0 CMP.W n_period(A6),D0 BGT.B pt_TonePortaSetPer MOVE.W n_wantedperiod(A6),n_period(A6) CLR.W n_wantedperiod(A6) BRA.B pt_TonePortaSetPer pt_TonePortaUp SUB.W D0,n_period(A6) MOVE.W n_wantedperiod(A6),D0 CMP.W n_period(A6),D0 BLT.B pt_TonePortaSetPer MOVE.W n_wantedperiod(A6),n_period(A6) CLR.W n_wantedperiod(A6) pt_TonePortaSetPer MOVE.W n_period(A6),D2 MOVE.B n_glissfunk(A6),D0 AND.B #$0F,D0 BEQ.B pt_GlissSkip MOVEQ #0,D0 MOVE.B n_finetune(A6),D0 MULU #37*2,D0 LEA pt_PeriodTable(PC),A0 ADD.L D0,A0 MOVEQ #0,D0 pt_GlissLoop CMP.W 0(a0,D0.W),D2 BHS.B pt_GlissFound ADDQ.W #2,D0 CMP.W #37*2,D0 BLO.B pt_GlissLoop MOVEQ #35*2,D0 pt_GlissFound MOVE.W 0(a0,D0.W),D2 pt_GlissSkip MOVE.W D2,6(A5) ;Set period RTS pt_Vibrato MOVE.B n_cmdlo(A6),D0 BEQ.B pt_Vibrato2 MOVE.B n_vibratocmd(A6),D2 AND.B #$0F,D0 BEQ.B pt_vibskip AND.B #$F0,D2 OR.B D0,D2 pt_vibskip MOVE.B n_cmdlo(A6),D0 AND.B #$F0,D0 BEQ.B pt_vibskip2 AND.B #$0F,D2 OR.B D0,D2 pt_vibskip2 MOVE.B D2,n_vibratocmd(A6) pt_Vibrato2 MOVE.L A4,-(SP) MOVE.B n_vibratopos(A6),D0 LEA pt_VibratoTable(PC),A4 LSR.W #2,D0 AND.W #$001F,D0 MOVEQ #0,D2 MOVE.B n_wavecontrol(A6),D2 AND.B #$03,D2 BEQ.B pt_vib_sine LSL.B #3,D0 CMP.B #1,D2 BEQ.B pt_vib_rampdown MOVE.B #255,D2 BRA.B pt_vib_set pt_vib_rampdown TST.B n_vibratopos(A6) BPL.B pt_vib_rampdown2 MOVE.B #255,D2 SUB.B D0,D2 BRA.B pt_vib_set pt_vib_rampdown2 MOVE.B D0,D2 BRA.B pt_vib_set pt_vib_sine MOVE.B 0(A4,D0.W),D2 pt_vib_set MOVE.B n_vibratocmd(A6),D0 AND.W #15,D0 MULU D0,D2 LSR.W #7,D2 MOVE.W n_period(A6),D0 TST.B n_vibratopos(A6) BMI.B pt_VibratoNeg ADD.W D2,D0 BRA.B pt_Vibrato3 pt_VibratoNeg SUB.W D2,D0 pt_Vibrato3 MOVE.W D0,6(A5) MOVE.B n_vibratocmd(A6),D0 LSR.W #2,D0 AND.W #$003C,D0 ADD.B D0,n_vibratopos(A6) MOVE.L (SP)+,A4 RTS pt_TonePlusVolSlide BSR.W pt_TonePortNoChange BRA.W pt_VolumeSlide pt_VibratoPlusVolSlide BSR.B pt_Vibrato2 BRA.W pt_VolumeSlide pt_Tremolo MOVE.L A4,-(SP) MOVE.B n_cmdlo(A6),D0 BEQ.B pt_Tremolo2 MOVE.B n_tremolocmd(A6),D2 AND.B #$0F,D0 BEQ.B pt_treskip AND.B #$F0,D2 OR.B D0,D2 pt_treskip MOVE.B n_cmdlo(A6),D0 AND.B #$F0,D0 BEQ.B pt_treskip2 AND.B #$0F,D2 OR.B D0,D2 pt_treskip2 MOVE.B D2,n_tremolocmd(A6) pt_Tremolo2 MOVE.B n_tremolopos(A6),D0 LEA pt_VibratoTable(PC),A4 LSR.W #2,D0 AND.W #$001F,D0 MOVEQ #0,D2 MOVE.B n_wavecontrol(A6),D2 LSR.B #4,D2 AND.B #$03,D2 BEQ.B pt_tre_sine LSL.B #3,D0 CMP.B #1,D2 BEQ.B pt_tre_rampdown MOVE.B #255,D2 BRA.B pt_tre_set pt_tre_rampdown TST.B n_vibratopos(A6) BPL.B pt_tre_rampdown2 MOVE.B #255,D2 SUB.B D0,D2 BRA.B pt_tre_set pt_tre_rampdown2 MOVE.B D0,D2 BRA.B pt_tre_set pt_tre_sine MOVE.B 0(A4,D0.W),D2 pt_tre_set MOVE.B n_tremolocmd(A6),D0 AND.W #15,D0 MULU D0,D2 LSR.W #6,D2 MOVEQ #0,D0 MOVE.B n_volume(A6),D0 TST.B n_tremolopos(A6) BMI.B pt_TremoloNeg ADD.W D2,D0 BRA.B pt_Tremolo3 pt_TremoloNeg SUB.W D2,D0 pt_Tremolo3 BPL.B pt_TremoloSkip CLR.W D0 pt_TremoloSkip CMP.W #$40,D0 BLS.B pt_TremoloOk MOVE.W #$40,D0 pt_TremoloOk MOVE.W D0,8(A5) MOVE.B n_tremolocmd(A6),D0 LSR.W #2,D0 AND.W #$003C,D0 ADD.B D0,n_tremolopos(A6) MOVE.L (SP)+,A4 ADDQ.L #4,SP RTS pt_SampleOffset MOVEQ #0,D0 MOVE.B n_cmdlo(A6),D0 BEQ.B pt_sononew MOVE.B D0,n_sampleoffset(A6) pt_sononew MOVE.B n_sampleoffset(A6),D0 LSL.W #7,D0 CMP.W n_length(A6),D0 BGE.B pt_sofskip SUB.W D0,n_length(A6) LSL.W #1,D0 ADD.L D0,n_start(A6) RTS pt_sofskip MOVE.W #1,n_length(A6) RTS pt_VolumeSlide MOVEQ #0,D0 MOVE.B n_cmdlo(A6),D0 LSR.B #4,D0 TST.B D0 BEQ.B pt_VolSlideDown pt_VolSlideUp ADD.B D0,n_volume(A6) CMP.B #$40,n_volume(A6) BMI.B pt_vsuskip MOVE.B #$40,n_volume(A6) pt_vsuskip MOVE.B n_volume(A6),D0 RTS pt_VolSlideDown MOVEQ #0,D0 MOVE.B n_cmdlo(A6),D0 AND.B #$0F,D0 pt_VolSlideDown2 SUB.B D0,n_volume(A6) BPL.B pt_vsdskip CLR.B n_volume(A6) pt_vsdskip MOVE.B n_volume(A6),D0 RTS pt_PositionJump MOVEQ #0,D0 MOVE.B n_cmdlo(A6),D0 SUBQ.B #1,D0 MOVE.L D0,pt_SongPosition pt_pj2 CLR.B pt_PBreakPosition ST pt_PosJumpAssert RTS pt_VolumeChange MOVEQ #0,D0 MOVE.B n_cmdlo(A6),D0 CMP.B #$40,D0 BLS.B pt_VolumeOk MOVEQ #$40,D0 pt_VolumeOk MOVE.B D0,n_volume(A6) RTS pt_PatternBreak MOVEQ #0,D0 MOVE.B n_cmdlo(A6),D0 MOVE.L D0,D2 LSR.B #4,D0 MULU #10,D0 AND.B #$0F,D2 ADD.B D2,D0 CMP.B #63,D0 BHI.B pt_pj2 MOVE.B D0,pt_PBreakPosition ST pt_PosJumpAssert RTS pt_SetSpeed MOVE.B 3(A6),D0 AND.W #$FF,D0 BEQ.B pt_SpeedNull ; CMP.W #32,D0 ;change this for lev6/CIA users ; BLO.B normspd ;it updates the countervalues (Tempo) ; MOVE.W D0,RealTempo ;for the BPM timer ; MOVEM.L D0-D7/A0-A6,-(SP) ; ST UpdateTempo ; JSR SetTempo ; MOVEM.L (SP)+,D0-D7/A0-A6 ; RTS pt_normspd CLR.L pt_Counter MOVE.W D0,pt_CurrSpeed+2 RTS pt_SpeedNull RTS pt_CheckMoreEffects MOVE.B 2(A6),D0 AND.B #$0F,D0 CMP.B #$9,D0 BEQ.W pt_SampleOffset CMP.B #$B,D0 BEQ.W pt_PositionJump CMP.B #$D,D0 BEQ.B pt_PatternBreak CMP.B #$E,D0 BEQ.B pt_ECommands CMP.B #$F,D0 BEQ.B pt_SetSpeed CMP.B #$C,D0 BEQ.W pt_VolumeChange BRA.W pt_PerNop pt_ECommands MOVE.B n_cmdlo(A6),D0 AND.B #$F0,D0 LSR.B #4,D0 BEQ.B pt_FilterOnOff CMP.B #1,D0 BEQ.W pt_FinePortaUp CMP.B #2,D0 BEQ.W pt_FinePortaDown CMP.B #3,D0 BEQ.B pt_SetGlissControl CMP.B #4,D0 BEQ.W pt_SetVibratoControl CMP.B #5,D0 BEQ.W pt_SetFineTune CMP.B #6,D0 BEQ.W pt_JumpLoop CMP.B #7,D0 BEQ.W pt_SetTremoloControl CMP.B #8,D0 BEQ.W pt_KarplusStrong CMP.B #$E,D0 BEQ.W pt_PatternDelay CMP.B #9,D0 BEQ.W pt_RetrigNote CMP.B #$A,D0 BEQ.W pt_VolumeFineUp CMP.B #$B,D0 BEQ.W pt_VolumeFineDown CMP.B #$C,D0 BEQ.W pt_NoteCut CMP.B #$D,D0 BEQ.W pt_NoteDelay CMP.B #$F,D0 BEQ.W pt_FunkIt RTS pt_FilterOnOff MOVE.B n_cmdlo(A6),D0 AND.B #1,D0 ASL.B #1,D0 AND.B #$FD,$BFE001 OR.B D0,$BFE001 RTS pt_SetGlissControl MOVE.B n_cmdlo(A6),D0 AND.B #$0F,D0 AND.B #$F0,n_glissfunk(A6) OR.B D0,n_glissfunk(A6) RTS pt_SetVibratoControl MOVE.B n_cmdlo(A6),D0 AND.B #$0F,D0 AND.B #$F0,n_wavecontrol(A6) OR.B D0,n_wavecontrol(A6) RTS pt_SetFineTune MOVE.B n_cmdlo(A6),D0 AND.B #$0F,D0 MOVE.B D0,n_finetune(A6) RTS pt_JumpLoop TST.L pt_Counter BNE.W pt_Return MOVE.B n_cmdlo(A6),D0 AND.B #$0F,D0 BEQ.B pt_SetLoop TST.B n_loopcount(A6) BEQ.B pt_jumpcnt SUB.B #1,n_loopcount(A6) BEQ.W pt_Return pt_jmploop MOVE.B n_pattpos(A6),pt_PBreakPosition ST pt_PBreakFlag RTS pt_jumpcnt MOVE.B D0,n_loopcount(A6) BRA.B pt_jmploop pt_SetLoop MOVE.L pt_PatternPosition,D0 LSR.L #4,D0 AND.B #63,D0 MOVE.B D0,n_pattpos(A6) RTS pt_SetTremoloControl MOVE.B n_cmdlo(A6),D0 AND.B #$0F,D0 LSL.B #4,D0 AND.B #$0F,n_wavecontrol(A6) OR.B D0,n_wavecontrol(A6) RTS pt_KarplusStrong MOVEM.L D1-D2/A0-A1,-(SP) MOVE.L n_loopstart(A6),A0 MOVE.L A0,A1 MOVE.W n_replen(A6),D0 ADD.W D0,D0 SUBQ.W #2,D0 pt_karplop MOVE.B (A0),D1 EXT.W D1 MOVE.B 1(A0),D2 EXT.W D2 ADD.W D1,D2 ASR.W #1,D2 MOVE.B D2,(A0)+ DBRA D0,pt_karplop MOVE.B (A0),D1 EXT.W D1 MOVE.B (A1),D2 EXT.W D2 ADD.W D1,D2 ASR.W #1,D2 MOVE.B D2,(A0) MOVEM.L (SP)+,D1-D2/A0-A1 RTS pt_RetrigNote MOVE.L D1,-(SP) MOVEQ #0,D0 MOVE.B n_cmdlo(A6),D0 AND.B #$0F,D0 BEQ.W pt_rtnend MOVE.L pt_Counter,D1 BNE.B pt_rtnskp MOVE.W n_note(A6),D1 AND.W #$0FFF,D1 BNE.W pt_rtnend MOVE.L pt_Counter,D1 pt_rtnskp DIVU D0,D1 SWAP D1 TST.W D1 BNE.W pt_rtnend pt_DoRetrg MOVE.W n_dmabit(A6),$DFF096 ;Audio DMA off MOVE.L n_start(A6),(A5) ;Set sampledata pointer MOVE.W n_length(A6),4(A5) ;Set length MOVE.W n_period(A6),6(A5) MOVEQ #0,D0 MOVE.B n_volume(A6),D0 move.b pt_timeout,$bfe701 ;TimerB HI move.b pt_timeout+1,$bfe601 ;TimerB LO move.b #%000011001,$bfef01 ;set commandbits: OneShot & CLK & Start pt_timerwait3 btst #0,$bfef01 ;timeout on timerB? (ICR TimerB) bne.s pt_timerwait3 ;nope... MOVE.W n_dmabit(A6),D0 BSET #15,D0 MOVE.W D0,$DFF096 move.b pt_timeout,$bfe701 ;TimerB HI move.b pt_timeout+1,$bfe601 ;TimerB LO move.b #%000011001,$bfef01 ;set commandbits: OneShot & CLK & Start pt_timerwait4 btst #0,$bfef01 ;timeout on timerB? (ICR TimerB) bne.s pt_timerwait4 ;nope... MOVE.L n_loopstart(A6),(A5) MOVE.L n_replen(A6),4(A5) pt_rtnend MOVE.L (SP)+,D1 RTS pt_VolumeFineUp TST.L pt_Counter BNE.W pt_Return MOVEQ #0,D0 MOVE.B n_cmdlo(A6),D0 AND.B #$F,D0 BRA.W pt_VolSlideUp pt_VolumeFineDown TST.L pt_Counter BNE.W pt_Return MOVEQ #0,D0 MOVE.B n_cmdlo(A6),D0 AND.B #$0F,D0 BRA.W pt_VolSlideDown2 pt_NoteCut MOVEQ #0,D0 MOVE.B n_cmdlo(A6),D0 AND.B #$0F,D0 CMP.L pt_Counter,D0 BNE.W pt_Return CLR.B n_volume(A6) RTS pt_NoteDelay MOVEQ #0,D0 MOVE.B n_cmdlo(A6),D0 AND.B #$0F,D0 CMP.L pt_Counter,D0 BNE.W pt_Return MOVE.W (A6),D0 AND.W #$0FFF,D0 BEQ.W pt_Return MOVE.L D1,-(SP) BRA.W pt_DoRetrg pt_PatternDelay TST.L pt_Counter BNE.W pt_Return MOVEQ #0,D0 MOVE.B n_cmdlo(A6),D0 AND.B #$0F,D0 TST.B pt_PattDelayTime2 BNE.W pt_Return ADDQ.B #1,D0 MOVE.B D0,pt_PattDelayTime RTS pt_FunkIt TST.L pt_Counter BNE.W pt_Return MOVE.B n_cmdlo(A6),D0 AND.B #$0F,D0 LSL.B #4,D0 AND.B #$0F,n_glissfunk(A6) OR.B D0,n_glissfunk(A6) TST.B D0 BEQ.W pt_Return pt_UpdateFunk MOVEM.L A0/D1,-(SP) MOVEQ #0,D0 MOVE.B n_glissfunk(A6),D0 LSR.B #4,D0 BEQ.B pt_funkend LEA pt_FunkTable(PC),A0 MOVE.B 0(a0,D0.W),D0 ADD.B D0,n_funkoffset(A6) BTST #7,n_funkoffset(A6) BEQ.B pt_funkend CLR.B n_funkoffset(A6) MOVE.L n_loopstart(A6),D0 MOVEQ #0,D1 MOVE.W n_replen(A6),D1 ADD.L D1,D0 ADD.L D1,D0 MOVE.L n_wavestart(A6),A0 ADDQ.L #1,A0 CMP.L D0,A0 BLO.B pt_funkok MOVE.L n_loopstart(A6),A0 pt_funkok MOVE.L A0,n_wavestart(A6) MOVEQ #-1,D0 SUB.B (A0),D0 MOVE.B D0,(A0) pt_funkend MOVEM.L (SP)+,A0/D1 RTS pt_FunkTable dc.b 0,5,6,7,8,10,11,13,16,19,22,26,32,43,64,128 pt_VibratoTable dc.b 0,24,49,74,97,120,141,161 dc.b 180,197,212,224,235,244,250,253 dc.b 255,253,250,244,235,224,212,197 dc.b 180,161,141,120,97,74,49,24 pt_PeriodTable ; -> Tuning 0 dc.w 856,808,762,720,678,640,604,570,538,508,480,453 dc.w 428,404,381,360,339,320,302,285,269,254,240,226 dc.w 214,202,190,180,170,160,151,143,135,127,120,113,0 ; -> Tuning 1 dc.w 850,802,757,715,674,637,601,567,535,505,477,450 dc.w 425,401,379,357,337,318,300,284,268,253,239,225 dc.w 213,201,189,179,169,159,150,142,134,126,119,113,0 ; -> Tuning 2 dc.w 844,796,752,709,670,632,597,563,532,502,474,447 dc.w 422,398,376,355,335,316,298,282,266,251,237,224 dc.w 211,199,188,177,167,158,149,141,133,125,118,112,0 ; -> Tuning 3 dc.w 838,791,746,704,665,628,592,559,528,498,470,444 dc.w 419,395,373,352,332,314,296,280,264,249,235,222 dc.w 209,198,187,176,166,157,148,140,132,125,118,111,0 ; -> Tuning 4 dc.w 832,785,741,699,660,623,588,555,524,495,467,441 dc.w 416,392,370,350,330,312,294,278,262,247,233,220 dc.w 208,196,185,175,165,156,147,139,131,124,117,110,0 ; -> Tuning 5 dc.w 826,779,736,694,655,619,584,551,520,491,463,437 dc.w 413,390,368,347,328,309,292,276,260,245,232,219 dc.w 206,195,184,174,164,155,146,138,130,123,116,109,0 ; -> Tuning 6 dc.w 820,774,730,689,651,614,580,547,516,487,460,434 dc.w 410,387,365,345,325,307,290,274,258,244,230,217 dc.w 205,193,183,172,163,154,145,137,129,122,115,109,0 ; -> Tuning 7 dc.w 814,768,725,684,646,610,575,543,513,484,457,431 dc.w 407,384,363,342,323,305,288,272,256,242,228,216 dc.w 204,192,181,171,161,152,144,136,128,121,114,108,0 ; -> Tuning -8 dc.w 907,856,808,762,720,678,640,604,570,538,508,480 dc.w 453,428,404,381,360,339,320,302,285,269,254,240 dc.w 226,214,202,190,180,170,160,151,143,135,127,120,0 ; -> Tuning -7 dc.w 900,850,802,757,715,675,636,601,567,535,505,477 dc.w 450,425,401,379,357,337,318,300,284,268,253,238 dc.w 225,212,200,189,179,169,159,150,142,134,126,119,0 ; -> Tuning -6 dc.w 894,844,796,752,709,670,632,597,563,532,502,474 dc.w 447,422,398,376,355,335,316,298,282,266,251,237 dc.w 223,211,199,188,177,167,158,149,141,133,125,118,0 ; -> Tuning -5 dc.w 887,838,791,746,704,665,628,592,559,528,498,470 dc.w 444,419,395,373,352,332,314,296,280,264,249,235 dc.w 222,209,198,187,176,166,157,148,140,132,125,118,0 ; -> Tuning -4 dc.w 881,832,785,741,699,660,623,588,555,524,494,467 dc.w 441,416,392,370,350,330,312,294,278,262,247,233 dc.w 220,208,196,185,175,165,156,147,139,131,123,117,0 ; -> Tuning -3 dc.w 875,826,779,736,694,655,619,584,551,520,491,463 dc.w 437,413,390,368,347,328,309,292,276,260,245,232 dc.w 219,206,195,184,174,164,155,146,138,130,123,116,0 ; -> Tuning -2 dc.w 868,820,774,730,689,651,614,580,547,516,487,460 dc.w 434,410,387,365,345,325,307,290,274,258,244,230 dc.w 217,205,193,183,172,163,154,145,137,129,122,115,0 ; -> Tuning -1 dc.w 862,814,768,725,684,646,610,575,543,513,484,457 dc.w 431,407,384,363,342,323,305,288,272,256,242,228 dc.w 216,203,192,181,171,161,152,144,136,128,121,114,0 pt_audchan1temp dc.l 0,0,0,0,0,$00010000,0,0,0,0,0 pt_audchan2temp dc.l 0,0,0,0,0,$00020000,0,0,0,0,0 pt_audchan3temp dc.l 0,0,0,0,0,$00040000,0,0,0,0,0 pt_audchan4temp dc.l 0,0,0,0,0,$00080000,0,0,0,0,0 pt_SampleStarts dcb.l 31,0 pt_timeout dc.w 330 ;CIA-B timeout-value pt_Counter dc.l 0 pt_CurrSpeed dc.l 6 pt_PattPos dc.w 0 pt_DMACONtemp dc.w 0 pt_ActiveChannels dc.w %00001111 pt_PatternPtr dc.l 0 pt_PatternPosition dc.l 0 pt_SongPosition dc.l 0 pt_SongDataPtr dc.l 0 pt_MetroSpeed dc.b 0 pt_MetroChannel dc.b 0 pt_Speed dc.b 6 pt_SongPos dc.b 0 pt_PBreakPosition dc.b 0 pt_PosJumpAssert dc.b 0 pt_PBreakFlag dc.b 0 pt_LowMask dc.b 0 pt_PattDelayTime dc.b 0 pt_PattDelayTime2 dc.b 0 even .