* * JamCracker V1.0 Replay routine, written by M. Gemmel * * Make sure you have read the ReadMe file on this disk too. * * This is not a demonstration source, showing how to write * a song-play routine. This source is merely ment for * inclusion in other sources, or as assembly module for * linkage with other programs. * * This source was written for the GenIm V2.12 assembler * and can be easily modified for other assemblers. * The song should be inserted at 'mysong' near the bottom of * this source, in chip memory. * * This is the correct calling procedure * Don't forget to save any important registers * because I don't care bsr.s pp_init First, initialize here bsr pp_play Then, play every 1/50 sec. hi cmpi.b #1,$dff006 bne.s hi btst #6,$bfe001 Check left mouse button bne.s here bsr pp_end Finally, stop playing rts *** This is the actual replay routine wavesize set $40 pp_init lea mysong,a0 addq.w #4,a0 move.w (a0)+,d0 move.w d0,d1 move.l a0,instable mulu #it_sizeof,d0 adda.w d0,a0 move.w (a0)+,d0 move.w d0,d2 move.l a0,patttable mulu #pt_sizeof,d0 adda.w d0,a0 move.w (a0)+,d0 move.w d0,songlen move.l a0,songtable lsl.w #1,d0 adda.w d0,a0 movea.l patttable,a1 move.w d2,d0 subq.w #1,d0 .l0 move.l a0,pt_address(a1) move.w pt_size(a1),d3 mulu #nt_sizeof*4,d3 adda.w d3,a0 addq.w #pt_sizeof,a1 dbf d0,.l0 movea.l instable,a1 move.w d1,d0 subq.w #1,d0 .l1 move.l a0,it_address(a1) move.l it_size(a1),d2 adda.l d2,a0 adda.w #it_sizeof,a1 dbf d0,.l1 move.l songtable,pp_songptr move.w songlen,pp_songcnt movea.l pp_songptr,a0 move.w (a0),d0 mulu #pt_sizeof,d0 add.l patttable,d0 movea.l d0,a0 move.l a0,pp_pattentry move.b pt_size+1(a0),pp_notecnt move.l pt_address(a0),pp_address move.b #6,pp_wait move.b #1,pp_waitcnt clr.w pp_nullwave move.w #$000f,$dff096 lea pp_variables,a0 lea $dff0a0,a1 move.w #$0001,d1 move.w #2*wavesize,d2 move.w #3,d0 .l2 clr.w 8(a1) move.w d2,pv_waveoffset(a0) move.w d1,pv_dmacon(a0) move.l a1,pv_custbase(a0) move.l #pp_periods,pv_peraddress(a0) move.w #1019,pv_pers(a0) clr.w pv_pers+2(a0) clr.w pv_pers+4(a0) clr.l pv_por(a0) clr.w pv_porlevel(a0) clr.l pv_vib(a0) clr.l pv_vol(a0) move.w #$0040,pv_vollevel(a0) clr.l pv_phase(a0) clr.w pv_vibcnt(a0) clr.b pv_flags(a0) adda.w #pv_sizeof,a0 adda.w #$0010,a1 lsl.w #1,d1 addi.w #wavesize,d2 dbf d0,.l2 rts pp_end clr.w $dff0a8 clr.w $dff0b8 clr.w $dff0c8 clr.w $dff0d8 move.w #$000f,$dff096 rts pp_play subq.b #1,pp_waitcnt bne.s .l0 bsr pp_nwnt move.b pp_wait,pp_waitcnt .l0 lea pp_variables,a1 bsr.s pp_uvs lea pp_variables+pv_sizeof,a1 bsr.s pp_uvs lea pp_variables+2*pv_sizeof,a1 bsr.s pp_uvs lea pp_variables+3*pv_sizeof,a1 pp_uvs movea.l pv_custbase(a1),a0 .l0 move.w pv_pers(a1),d0 bne.s .l1 bsr pp_rot bra.s .l0 .l1 add.w pv_por(a1),d0 tst.w pv_por(a1) beq.s .l1c bpl.s .l1a cmp.w pv_porlevel(a1),d0 bge.s .l1c bra.s .l1b .l1a cmp.w pv_porlevel(a1),d0 ble.s .l1c .l1b move.w pv_porlevel(a1),d0 .l1c add.w pv_vib(a1),d0 cmpi.w #135,d0 bge.s .l1d move.w #135,d0 bra.s .l1e .l1d cmpi.w #1019,d0 ble.s .l1e move.w #1019,d0 .l1e move.w d0,6(a0) bsr pp_rot move.w pv_deltapor(a1),d0 add.w d0,pv_por(a1) cmpi.w #-1019,pv_por(a1) bge.s .l3 move.w #-1019,pv_por(a1) bra.s .l5 .l3 cmpi.w #1019,pv_por(a1) ble.s .l5 move.w #1019,pv_por(a1) .l5 tst.b pv_vibcnt(a1) beq.s .l7 move.w pv_deltavib(a1),d0 add.w d0,pv_vib(a1) subq.b #1,pv_vibcnt(a1) bne.s .l7 neg.w pv_deltavib(a1) move.b pv_vibmax(a1),pv_vibcnt(a1) .l7 move.w pv_dmacon(a1),d0 move.w pv_vol(a1),8(a0) move.w pv_deltavol(a1),d0 add.w d0,pv_vol(a1) tst.w pv_vol(a1) bpl.s .l8 clr.w pv_vol(a1) bra.s .la .l8 cmpi.w #$40,pv_vol(a1) ble.s .la move.w #$40,pv_vol(a1) .la btst #1,pv_flags(a1) beq.s .l10 movea.l pv_insaddress(a1),a0 move.w pv_waveoffset(a1),d0 neg.w d0 lea 0(a0,d0.w),a2 movea.l a2,a3 move.w pv_phase(a1),d0 lsr.w #2,d0 adda.w d0,a3 move.w #wavesize-1,d0 .lb move.b (a2)+,d1 ext.w d1 move.b (a3)+,d2 ext.w d2 add.w d1,d2 asr.w #1,d2 move.b d2,(a0)+ dbf d0,.lb move.w pv_deltaphase(a1),d0 add.w d0,pv_phase(a1) cmpi.w #wavesize<<2,pv_phase(a1) blt.s .l10 subi.w #wavesize<<2,pv_phase(a1) .l10 rts pp_rot move.w pv_pers(a1),d0 move.w pv_pers+2(a1),pv_pers(a1) move.w pv_pers+4(a1),pv_pers+2(a1) move.w d0,pv_pers+4(a1) rts pp_nwnt movea.l pp_address,a0 addi.l #4*nt_sizeof,pp_address subq.b #1,pp_notecnt bne.s .l5 .l0 addq.l #2,pp_songptr subq.w #1,pp_songcnt bne.s .l1 move.l songtable,pp_songptr move.w songlen,pp_songcnt .l1 movea.l pp_songptr,a1 move.w (a1),d0 mulu #pt_sizeof,d0 add.l patttable,d0 movea.l d0,a1 move.b pt_size+1(a1),pp_notecnt move.l pt_address(a1),pp_address .l5 clr.w pp_tmpdmacon lea pp_variables,a1 bsr pp_nnt addq.w #nt_sizeof,a0 lea pp_variables+pv_sizeof,a1 bsr pp_nnt addq.w #nt_sizeof,a0 lea pp_variables+2*pv_sizeof,a1 bsr pp_nnt addq.w #nt_sizeof,a0 lea pp_variables+3*pv_sizeof,a1 bsr pp_nnt move.w pp_tmpdmacon,$dff096 move.w #300,d0 .l6 dbf d0,.l6 lea pp_variables,a1 bsr pp_scr lea pp_variables+pv_sizeof,a1 bsr.s pp_scr lea pp_variables+2*pv_sizeof,a1 bsr.s pp_scr lea pp_variables+3*pv_sizeof,a1 bsr.s pp_scr bset #7,pp_tmpdmacon move.w pp_tmpdmacon,$dff096 move.w #300,d0 .l7 dbf d0,.l7 move.l pp_variables+pv_insaddress,$dff0a0 move.w pp_variables+pv_inslen,$dff0a4 move.l pp_variables+pv_sizeof+pv_insaddress,$dff0b0 move.w pp_variables+pv_sizeof+pv_inslen,$dff0b4 move.l pp_variables+2*pv_sizeof+pv_insaddress,$dff0c0 move.w pp_variables+2*pv_sizeof+pv_inslen,$dff0c4 move.l pp_variables+3*pv_sizeof+pv_insaddress,$dff0d0 move.w pp_variables+3*pv_sizeof+pv_inslen,$dff0d4 rts pp_scr move.w pp_tmpdmacon,d0 and.w pv_dmacon(a1),d0 beq.s .l5 movea.l pv_custbase(a1),a0 move.l pv_insaddress(a1),(a0) move.w pv_inslen(a1),4(a0) move.w pv_pers(a1),6(a0) btst #0,pv_flags(a1) bne.s .l5 move.l #pp_nullwave,pv_insaddress(a1) move.w #1,pv_inslen(a1) .l5 rts pp_nnt move.b nt_period(a0),d1 beq .l5 andi.l #$000000ff,d1 lsl.w #1,d1 addi.l #pp_periods-2,d1 movea.l d1,a2 btst #6,nt_speed(a0) beq.s .l2 move.w (a2),pv_porlevel(a1) bra .l5 .l2 move.w pv_dmacon(a1),d0 or.w d0,pp_tmpdmacon move.l a2,pv_peraddress(a1) move.w (a2),pv_pers(a1) move.w (a2),pv_pers+2(a1) move.w (a2),pv_pers+4(a1) clr.w pv_por(a1) move.b nt_instr(a0),d0 ext.w d0 mulu #it_sizeof,d0 add.l instable,d0 movea.l d0,a2 tst.l it_address(a2) bne.s .l1 move.l #pp_nullwave,pv_insaddress(a1) move.w #1,pv_inslen(a1) clr.b pv_flags(a1) bra.s .l5 .l1 movea.l it_address(a2),a3 btst #1,it_flags(a2) bne.s .l0a move.l it_size(a2),d0 lsr.l #1,d0 move.w d0,pv_inslen(a1) bra.s .l0 .l0a move.w pv_waveoffset(a1),d0 adda.w d0,a3 move.w #wavesize>>1,pv_inslen(a1) .l0 move.l a3,pv_insaddress(a1) move.b it_flags(a2),pv_flags(a1) move.w pv_vollevel(a1),pv_vol(a1) .l5 move.b nt_speed(a0),d0 andi.b #$0f,d0 beq.s .l6 move.b d0,pp_wait .l6 movea.l pv_peraddress(a1),a2 move.b nt_arpeggio(a0),d0 beq.s .l9 cmpi.b #$ff,d0 bne.s .l7 move.w (a2),pv_pers(a1) move.w (a2),pv_pers+2(a1) move.w (a2),pv_pers+4(a1) bra.s .l9 .l7 andi.b #$0f,d0 lsl.b #1,d0 ext.w d0 move.w 0(a2,d0.w),pv_pers+4(a1) move.b nt_arpeggio(a0),d0 lsr.b #4,d0 lsl.b #1,d0 ext.w d0 move.w 0(a2,d0.w),pv_pers+2(a1) move.w (a2),pv_pers(a1) .l9 move.b nt_vibrato(a0),d0 beq.s .ld cmpi.b #$ff,d0 bne.s .la clr.l pv_vib(a1) clr.b pv_vibcnt(a1) bra.s .ld .la clr.w pv_vib(a1) andi.b #$0f,d0 ext.w d0 move.w d0,pv_deltavib(a1) move.b nt_vibrato(a0),d0 lsr.b #4,d0 move.b d0,pv_vibmax(a1) lsr.b #1,d0 move.b d0,pv_vibcnt(a1) .ld move.b nt_phase(a0),d0 beq.s .l10 cmpi.b #$ff,d0 bne.s .le clr.l pv_phase(a1) bra.s .l10 .le andi.b #$0f,d0 ext.w d0 move.w d0,pv_deltaphase(a1) clr.w pv_phase(a1) .l10 move.b nt_volume(a0),d0 bne.s .l10a btst #7,nt_speed(a0) beq.s .l16 bra.s .l11a .l10a cmpi.b #$ff,d0 bne.s .l11 clr.w pv_deltavol(a1) bra.s .l16 .l11 btst #7,nt_speed(a0) beq.s .l12 .l11a move.b d0,pv_vol+1(a1) move.b d0,pv_vollevel+1(a1) clr.w pv_deltavol(a1) bra.s .l16 .l12 bclr #7,d0 beq.s .l13 neg.b d0 .l13 ext.w d0 move.w d0,pv_deltavol(a1) .l16 move.b nt_porta(a0),d0 beq.s .l1a cmpi.b #$ff,d0 bne.s .l17 clr.l pv_por(a1) bra.s .l1a .l17 clr.w pv_por(a1) btst #6,nt_speed(a0) beq.s .l17a move.w pv_porlevel(a1),d1 cmp.w pv_pers(a1),d1 bgt.s .l17c neg.b d0 bra.s .l17c .l17a bclr #7,d0 bne.s .l18 neg.b d0 move.w #135,pv_porlevel(a1) bra.s .l17c .l18 move.w #1019,pv_porlevel(a1) .l17c ext.w d0 .l18a move.w d0,pv_deltapor(a1) .l1a rts * Replayer data section reppubdata,data pp_periods dc.w 1019,962,908,857,809,763,720,680,642,606,572,540 dc.w 509,481,454,428,404,381,360,340,321,303,286,270 dc.w 254,240,227,214,202,190,180,170,160,151,143,135 dc.w 135,135,135,135,135,135,135,135,135 dc.w 135,135,135,135,135,135 section repchipdata,data_c mysong ;Insert your song here! section reppubbss,bss songlen ds.w 1 songtable ds.l 1 instable ds.l 1 patttable ds.l 1 pp_wait ds.b 1 pp_waitcnt ds.b 1 pp_notecnt ds.b 1 pp_address ds.l 1 pp_songptr ds.l 1 pp_songcnt ds.w 1 pp_pattentry ds.l 1 pp_tmpdmacon ds.w 1 pp_variables ds.b 4*48 section repchipbss,bss_c pp_nullwave ds.w 1 rsreset it_name rs.b 31 it_flags rs.b 1 it_size rs.l 1 it_address rs.l 1 it_sizeof rs.w 0 rsreset pt_size rs.w 1 pt_address rs.l 1 pt_sizeof rs.w 0 rsreset nt_period rs.b 1 nt_instr rs.b 1 nt_speed rs.b 1 nt_arpeggio rs.b 1 nt_vibrato rs.b 1 nt_phase rs.b 1 nt_volume rs.b 1 nt_porta rs.b 1 nt_sizeof rs.w 0 rsreset pv_waveoffset rs.w 1 pv_dmacon rs.w 1 pv_custbase rs.l 1 pv_inslen rs.w 1 pv_insaddress rs.l 1 pv_peraddress rs.l 1 pv_pers rs.w 3 pv_por rs.w 1 pv_deltapor rs.w 1 pv_porlevel rs.w 1 pv_vib rs.w 1 pv_deltavib rs.w 1 pv_vol rs.w 1 pv_deltavol rs.w 1 pv_vollevel rs.w 1 pv_phase rs.w 1 pv_deltaphase rs.w 1 pv_vibcnt rs.b 1 pv_vibmax rs.b 1 pv_flags rs.b 1 pv_sizeof rs.w 0 .