;-----------------------------------------------------------------------; ; ; ; TTP .MOD Player ; ; 7 Bit Ste/TT Pro-Tracker 2.1A Driver ; ; (C) October/November 1992 Griff of Electronic Images ; ; ; ; - 50 khz stereo sound, with microwire control. ; ; - The ONLY player in the whole wide world to emulate TEMPO properly. ; ; - SEE DOC file for furthur info. ; ;-----------------------------------------------------------------------; ; Quick notes about this source. ; ; - Assemble using DEVPAC 2 or 3. ; ; - This replay is NOT fast and nor should it be. ; ; - It is designed for QUALITY and ACCURATE replay of ProTracker MODS. ; ; - It doe NOT pad samples and so doesn't waste any setup time/memory. ; ; - If you use it, then please credit me. ; ;-----------------------------------------------------------------------; test EQU 0 ; if test=1 then run from assember ; (with a pre-included module) bufsize EQU 5500 ; maximum size of buffer ; (when tempo =32) dmamask EQU %00000011 ; STE dmamask for 50khz OPT O+,OW- letsgo IFEQ test MOVEA.L 4(A7),A5 LEA $80(A5),A5 ; -> length,filename ELSEIF LEA testfile,A5 ; if in testmode ENDC ; then -> testfilename MOVE.B (A5)+,D0 ; get filename length. BEQ mustinstall ; no filename given? LEA filename(PC),A4 .lp MOVE.B (A5)+,(A4)+ SUBQ.B #1,D0 BNE.S .lp CLR.B (A4) ; terminate filename MOVE.L 4(SP),A5 MOVE.L $C(A5),A4 ADD.L $14(A5),A4 ADD.L $1C(A5),A4 LEA $100(A4),A4 ; proggy size+basepage PEA (A4) PEA (A5) CLR -(SP) MOVE #$4A,-(SP) TRAP #1 ; reserve some memory LEA 12(SP),SP CLR.L -(SP) MOVE #$20,-(SP) TRAP #1 ; supervisor mode ADDQ.L #6,SP MOVE.L D0,oldsp MOVE.L USP,A0 MOVE.L A0,oldusp ; save user stack ptr. LEA my_stack,SP ; our own stack. DC.W $A00A ; hide mouse BSR set_screen ; setup the screen BSR SoundTest ; check for dma sound TST.L D1 ; if this is an old ST BEQ wrongST_error ; then quit out! MOVE #$777,D7 ;;; in future .fadedownfirst BSR Wait_Vbl ;;; will use o.s BSR Wait_Vbl ;;; set colour. MOVE.W D7,$FFFF8240.W SUB #$111,D7 BGE.S .fadedownfirst MOVE.L #$00000777,$FFFF8240.W ;;; MOVE.L #$00000777,$FFFF8244.W ;;; BSR load_mod ; load the module TST.B errorflag BNE load_error ; exit if load error BSR print_mainscr ; print main screen BSR set_microwire ; setup micrwire BSR Wait_Vbl .goformusic BSR init_ints ; and kill ints MOVEQ #1,D0 MOVEQ #0,D1 BSR Init_ST ; install music ; Music playing, key selection loop follows(microwire control) .waitk BSR Wait_VblNG BSR Wait_VblNG BSR Wait_VblNG BSR print_tempo BSR microwire_cont ; microwire keyboard control MOVE.B key(PC),D0 CMP.B #$14+$80,D0 ; t pressed and released? BNE.S .nottempo BSR toggle_tempo ; yes then toggle tempo CLR.B key .nottempo CMP.B #$39+$80,D0 ; space exits. BNE .waitk BSR stop_music BSR restore_ints ; restore gem.. exit BSR restore_screen exitloaderr DC.W $A009 MOVE.L oldsp(PC),-(SP) MOVE #$20,-(SP) TRAP #1 ; user mode ADDQ.L #6,SP redir PEA dummy(PC) MOVE.W #$4e,-(SP) TRAP #1 ADDQ.L #6,SP CLR.W -(SP) ; Get dir. PEA dir MOVE.W #$47,-(SP) TRAP #1 ADDQ.L #8,SP CLR -(SP) TRAP #1 ;------------------------------------------------------------------------- ; A few error handlers. ; NO DMA Sound so can't use this player. wrongST_error PEA wrongST_err_txt(PC) MOVE.W #9,-(SP) TRAP #1 ADDQ.L #6,SP MOVE.W #7,-(SP) TRAP #1 ADDQ.L #2,SP BRA exit load_error BSR restore_screen CMP.L #-33,error_no BNE.S .not_fnf PEA filenf_errortxt(PC) BRA.S .cont .not_fnf PEA load_errortxt(PC) .cont MOVE.W #9,-(SP) TRAP #1 ADDQ.L #6,SP MOVE.W #7,-(SP) TRAP #1 ADDQ.L #2,SP BRA exitloaderr ; No FILENAME was passed error - so tell 'em how to install !! mustinstall DC.W $A00A PEA installtxt(PC) MOVE.W #9,-(SP) TRAP #1 ADDQ.L #6,SP MOVE.W #7,-(SP) TRAP #1 ADDQ.L #2,SP DC.W $A009 BRA.S redir installtxt DC.B 27,"E" DC.B "You must install this program as an",10,13 DC.B "application on the Gem desktop,",10,13 DC.B "OR Type the Module Name if you are",10,13 DC.B "running this from a command line!",10,13 DC.B "Press any key.",10,13,0 load_errortxt DC.B 27,"E" DC.B "Load Error(disk error?)",10,13 DC.B "Press any key.",10,13,0 filenf_errortxt DC.B 27,"E" DC.B "File Not Found",10,13 DC.B "Press any key.",10,13,0 wrongST_err_txt DC.B 27,"E" DC.B "You must have an Ste,Mega Ste or TT",10,13 DC.B "to run this module player..(sorry!)",10,13 DC.B "Press any key.",10,13,0 EVEN ;------------------------------------------------------------------------- ; Subroutines for interrupts and replay. ; Save mfp vectors and ints and install our own.(very 'clean' setup rout) init_ints MOVEQ #$13,D0 ; pause keyboard BSR Writeikbd ; (stop from sending) MOVE #$2700,SR LEA old_stuff+32(PC),A0 MOVE.B $FFFFFA07.W,(A0)+ MOVE.B $FFFFFA09.W,(A0)+ MOVE.B $FFFFFA13.W,(A0)+ MOVE.B $FFFFFA15.W,(A0)+ ; Save mfp registers MOVE.B $FFFFFA19.W,(A0)+ MOVE.B $FFFFFA1F.W,(A0)+ MOVE.L $70.W,(A0)+ MOVE.L $B0.W,(A0)+ MOVE.L $118.W,(A0)+ MOVE.L $134.W,(A0)+ CLR.B $fffffa07.W MOVE.B #$40,$fffffa09.W CLR.B $fffffa13.W MOVE.B #$40,$fffffa15.W BCLR.B #3,$fffffa17.W ; software end of int. LEA my_vbl(PC),A0 MOVE.L A0,$70.W ; set our vbl LEA key_rout(PC),A0 MOVE.L A0,$118.W ; and our keyrout. LEA supers(PC),A0 MOVE.L A0,$B0.W CLR key MOVE #$2300,SR MOVEQ #$11,D0 ; resume sending BSR Writeikbd MOVEQ #$12,D0 ; kill mouse BSR Writeikbd BSR flush RTS supers BCHG #13-8,(SP) ; toggle super RTE ; Restore mfp vectors and ints. restore_ints MOVE.L oldusp(PC),A0 MOVE.L A0,USP MOVEQ #$13,D0 ; pause keyboard BSR Writeikbd ; (stop from sending) MOVE #$2700,SR LEA old_stuff+32(PC),A0 MOVE.B (A0)+,$FFFFFA07.W MOVE.B (A0)+,$FFFFFA09.W MOVE.B (A0)+,$FFFFFA13.W MOVE.B (A0)+,$FFFFFA15.W ; restore mfp MOVE.B (A0)+,$FFFFFA19.W MOVE.B (A0)+,$FFFFFA1F.W MOVE.L (A0)+,$70.W MOVE.L (A0)+,$B0.W MOVE.L (A0)+,$118.W MOVE.L (A0)+,$134.W BSET.B #3,$FFFFFA17.W MOVE #$2300,SR MOVEQ #$11,D0 ; resume BSR Writeikbd MOVEQ #$8,D0 ; restore mouse. BSR Writeikbd BSR flush RTS ;-------------------------------------------------------------------------- ; CookieJar Check to see if we have DMA sound.(i.e STE/TT) ; Return D1=0 if DMA sound is not available on this machine. (else d1=-1) ;-------------------------------------------------------------------------- SoundTest move.l $5A0.W,d0 ; get cookie jar ptr beq.s no_dmasnd ;; nul ptr = no cookie jar move.l d0,a0 ;; (no cookie jar= no dma snd) .search_next tst.l (a0) beq.s no_dmasnd cmp.l #'_SND',(a0) ; cookie found? beq.s .search_found addq.l #8,a0 bra.s .search_next .search_found move.l 4(a0),d0 ; get _SND const. cmp.l #3,D0 blt.s no_dmasnd moveq #-1,d1 ; DMA SOUND FOUND! rts no_dmasnd moveq #0,d1 ; NO DMA SOUND! rts ; Wait for a vbl.. Wait_Vbl MOVE #37,-(SP) TRAP #14 ADDQ.L #2,SP RTS ; Wait for a vbl,(Not Gems..) Wait_VblNG MOVE.W vbl_timer(PC),D0 .waitvb CMP.W vbl_timer(PC),D0 BEQ.S .waitvb RTS old_stuff: DS.L 18 oldres DS.W 1 oldsp DS.L 1 oldusp DS.L 1 ; Flush IKBD flush BTST.B #0,$FFFFFC00.W ; any waiting? BEQ.S .flok ; exit if none waiting. MOVE.B $FFFFFC02.W,D0 ; get next in queue BRA.S flush ; and continue .flok RTS ; Write d0 to IKBD Writeikbd BTST.B #1,$FFFFFC00.W BEQ.S Writeikbd ; wait for ready MOVE.B D0,$FFFFFC02.W ; and send... RTS ; Keyboard handler interrupt routine... ; (crap) key_rout PEA (A0) MOVE D0,-(SP) MOVE.B $FFFFFC00.W,D0 BTST #7,D0 ; int req? BEQ.S .end BTST #0,D0 ; BEQ.S .end LEA keytab(PC),A0 MOVE.B $FFFFFC02.W,D0 MOVE.B D0,key ; store keypress BGE.S .pressed ; naff naff ultra naff .released AND.W #$7F,D0 SF.B (A0,D0) .end MOVE (SP)+,D0 MOVE.L (SP)+,A0 RTE .pressed AND.W #$7F,D0 ST.B (A0,D0) MOVE (SP)+,D0 MOVE.L (SP)+,A0 RTE key DC.W 0 keytab DS.B 256 ; 'held' down table! ; The vbl - simply increments a timer. my_vbl MOVE.W #$2700,SR ADDQ #1,vbl_timer RTE vbl_timer DC.W 0 ; Clear screen fast(ish) ->A0 clsfast MOVEQ #0,D0 MOVE #(32000/32)-1,D1 .cls REPT 8 MOVE.L D0,(A0)+ ENDR DBF D1,.cls RTS ; Load that Module load_mod BSR Wait_Vbl MOVE.L log_base(PC),A0 BSR clsfast ; clear the screen CLR.B txpos ; and print MOVE.B #12,typos ; 'loading' LEA loading(PC),A0 ; file xxxxxx BSR print .loadit LEA filename(PC),A4 LEA mt_data,A5 MOVE.L #4000000,D7 BSR Load_file ; load the file RTS ; Load a file of D7 bytes, Filename at A4 into address A5. Load_file SF.B errorflag ; assume no error! MOVE #2,-(SP) MOVE.L A4,-(SP) MOVE #$3D,-(SP) TRAP #1 ; open da file ADDQ.L #8,SP TST.L D0 BMI.S .error MOVE D0,D4 .read MOVE.L A5,-(SP) MOVE.L D7,-(SP) MOVE D4,-(SP) MOVE #$3F,-(SP) TRAP #1 ; read da file LEA 12(SP),SP TST.L D0 BMI.S .error MOVE.L D0,modlength .close MOVE D4,-(SP) MOVE #$3E,-(SP) TRAP #1 ; close da file! ADDQ.L #4,SP RTS .error MOVE.L D0,error_no ST.B errorflag ; shit a load error! RTS ; Various screen stuff. ; Init screen . (save palette,and screen res etc etc.) set_screen MOVEM.L $FFFF8240.W,D0-D7 MOVEM.L D0-D7,old_stuff ; save palette MOVE.W #2,-(SP) TRAP #14 ; get phybase ADDQ.L #2,SP MOVE.L D0,log_base ; store it. MOVE #4,-(SP) TRAP #14 ; get rez ADDQ.L #2,SP MOVE.W D0,oldres CMP.W #2,D0 BEQ.S .high .low_med MOVE.W #160,linewid LEA xtab(PC),A0 MOVEQ #0,D0 MOVEQ #40-1,D1 .lp1 MOVE.B D0,(A0)+ ADDQ.B #1,D0 MOVE.B D0,(A0)+ ADDQ.B #3,D0 DBF D1,.lp1 MOVE #1,-(SP) PEA -1.W PEA -1.W MOVE #5,-(SP) TRAP #14 LEA 12(SP),SP BRA.S plotres .high MOVE.W #80,linewid LEA xtab(PC),A0 MOVEQ #0,D0 MOVEQ #40-1,D1 .lp2 MOVE.B D0,(A0)+ ADDQ.B #1,D0 MOVE.B D0,(A0)+ ADDQ.B #1,D0 DBF D1,.lp2 plotres LEA naughtysmod+2(PC),A0 MOVEQ #7-1,D0 MOVEQ #0,D1 .lp2 MOVE.W D1,(A0) ADD.W linewid(PC),D1 ADDQ.L #4,A0 DBF D0,.lp2 RTS ; Restore Res/palette etc. restore_screen MOVE oldres(PC),-(SP) PEA -1.W PEA -1.W MOVE #5,-(SP) TRAP #14 LEA 12(SP),SP MOVEM.L old_stuff(PC),D0-D7 ; restore palette MOVEM.L D0-D7,$FFFF8240.W RTS ; Print Main Screen print_mainscr BSR Wait_Vbl MOVE.L log_base(PC),A0 BSR clsfast ; clear the screen CLR.B txpos CLR.B typos LEA thetext(PC),A0 ; main text BSR print ; draw text BSR print_tempo .printplaying LEA mt_data,A0 LEA realmodname(PC),A1 TST.B (A0) BNE.S .okhasname LEA unnamed_mod(PC),A0 .okhasname CLR D0 .lp1 TST.B (A0) BEQ.S .out1 MOVE.B (A0)+,(A1)+ ADDQ #1,D0 CMP.W #20,D0 BLE.S .lp1 .out1 MOVE.B #0,(A1)+ CLR.B txpos MOVE.B #10,typos LEA playingtxt(PC),A0 BSR print RTS ; Print tempo information bits. print_tempo LEA tempotxt(PC),A0 MOVE.L A0,A1 MOVE.W RealTempo(PC),D0 EXT.L D0 DIVU #100,D0 ADD.B #'0',D0 MOVE.B D0,(A1)+ SWAP D0 EXT.L D0 DIVU #10,D0 ADD.B #'0',D0 MOVE.B D0,(A1)+ SWAP D0 ADD.B #'0',D0 MOVE.B D0,(A1)+ CLR.B (A1)+ MOVE.B #55,txpos MOVE.B #8,typos BSR print MOVE.B #37,txpos MOVE.B #8,typos LEA tempo_ontxt(PC),A0 TST.B tempo_cont_flg BNE .tempooff LEA tempo_offtxt(PC),A0 .tempooff BRA print ; Draw Bar (slider thingy) ; D0=length of bar D1=position for level. D2=x, D3=y draw_bar MOVE.B D2,txpos MOVE.B D3,typos LEA bar_buf(PC),A0 MOVE.L A0,A1 .lp MOVE.B #'-',(A1)+ DBF D0,.lp CLR.B (A1)+ MOVE.B #'|',(A0,D1.W) BSR print RTS ; Print Rout -> Text address in A0... Uses TXPOS and TYPOS (.B) ; (not fast or anything but works nicely thank you!) print: printline: move.b (a0)+,d0 beq endprin notend: cmpi.b #3,d0 bne.s notcent move.l a0,a1 moveq #0,d3 .lp move.b (a1)+,d4 beq.s .out cmp.b #4,d4 beq.s .out addq #1,d3 bra.s .lp .out neg d3 add.w #80,d3 asr.w #1,d3 add.b d3,txpos bra.s printline notcent cmpi.b #4,d0 bne.s notlf addq.b #1,typos clr.b txpos bra.s printline notlf: moveq #0,D3 moveq #0,D4 move.b txpos(PC),D3 move.b typos(PC),D4 lsl #3,d4 ;*8(1char=8pixhigh) mulu linewid(pc),d4 movea.l log_base(pc),A2 ; Screen adda.l d4,A2 lea xtab(PC),a3 move.b 0(a3,D3.w),D3 adda.w D3,A2 lea font(PC),a3 moveq #0,D3 move.b D0,D3 sub.b #32,D3 lsl.w #3,D3 adda.w D3,a3 move.b (a3)+,(A2) naughtysmod move.b (a3)+,160(A2) move.b (a3)+,320(A2) move.b (a3)+,480(A2) move.b (a3)+,640(A2) move.b (a3)+,800(A2) move.b (a3)+,960(A2) move.b (a3),1120(A2) addq.b #1,txpos bra printline endprin rts font: incbin i:\graphics\fonts__8.raw\met_09.fn8 linewid dc.w 0 xtab: ds.b 80 txpos: ds.b 1 typos: ds.b 1 ; Toggle Tempo Control. toggle_tempo TST.B tempo_cont_flg ; toggle tempo BEQ.S .tempoon .tempooff SF.B tempo_cont_flg ; turn tempo control OFF MOVE.W RealTempo(pc),OldTempo ; save current tempo MOVE.W #125,RealTempo ; switch to default tempo BRA.S .endtempo .tempoon ST.B tempo_cont_flg ; turn tempo control ON MOVE.W OldTempo(PC),RealTempo .endtempo RTS OldTempo dc.w 125 RealTempo dc.w 125 ; Micro-wire keyboard control and screen update. microwire_cont .mainvol LEA keytab(PC),A0 TST.B $3B(A0) BEQ.S .notvoldown TST.W mw_mastervol BEQ.S .notvoldown SUBQ #1,mw_mastervol BSR set_mastervol BRA .setit .notvoldown TST.B $3C(A0) BEQ.S .notvolup CMP.W #40,mw_mastervol BEQ.S .notvolup ADDQ #1,mw_mastervol BSR set_mastervol BRA .setit .notvolup .leftvol TST.B $3D(A0) BEQ.S .notlvoldown TST.W mw_leftvol BEQ.S .notlvoldown SUBQ #1,mw_leftvol BSR set_leftvol BRA .setit .notlvoldown TST.B $3E(A0) BEQ.S .notlvolup CMP.W #20,mw_leftvol BEQ.S .notlvolup ADDQ #1,mw_leftvol BSR set_leftvol BRA .setit .notlvolup .rightvol TST.B $3F(A0) BEQ.S .notrvoldown TST.W mw_rightvol BEQ.S .notrvoldown SUBQ #1,mw_rightvol BSR set_rightvol BRA .setit .notrvoldown TST.B $40(A0) BEQ.S .notrvolup CMP.W #20,mw_rightvol BEQ.S .notrvolup ADDQ #1,mw_rightvol BSR set_rightvol BRA .setit .notrvolup .bass TST.B $41(A0) BEQ.S .notbassdown TST.W mw_bass BEQ.S .notbassdown SUBQ #1,mw_bass BSR set_bass BRA .setit .notbassdown TST.B $42(A0) BEQ.S .notbassup CMP.W #12,mw_bass BEQ.S .notbassup ADDQ #1,mw_bass BSR set_bass BRA .setit .notbassup .treble TST.B $43(A0) BEQ.S .nottrebledown TST.W mw_treble BEQ.S .nottrebledown SUBQ #1,mw_treble BSR set_treble BRA .setit .nottrebledown TST.B $44(A0) BEQ.S .nottrebleup CMP.W #12,mw_treble BEQ.S .nottrebleup ADDQ #1,mw_treble BSR set_treble BRA .setit .nottrebleup .setit .notfunk RTS ; Set Microwire stuff/ and draw on screen. set_microwire BSR set_bass BSR set_treble BSR set_mastervol BSR set_leftvol BSR set_rightvol RTS set_mastervol MOVE.W #$4C0,D0 ADD.W mw_mastervol(PC),D0 BSR mw_write MOVEQ #40,D0 MOVE.W mw_mastervol(PC),D1 MOVEQ #26,D2 MOVEQ #12,D3 BRA draw_bar set_bass MOVE.W #$440,D0 ADD.W mw_bass(PC),D0 BSR mw_write MOVEQ #12,D0 MOVE.W mw_bass(PC),D1 MOVEQ #26,D2 MOVEQ #15,D3 BRA draw_bar set_treble MOVE.W #$480,D0 ADD.W mw_treble(PC),D0 BSR mw_write MOVEQ #12,D0 MOVE.W mw_treble(PC),D1 MOVEQ #26,D2 MOVEQ #16,D3 BRA draw_bar set_leftvol MOVE.W #$540,D0 ADD.W mw_leftvol(PC),D0 BSR mw_write MOVEQ #20,D0 MOVE.W mw_leftvol(PC),D1 MOVEQ #26,D2 MOVEQ #13,D3 BRA draw_bar set_rightvol MOVE.W #$500,D0 ADD.W mw_rightvol(PC),D0 BSR mw_write MOVEQ #20,D0 MOVE.W mw_rightvol(PC),D1 MOVEQ #26,D2 MOVEQ #14,D3 BRA draw_bar ; Write d0 to microwire. mw_write: MOVE.W #$7ff,$ffff8924.W MOVE.W D0,$ffff8922.W mw_wait CMP.W #$7ff,$ffff8924.W BNE.S mw_wait ; loop until equal RTS ; and return ; Various variables. log_base DC.L 0 ; screen ptr mw_mastervol DC.W 40 ; 0-40 mw_leftvol DC.W 20 ; 0-20 mw_rightvol DC.W 20 ; 0-20 mw_bass DC.W 9 ; 0-14 mw_treble DC.W 9 ; 0-14 modlength DC.L 0 error_no DC.L 0 errorflag DC.B 0 tempo_cont_flg DC.B -1 dummy: DC.B '*.*',0 playingtxt DC.B 3,"Now Playing : " realmodname DS.B 24 unnamed_mod DC.B "Unnamed Module!",0 loading DC.B 3,"Loading : " filename DS.B 128 EVEN tempotxt DS.L 1 tempo_ontxt DC.B "On ",0 tempo_offtxt DC.B "Off",0 EVEN bar_buf DS.B 80 thetext dc.b 4,4,4,4 dc.b 3,"ProTracker V2.1a Replay",4 dc.b 3,"Programmed by Griff of Electronic Images",4 dc.b 3,"- 50Khz STE/TT Version v1.2B -",4,4 dc.b 3,"Tempo Control: On Tempo: 125",4,4,4,4 dc.b " Main Volume:",4 dc.b " Left Volume:",4 dc.b " Right Volume:",4 dc.b " Bass:",4 dc.b " Treble:",4,4 dc.b 3,"Use F1-F10 to control sliders and T to toggle TEMPO on/off",4 dc.b 0 EVEN ;-----------------------------------------------------------------------; ; Here we have the replay rout. ; Initialise Music Sequencer and ST Specific bits (e.g interrupts etc.) ; D0=0 then turn music OFF. D1=0 straight off else d1=fadeOUT speed. ; D0=1 then turn music ON. D1=0 straight on else d1=fadeIN speed. Init_ST LEA vol_bitflag(PC),A0 BSET #0,(A0) ; still fading. LEA fadeINflag(PC),A0 SF (A0) ; reset fade IN flag LEA fadeOUTflag(PC),A0 SF (A0) ; reset fade OUT flag TST.B D0 BNE.S .init_music ; Deinitialise music - turn off/fade out. .deinit_music TST.B D1 ; any fade down? BNE.S .trigfadedown LEA global_vol(PC),A0 MOVE.W #$0,(A0) ; turn off music RTS .trigfadedown LEA fadeOUTflag(PC),A0 ST.B (A0)+ MOVE.B D1,(A0)+ MOVE.B D1,(A0)+ RTS ; Initialise music - turn on/fade in. .init_music TST.B D1 BNE.S .trigfadein LEA global_vol(PC),A0 MOVE.W #$40,(A0) ; assume no fade in. BSR mt_init BRA STspecific .trigfadein LEA global_vol(PC),A0 MOVE.W #$0,(A0) ; ensure zero to start with! LEA fadeINflag(PC),A0 ST.B (A0)+ MOVE.B D1,(A0)+ MOVE.B D1,(A0)+ BSR mt_init BRA STspecific vol_bitflag DC.W 0 ; bit 0 is 1 if we are fading! global_vol DC.W 0 fadeOUTflag DC.B 0 fadeOUTcurr DC.B 0 fadeOUTspeed DC.B 0 fadeINflag DC.B 0 fadeINcurr DC.B 0 fadeINspeed DC.B 0 EVEN ; Paula emulation storage structure. RSRESET sam_start RS.L 1 ; sample start sam_length RS.L 1 ; sample length sam_period RS.W 1 ; sample period(freq) sam_vol RS.W 1 ; sample volume sam_lpstart RS.L 1 ; sample loop start sam_lplength RS.L 1 ; sample loop length sam_vcsize RS.B 1 ; structure size. ch1s DS.B sam_vcsize ch2s DS.B sam_vcsize ; shadow channel regs ch3s DS.B sam_vcsize ch4s DS.B sam_vcsize shadow_dmacon DS.W 1 shadow_filter DS.W 1 ; Macro to move parameter '\1' into the shadow dma register... ; (Remember - bit 15 of 'dmacon' determines clearing or setting of bits!) move_dmacon MACRO .setdma\@ MOVE.W D4,-(Sp) ; save D4 MOVE.W \1,D4 BTST #15,D4 ; set or clear? BNE.S .setbits\@ .clearbits\@ NOT.W D4 ; zero so clear AND.W D4,shadow_dmacon ; mask bits in dmacon BRA.S .dmacon_set\@ ; and exit... .setbits\@ OR.W D4,shadow_dmacon ; not zero so set 'em .dmacon_set\@ MOVE.W (sp)+,D4 ; restore D4 ENDM ; Player - This is THE 'Paula' Emulator. do_music: TST.B music_on ; music on? BEQ skipit ; if not skip all! MOVE.W #$2500,SR BSR Set_DMA MOVEM.L D0-D7/A0-A6,-(SP) .do_fadein LEA fadeINflag(PC),A0 TST.B (A0) ; are we fadeing down? BEQ.S .nofadein SUBQ.B #1,1(A0) ; curr count-1 BNE.S .nofadein MOVE.B 2(A0),1(A0) ; reset count LEA global_vol(PC),A1 CMP #$40,(A1) ; reached max? BLT.S .notinyet SF (A0) ; global vol=$40! LEA vol_bitflag(PC),A1 BCLR #0,(A1) ; signal fade done BRA.S .nofadein .notinyet ADDQ #1,(A1) ; global vol+1 .nofadein .do_fadedown LEA fadeOUTflag(PC),A0 TST.B (A0) ; are we fadeing down? BEQ.S .nofadedown SUBQ.B #1,1(A0) ; curr count-1 BNE.S .nofadedown MOVE.B 2(A0),1(A0) ; reset count LEA global_vol(PC),A1 TST.W (A1) BNE.S .notdownyet SF (A0) ; global vol=0! LEA vol_bitflag(PC),A1 BCLR #0,(A1) ; signal fade done BRA.S .nofadedown .notdownyet SUBQ #1,(A1) ; global vol-1 .nofadedown LEA.L Voice1Set(PC),A0 ; Setup Chan 1 LEA.L ch1s(PC),A5 MOVEQ #0,D4 BSR SetupVoice LEA.L Voice2Set(PC),A0 ; " 2 LEA.L ch2s(PC),A5 MOVEQ #1,D4 BSR SetupVoice LEA.L Voice3Set(PC),A0 ; " 3 LEA.L ch3s(PC),A5 MOVEQ #2,D4 BSR SetupVoice LEA.L Voice4Set(PC),A0 ; " 4 LEA.L ch4s(PC),A5 MOVEQ #3,D4 BSR SetupVoice BSR Goforit BSR mt_music skipit1 MOVEM.L (SP)+,D0-D7/A0-A6 skipit RTE RSRESET Vaddr RS.L 1 Voffy RS.L 1 Vfrac RS.L 1 Vfreqint RS.W 1 ; structure produced Vfreqfrac RS.L 1 Vvoltab RS.W 1 ; from 'paula' data Vlpaddr RS.L 1 Vlpoffy RS.L 1 Vlpfreqint RS.W 1 Vlpfreqfrac RS.L 1 ; Routine to add/move one voice to buffer. The real Paula emulation part!! SetupVoice MOVE.L sam_start(A5),A2 ; current sample end address(shadow amiga!) MOVE.L sam_length(A5),D0 MOVEM.W sam_period(A5),D1/D2 ; offset/period/volume CMP.W #$40,D2 BLS.S .ok MOVEQ #$40,D2 .ok MULU global_vol(PC),D2 LSR #6,D2 ; /64 LSL.W #8,D2 ; offset into volume tab LEA ftab(PC),A6 .OK2 MULU #6,D1 ADD.L D1,A6 MOVE.W (A6)+,D1 ; int part MOVE.L (A6)+,D3 .zero NEG.L D0 ; negate sample offset MOVE.W shadow_dmacon(PC),D7 BTST D4,D7 BNE.S .vcon2 MOVEQ #0,D1 ; clear freq if off. MOVEQ #0,D3 ; clear freq if off. MOVEQ #0,D2 ; volume off for safety!! .vcon2 LEA nulsamp+2(PC),A6 CMP.L A6,A2 BNE.S .vcon MOVEQ #0,D1 ; clear freq if off. MOVEQ #0,D3 ; clear freq if off. MOVEQ #0,D2 ; volume off for safety!! .vcon MOVE.L sam_lpstart(a5),A6 ; loop addr MOVE.L sam_lplength(a5),D5 ; loop length NEG.L D5 ; negate it. MOVE.W D1,D6 ; freq on loop MOVE.L D3,D7 ; CMP.L #-2,D5 BNE.S .isloop .noloop MOVEQ #0,D6 MOVEQ #0,D7 ; no loop-no frequency LEA nulsamp+2(PC),A6 ; no loop-point to nul .isloop MOVE.L A2,(A0)+ ; store address MOVE.L D0,(A0)+ ; store offset int.L ADDQ.L #4,A0 ; skip current frac.l MOVE.W D1,(A0)+ ; store freq int.w MOVE.L D3,(A0)+ ; store freq 32bit fraction MOVE.W D2,(A0)+ ; address of volume tab. MOVE.L A6,(A0)+ ; store loop addr MOVE.L D5,(A0)+ ; store loop offset.L MOVE.W D6,(A0)+ ; store loop freq int.w MOVE.L D7,(A0)+ ; store loop freq frac.L RTS ftab DS.W 3 INCBIN i:\PROTRACK.S\50PLAY.STE\FRQ32BIT.TAB ; Make that buffer! (channels are paired together!) Goforit LEA ch1s(PC),A2 LEA ch3s(PC),A3 LEA Voice1Set(PC),A5 LEA Voice3Set(PC),A6 MOVE.W #0,bufoff+2 BSR do2chans LEA ch2s(PC),A2 LEA ch4s(PC),A3 LEA Voice2Set(PC),A5 LEA Voice4Set(PC),A6 MOVE.W #1,bufoff+2 BSR do2chans RTS ; Create 2 channels in the buffer. do2chans MOVEM.L A2-A3/A5-A6,-(SP) MOVE.L voltab_ptr(PC),D2 MOVE.L D2,D3 MOVEQ #0,D4 MOVE.W Vvoltab(A5),D4 ADD.L D4,D2 ; volume tab chan 1 MOVE.W Vvoltab(A6),D4 ADD.L D4,D3 ; volume tab chan 2 MOVE.L Vaddr(A5),A0 ; ptr to end of each sample! MOVE.L Voffy(A5),D0 ; int.w offset MOVE.L Vfrac(A5),D4 ; frac.w offset MOVE.W Vfreqint(A5),D6 MOVE.L Vfreqfrac(A5),A2 ; frac.w/int.w freq MOVE.L Vaddr(A6),A1 MOVE.L Voffy(A6),D1 MOVE.L Vfrac(A6),D5 MOVE.W Vfreqint(A6),D7 MOVE.L Vfreqfrac(A6),A3 SWAP D6 MOVE.L Vlpaddr(A5),lpvc1ste+2+2 ; loop for voice 1 MOVE.L Vlpoffy(A5),lpvc1ste+8+2 MOVE.L Vlpfreqfrac(A5),lpvc1ste+14+2 MOVE.W Vlpfreqint(A5),lpvc1ste+20+2 MOVE.L Vlpaddr(A6),lpvc2ste+2+2 ; loop for voice 1 MOVE.L Vlpoffy(A6),lpvc2ste+8+2 MOVE.L Vlpfreqfrac(A6),lpvc2ste+14+2 MOVE.W Vlpfreqint(A6),lpvc2ste+20+2 LEA ciaem_tab(PC),A4 MOVE.W RealTempo(PC),D6 ADD.W D6,D6 MOVE.W (A4,D6),D6 MOVE.L stebuf_ptrs(pc),a4 BSR add2 MOVEM.L (SP)+,A2-A3/A5-A6 NEG.L D0 ; +ve offset(as original!) NEG.L D1 MOVE.L A0,sam_start(A2) ; store voice address MOVE.L D0,sam_length(A2) ; store offset for next time MOVE.L D4,Vfrac(A5) ; store frac part MOVE.L A1,sam_start(A3) ; same for chan 2 MOVE.L D1,sam_length(A3) MOVE.L D5,Vfrac(A6) RTS ciaem_tab INCBIN i:\PROTRACK.S\50PLAY.STE\CIA_EMU.TAB add2 TRAP #12 bufoff LEA 1(A4),SP make12_stelp MOVE.B (A0,D0.L),D2 MOVE.L D2,A4 MOVE.B (A4),D2 MOVE.B (A1,D1.L),D3 MOVE.L D3,A4 ADD.B (A4),D2 MOVE.B D2,(SP)+ MOVE.B D2,(SP)+ ; oversample(!) SWAP D6 ADD.L A2,D4 ; 32 bit fraction ADDX.W D6,D0 BCS.S lpvc1ste contlp1ste SWAP D6 ADD.L A3,D5 ; ADDX.W D7,D1 contlp2ste DBCS D6,make12_stelp BCS.S lpvc2ste REPT 4 MOVE.B D2,(SP)+ ; smooth MOVE.B D2,(SP)+ ; in case! ENDR TRAP #12 exitadd12 RTS lpvc1ste EXT.L D0 LEA.L $12345678,A0 ; 0+2 ADD.L #0,D0 ; 6+4 LEA.L $12345678,A2 ; 12+2 MOVE.W #$1234,D6 ; 18+2 BRA.S contlp1ste lpvc2ste EXT.L D1 LEA.L $12345678,A1 ; 0+2 ADD.L #0,D1 ; 6+2 LEA.L $12345678,A3 ; 12+2 MOVE.W #$1234,D7 ; 18+2 MOVE.W #0,CCR BRA.S contlp2ste Voice1Set DS.L 10 Voice2Set DS.L 10 ; voice data (setup from 'paula' data) Voice3Set DS.L 10 Voice4Set DS.L 10 DS.L 8 ; (in case!!) nulsamp DS.L 8 ; nul sample music_on DC.W 0 ; music on flag voltab_ptr DC.L 0 ; ptr to volume table ; ST specific initialise - sets up shadow amiga registers etc STspecific: BSR makevoltab LEA nulsamp+2(PC),A2 MOVEQ #0,D0 LEA ch1s(pc),A0 BSR initvoice LEA ch2s(pc),A0 BSR initvoice LEA ch3s(pc),A0 BSR initvoice LEA ch4s(pc),A0 BSR initvoice BSR start_music LEA music_on(PC),A0 ST (A0) RTS ; A0-> voice data (paula voice) to initialise. initvoice: MOVE.L A2,sam_start(A0) ; point voice to nul sample MOVE.L #2,sam_length(A0) MOVE.W D0,sam_period(A0) ; period=0 MOVE.W D0,sam_vol(A0) ; volume=0 MOVE.L A2,sam_lpstart(A0) ; and loop point to nul sample MOVE.L #2,sam_lplength(A0) RTS ; Start up music. start_music: CLR.B $FFFF8901.W BSR Set_DMA MOVE.W #$2700,SR BSET.B #5,$FFFFFA07.W ;iera BSET.B #5,$FFFFFA13.W ;imra CLR.B $FFFFFA19.W MOVE.B #1,$FFFFFA1F.W MOVE.B #8,$FFFFFA19.W ;timer a event mode. MOVE.L #do_music,$134.W BSR Start_DMA .exitste MOVE.W #$2300,SR RTS ; Set DMA to play buffer(buffer len based on TEMPO) Set_DMA MOVEM.L D0/A0/A1,-(SP) MOVE.L stebuf_ptrs+4(PC),A0 MOVE.L A0,temp LEA ciaem_tab(PC),A1 MOVE.W RealTempo(PC),D0 ADD.W D0,D0 MOVE.W (A1,D0),D0 ADD.W D0,D0 ADD.W D0,D0 ADD.W D0,A0 MOVE.L A0,temp+4 MOVE.B temp+1(PC),$ffff8903.W MOVE.B temp+2(PC),$ffff8905.W ; set start of buffer MOVE.B temp+3(PC),$ffff8907.W MOVE.B temp+5(PC),$ffff890f.W MOVE.B temp+6(PC),$ffff8911.W ; set end of buffer MOVE.B temp+7(PC),$ffff8913.W MOVEM.L stebuf_ptrs(PC),A0/A1 EXG A0,A1 MOVEM.L A0-A1,stebuf_ptrs MOVEM.L (SP)+,D0/A0/A1 RTS Start_DMA MOVE.B #dmamask,$FFFF8921.W ; set khz MOVE.B #3,$FFFF8901.W ; start STE dma. RTS stebuf_ptrs DC.L stebuf1,stebuf2 temp: dc.l 0,0 stop_music: CLR.B $FFFF8901.W ; stop STE dma. MOVE.W #$2700,SR BCLR.B #5,$FFFFFA07.W ; iera BCLR.B #5,$FFFFFA13.W ; imra MOVE.W #$2300,SR RTS ; Create the 65 volume lookup tables makevoltab: MOVE.L #vols+256,D0 CLR.B D0 MOVE.L D0,A0 MOVE.L A0,voltab_ptr LEA 16640(A0),A0 MOVEQ #$40,D0 .lp1 MOVE.W #$FF,D1 .lp2 MOVE.W D1,D2 EXT.W D2 MULS D0,D2 ASR.L #7,D2 MOVE.B D2,-(A0) DBF D1,.lp2 DBF D0,.lp1 LEA stebuf1,A0 LEA stebuf2,A1 MOVE.W #(bufsize/2)-1,d0 MOVEQ #0,D1 .lp MOVE.L D1,(A0)+ MOVE.L D1,(A1)+ DBF D0,.lp RTS ;************************************************** ;* ----- Protracker V2.1A Playroutine ----- * ;* Peter "CRAYON" Hanning / Mushroom Studios 1992 * ;* Vinterstigen 12, 14440 Ronninge, Sweden * ;************************************************** ; CIA Version 1: ; This playroutine is not very fast, optimized or well commented, ; but all the new commands in PT2.1 should work. ; If it's not good enough, you'll have to change it yourself. ; We'll try to write a faster routine soon... ; Changes from V1.0C playroutine: ; - Vibrato depth changed to be compatible with Noisetracker 2.0. ; You'll have to double all vib. depths on old PT modules. ; - Funk Repeat changed to Invert Loop. ; - Period set back earlier when stopping an effect. ;---- Playroutine ---- n_note EQU 0 ; W n_cmd EQU 2 ; W n_cmdlo EQU 3 ; B 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 mt_init LEA mt_data,A0 MOVE.L A0,mt_SongDataPtr MOVE.L A0,A1 LEA 952(A1),A1 MOVEQ #127,D0 MOVEQ #0,D1 mtloop MOVE.L D1,D2 SUBQ.W #1,D0 mtloop2 MOVE.B (A1)+,D1 CMP.B D2,D1 BGT.S mtloop DBRA D0,mtloop2 ADDQ.B #1,D2 LEA mt_SampleStarts(PC),A1 ASL.L #8,D2 ASL.L #2,D2 ADD.L #1084,D2 ADD.L A0,D2 MOVE.L D2,A2 MOVEQ #30,D0 mtloop3 CLR.L (A2) MOVE.L A2,(A1)+ MOVEQ #0,D1 MOVE.W 42(A0),D1 ASL.L #1,D1 ADD.L D1,A2 ADD.L #30,A0 DBRA D0,mtloop3 MOVE.B #6,mt_speed CLR.B mt_counter CLR.B mt_SongPos CLR.W mt_PatternPos ST mt_Enable move_dmacon #$F RTS mt_end SF mt_Enable move_dmacon #$F RTS mt_music TST.B mt_Enable BEQ mt_exit ADDQ.B #1,mt_counter MOVE.B mt_counter(PC),D0 CMP.B mt_speed(PC),D0 BLO.S mt_NoNewNote CLR.B mt_counter TST.B mt_PattDelTime2 BEQ.S mt_GetNewNote BSR.S mt_NoNewAllChannels BRA mt_dskip mt_NoNewNote BSR.S mt_NoNewAllChannels BRA mt_NoNewPosYet mt_NoNewAllChannels LEA ch1s(PC),A5 LEA mt_chan1temp(PC),A6 BSR mt_CheckEfx LEA ch2s(PC),A5 LEA mt_chan2temp(PC),A6 BSR mt_CheckEfx LEA ch3s(PC),A5 LEA mt_chan3temp(PC),A6 BSR mt_CheckEfx LEA ch4s(PC),A5 LEA mt_chan4temp(PC),A6 BRA mt_CheckEfx mt_GetNewNote MOVE.L mt_SongDataPtr(PC),A0 LEA 12(A0),A3 LEA 952(A0),A2 ;pattpo LEA 1084(A0),A0 ;patterndata MOVEQ #0,D0 MOVEQ #0,D1 MOVE.B mt_SongPos(PC),D0 MOVE.B (A2,D0.W),D1 ASL.L #8,D1 ASL.L #2,D1 ADD.W mt_PatternPos(PC),D1 CLR.W mt_DMACONtemp LEA ch1s(PC),A5 LEA mt_chan1temp(PC),A6 BSR.S mt_PlayVoice LEA ch2s(PC),A5 LEA mt_chan2temp(PC),A6 BSR.S mt_PlayVoice LEA ch3s(PC),A5 LEA mt_chan3temp(PC),A6 BSR.S mt_PlayVoice LEA ch4s(PC),A5 LEA mt_chan4temp(PC),A6 BSR.S mt_PlayVoice BRA mt_SetDMA mt_PlayVoice TST.L (A6) BNE.S mt_plvskip BSR mt_PerNop mt_plvskip MOVE.L (A0,D1.L),(A6) ADDQ.L #4,D1 MOVEQ #0,D2 MOVE.B n_cmd(A6),D2 AND.B #$F0,D2 LSR.B #4,D2 MOVE.B (A6),D0 AND.B #$F0,D0 OR.B D0,D2 TST.B D2 BEQ mt_SetRegs MOVEQ #0,D3 LEA mt_SampleStarts(PC),A1 MOVE D2,D4 SUBQ.L #1,D2 ASL.L #2,D2 MULU #30,D4 MOVE.L (A1,D2.L),n_start(A6) MOVE.W (A3,D4.L),n_length(A6) MOVE.W (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.S mt_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 MOVEQ #0,D0 MOVE.B n_volume(A6),D0 MOVE.W D0,sam_vol(A5) ; Set volume BRA.S mt_SetRegs mt_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 MOVEQ #0,D0 MOVE.B n_volume(A6),D0 MOVE.W D0,sam_vol(A5) ; Set volume mt_SetRegs MOVE.W (A6),D0 AND.W #$0FFF,D0 BEQ mt_CheckMoreEfx ; If no note MOVE.W 2(A6),D0 AND.W #$0FF0,D0 CMP.W #$0E50,D0 BEQ.S mt_DoSetFineTune MOVE.B 2(A6),D0 AND.B #$0F,D0 CMP.B #3,D0 ; TonePortamento BEQ.S mt_ChkTonePorta CMP.B #5,D0 BEQ.S mt_ChkTonePorta CMP.B #9,D0 ; Sample Offset BNE.S mt_SetPeriod BSR mt_CheckMoreEfx BRA.S mt_SetPeriod mt_DoSetFineTune BSR mt_SetFineTune BRA.S mt_SetPeriod mt_ChkTonePorta BSR mt_SetTonePorta BRA mt_CheckMoreEfx mt_SetPeriod MOVEM.L D0-D1/A0-A1,-(SP) MOVE.W (A6),D1 AND.W #$0FFF,D1 LEA mt_PeriodTable(PC),A1 MOVEQ #0,D0 MOVEQ #36,D2 mt_ftuloop CMP.W (A1,D0.W),D1 BHS.S mt_ftufound ADDQ.L #2,D0 DBRA D2,mt_ftuloop mt_ftufound MOVEQ #0,D1 MOVE.B n_finetune(A6),D1 MULU #36*2,D1 ADD.L D1,A1 MOVE.W (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 ; Notedelay BEQ mt_CheckMoreEfx move_dmacon n_dmabit(A6) BTST #2,n_wavecontrol(A6) BNE.S mt_vibnoc CLR.B n_vibratopos(A6) mt_vibnoc BTST #6,n_wavecontrol(A6) BNE.S mt_trenoc CLR.B n_tremolopos(A6) mt_trenoc MOVE.L n_start(A6),sam_start(A5) ; Set start MOVEQ #0,D0 MOVE.W n_length(A6),D0 ADD.L D0,D0 ADD.L D0,sam_start(A5) MOVE.L D0,sam_length(A5) ; Set length MOVE.W n_period(A6),D0 MOVE.W D0,sam_period(A5) ; Set period MOVE.W n_dmabit(A6),D0 OR.W D0,mt_DMACONtemp BRA mt_CheckMoreEfx mt_SetDMA MOVE.W mt_DMACONtemp(PC),D0 OR.W #$8000,D0 move_dmacon d0 LEA ch4s(PC),A5 LEA mt_chan4temp(PC),A6 MOVE.L n_loopstart(A6),sam_lpstart(A5) MOVEQ #0,D0 MOVE.W n_replen(A6),D0 ADD.L D0,D0 MOVE.L D0,sam_lplength(A5) ADD.L D0,sam_lpstart(A5) LEA ch3s(PC),A5 LEA mt_chan3temp(PC),A6 MOVE.L n_loopstart(A6),sam_lpstart(A5) MOVEQ #0,D0 MOVE.W n_replen(A6),D0 ADD.L D0,D0 MOVE.L D0,sam_lplength(A5) ADD.L D0,sam_lpstart(A5) LEA ch2s(PC),A5 LEA mt_chan2temp(PC),A6 MOVE.L n_loopstart(A6),sam_lpstart(A5) MOVEQ #0,D0 MOVE.W n_replen(A6),D0 ADD.L D0,D0 MOVE.L D0,sam_lplength(A5) ADD.L D0,sam_lpstart(A5) LEA ch1s(PC),A5 LEA mt_chan1temp(PC),A6 MOVE.L n_loopstart(A6),sam_lpstart(A5) MOVEQ #0,D0 MOVE.W n_replen(A6),D0 ADD.L D0,D0 MOVE.L D0,sam_lplength(A5) ADD.L D0,sam_lpstart(A5) mt_dskip ADD.W #16,mt_PatternPos MOVE.B mt_PattDelTime,D0 BEQ.S mt_dskc MOVE.B D0,mt_PattDelTime2 CLR.B mt_PattDelTime mt_dskc TST.B mt_PattDelTime2 BEQ.S mt_dska SUBQ.B #1,mt_PattDelTime2 BEQ.S mt_dska SUB.W #16,mt_PatternPos mt_dska TST.B mt_PBreakFlag BEQ.S mt_nnpysk SF mt_PBreakFlag MOVEQ #0,D0 MOVE.B mt_PBreakPos(PC),D0 CLR.B mt_PBreakPos LSL.W #4,D0 MOVE.W D0,mt_PatternPos mt_nnpysk CMP.W #1024,mt_PatternPos BLO.S mt_NoNewPosYet mt_NextPosition MOVEQ #0,D0 MOVE.B mt_PBreakPos(PC),D0 LSL.W #4,D0 MOVE.W D0,mt_PatternPos CLR.B mt_PBreakPos CLR.B mt_PosJumpFlag ADDQ.B #1,mt_SongPos AND.B #$7F,mt_SongPos MOVE.B mt_SongPos(PC),D1 MOVE.L mt_SongDataPtr(PC),A0 CMP.B 950(A0),D1 BLO.S mt_NoNewPosYet CLR.B mt_SongPos mt_NoNewPosYet TST.B mt_PosJumpFlag BNE.S mt_NextPosition mt_exit RTS mt_CheckEfx BSR mt_UpdateFunk MOVE.W n_cmd(A6),D0 AND.W #$0FFF,D0 BEQ.S mt_PerNop MOVE.B n_cmd(A6),D0 AND.B #$0F,D0 BEQ.S mt_Arpeggio CMP.B #1,D0 BEQ mt_PortaUp CMP.B #2,D0 BEQ mt_PortaDown CMP.B #3,D0 BEQ mt_TonePortamento CMP.B #4,D0 BEQ mt_Vibrato CMP.B #5,D0 BEQ mt_TonePlusVolSlide CMP.B #6,D0 BEQ mt_VibratoPlusVolSlide CMP.B #$E,D0 BEQ mt_E_Commands SetBack MOVE.W n_period(A6),sam_period(A5) CMP.B #7,D0 BEQ mt_Tremolo CMP.B #$A,D0 BEQ mt_VolumeSlide mt_Return RTS mt_PerNop MOVE.W n_period(A6),sam_period(A5) RTS mt_Arpeggio MOVEQ #0,D0 MOVE.B mt_counter(PC),D0 DIVS #3,D0 SWAP D0 CMP.W #0,D0 BEQ.S mt_Arpeggio2 CMP.W #2,D0 BEQ.S mt_Arpeggio1 MOVEQ #0,D0 MOVE.B n_cmdlo(A6),D0 LSR.B #4,D0 BRA.S mt_Arpeggio3 mt_Arpeggio1 MOVEQ #0,D0 MOVE.B n_cmdlo(A6),D0 AND.B #15,D0 BRA.S mt_Arpeggio3 mt_Arpeggio2 MOVE.W n_period(A6),D2 BRA.S mt_Arpeggio4 mt_Arpeggio3 ASL.W #1,D0 MOVEQ #0,D1 MOVE.B n_finetune(A6),D1 MULU #36*2,D1 LEA mt_PeriodTable(PC),A0 ADD.L D1,A0 MOVEQ #0,D1 MOVE.W n_period(A6),D1 MOVEQ #36,D3 mt_arploop MOVE.W (A0,D0.W),D2 CMP.W (A0),D1 BHS.S mt_Arpeggio4 ADDQ.L #2,A0 DBRA D3,mt_arploop RTS mt_Arpeggio4 MOVE.W D2,sam_period(A5) RTS mt_FinePortaUp TST.B mt_counter BNE.S mt_Return MOVE.B #$0F,mt_LowMask mt_PortaUp MOVEQ #0,D0 MOVE.B n_cmdlo(A6),D0 AND.B mt_LowMask(PC),D0 MOVE.B #$FF,mt_LowMask SUB.W D0,n_period(A6) MOVE.W n_period(A6),D0 AND.W #$0FFF,D0 CMP.W #113,D0 BPL.S mt_PortaUskip AND.W #$F000,n_period(A6) OR.W #113,n_period(A6) mt_PortaUskip MOVE.W n_period(A6),D0 AND.W #$0FFF,D0 MOVE.W D0,sam_period(A5) RTS mt_FinePortaDown TST.B mt_counter BNE mt_Return MOVE.B #$0F,mt_LowMask mt_PortaDown CLR.W D0 MOVE.B n_cmdlo(A6),D0 AND.B mt_LowMask(PC),D0 MOVE.B #$FF,mt_LowMask ADD.W D0,n_period(A6) MOVE.W n_period(A6),D0 AND.W #$0FFF,D0 CMP.W #856,D0 BMI.S mt_PortaDskip AND.W #$F000,n_period(A6) OR.W #856,n_period(A6) mt_PortaDskip MOVE.W n_period(A6),D0 AND.W #$0FFF,D0 MOVE.W D0,sam_period(A5) RTS mt_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 mt_PeriodTable(PC),A0 ADD.L D0,A0 MOVEQ #0,D0 mt_StpLoop CMP.W (A0,D0.W),D2 BHS.S mt_StpFound ADDQ.W #2,D0 CMP.W #37*2,D0 BLO.S mt_StpLoop MOVEQ #35*2,D0 mt_StpFound MOVE.B n_finetune(A6),D2 AND.B #8,D2 BEQ.S mt_StpGoss TST.W D0 BEQ.S mt_StpGoss SUBQ.W #2,D0 mt_StpGoss MOVE.W (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.S mt_ClearTonePorta BGE mt_Return MOVE.B #1,n_toneportdirec(A6) RTS mt_ClearTonePorta CLR.W n_wantedperiod(A6) RTS mt_TonePortamento MOVE.B n_cmdlo(A6),D0 BEQ.S mt_TonePortNoChange MOVE.B D0,n_toneportspeed(A6) CLR.B n_cmdlo(A6) mt_TonePortNoChange TST.W n_wantedperiod(A6) BEQ mt_Return MOVEQ #0,D0 MOVE.B n_toneportspeed(A6),D0 TST.B n_toneportdirec(A6) BNE.S mt_TonePortaUp mt_TonePortaDown ADD.W D0,n_period(A6) MOVE.W n_wantedperiod(A6),D0 CMP.W n_period(A6),D0 BGT.S mt_TonePortaSetPer MOVE.W n_wantedperiod(A6),n_period(A6) CLR.W n_wantedperiod(A6) BRA.S mt_TonePortaSetPer mt_TonePortaUp SUB.W D0,n_period(A6) MOVE.W n_wantedperiod(A6),D0 CMP.W n_period(A6),D0 BLT.S mt_TonePortaSetPer MOVE.W n_wantedperiod(A6),n_period(A6) CLR.W n_wantedperiod(A6) mt_TonePortaSetPer MOVE.W n_period(A6),D2 MOVE.B n_glissfunk(A6),D0 AND.B #$0F,D0 BEQ.S mt_GlissSkip MOVEQ #0,D0 MOVE.B n_finetune(A6),D0 MULU #36*2,D0 LEA mt_PeriodTable(PC),A0 ADD.L D0,A0 MOVEQ #0,D0 mt_GlissLoop CMP.W (A0,D0.W),D2 BHS.S mt_GlissFound ADDQ.W #2,D0 CMP.W #36*2,D0 BLO.S mt_GlissLoop MOVEQ #35*2,D0 mt_GlissFound MOVE.W (A0,D0.W),D2 mt_GlissSkip MOVE.W D2,sam_period(A5) ; Set period RTS mt_Vibrato MOVE.B n_cmdlo(A6),D0 BEQ.S mt_Vibrato2 MOVE.B n_vibratocmd(A6),D2 AND.B #$0F,D0 BEQ.S mt_vibskip AND.B #$F0,D2 OR.B D0,D2 mt_vibskip MOVE.B n_cmdlo(A6),D0 AND.B #$F0,D0 BEQ.S mt_vibskip2 AND.B #$0F,D2 OR.B D0,D2 mt_vibskip2 MOVE.B D2,n_vibratocmd(A6) mt_Vibrato2 MOVE.B n_vibratopos(A6),D0 LEA mt_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.S mt_vib_sine LSL.B #3,D0 CMP.B #1,D2 BEQ.S mt_vib_rampdown MOVE.B #255,D2 BRA.S mt_vib_set mt_vib_rampdown TST.B n_vibratopos(A6) BPL.S mt_vib_rampdown2 MOVE.B #255,D2 SUB.B D0,D2 BRA.S mt_vib_set mt_vib_rampdown2 MOVE.B D0,D2 BRA.S mt_vib_set mt_vib_sine MOVE.B (A4,D0.W),D2 mt_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.S mt_VibratoNeg ADD.W D2,D0 BRA.S mt_Vibrato3 mt_VibratoNeg SUB.W D2,D0 mt_Vibrato3 MOVE.W D0,sam_period(A5) MOVE.B n_vibratocmd(A6),D0 LSR.W #2,D0 AND.W #$003C,D0 ADD.B D0,n_vibratopos(A6) RTS mt_TonePlusVolSlide BSR mt_TonePortNoChange BRA mt_VolumeSlide mt_VibratoPlusVolSlide BSR.S mt_Vibrato2 BRA mt_VolumeSlide mt_Tremolo MOVE.B n_cmdlo(A6),D0 BEQ.S mt_Tremolo2 MOVE.B n_tremolocmd(A6),D2 AND.B #$0F,D0 BEQ.S mt_treskip AND.B #$F0,D2 OR.B D0,D2 mt_treskip MOVE.B n_cmdlo(A6),D0 AND.B #$F0,D0 BEQ.S mt_treskip2 AND.B #$0F,D2 OR.B D0,D2 mt_treskip2 MOVE.B D2,n_tremolocmd(A6) mt_Tremolo2 MOVE.B n_tremolopos(A6),D0 LEA mt_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.S mt_tre_sine LSL.B #3,D0 CMP.B #1,D2 BEQ.S mt_tre_rampdown MOVE.B #255,D2 BRA.S mt_tre_set mt_tre_rampdown TST.B n_vibratopos(A6) BPL.S mt_tre_rampdown2 MOVE.B #255,D2 SUB.B D0,D2 BRA.S mt_tre_set mt_tre_rampdown2 MOVE.B D0,D2 BRA.S mt_tre_set mt_tre_sine MOVE.B (A4,D0.W),D2 mt_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.S mt_TremoloNeg ADD.W D2,D0 BRA.S mt_Tremolo3 mt_TremoloNeg SUB.W D2,D0 mt_Tremolo3 BPL.S mt_TremoloSkip CLR.W D0 mt_TremoloSkip CMP.W #$40,D0 BLS.S mt_TremoloOk MOVE.W #$40,D0 mt_TremoloOk MOVE.W D0,sam_vol(A5) MOVE.B n_tremolocmd(A6),D0 LSR.W #2,D0 AND.W #$003C,D0 ADD.B D0,n_tremolopos(A6) RTS mt_SampleOffset MOVEQ #0,D0 MOVE.B n_cmdlo(A6),D0 BEQ.S mt_sononew MOVE.B D0,n_sampleoffset(A6) mt_sononew MOVE.B n_sampleoffset(A6),D0 LSL.W #7,D0 CMP.W n_length(A6),D0 BGE.S mt_sofskip SUB.W D0,n_length(A6) LSL.W #1,D0 ADD.L D0,n_start(A6) RTS mt_sofskip MOVE.W #$0001,n_length(A6) RTS mt_VolumeSlide MOVEQ #0,D0 MOVE.B n_cmdlo(A6),D0 LSR.B #4,D0 TST.B D0 BEQ.S mt_VolSlideDown mt_VolSlideUp ADD.B D0,n_volume(A6) CMP.B #$40,n_volume(A6) BMI.S mt_vsuskip MOVE.B #$40,n_volume(A6) mt_vsuskip MOVE.B n_volume(A6),D0 MOVE.W D0,sam_vol(A5) RTS mt_VolSlideDown MOVEQ #0,D0 MOVE.B n_cmdlo(A6),D0 AND.B #$0F,D0 mt_VolSlideDown2 SUB.B D0,n_volume(A6) BPL.S mt_vsdskip CLR.B n_volume(A6) mt_vsdskip MOVE.B n_volume(A6),D0 MOVE.W D0,sam_vol(A5) RTS mt_PositionJump MOVE.B n_cmdlo(A6),D0 SUBQ.B #1,D0 MOVE.B D0,mt_SongPos mt_pj2 CLR.B mt_PBreakPos ST mt_PosJumpFlag RTS mt_VolumeChange MOVEQ #0,D0 MOVE.B n_cmdlo(A6),D0 CMP.B #$40,D0 BLS.S mt_VolumeOk MOVEQ #$40,D0 mt_VolumeOk MOVE.B D0,n_volume(A6) MOVE.W D0,sam_vol(A5) RTS mt_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.S mt_pj2 MOVE.B D0,mt_PBreakPos ST mt_PosJumpFlag RTS mt_SetSpeed MOVEQ #0,D0 MOVE.B 3(A6),D0 BEQ mt_end TST.B tempo_cont_flg ; tempo control on? BEQ.S .notempo CMP.B #32,D0 ; yes then d0>=32 BHS SetTempo ; then Set Tempo CLR.B mt_counter MOVE.B D0,mt_speed RTS .notempo ; tempo control is OFF CLR.B mt_counter MOVE.B D0,mt_speed ; so set speed regardless CMP.W #32,D0 BLO.S .okdefspeed MOVE.W D0,OldTempo ; but store in old tempo .okdefspeed ; for tempo turn back on. RTS SetTempo CMP.W #32,D0 BHS.S setemsk MOVEQ #32,D0 setemsk MOVE.W D0,RealTempo ; set tempo speed RTS mt_CheckMoreEfx BSR mt_UpdateFunk MOVE.B 2(A6),D0 AND.B #$0F,D0 CMP.B #$9,D0 BEQ mt_SampleOffset CMP.B #$B,D0 BEQ mt_PositionJump CMP.B #$D,D0 BEQ mt_PatternBreak CMP.B #$E,D0 BEQ.S mt_E_Commands CMP.B #$F,D0 BEQ mt_SetSpeed CMP.B #$C,D0 BEQ mt_VolumeChange BRA mt_PerNop mt_E_Commands MOVE.B n_cmdlo(A6),D0 AND.B #$F0,D0 LSR.B #4,D0 BEQ.S mt_FilterOnOff CMP.B #1,D0 BEQ mt_FinePortaUp CMP.B #2,D0 BEQ mt_FinePortaDown CMP.B #3,D0 BEQ.S mt_SetGlissControl CMP.B #4,D0 BEQ mt_SetVibratoControl CMP.B #5,D0 BEQ mt_SetFineTune CMP.B #6,D0 BEQ mt_JumpLoop CMP.B #7,D0 BEQ mt_SetTremoloControl CMP.B #9,D0 BEQ mt_RetrigNote CMP.B #$A,D0 BEQ mt_VolumeFineUp CMP.B #$B,D0 BEQ mt_VolumeFineDown CMP.B #$C,D0 BEQ mt_NoteCut CMP.B #$D,D0 BEQ mt_NoteDelay CMP.B #$E,D0 BEQ mt_PatternDelay CMP.B #$F,D0 BEQ mt_FunkIt RTS mt_FilterOnOff MOVE.B n_cmdlo(A6),D0 AND.B #1,D0 ASL.B #1,D0 ; AND.B #$FD,$BFE001 ; filter! ; OR.B D0,$BFE001 ; hehe RTS mt_SetGlissControl MOVE.B n_cmdlo(A6),D0 AND.B #$0F,D0 AND.B #$F0,n_glissfunk(A6) OR.B D0,n_glissfunk(A6) RTS mt_SetVibratoControl MOVE.B n_cmdlo(A6),D0 AND.B #$0F,D0 AND.B #$F0,n_wavecontrol(A6) OR.B D0,n_wavecontrol(A6) RTS mt_SetFineTune MOVE.B n_cmdlo(A6),D0 AND.B #$0F,D0 MOVE.B D0,n_finetune(A6) RTS mt_JumpLoop TST.B mt_counter BNE mt_Return MOVE.B n_cmdlo(A6),D0 AND.B #$0F,D0 BEQ.S mt_SetLoop TST.B n_loopcount(A6) BEQ.S mt_jumpcnt SUBQ.B #1,n_loopcount(A6) BEQ mt_Return mt_jmploop MOVE.B n_pattpos(A6),mt_PBreakPos ST mt_PBreakFlag RTS mt_jumpcnt MOVE.B D0,n_loopcount(A6) BRA.S mt_jmploop mt_SetLoop MOVE.W mt_PatternPos(PC),D0 LSR.W #4,D0 MOVE.B D0,n_pattpos(A6) RTS mt_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 mt_RetrigNote MOVE.L D1,-(SP) MOVEQ #0,D0 MOVE.B n_cmdlo(A6),D0 AND.B #$0F,D0 BEQ mt_rtnend MOVEQ #0,D1 MOVE.B mt_counter(PC),D1 BNE.S mt_rtnskp MOVE.W (A6),D1 AND.W #$0FFF,D1 BNE.S mt_rtnend MOVEQ #0,D1 MOVE.B mt_counter(PC),D1 mt_rtnskp DIVU D0,D1 SWAP D1 TST.W D1 BNE.S mt_rtnend mt_DoRetrig move_dmacon n_dmabit(A6) ; Channel DMA off MOVE.L n_start(A6),sam_start(A5) ; Set sampledata pointer MOVEQ #0,D0 MOVE.W n_length(A6),D0 ; Set length ADD.L D0,D0 ADD.L D0,sam_start(A5) MOVE.L D0,sam_length(A5) ; Set length MOVE.W n_dmabit(A6),D0 BSET #15,D0 move_dmacon d0 MOVE.L n_loopstart(A6),sam_lpstart(A5) MOVEQ #0,D0 MOVE.W n_replen(A6),D0 ADD.L D0,D0 ADD.L D0,sam_lpstart(A5) MOVE.L D0,sam_lplength(A5) MOVE.W n_replen+2(A6),sam_period(A5) mt_rtnend MOVE.L (SP)+,D1 RTS mt_VolumeFineUp TST.B mt_counter BNE mt_Return MOVEQ #0,D0 MOVE.B n_cmdlo(A6),D0 AND.B #$F,D0 BRA mt_VolSlideUp mt_VolumeFineDown TST.B mt_counter BNE mt_Return MOVEQ #0,D0 MOVE.B n_cmdlo(A6),D0 AND.B #$0F,D0 BRA mt_VolSlideDown2 mt_NoteCut MOVEQ #0,D0 MOVE.B n_cmdlo(A6),D0 AND.B #$0F,D0 CMP.B mt_counter(PC),D0 BNE mt_Return CLR.B n_volume(A6) MOVE.W #0,sam_vol(A5) RTS mt_NoteDelay MOVEQ #0,D0 MOVE.B n_cmdlo(A6),D0 AND.B #$0F,D0 CMP.B mt_Counter,D0 BNE mt_Return MOVE.W (A6),D0 BEQ mt_Return MOVE.L D1,-(SP) BRA mt_DoRetrig mt_PatternDelay TST.B mt_counter BNE mt_Return MOVEQ #0,D0 MOVE.B n_cmdlo(A6),D0 AND.B #$0F,D0 TST.B mt_PattDelTime2 BNE mt_Return ADDQ.B #1,D0 MOVE.B D0,mt_PattDelTime RTS mt_FunkIt TST.B mt_counter BNE mt_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 mt_Return mt_UpdateFunk MOVEM.L A0/D1,-(SP) MOVEQ #0,D0 MOVE.B n_glissfunk(A6),D0 LSR.B #4,D0 BEQ.S mt_funkend LEA mt_FunkTable(PC),A0 MOVE.B (A0,D0.W),D0 ADD.B D0,n_funkoffset(A6) BTST #7,n_funkoffset(A6) BEQ.S mt_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.S mt_funkok MOVE.L n_loopstart(A6),A0 mt_funkok MOVE.L A0,n_wavestart(A6) MOVEQ #-1,D0 SUB.B (A0),D0 MOVE.B D0,(A0) mt_funkend MOVEM.L (SP)+,A0/D1 RTS mt_FunkTable dc.b 0,5,6,7,8,10,11,13,16,19,22,26,32,43,64,128 mt_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 mt_PeriodTable ; Tuning 0, Normal 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 ; 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 ; 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 ; 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 ; 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 ; 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 ; 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 ; 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 ; 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 ; 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 ; 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 ; 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 ; 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 ; 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 ; 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 ; 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 mt_chan1temp dc.l 0,0,0,0,0,$00010000,0, 0,0,0,0 mt_chan2temp dc.l 0,0,0,0,0,$00020000,0, 0,0,0,0 mt_chan3temp dc.l 0,0,0,0,0,$00040000,0, 0,0,0,0 mt_chan4temp dc.l 0,0,0,0,0,$00080000,0, 0,0,0,0 mt_SampleStarts dc.l 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 dc.l 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 mt_SongDataPtr dc.l 0 mt_speed dc.b 6 mt_counter dc.b 0 mt_SongPos dc.b 0 mt_PBreakPos dc.b 0 mt_PosJumpFlag dc.b 0 mt_PBreakFlag dc.b 0 mt_LowMask dc.b 0 mt_PattDelTime dc.b 0 mt_PattDelTime2 dc.b 0 mt_Enable dc.b 0 mt_PatternPos dc.w 0 mt_DMACONtemp dc.w 0 ;/* End of File */ IFNE test testfile DC.B (endtestfilename-testfilename) testfilename DC.B "j:\mods\madness.MOD" endtestfilename ENDC SECTION BSS vols DS.L 64 DS.L 16640/4 stebuf1: DS.W bufsize ; buffers must be this big to handle stebuf2: DS.W bufsize ; downto tempo 32 DS.L 349 my_stack DS.L 3 dir DS.W 1 mt_data ; module is loaded here.