* * "AC1D" Playermodule V1.0 * for DeliTracker * by MnemoTroN/Spreadpoint * * Assembled with HiSoft's Devpac 3.02 (for AmigaDOS 37+) * * DeliTracker is * (C) 1991/92 by Delirium * * This Playermodule is * (C) 1992 by MnemoTroN * * The player itself is * (C) 19xx by who-knows? * * * This player could only be tested with the module from the "In The Kitchen" * demo from Anarchy (that's where the player comes from too), so I don't know * if all future modules will run correctly with this. * * I improved the DMA handling because the player didn't play the module * correctly on my A3000 - now it should work fine, hopefully even on the * A4000 (and better ;) * * The player is Enforcer and Mungwall proof - at least with the "In The * Kitchen" module... (Finally I discovered the reason why I own a PC: * It's very useful as an Enforcer/Mungwall terminal!! :) * * * Revision history: * 08 Nov 92 - disassembled the player * 09 Nov 92 - implemented the DeliTracker skeleton * 10 Nov 92 - implemented Volume and Balance control * implemented NextPatt/PrevPatt control * (Bug in DeliTracker discovered: If you specify only ONE * xxxxPatt-Tag, the OTHER one becomes enabled in DeliTracker!) * 11 Nov 92 - removed filter control from the player * 17 Nov 92 - when the volume is set to any other value than $40 at the * initialization, the player didn't notice - fixed * opt o+,ow2-,o10- ;all opts, except ADD-to-LEA opt and ;warnings about 0(Ax)-to-(Ax) opt ;------------------------------------------------------------------------------ ; change this to the appropriate path in your system. ;------------------------------------------------------------------------------ output work:programs/sound/delitracker/deliplayers/AC1D ;------------------------------------------------------------------------------ ; ditto. ;------------------------------------------------------------------------------ incdir "work:assembler/include/" ifnd DELITRACKER_PLAYER_I include "misc/deliplayer.i" endc ;------------------------------------------------------------------------------ ; *** Beginning of Playermodule *** ;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------ ; first we have to create the header, so DeliTracker can recognize us. ;------------------------------------------------------------------------------ PLAYERHEADER player_tags ;------------------------------------------------------------------------------ ; now, a version string for the curious. ;------------------------------------------------------------------------------ dc.b "$VER: AC1D player module V1.0 (17 Nov 92)",10,13,0 even ;------------------------------------------------------------------------------ ; all Tags our player supports. ;------------------------------------------------------------------------------ player_tags: dc.l DTP_PlayerVersion,1 dc.l DTP_PlayerName,playername_txt dc.l DTP_Creator,author_txt dc.l DTP_Check2,check_code dc.l DTP_Interrupt,player_music dc.l DTP_InitPlayer,player_init dc.l DTP_EndPlayer,player_end dc.l DTP_InitSound,sound_init dc.l DTP_Volume,player_setvolume dc.l DTP_Balance,player_setvolume dc.l DTP_NextPatt,player_nextpatt dc.l DTP_PrevPatt,player_prevpatt dc.l TAG_DONE ;forget about the 2nd long ;) playername_txt: dc.b "AC1D",0 ;------------------------------------------------------------------------------ ; General Surgeon's Warning: ; Changing the credits of other people's work can damage your health! :) ;------------------------------------------------------------------------------ author_txt: dc.b "???,",10 dc.b "adapted by MnemoTroN",0 even ;------------------------------------------------------------------------------ ; this routine checks if DeliTracker presented us with a AC1D module. ; it's very simply - the 2nd word in a module seems to contain the ; word $AC1D; at least the initialization routine of the player checks ; for it, so we should be on the safe side. ;------------------------------------------------------------------------------ check_code: move.l dtg_ChkData(a5),a0 ;get address of the module moveq #0,d0 ;clear returncode cmp.w #$ac1d,2(a0) ;do we have a "AC1D" module? sne d0 ;set d0 if it isn't rts ;------------------------------------------------------------------------------ ; player_init gets the address of the module from DeliTracker and stores it ; for later use by the sound_init routine. the audio channels are allocated ; using DeliTracker's routine. ;------------------------------------------------------------------------------ player_init: moveq #0,d0 move.l dtg_GetListData(a5),a0 jsr (a0) lea mt_addr(pc),a1 move.l a0,(a1) ;store module address move.l dtg_AudioAlloc(a5),a0 jmp (a0) ;allocate all channels ;------------------------------------------------------------------------------ ; player_end frees the audio channels - we use DeliTracker here, too. ;------------------------------------------------------------------------------ player_end: move.l dtg_AudioFree(a5),a0 jmp (a0) ;free the audio channels ;------------------------------------------------------------------------------ ; sound_init calls the mt_init routine of the player with the first position ; (null) and the address of the module. ;------------------------------------------------------------------------------ sound_init: lea delidata(pc),a0 move.l a5,(a0) ;store addr of DeliTracker's data array moveq #0,d0 ;start at first pattern move.l mt_addr(pc),a0 ;get addr of the module bsr _mt_init ;call player initialization routine bra.s player_setvolume ;set volume right ;------------------------------------------------------------------------------ ; player_music is called every 1/50th of a second. normally, we could've given ; the address of the _mt_music entry directly to DeliTracker, but if you want ; to do stuff like this, to see how long the routine takes to finish, it's ; easier this way. ;------------------------------------------------------------------------------ player_music: ; move.w #$f00,$dff180 ;red background to see how much time ;the player consumes bsr _mt_music ; move.w #$aaa,$dff180 ;restore background (grey) rts ;------------------------------------------------------------------------------ ; player_setvolume copies the contents of the balance variables in DeliTracker ; to the player's data array (I added the balance to the player myself). also, ; the main volume of the player is set. because the player expects values from ; 0 (loudest) to 64 (silence), we have to calculate a bit... ;------------------------------------------------------------------------------ player_setvolume: lea mt_data(pc),a0 move.w dtg_SndLBal(a5),mt_leftvol-mt_data(a0) move.w dtg_SndRBal(a5),mt_rightvol-mt_data(a0) moveq #64,d0 sub.w dtg_SndVol(a5),d0 move.w d0,mt_volume-mt_data(a0) rts ;------------------------------------------------------------------------------ ; player_nextpatt makes the player think that it has to go to the next pattern. ; no big deal... ;------------------------------------------------------------------------------ player_nextpatt: lea mt_data(pc),a0 st mt_breakflag-mt_data(a0) ;force patternbreak move.w #-1,mt_destpatt-mt_data(a0) ;jump to next position move.w #$f,$dff096 rts ;------------------------------------------------------------------------------ ; player_prevpatt sets the position counter to the previous position. if the ; beginning of the song was reached, the counter is set to the last position. ;------------------------------------------------------------------------------ player_prevpatt: lea mt_data(pc),a0 st mt_breakflag-mt_data(a0) ;force patternbreak move.w lbW000AF8-mt_data(a0),d0 ;get actual position subq.w #1,d0 ;decrease bpl.s .ok ;if >=0 it's ok move.w lbW000AFA-mt_data(a0),d0 ;otherwise get length subq.w #1,d0 ;decrease (this is the last pos) .ok: move.w d0,mt_destpatt-mt_data(a0) ;jump to this position move.w #$f,$dff096 rts delidata: dc.l 0 ;holds address of DeliTracker's data area mt_addr: dc.l 0 ;holds the address of the module ; **************************** ; * ; * AC1D Replayer Source ; * ; * Done by ; * ; * ReSourced and improved by ; * MnemoTroN/Spreadpoint ; * ; **************************** ifd Lame_Programming _InitInt: bra InitInterrupt _RestoreInt: bra RestoreInt endc _mt_init: bra mt_init _mt_music: bra mt_music _mt_end: bra mt_end _mt_setfade: bra mt_setfade _mt_switchchannels: bra mt_switchchannels _mt_mutechannels: bra mt_mutechannels _mt_getfadestatus: bra mt_getfadestatus _mt_getstatus: bra mt_getstatus ifd Lame_Programming InitInterrupt: bsr.s mt_init lea IntAdr(pc),a0 move.l $6C.w,2(a0) lea MusicInt(pc),a0 move.l a0,$6C.w rts RestoreInt: lea IntAdr(pc),a0 move.l 2(a0),$6C.w bsr mt_end rts MusicInt: move.l d0,-(sp) move.w $DFF01E,d0 and.w #$20,d0 beq.s .NoVInt bsr mt_music .NoVInt: move.l (sp)+,d0 IntAdr: jmp $10000 endc mt_init: movem.l d1-d7/a0-a6,-(sp) and.w #$FF,d0 ;max. patternno. is $FF move.w d0,-(sp) ;save on stack lea mt_data(pc),a6 ;ptr to player's global datas in a6 clr.w mt_fadestatus-mt_data(a6) move.l a0,mt_data-mt_data(a6) ;store start addr of module move.l a0,a1 add.l 4(a0),a1 lea 8(a0),a2 lea mt_sampletab(pc),a3 move.w #31,d7 ;32 samples?!?!?? InitSample_Loop: movem.l NullLongs(pc),d0-d6 move.w (a2)+,d0 move.w (a2)+,d1 move.w d1,d4 and.w #$7F,d1 lsr.w #8,d4 and.w #15,d4 move.w (a2)+,d2 move.w (a2)+,d3 move.l a1,a4 add.w d2,d2 add.l d2,a4 move.l a1,(a3)+ move.w d0,(a3)+ move.l a4,(a3)+ move.w d3,(a3)+ move.w d1,(a3)+ move.w d4,(a3)+ add.w d0,d0 add.l d0,a1 dbra d7,InitSample_Loop lea $300(a0),a1 move.l a1,lbL000AEC-mt_data(a6) lea $380(a0),a1 move.l a1,lbL000AF0-mt_data(a6) lea $100(a0),a1 move.l a1,lbL000AF4-mt_data(a6) move.w 2(a0),d0 cmp.w #$AC1D,d0 ;AC1D code? bne.s lbC000120 ;no, player has been initalized already move.w #$D1CA,2(a0) ;kill code move.w #$7F,d7 lbC0000F0: tst.l (a1) beq.s lbC000120 move.l (a1),a2 add.l a0,a2 move.l a2,(a1)+ move.l a2,d0 add.l #12,d0 move.l (a2),d1 add.l d0,d1 move.l d1,(a2) move.l 4(a2),d1 add.l d0,d1 move.l d1,4(a2) move.l 8(a2),d1 add.l d0,d1 move.l d1,8(a2) dbra d7,lbC0000F0 lbC000120: ; moveq #64,d0 ; move.w d0,mt_leftvol-mt_data(a6) ; move.w d0,mt_rightvol-mt_data(a6) moveq #0,d0 sf mt_fadeendflag-mt_data(a6) ; move.w d0,mt_volume-mt_data(a6) sf mt_breakflag-mt_data(a6) move.w d0,lbW000B18-mt_data(a6) move.w d0,mt_framecount-mt_data(a6) move.w d0,mt_stepcount-mt_data(a6) move.w d0,lbW000B1E-mt_data(a6) move.b (a0),d0 move.w d0,lbW000AFA-mt_data(a6) move.b 1(a0),d0 cmp.w #$7F,d0 blt.s mt_lengthok moveq #0,d0 mt_lengthok: move.w d0,lbW000AFC-mt_data(a6) move.w #6,mt_speed-mt_data(a6) move.w #15,mt_chanenable-mt_data(a6) move.w #$FFFF,mt_destpatt-mt_data(a6) move.w (sp)+,d7 move.w d7,lbW000AF8-mt_data(a6) move.l lbL000AEC-mt_data(a6),a1 moveq #0,d0 move.b (a1,d7.w),d0 move.w d0,lbW000AFE-mt_data(a6) lsl.w #2,d0 move.l lbL000AF4-mt_data(a6),a1 add.w d0,a1 move.l (a1),d0 move.l d0,a1 add.l #12,d0 lea mt_periods(pc),a4 lea mt_chandat0(pc),a0 move.l d0,(a0) clr.w $46(a0) move.w #$FFFF,$12(a0) move.l a4,8(a0) lea mt_chandat1(pc),a0 move.l (a1)+,(a0) clr.w $46(a0) move.w #$FFFF,$12(a0) move.l a4,8(a0) lea mt_chandat2(pc),a0 move.l (a1)+,(a0) clr.w $46(a0) move.w #$FFFF,$12(a0) move.l a4,8(a0) lea mt_chandat3(pc),a0 move.l (a1)+,(a0) clr.w $46(a0) move.w #$FFFF,$12(a0) move.l a4,8(a0) move.w #15,$DFF096 move.w #$FF,$DFF09E ; bset #1,$BFE001 clr.w $DFF0A8 clr.w $DFF0B8 clr.w $DFF0C8 clr.w $DFF0D8 move.w #$FFFF,mt_fadestatus-mt_data(a6) moveq #0,d0 move.w lbW000AFA-mt_data(a6),d0 movem.l (sp)+,d1-d7/a0-a6 rts NullLongs: dcb.w $10,0 mt_end: move.l a6,-(sp) lea mt_data(pc),a6 clr.w mt_fadestatus-mt_data(a6) move.w #15,$DFF096 clr.w $DFF0A8 clr.w $DFF0B8 clr.w $DFF0C8 clr.w $DFF0D8 move.l (sp)+,a6 rts mt_switchchannels: move.l a6,-(sp) lea mt_data(pc),a6 move.w mt_chanenable-mt_data(a6),d0 eor.w #15,d0 move.l (sp)+,a6 rts mt_mutechannels: move.l a6,-(sp) lea mt_data(pc),a6 and.w #15,d0 move.w d0,$DFF096 eor.w #15,d0 move.w d0,mt_chanenable-mt_data(a6) move.l (sp)+,a6 rts mt_getfadestatus: move.l a6,-(sp) lea mt_data(pc),a6 move.w mt_fadestatus-mt_data(a6),d0 move.l (sp)+,a6 rts mt_getstatus: movem.l a0/a4/a6,-(sp) move.l a0,a4 lea mt_chandat0(pc),a0 move.l $1C(a0),(a4)+ move.l $14(a0),(a4)+ move.l $18(a0),(a4)+ clr.l (a4)+ lea mt_chandat1(pc),a0 move.l $1C(a0),(a4)+ move.l $14(a0),(a4)+ move.l $18(a0),(a4)+ clr.l (a4)+ lea mt_chandat2(pc),a0 move.l $1C(a0),(a4)+ move.l $14(a0),(a4)+ move.l $18(a0),(a4)+ clr.l (a4)+ lea mt_chandat3(pc),a0 move.l $1C(a0),(a4)+ move.l $14(a0),(a4)+ move.l $18(a0),(a4)+ clr.l (a4)+ lea mt_data(pc),a6 move.w lbW000B0E-mt_data(a6),(a4)+ move.w lbW000B18-mt_data(a6),(a4)+ move.w mt_stepcount-mt_data(a6),(a4)+ move.w lbW000AFE-mt_data(a6),(a4)+ move.w lbW000AF8-mt_data(a6),(a4)+ move.w lbW000B1E-mt_data(a6),(a4) movem.l (sp)+,a0/a4/a6 rts mt_setfade: move.l a6,-(sp) lea mt_data(pc),a6 and.w #$3F,d0 move.w d0,mt_fadedelay-mt_data(a6) move.w d0,mt_fadedelay_count-mt_data(a6) st mt_fadeendflag-mt_data(a6) clr.w mt_volume-mt_data(a6) move.l (sp)+,a6 rts mt_music: movem.l d0-d7/a0-a6,-(sp) lea mt_data(pc),a6 tst.b mt_fadeendflag-mt_data(a6) beq.s lbC00035A bsr mt_handlefade lbC00035A: tst.w mt_fadestatus-mt_data(a6) beq mt_exit move.w mt_chanenable-mt_data(a6),d7 btst #0,d7 beq.s mt_skipchan0 lea mt_chandat0(pc),a0 bsr HandleChannel mt_skipchan0: btst #1,d7 beq.s mt_skipchan1 lea mt_chandat1(pc),a0 bsr HandleChannel mt_skipchan1: btst #2,d7 beq.s mt_skipchan2 lea mt_chandat2(pc),a0 bsr HandleChannel mt_skipchan2: btst #3,d7 beq.s mt_skipchan3 lea mt_chandat3(pc),a0 bsr HandleChannel mt_skipchan3: tst.w lbW000B18-mt_data(a6) beq.s mt_nonewsamples clr.w lbW000B18-mt_data(a6) bsr mt_setdma bra mt_nextframe mt_nonewsamples: tst.w mt_framecount-mt_data(a6) beq.s lbC0003BA bra mt_nextframe lbC0003BA: lea mt_sampletab(pc),a3 clr.w lbW000B0E-mt_data(a6) lea mt_chandat0(pc),a0 bsr mt_docommands lea mt_chandat1(pc),a0 bsr mt_docommands lea mt_chandat2(pc),a0 bsr mt_docommands lea mt_chandat3(pc),a0 bsr mt_docommands move.w lbW000B0E-mt_data(a6),lbW000B16-mt_data(a6) move.w #$FFFF,lbW000B18-mt_data(a6) move.w mt_speed-mt_data(a6),mt_framecount-mt_data(a6) tst.b mt_breakflag-mt_data(a6) beq.s mt_nextstep sf mt_breakflag-mt_data(a6) tst.w mt_destpatt-mt_data(a6) bmi.s mt_nextpos move.w mt_destpatt-mt_data(a6),d0 move.w #$FFFF,mt_destpatt-mt_data(a6) bra.s lbC000432 mt_nextstep: addq.w #1,mt_stepcount-mt_data(a6) cmp.w #$40,mt_stepcount-mt_data(a6) bne.s mt_nextframe mt_nextpos: moveq #0,d0 move.w lbW000AF8-mt_data(a6),d0 addq.w #1,d0 cmp.w lbW000AFA-mt_data(a6),d0 bne.s lbC000432 addq.w #1,lbW000B1E-mt_data(a6) move.l delidata(pc),a0 move.l dtg_SongEnd(a0),a0 ;signal end of module jsr (a0) ;to DeliTracker move.w lbW000AFC-mt_data(a6),d0 lbC000432: move.w d0,lbW000AF8-mt_data(a6) move.l lbL000AEC-mt_data(a6),a1 move.b (a1,d0.w),d0 move.w d0,lbW000AFE-mt_data(a6) lsl.w #2,d0 move.l lbL000AF4-mt_data(a6),a1 add.w d0,a1 move.l (a1),d0 move.l d0,a1 add.l #12,d0 lea mt_chandat0(pc),a0 move.l d0,(a0) clr.w $46(a0) lea mt_chandat1(pc),a0 move.l (a1)+,(a0) clr.w $46(a0) lea mt_chandat2(pc),a0 move.l (a1)+,(a0) clr.w $46(a0) lea mt_chandat3(pc),a0 move.l (a1)+,(a0) clr.w $46(a0) clr.w mt_stepcount-mt_data(a6) mt_nextframe: subq.w #1,mt_framecount-mt_data(a6) mt_exit: movem.l (sp)+,d0-d7/a0-a6 rts mt_docommands: moveq #0,d0 move.w d0,$24(a0) move.w d0,$26(a0) move.w d0,$2E(a0) move.w d0,$38(a0) move.w d0,$36(a0) move.w d0,$20(a0) move.w d0,$44(a0) move.w d0,$3E(a0) move.w d0,$16(a0) move.w d0,$18(a0) move.w d0,$1A(a0) subq.w #1,d0 move.w d0,$42(a0) move.w #$3F,$14(a0) tst.w $46(a0) bne lbC0007B6 move.l (a0),a5 move.b (a5),d0 btst #7,d0 bne lbC0007D2 move.l 8(a0),a4 move.w #3,lbW000B1A-mt_data(a6) moveq #0,d0 move.b 1(a5),d0 lsr.w #4,d0 move.b (a5),d1 and.b #$40,d1 lsr.b #2,d1 or.b d1,d0 tst.w d0 beq.s lbC000542 move.w d0,$12(a0) move.w d0,$16(a0) subq.w #1,d0 lsl.w #4,d0 move.w 12(a3,d0.w),$1E(a0) moveq #0,d1 move.w 14(a3,d0.w),d1 lsl.w #7,d1 lea mt_periods(pc),a4 add.l d1,a4 move.l a4,8(a0) move.b (a5),d1 and.w #$3F,d1 cmp.w #$3F,d1 bne.s lbC000542 move.l 4(a0),a1 move.w 10(a3,d0.w),4(a1) move.l 6(a3,d0.w),(a1) lbC000542: move.b 1(a5),d0 and.w #15,d0 moveq #0,d1 move.b 2(a5),d1 move.w d0,$18(a0) move.w d1,$1A(a0) lea mt_cmdjmptab(pc),a1 lsl.w #2,d0 jmp (a1,d0.w) mt_cmdjmptab: bra mt_arpeggio ;cmd 0 bra mt_portup ;cmd 1 bra mt_portdown ;cmd 2 bra mt_toneport ;cmd 3 bra mt_handlevib ;cmd 4 bra mt_tonep_volsl ;cmd 5 bra mt_vib_volsl ;cmd 6 bra mt_tremolo ;cmd 7 bra mt_stopsong ;cmd 8 bra mt_cmdok ;cmd 9 bra mt_volslide ;cmd a bra mt_posjump ;cmd b bra mt_setvol ;cmd c bra mt_pattbreak ;cmd d bra mt_doextcmd ;cmd e bra mt_setspeed ;cmd f mt_arpeggio: tst.w d1 beq mt_cmdok move.w d1,d2 and.w #15,d1 lsr.w #4,d2 move.w d1,$28(a0) move.w d2,$2A(a0) move.w #$FFFF,$26(a0) clr.w $2C(a0) bra mt_cmdok mt_portup: neg.w d1 move.w d1,$24(a0) bra mt_cmdok mt_portdown: move.w d1,$24(a0) bra mt_cmdok mt_toneport: move.b (a5),d0 and.w #$3F,d0 cmp.w #$3F,d0 beq.s lbC00060A move.w d0,$10(a0) move.w d0,$14(a0) add.w d0,d0 move.w (a4,d0.w),d0 move.w d0,$3C(a0) tst.w d1 beq.s lbC000616 sub.w $1C(a0),d0 bpl.s lbC000604 neg.w d1 lbC000604: move.w d1,$3A(a0) bra.s lbC000616 lbC00060A: tst.w $3A(a0) bpl.s lbC000612 neg.w d1 lbC000612: move.w d1,$3A(a0) lbC000616: move.w #$FFFF,$38(a0) bra lbC0007A8 mt_handlevib: move.w #$FFFF,$2E(a0) tst.w d1 beq mt_cmdok move.w d1,d2 and.w #$F0,d2 lsr.w #4,d2 and.w #15,d1 lea lbW001468(pc),a1 add.w d1,d1 move.w (a1,d1.w),d1 move.w d1,$34(a0) move.w d2,$32(a0) clr.w $30(a0) bra mt_cmdok mt_tonep_volsl: move.w #$FFFF,$38(a0) bra.s mt_volslide mt_vib_volsl: move.w #$FFFF,$2E(a0) bra.s mt_volslide mt_tremolo: move.w #2,lbW000B1A-mt_data(a6) clr.w $1A(a0) bra mt_cmdok mt_stopsong: bsr mt_end bra mt_cmdok mt_volslide: move.w #$FFFF,d7 cmp.w #$10,d1 blt.s lbC00068A move.w #1,d7 lsr.w #4,d1 bra.s lbC00068E lbC00068A: and.w #15,d1 lbC00068E: move.w d1,$22(a0) move.w d7,$20(a0) bra mt_cmdok mt_posjump: st mt_breakflag-mt_data(a6) move.w d1,mt_destpatt-mt_data(a6) addq.w #1,lbW000B1E-mt_data(a6) bra mt_cmdok mt_setvol: cmp.w #$40,d1 ble.s .mt_volok move.w #$40,d1 .mt_volok: move.w d1,$1E(a0) bra mt_cmdok mt_pattbreak: st mt_breakflag-mt_data(a6) bra mt_cmdok mt_setspeed: cmp.w #1,d1 bgt.s .speed_ok tst.w d1 beq mt_cmdok move.w #2,d1 .speed_ok: move.w d1,mt_speed-mt_data(a6) bra mt_cmdok mt_doextcmd: move.w d1,d0 and.w #15,d1 lsr.w #4,d0 lea mt_extjmptab(pc),a1 lsl.w #2,d0 jmp (a1,d0.w) mt_extjmptab: bra mt_setfilter ;cmd e0 bra mt_fineslide_up ;cmd e1 bra mt_fineslide_down ;cmd e2 bra mt_cmdok ;cmd e3 bra mt_cmdok ;cmd e4 bra mt_cmdok ;cmd e5 bra mt_cmdok ;cmd e6 bra mt_cmdok ;cmd e7 bra mt_cmdok ;cmd e8 bra mt_retrignote ;cmd e9 bra mt_finevol_up ;cmd ea bra mt_finevol_down ;cmd eb bra mt_cmdok ;cmd ec bra mt_cmdok ;cmd ed bra mt_cmdok ;cmd ee bra mt_cmdok ;cmd ef mt_setfilter: tst.w d1 bne.s mt_filter_off ; bclr #1,$BFE001 bra.s mt_cmdok mt_filter_off: ; bset #1,$BFE001 bra.s mt_cmdok mt_fineslide_up: neg.w d1 move.w d1,$24(a0) move.w #$FFFF,$44(a0) bra.s mt_cmdok mt_fineslide_down: move.w d1,$24(a0) move.w #$FFFF,$44(a0) bra.s mt_cmdok mt_retrignote: tst.w d1 beq.s mt_cmdok move.w d1,$3E(a0) move.w d1,$40(a0) bra.s mt_cmdok mt_finevol_up: move.w d1,$22(a0) move.w #1,$20(a0) move.w #$FFFF,$44(a0) bra.s mt_cmdok mt_finevol_down: move.w d1,$22(a0) move.w #$FFFF,$20(a0) move.w #$FFFF,$44(a0) mt_cmdok: move.b (a5),d0 and.w #$3F,d0 move.w d0,$14(a0) cmp.w #$3F,d0 beq.s lbC0007A8 bsr.s lbC0007F0 lbC0007A8: moveq #0,d0 move.w lbW000B1A-mt_data(a6),d0 add.l d0,a5 move.l a5,(a0) rts lbC0007B6: move.w $48(a0),d0 cmp.w #1,d0 bne.s lbC0007CA clr.w $48(a0) clr.w $46(a0) bra.s lbC0007D0 lbC0007CA: subq.l #1,d0 move.w d0,$48(a0) lbC0007D0: rts lbC0007D2: and.w #$7F,d0 cmp.w #1,d0 beq.s lbC0007E8 subq.l #1,d0 move.w d0,$48(a0) move.w #$FFFF,$46(a0) lbC0007E8: addq.w #1,a5 move.l a5,(a0) rts lbC0007F0: move.w d0,$10(a0) add.w d0,d0 move.w (a4,d0.w),d0 move.w d0,$1C(a0) move.w 12(a0),d0 and.w mt_chanenable-mt_data(a6),d0 beq.s lbC000834 move.w $12(a0),d0 subq.w #1,d0 lsl.w #4,d0 move.w 12(a0),d1 or.w d1,lbW000B0E-mt_data(a6) moveq #0,d1 move.w 14(a0),d1 lea lbL001488(pc),a1 add.l d1,a1 move.l (a3,d0.w),(a1)+ move.w 4(a3,d0.w),(a1)+ move.l 6(a3,d0.w),(a1)+ move.w 10(a3,d0.w),(a1)+ lbC000834: rts mt_setdma: move.w lbW000B16-mt_data(a6),d6 clr.w lbW000B16-mt_data(a6) move.w d6,d7 ;copy DMA bits to d7 or.w #$8000,d7 ;set SET-bit move.w d6,$DFF096 ;stop current samples moveq #4,d1 ;wait for DMA to REALLY stop .mt_waitlines: bsr mt_waitline dbra d1,.mt_waitlines lea lbL001488(pc),a1 ;set new sample-addrs/lengths btst #0,d6 beq.s mt_dontset0 move.w 4(a1),$DFF0A4 move.l (a1),$DFF0A0 mt_dontset0: add.w #12,a1 btst #1,d6 beq.s mt_dontset1 move.w 4(a1),$DFF0B4 move.l (a1),$DFF0B0 mt_dontset1: add.w #12,a1 btst #2,d6 beq.s mt_dontset2 move.w 4(a1),$DFF0C4 move.l (a1),$DFF0C0 mt_dontset2: add.w #12,a1 btst #3,d6 beq.s mt_dontset3 move.w 4(a1),$DFF0D4 move.l (a1),$DFF0D0 mt_dontset3: move.w d7,$DFF096 ;start new DMA with new samples moveq #2,d1 ;wait for DMA to read sample-addrs/lengths .mt_waitlines: bsr mt_waitline dbra d1,.mt_waitlines lea lbL001488+6(pc),a1 ;set repeat-addrs/lengths btst #0,d6 beq.s mt_dontsetrep0 move.w 4(a1),$DFF0A4 move.l (a1),$DFF0A0 mt_dontsetrep0: add.w #12,a1 btst #1,d6 beq.s mt_dontsetrep1 move.w 4(a1),$DFF0B4 move.l (a1),$DFF0B0 mt_dontsetrep1: add.w #12,a1 btst #2,d6 beq.s mt_dontsetrep2 move.w 4(a1),$DFF0C4 move.l (a1),$DFF0C0 mt_dontsetrep2: add.w #12,a1 btst #3,d6 beq.s mt_dontsetrep3 move.w 4(a1),$DFF0D4 move.l (a1),$DFF0D0 mt_dontsetrep3: rts mt_waitline: move.b $DFF006,d0 .loop: cmp.b $DFF006,d0 beq.s .loop rts HandleChannel: move.l 8(a0),a4 tst.w $42(a0) beq.s lbC00094A clr.w $42(a0) bra lbC0009E6 lbC00094A: tst.w $24(a0) beq.s lbC000966 move.w $1C(a0),d0 add.w $24(a0),d0 move.w d0,$1C(a0) tst.w $44(a0) beq.s lbC000966 clr.w $24(a0) lbC000966: tst.w $38(a0) beq.s lbC0009A0 move.w $1C(a0),d0 add.w $3A(a0),d0 move.w d0,$1C(a0) move.w $3C(a0),d0 tst.w $3A(a0) bmi.s lbC000992 cmp.w $1C(a0),d0 bge.s lbC0009A0 move.w d0,$1C(a0) clr.w $38(a0) bra.s lbC0009A0 lbC000992: cmp.w $1C(a0),d0 ble.s lbC0009A0 move.w d0,$1C(a0) clr.w $38(a0) lbC0009A0: tst.w $20(a0) beq.s lbC0009E6 tst.w $20(a0) bmi.s lbC0009C6 move.w $1E(a0),d0 move.w $22(a0),d1 add.w d1,d0 cmp.w #$40,d0 ble.s lbC0009C0 move.w #$40,d0 lbC0009C0: move.w d0,$1E(a0) bra.s lbC0009DC lbC0009C6: move.w $1E(a0),d0 move.w $22(a0),d1 sub.w d1,d0 bpl.s lbC0009D8 clr.w d0 move.w #0,d0 lbC0009D8: move.w d0,$1E(a0) lbC0009DC: tst.w $44(a0) beq.s lbC0009E6 clr.w $20(a0) lbC0009E6: tst.w $26(a0) beq.s lbC000A1E move.w $2C(a0),d0 addq.w #1,d0 move.w d0,$2C(a0) cmp.w #3,d0 bne.s lbC000A04 moveq #0,d0 move.w d0,$2C(a0) bra.s lbC000A1E lbC000A04: move.l $28(a0),d1 move.w d1,d0 swap d1 move.l d1,$28(a0) add.w $10(a0),d0 add.w d0,d0 move.w (a4,d0.w),d0 move.w d0,$1C(a0) lbC000A1E: tst.w $2E(a0) ;do vibrato? beq.s lbC000A52 ;no -> move.w $34(a0),d2 beq.s lbC000A52 move.w $30(a0),d0 lea mt_sinetab(pc),a1 move.b (a1,d0.w),d1 ;get sine-value ext.w d1 ext.l d1 divs d2,d1 neg.w d1 move.w d1,$36(a0) add.w $32(a0),d0 cmp.w #$3F,d0 ble.s lbC000A4E moveq #0,d0 lbC000A4E: move.w d0,$30(a0) lbC000A52: tst.w $3E(a0) beq.s lbC000A7C subq.w #1,$40(a0) tst.w $40(a0) bne.s lbC000A7C move.w $3E(a0),$40(a0) tst.w mt_framecount-mt_data(a6) beq.s lbC000A7C move.w 12(a0),d0 or.w d0,lbW000B16-mt_data(a6) move.w #$FFFF,lbW000B18-mt_data(a6) lbC000A7C: move.l 4(a0),a1 move.w $1E(a0),d0 moveq #64,d1 sub.w mt_volume-mt_data(a6),d1 mulu d1,d0 move.w a1,d1 cmp.b #$a0,d1 beq.s .setleft cmp.b #$d0,d1 bne.s .setright .setleft: mulu mt_leftvol-mt_data(a6),d0 bra.s .skipright .setright: mulu mt_rightvol-mt_data(a6),d0 .skipright: lsr.l #6,d0 ; >>6 for first mulu lsr.l #6,d0 ; >>6 for second mulu move.w d0,8(a1) move.w $1C(a0),d0 add.w $36(a0),d0 move.w d0,6(a1) rts mt_handlefade: tst.w mt_fadedelay_count-mt_data(a6) bne.s .delay move.w mt_fadedelay-mt_data(a6),mt_fadedelay_count-mt_data(a6) addq.w #1,mt_volume-mt_data(a6) cmp.w #$41,mt_volume-mt_data(a6) bne.s .notended move.w #15,$DFF096 moveq #0,d0 move.w d0,$DFF0A8 move.w d0,$DFF0B8 move.w d0,$DFF0C8 move.w d0,$DFF0D8 sf mt_fadeendflag-mt_data(a6) move.w d0,mt_fadestatus-mt_data(a6) .delay: subq.w #1,mt_fadedelay_count-mt_data(a6) .notended: rts mt_data: dc.l 0 ;address of module lbL000AEC: dc.l 0 lbL000AF0: dc.l 0 lbL000AF4: dc.l 0 lbW000AF8: dc.w 0 lbW000AFA: dc.w 0 lbW000AFC: dc.w 0 lbW000AFE: dc.w 0 mt_stepcount: dc.w 0 mt_speed: dc.w 0 mt_framecount: dc.w 0 mt_volume: dc.w 0 mt_leftvol: dc.w 0 mt_rightvol: dc.w 0 mt_fadedelay: dc.w 0 mt_fadedelay_count: dc.w 0 lbW000B0E: dc.w 0 mt_breakflag: dc.b 0 mt_fadeendflag: dc.b 0 mt_destpatt: dc.w 0 mt_chanenable: dc.w 0 lbW000B16: dc.w 0 lbW000B18: dc.w 0 lbW000B1A: dc.w 0 mt_fadestatus: dc.w 0 lbW000B1E: dc.w 0 mt_chandat0: dc.l 0,$DFF0A0,0,$10000 dcb.l $E,0 dc.w 0 mt_chandat1: dc.l 0,$DFF0B0,0,$2000C dcb.l $E,0 dc.w 0 mt_chandat2: dc.l 0,$DFF0C0,0,$40018 dcb.l $E,0 dc.w 0 mt_chandat3: dc.l 0,$DFF0D0,0,$80024 dcb.l $E,0 dc.w 0 mt_periods: dc.w $6B0,$650,$5F4,$5A0,$54C,$500,$4B8,$474,$434,$3F8,$3C0,$38A dc.w $358,$328,$2FA,$2D0,$2A6,$280,$25C,$23A,$21A,$1FC,$1E0,$1C5 dc.w $1AC,$194,$17D,$168,$153,$140,$12E,$11D,$10D,$FE,$F0,$E2 dc.w $D6,$CA,$BE,$B4,$AA,$A0,$97,$8F,$87,$7F,$78,$71 dcb.w $10,0 dc.w $6A4,$644,$5EA,$596,$544,$4FA,$4B2,$46E,$42E,$3F2,$3BA,$384 dc.w $352,$322,$2F5,$2CB,$2A2,$27D,$259,$237,$217,$1F9,$1DD,$1C2 dc.w $1A9,$191,$17B,$165,$151,$13E,$12C,$11C,$10C,$FD,$EF,$E1 dc.w $D5,$C9,$BD,$B3,$A9,$9F,$96,$8E,$86,$7E,$77,$71 dcb.w $10,0 dc.w $698,$638,$5E0,$58A,$53C,$4F0,$4AA,$466,$428,$3EC,$3B4,$37E dc.w $34C,$31C,$2F0,$2C5,$29E,$278,$255,$233,$214,$1F6,$1DA,$1BF dc.w $1A6,$18E,$178,$163,$14F,$13C,$12A,$11A,$10A,$FB,$ED,$E0 dc.w $D3,$C7,$BC,$B1,$A7,$9E,$95,$8D,$85,$7D,$76,$70 dcb.w $10,0 dc.w $68C,$62E,$5D4,$580,$532,$4E8,$4A0,$45E,$420,$3E4,$3AC,$378 dc.w $346,$317,$2EA,$2C0,$299,$274,$250,$22F,$210,$1F2,$1D6,$1BC dc.w $1A3,$18B,$175,$160,$14C,$13A,$128,$118,$108,$F9,$EB,$DE dc.w $D1,$C6,$BB,$B0,$A6,$9D,$94,$8C,$84,$7D,$76,$6F dcb.w $10,0 dc.w $680,$622,$5CA,$576,$528,$4DE,$498,$456,$418,$3DE,$3A6,$372 dc.w $340,$311,$2E5,$2BB,$294,$26F,$24C,$22B,$20C,$1EF,$1D3,$1B9 dc.w $1A0,$188,$172,$15E,$14A,$138,$126,$116,$106,$F7,$E9,$DC dc.w $D0,$C4,$B9,$AF,$A5,$9C,$93,$8B,$83,$7C,$75,$6E dcb.w $10,0 dc.w $674,$616,$5C0,$56C,$51E,$4D6,$490,$44E,$410,$3D6,$39E,$36A dc.w $33A,$30B,$2E0,$2B6,$28F,$26B,$248,$227,$208,$1EB,$1CF,$1B5 dc.w $19D,$186,$170,$15B,$148,$135,$124,$114,$104,$F5,$E8,$DB dc.w $CE,$C3,$B8,$AE,$A4,$9B,$92,$8A,$82,$7B,$74,$6D dcb.w $10,0 dc.w $668,$60C,$5B4,$562,$516,$4CC,$488,$446,$408,$3CE,$398,$364 dc.w $334,$306,$2DA,$2B1,$28B,$266,$244,$223,$204,$1E7,$1CC,$1B2 dc.w $19A,$183,$16D,$159,$145,$133,$122,$112,$102,$F4,$E6,$D9 dc.w $CD,$C1,$B7,$AC,$A3,$9A,$91,$89,$81,$7A,$73,$6D dcb.w $10,0 dc.w $65C,$600,$5AA,$558,$50C,$4C4,$47E,$43E,$402,$3C8,$392,$35E dc.w $32E,$300,$2D5,$2AC,$286,$262,$23F,$21F,$201,$1E4,$1C9,$1AF dc.w $197,$180,$16B,$156,$143,$131,$120,$110,$100,$F2,$E4,$D8 dc.w $CC,$C0,$B5,$AB,$A1,$98,$90,$88,$80,$79,$72,$6C dcb.w $10,0 dc.w $716,$6B0,$650,$5F4,$5A0,$54C,$500,$4B8,$474,$434,$3F8,$3C0 dc.w $38B,$358,$328,$2FA,$2D0,$2A6,$280,$25C,$23A,$21A,$1FC,$1E0 dc.w $1C5,$1AC,$194,$17D,$168,$153,$140,$12E,$11D,$10D,$FE,$F0 dc.w $E2,$D6,$CA,$BE,$B4,$AA,$A0,$97,$8F,$87,$7F,$78 dcb.w $10,0 dc.w $708,$6A4,$644,$5EA,$596,$546,$4F8,$4B2,$46E,$42E,$3F2,$3BA dc.w $384,$352,$322,$2F5,$2CB,$2A3,$27C,$259,$237,$217,$1F9,$1DD dc.w $1C2,$1A9,$191,$17B,$165,$151,$13E,$12C,$11C,$10C,$FD,$EE dc.w $E1,$D4,$C8,$BD,$B3,$A9,$9F,$96,$8E,$86,$7E,$77 dcb.w $10,0 dc.w $6FC,$698,$638,$5E0,$58A,$53C,$4F0,$4AA,$466,$428,$3EC,$3B4 dc.w $37E,$34C,$31C,$2F0,$2C5,$29E,$278,$255,$233,$214,$1F6,$1DA dc.w $1BF,$1A6,$18E,$178,$163,$14F,$13C,$12A,$11A,$10A,$FB,$ED dc.w $DF,$D3,$C7,$BC,$B1,$A7,$9E,$95,$8D,$85,$7D,$76 dcb.w $10,0 dc.w $6EE,$68C,$62E,$5D4,$580,$532,$4E8,$4A0,$45E,$420,$3E4,$3AC dc.w $377,$346,$317,$2EA,$2C0,$299,$274,$250,$22F,$210,$1F2,$1D6 dc.w $1BC,$1A3,$18B,$175,$160,$14C,$13A,$128,$118,$108,$F9,$EB dc.w $DE,$D1,$C6,$BB,$B0,$A6,$9D,$94,$8C,$84,$7D,$76 dcb.w $10,0 dc.w $6E2,$680,$622,$5CA,$576,$528,$4DE,$498,$456,$418,$3DC,$3A6 dc.w $371,$340,$311,$2E5,$2BB,$294,$26F,$24C,$22B,$20C,$1EE,$1D3 dc.w $1B9,$1A0,$188,$172,$15E,$14A,$138,$126,$116,$106,$F7,$E9 dc.w $DC,$D0,$C4,$B9,$AF,$A5,$9C,$93,$8B,$83,$7B,$75 dcb.w $10,0 dc.w $6D6,$674,$616,$5C0,$56C,$51E,$4D6,$490,$44E,$410,$3D6,$39E dc.w $36B,$33A,$30B,$2E0,$2B6,$28F,$26B,$248,$227,$208,$1EB,$1CF dc.w $1B5,$19D,$186,$170,$15B,$148,$135,$124,$114,$104,$F5,$E8 dc.w $DB,$CE,$C3,$B8,$AE,$A4,$9B,$92,$8A,$82,$7B,$74 dcb.w $10,0 dc.w $6C8,$668,$60C,$5B4,$562,$516,$4CC,$488,$446,$408,$3CE,$398 dc.w $364,$334,$306,$2DA,$2B1,$28B,$266,$244,$223,$204,$1E7,$1CC dc.w $1B2,$19A,$183,$16D,$159,$145,$133,$122,$112,$102,$F4,$E6 dc.w $D9,$CD,$C1,$B7,$AC,$A3,$9A,$91,$89,$81,$7A,$73 dcb.w $10,0 dc.w $6BC,$65C,$600,$5AA,$558,$50C,$4C4,$47E,$43E,$402,$3C8,$392 dc.w $35E,$32E,$300,$2D5,$2AC,$286,$262,$23F,$21F,$201,$1E4,$1C9 dc.w $1AF,$197,$180,$16B,$156,$143,$131,$120,$110,$100,$F2,$E4 dc.w $D8,$CB,$C0,$B5,$AB,$A1,$98,$90,$88,$80,$79,$72 mt_sinetab: dc.b 1,7,14,$1C,$2A,$38,$46,$54,$59,$5E,$63,$68,$6D,$72,$78,$7C,$7F dc.b $7C,$78,$72,$6D,$68,$63,$5E,$59,$54,$46,$38,$2A,$1C,14,7,$FF dc.b $F9,$F2,$E4,$D6,$C8,$BA,$AC,$A7,$A2,$9D,$98,$93,$8E,$88,$84 dc.b $81,$84,$88,$8E,$93,$98,$9D,$A2,$A7,$AC,$BA,$C8,$D6,$E4,$F2 dc.b $F9 lbW001468: dc.w 0,$32,$23,$1C,$18,$16,$14,$12,$10,14,12,10,8,6,4,2 lbL001488: dcb.l $20,0 mt_sampletab: dcb 32*16,0