home *** CD-ROM | disk | FTP | other *** search
Text File | 1993-02-08 | 35.5 KB | 1,394 lines |
- ; MED V2.10 player routine by Teijo Kinnunen 1990
- ; modplayer.a - the module player
- ; use the A68k-assembler (or compatible) from Fish #186
- ac_ptr EQU $00
- ac_len EQU $04
- ac_per EQU $06
- ac_vol EQU $08
- T03SZ EQU 24
- T415SZ EQU 8
-
- DIM EQU 1 ;set to 0 if you don't need _DimOffPlayer
- MIDI EQU 1 ;If your song(s) contain only Amiga-samples and
- ;4 tracks, set MIDI to 0. This makes the player
- ;much shorter.
-
- IFNE MIDI
- xdef _ResetMIDI
- ENDC
-
- section "text",code
- EVEN
-
- _ChannelOff: ;d0 = channel #
- IFNE MIDI
- lea trackdataptrs(pc),a1
- lsl.b #2,d0
- adda.w d0,a1
- lsr.b #2,d0
- movea.l (a1),a1
- move.b 6(a1),d1 ;first: is it MIDI??
- beq.s notcomidi ;not a midi note
- clr.b 6(a1)
- lea noteondata(pc),a0
- clr.l (a0) ; new midi msg
- move.b d1,1(a0)
- move.b 3(a1),(a0) ;prev midi channel
- or.b #$80,(a0) ;note off
- moveq.l #3,d0
- bra.w _AddMIDIData
- notcomidi:
- ENDC
- cmp.b #4,d0
- bge.s notamigatrk
- moveq.l #1,d1
- lsl.w d0,d1
- move.w d1,$dff096
- notamigatrk: rts
- ; track # = d7, note vol = d0, song = a4
- GetRelVol: clr.w d1
- clr.w d2
- move.b 786(a4),d1 ;master volume
- lea 770(a4),a0
- move.b 0(a0,d7.w),d2 :track volume
- mulu d2,d0
- mulu d1,d0 ;d0 = master v. * track v. * volume
- lsr.l #4,d0
- lsr.w #8,d0
- rts
- _SoitaNuotti: ;d0 = trk #, d1 = note #, d2 = vol, d3 = instr # a3 = addr of instr
- movem.l d3-d7,-(sp) ;All right, let's start!!
- move.w d2,-(sp)
- clr.l d4
- bset d0,d4 ;d4 is mask for this channel
- movea.l 24(a6),a0 ;Is this instrument in mem?
- move.w d3,d7
- lsl.w #2,d7 ;d7 = instr.num << 2
- tst.l 0(a0,d7.w)
- IFNE MIDI
- bne.s inmem
- tst.b 4(a3) ;is MIDI channel set
- ENDC
- beq.w retsn2 ; NO!!!
- inmem: add.b 766(a4),d1 ;add play transpose
- add.b 7(a3),d1 ;and instr. transpose
- cmp.b #4,d0
- bge.s nodmaoff ;track #á>= 4: not an Amiga channel
- move.w d4,$dff096 ;stop this channel (dmacon)
- nodmaoff:
- IFNE MIDI
- move.b 6(a5),d6 ;get prev. midi note
- beq.s noprevmidi
- clr.b 6(a5)
- lea noteondata(pc),a0
- move.b d6,1(a0)
- move.b 3(a5),(a0) ;prev midi channel
- or.b #$90,(a0) ;note off
- clr.b 2(a0) ;clear volume
- movem.l d0-d1,-(sp)
- moveq.l #3,d0
- bsr.w _AddMIDIData
- movem.l (sp)+,d0-d1
- noprevmidi: tst.b 4(a3)
- bne.w handleMIDInote
- ENDC
- tlwtst0: tst.b d1
- bgt.s notenot2low
- add.b #12,d1 ;note was too low, octave up
- bra.s tlwtst0
- notenot2low: cmp.b #63,d1
- ble.s endpttest
- sub.b #12,d1 ;note was too high, octave down
- endpttest: cmp.b #4,d0 ;test track # again
- bge.w retsn2 ;no Amiga instruments in tracks > 3
- or.w d4,dmaonmsk
- subq.b #1,d1
- movea.l 10(a5),a1 ;base of this channel's regs
- movea.l 24(a6),a0 ;get the address of...
- movea.l 0(a0,d7.w),a0 ;...this instrument
- lsl.w #1,d3
- bsr.w getinsdata
- move.l d0,ac_ptr(a1) ;put it in ac_ptr
- cmp.w #1,d3
- bhi.s repeat
-
- move.l chipzero(pc),14(a5) ;pointer of zero word
- move.w #1,18(a5) ;length: 1 word
- lsr.l #1,d1 ;shift length right
- move.w d1,ac_len(a1) ;and put to custom chip
- bra.s retsn1
-
- repeat: tst.w d2
- beq.s begin0 ;rep. start < 2
- move.w d2,ac_len(a1) ;move repeat to hardware
- bra.s beginn0
- begin0: move.w d3,ac_len(a1)
- beginn0: lsl.l #1,d2 ;shift
- add.l d2,d0 ;d0 = starting address of repeat
- move.l d0,14(a5) ;remember rep. start
- move.w d3,18(a5) ;remember rep. length
-
- retsn1: move.w d5,ac_per(a1) ;getinsdata puts period to d5
- move.w d5,8(a5)
- move.w (sp),ac_vol(a1) ;volume
- retsn2: addq.l #2,sp ;forget volume
- movem.l (sp)+,d3-d7
- rts
-
- IFNE MIDI
- handleMIDInote:
- lea noteondata(pc),a0
- add.b #23,d1 ;2 octaves higher and -1
- bpl.s mnot2low ;note number not too low
- add.b #12,d1 ;it was too low, 1 octave up
- bra.s endmtst
- mnot2low: tst.b d1 ;is it too high then??
- bpl.s endmtst ;no, not greater than 127
- sub.b #12,d1 ;1 octave down, if yes
- endmtst: move.b d1,1(a0) ;MIDI msg note #
- move.b d1,6(a5) ;save this note number
- move.b d2,d4 ;temporary save the volume
- subq.b #1,d2 ;if 64 => 63
- bpl.s nooops
- clr.b d2 ;oops, too low!!
- nooops: lsl.b #1,d2 ;volume 0 - 63 => 0 - 127
- bclr #7,d2 ;be sure that bit 7 is clear
- move.b d2,2(a0) ;MIDI msg volume
- clr.w d1
- move.b 4(a3),d1 ;get midi chan of this instrument
- subq.b #1,d1 ;from 1-16 to 0-15
- move.b d1,3(a5) ;save to prev midi channel
- move.b #$90,(a0) ;MIDI: Note on
- or.b d1,(a0) ;MIDI msg Note on & channel
- move.b 5(a3),d2 ;get preset #
- beq.s nochgpres ;zero = no preset
- lea prevmidicpres(pc),a1
- cmp.b 0(a1,d1.w),d2 ;is this previous preset ??
- beq.s nochgpres ;yes...no need to change
- move.b d2,0(a1,d1.w) ;save preset to prevmidicpres
- subq.b #1,d2 ;sub 1 to get 0 - 127
- lea preschgdata(pc),a0
- move.b #$c0,(a0) ;command: $C
- or.b d1,(a0) ;"or" midi channel
- move.b d2,1(a0) ;push the number to second byte
- moveq.l #5,d0 ;Noteondata follows preschgdata
- bra.s preschanged ;struct, so this is a bit faster
- nochgpres: moveq.l #3,d0
- preschanged: bsr.w _AddMIDIData
- move.w d3,d7
- bra.w retsn2
- ENDC
-
- waitamoment: move.l d0,-(sp)
- moveq.l #$79,d0
- wl0: move.b $dff007,d1
- wl1: cmp.b $dff007,d1
- beq.s wl1
- dbf d0,wl0
- move.l (sp)+,d0
- rts
- pushnewvals: movea.l (a1)+,a5
- lsr.b #1,d0
- bcc.s rpnewv
- movea.l 10(a5),a0
- move.l 14(a5),ac_ptr(a0)
- move.w 18(a5),ac_len(a0)
- rpnewv: rts
- _StartDMA: ;This small routine turns on audio DMA
- move.w dmaonmsk(pc),d0 ;dmaonmsk contains the mask of
- beq.s rpnewv ;the channels that must be turned on
- bset #15,d0 ;DMAF_SETCLR: set these bits in dmacon
- bsr.s waitamoment
- move.w d0,$dff096 ;do that!!!
- bsr.s waitamoment
- lea trackdataptrs(pc),a1
- bsr.s pushnewvals
- bsr.s pushnewvals
- bsr.s pushnewvals
- bra.s pushnewvals
-
- dmaonmsk: dc.w 0
- IFNE MIDI
- prevmidicpres: dc.l 0,0,0,0 ; 16 bytes
- prevmidipbend: dc.w $2000,$2000,$2000,$2000,$2000,$2000,$2000,$2000
- dc.w $2000,$2000,$2000,$2000,$2000,$2000,$2000,$2000
- ENDC
- ; Track-data structure for each track
- ; 0(ax) previous note 1(ax) previous instrument
- ; 2(ax) previous volume 3(ax) previous midi channel
- ; 4(ax) command 5(ax) command qualifier (data byte)
- ; 6(ax) prev MIDI note 7(ax) prev. portamento speed (on MIDI
- ;---and for Amiga tracks also.. tracks it's only pad byte)
- ; 8(ax) previous period(w) 10(ax) base address of audio registers(l)
- ; 14(ax) new sample ptr(l) 18(ax) new sample length(w)
- ; 20(ax) portamento target period(w)
- ; 22(ax) curr vibrato offs 23(ax) curr vibrato speed/size
- t03d: dc.w 0,0,0,0,0
- dc.l $dff0a0,0
- dc.w 0,0,0,0,0,0,0,0
- dc.l $dff0b0,0
- dc.w 0,0,0,0,0,0,0,0
- dc.l $dff0c0,0
- dc.w 0,0,0,0,0,0,0,0
- dc.l $dff0d0,0
- dc.w 0,0,0 ;24 bytes * 4 tracks = 92 bytes
- IFNE MIDI
- t415d: ds.b 8*12 ;8 bytes * 12 tracks = 96 bytes
- ENDC
- trackdataptrs: dc.l t03d,t03d+T03SZ,t03d+2*T03SZ,t03d+3*T03SZ
- IFNE MIDI
- dc.l t415d,t415d+T415SZ,t415d+2*T415SZ,t415d+3*T415SZ
- dc.l t415d+4*T415SZ,t415d+5*T415SZ,t415d+6*T415SZ
- dc.l t415d+7*T415SZ,t415d+8*T415SZ,t415d+9*T415SZ
- dc.l t415d+10*T415SZ,t415d+11*T415SZ
- ENDC
- nextblock: dc.b 0
- even
- numtracks: dc.w 0
- _IntHandler:
- movem.l d2-d7/a2-a6,-(sp)
- move.l currentmodule(pc),d0
- beq.s stopplay
- move.l d0,a6 ;a6 contains ptr to this mod
- tst.w 40(a6) ;are we playing
- bne.s playing ;yes, we are
- stopplay1: move.b #$05,50(a6) ;counter ready for next note
- stopplay: bclr #0,$bfee01 ;stop the timer
- move.w #$000f,$dff096 ;stop audio DMA
- movem.l (sp)+,d2-d7/a2-a6 ;exit interrupt
- rts
- playing: clr.w dmaonmsk
- movea.l 8(a6),a4 ;ptr to MMD0song
- add.b #1,50(a6)
- cmp.b #6,50(a6) ;if counter = 6: new note and fx
- bne.w nonewnote ;if counter is not 6: just do fx
- IFNE DIM
- move.w dimval(pc),d0
- beq.s nodim
- sub.w dimstep(pc),d0
- bgt.s nostpdim
- move.b dimstart(pc),786(a4)
- clr.w 40(a6)
- clr.w dimval
- bra.s stopplay1
- nostpdim: move.w d0,dimval
- lsr.w #7,d0
- move.b d0,786(a4)
- ENDC
- ; --- new note!! first get address of current block
- nodim: movea.l 16(a6),a0 ;a0 = address of 1st block's address
- move.w 42(a6),d2
- lsl.w #2,d2 ;shift to longword index
- movea.l 0(a0,d2.w),a2 ;get the pointer of the block
- clr.w d0
- move.b 1(a2),d0 ;get number of lines in this block
- ; and advance song pointers
- lea 48(a6),a3
- addq.w #1,(a3) ;very important!!! advance line!!
- cmp.w (a3),d0 ;important too!!! advance block??
- blt.s chgblock ;yes!!!
- tst.b nextblock ;command F00 ??
- beq.s nochgblock ;no, don't change block
- chgblock: clr.w (a3) ;clear line number
- cmp.w #2,40(a6) ;play block or play song
- bne.s nonewseq ;play block only...
- cmp.b #$01,nextblock
- beq.s posjump
- addq.w #1,46(a6) ;advance sequence number
- posjump: move.w 506(a4),d0 ;get the highest seq number
- move.w 46(a6),d1 ;and current seq number
- cmp.w d0,d1 ;is this the highest seq number
- blt.s nostartagain ;no
- clr.w 46(a6) ;yes: play song again
- clr.w d1 ;...forever!!!
- nostartagain: clr.w d0
- lea 508(a4),a1 ;offset of sequence table
- move.b 0(a1,d1.w),d0 ;get number of the block
- move.w d0,42(a6) ;and put it to block number var
- clr.w d1
- move.b 505(a4),d1 ;get number of blocks
- subq.w #1,d1 ;# of blocks-1 = # of highest block
- cmp.w d1,d0 ;is this block number too big
- blt.s nolstblk ;no
- move.w d1,42(a6) ;yes..then play just the last block
- move.w d1,d0
- nolstblk: lsl.w #2,d0
- movea.l 0(a0,d0.w),a2 ;get address of new block
- nonewseq: clr.b nextblock ;clear this if F00 set it
- nochgblock: move.w (a3),44(a6)
- ; --- now start to play it
- clr.b 50(a6)
- clr.l d7 ;number of track
- move.b (a2),numtracks+1 ;save #áof tracks
- addq.l #2,a2 ;skip block header...
- move.w numtracks(pc),d3
- mulu #3,d3
- move.w 44(a6),d2
- mulu d2,d3
- adda.l d3,a2 ;a2 = address of this line
- pea trackdataptrs(pc)
- trloop0: clr.w d5
- move.l (sp),a1
- movea.l (a1)+,a5 ;get address of this track's struct
- move.l a1,(sp)
- ; ---------------- get the note numbers
- move.b (a2)+,d5 ;get the number of this note
- move.b (a2)+,d6 ;and the 4 numbers containing fx
- lsl.w #8,d6
- move.b (a2)+,d6
- move.b d6,5(a5) ;save the fx numbers
- ; ---------------- clear some instrument # flags
- clr.b d4 ;d4 is a flag: if set, instr. is
- clr.b d3 ;in range G-V. If clr, it's 1-F.
- ; ---------------- and set them, if needed
- bclr #7,d5 ;d3 is also a flag. If it's set,
- sne.b d4 ;the instr. is in range 10 - 1V
- bclr #6,d5
- sne.b d3
- ; ---------------- check if there's an instrument number
- move.w #$f000,d0
- and.w d6,d0 ;d0 now contains only the # of instr
- bne.s instnum ;instrument number is not 0
- tst.b d4 ;maybe it's G (instr. #0, d4 set)
- bne.s instnum ;yes, it really was G!!
- tst.b d3
- beq.s noinstnum ;it wasn't 10 - 1V either..
- ; ---------------- if there was, GET IT!!
- instnum: lsr.w #8,d0 ;shift it right to get number 0-F
- lsr.b #4,d0
- tst.b d4
- beq.s nogtov2
- add.w #16,d0 ;if G-V, add 16 to the number
- nogtov2: tst.b d3
- beq.s no10to1v
- add.w #32,d0
- ; ---------------- finally, save the number
- no10to1v: subq.b #1,d0
- move.b d0,1(a5) ;remember instr. number!
- ; ---------------- get the pointer of data's of this sample in Song-struct
- asl.w #3,d0 ;get address of this sample's data
- lea 0(a4,d0.w),a3
- moveq.l #0,d0
- ; ---------------- get volume and make it relative (0 - 100 %)
- move.b 6(a3),d0
- bsr.w GetRelVol
- move.b d0,2(a5) ;vol of this instr to prevvol
- ; ---------------- check the commands
- noinstnum: move.w d6,d0 ;effect again...
- lsr.w #8,d0
- and.b #$0f,d0 ;now check only the effect part
- move.b d0,4(a5) ;save the effect number
- beq.w noeffect ;no effect
- ; ---------------- there was a command (effect), but what??
- cmp.b #$0f,d0 ;yes effect...is it Tempo???
- bne.s not0f ;not Tempo
- ; ---------------- it was tempo (F)
- tst.b d6 ;Tempo !!!
- beq.s fx0fchgblck ;if effect qualifier (last 2 #'s)..
- cmp.b #$f0,d6 ;..is zero, go to next block
- bhi.s fx0fspecial ;if it's F1-FF something special
- ; ---------------- just an ordinary "change tempo"-request
- clr.l d0 ;will happen!!!
- move.b d6,d0
- bsr _SetTempo ;change The Tempo
- bra.w noeffect
- ; ---------------- no, it was FFx, something special will happen!!
- fx0fspecial: cmp.b #$f2,d6 ; | rest - play | SpecialFX#2: no note..yet
- bne.s isfxfe ;not SpecFX2
- ; ---------------- it was FF2, nothing to do now
- move.b d5,(a5) ;Yes!!! Save the note number
- clr.w d5 ; clear the number for awhile
- bra.w noeffect
- isfxfe: cmp.b #$fe,d6
- bne.s notcmdfe
- ; ---------------- it was FFE, stop playing
- clr.w 40(a6)
- bra.w noeffect
- notcmdfe: cmp.b #$fd,d6 ;change period
- bne.w noeffect
- ; ---------------- FFD, change the period, don't replay the note
- cmp.b #$04,d7 ;no tracks 4 - 15, thank you!!
- bge.w noeffect
- lea periods(pc),a0
- tst.b d5
- beq.w noeffect ;hey, no note here!!
- subq.b #1,d5 ;sub 1 to make "real" note number
- lsl.b #1,d5
- move.w 0(a0,d5.w),d0 ;get the period
- movea.l 10(a5),a0
- move.w d0,ac_per(a0) ;push the period
- clr.b d5 ;and clear it so that it won't be replayed
- bra.w noeffect ;done!!
- ; ---------------- F00, called Pattern Break in ST
- fx0fchgblck: st.b nextblock ;next block????...YES!!!! (F00)
- bra.w noeffect
- ; ---------------- was not Fxx, then it's something else!!
- not0f: cmp.b #$0c,d0 ;new volume???
- bne.s not0c ;NO!!!!!!!!!!!!!!!!!!!!!!
- ; ---------------- change volume
- move.b d6,d0
- lsr.b #4,d0 ;get number from left
- mulu #10,d0 ;number of tens
- move.b d6,d1 ;get again
- and.b #$0f,d1 ;this time don't get tens
- add.b d1,d0 ;add them
- cmp.b #64,d0
- bls.s novolov64
- moveq.l #64,d0
- novolov64: bsr.w GetRelVol
- move.b d0,2(a5) ;and save it....
- bra.s noeffect
- not0c: cmp.b #$0b,d0
- bne.s not0b
- ; ---------------- cmd Bxx, "position jump", like Goto, yΣk!!
- move.w d6,d0
- and.w #$00ff,d0
- cmp.w 506(a4),d0 ;test the song length
- bhi.s noeffect
- move.w d0,46(a6)
- move.b #$01,nextblock
- bra.s noeffect
- ; ---------------- try portamento (3)
- not0b: cmp.b #$03,d0
- bne.s noeffect
- subq.b #1,d5
- bmi.s endtrkloop ;it was 0, do nothing
- cmp.b #4,d7
- bge.s endtrkloop ;hey, what are you trying to do??
- lea periods(pc),a0
- add.b 766(a4),d5 ;play transpose
- clr.w d0
- move.b 1(a5),d0
- asl.w #3,d0
- add.b 7(a4,d0.w),d5 ;and instrument transpose
- bmi.s endtrkloop ;again.. too low
- lsl.w #1,d5
- move.w 0(a0,d5.w),20(a5) ;period of this note is the target
- move.b d6,7(a5) ;remember size
- clr.b d5 ;don't play this one
- ; ---------------- everything is checked now: play or not to play??
- noeffect: tst.b d5 ;Now we'll check if we have to play a note
- beq.s endtrkloop ;no.
- ; ---------------- we decided to play
- move.b d5,(a5)
- move.w d7,d0
- move.w d5,d1
- clr.w d3
- move.b 1(a5),d3
- move.w d3,d2
- asl.w #3,d3 ;get address of this sample's data
- lea 0(a4,d3.w),a3
- move.w d2,d3
- clr.w d2
- move.b 2(a5),d2 ;get volume
- bsr _SoitaNuotti ;play it!!!!!!!!!!!
- ; ---------------- end of loop: handle next track, or quit
- endtrkloop: addq.b #1,d7
- cmp.w numtracks(pc),d7
- blt.w trloop0
- addq.l #4,sp ;trackdataptrs
- nonewnote:
- ; *********************** This code produces the effects **
- clr.l d7 ;clear track count
- lea trackdataptrs(pc),a2
- trloop1: movea.l (a2)+,a5
- clr.w d5
- clr.w d4
- move.b 4(a5),d6 ;get the fx number
- move.b 5(a5),d4 ;and the last 2 #'s
- IFNE MIDI
- tst.b 6(a5) ;first: is it MIDI??
- bne.w midifx
- ENDC
- cmp.b #4,d7
- bge.w endl ;no non-MIDI effects in tracks 4 - 15
- cmp.b #1,d6 ;effect #1
- bne.s nofx01
- ; **************************************** Effect 01 ******
- btst #5,767(a4)
- beq.s nost1
- move.b 769(a4),d0
- cmp.b 50(a6),d0
- ble.w endl
- nost1: sub.w d4,8(a5) ;slide it up!!!
- move.w 8(a5),d5
- cmp.w #113,d5 ;too high???
- bge newvals
- move.w #113,d5 ;yes, too high!!!
- move.w d5,8(a5)
- bra newvals
- ; *********************************************************
- nofx01: cmp.b #2,d6
- bne.s nofx02
- ; **************************************** Effect 02 ******
- btst #5,767(a4)
- beq.s nost2
- move.b 769(a4),d0
- cmp.b 50(a6),d0
- ble.w endl
- nost2: add.w d4,8(a5) ;slide it down!!!!!!!!!
- move.w 8(a5),d5
- cmp.w #856,d5 ;too low??
- ble newvals
- move.w #856,d5 ;too low.
- move.w d5,8(a5)
- bra newvals
- ; *********************************************************
- nofx02: tst.b d6
- bne.s nofx00
- ; **************************************** Effect 00 ******
- tst.b d4 ;both fxqualifiers are 0s: no arpeggio!!
- beq.w endl
- move.b (a5),d1
- bsr.w DoArpeggio
- subq.b #1,d4 ;-1 to make it 0 - 127
- add.b 766(a4),d4 ;add play transpose
- clr.w d0
- move.b 1(a5),d0 ;prev. instr #
- asl.w #3,d0 ;get address of this sample's data
- add.b 7(a4,d0.w),d4 ;add instrument transpose
- lsl.b #1,d4 ;shift to make index for UWORD
- lea periods(pc),a1
- move.w 0(a1,d4.w),d5
- bra.w newvals
- ; *********************************************************
- nofx00: cmp.b #$0d,d6
- beq.s fx0d
- cmp.b #$0a,d6
- bne.s nofx0d
- ; **************************************** Effect 0D ******
- fx0d: btst #5,767(a4)
- beq.s nostD
- move.b 769(a4),d0
- cmp.b 50(a6),d0
- ble.w endl
- nostD: move.b d4,d1
- move.b 2(a5),d0 ;move previous vol to d0
- and.b #$f0,d1
- bne.s crescendo
- sub.b d4,d0 ;sub from prev. vol
- bpl.s novolund0
- clr.b d0 ;volumes under zero not accepted!!!
- novolund0: move.b d0,2(a5) ;put new vol back
- bra.w newvals
- crescendo: lsr.b #4,d1
- add.b d1,d0
- cmp.b #64,d0
- ble.s novolover64
- moveq.l #64,d0
- novolover64: move.b d0,2(a5)
- bra.w newvals
- ; *********************************************************
- nofx0d: cmp.b #5,d6
- bne.s nofx05
- ; **************************************** Effect 05 ******
- move.w 8(a5),d5 ;this is very simple: get the old period
- cmp.b #3,50(a6) ;and..
- bge.w newvals ;if counter < 3
- sub.w d4,d5 ;subtract effect qualifier
- bra.w newvals
- ; *********************************************************
- nofx05: cmp.b #$03,d6
- bne.s nofx03
- ; **************************************** Effect 03 ******
- btst #5,767(a4)
- beq.s nost3
- move.b 769(a4),d0
- cmp.b 50(a6),d0
- ble.w endl
- nost3: move.w 20(a5),d0 ;d0 = target period
- beq.w newvals ;no target period specified
- move.w 8(a5),d1 ;d1 = curr. period
- move.b 7(a5),d4 ;get prev. speed
- cmp.w d0,d1
- bhi.s subper ;curr. period > target period
- add.w d4,d1 ;add the period
- cmp.w d0,d1
- bge.s targreached
- bra.s targnreach
- subper: sub.w d4,d1 ;subtract
- cmp.w d0,d1
- bgt.s targnreach
- targreached: move.w 20(a5),d1 ;eventually push target period
- clr.w 20(a5) ;now we can forget everything
- targnreach: move.w d1,8(a5)
- move.w d1,d5
- bra.w newvals
- ; *********************************************************
- nofx03: cmp.b #$0c,d6
- bne.s nofx0c
- tst.b 50(a6)
- bne.w endl
- bra.w newvals
- ; *********************************************************
- nofx0c: cmp.b #$04,d6
- bne.s nofx04
- ; **************************************** Effect 04 ******
- tst.b d4
- beq.s nonvib
- move.b d4,23(a5)
- nonvib: move.b 22(a5),d0
- lsr.b #2,d0
- and.w #$1f,d0
- clr.w d1
- move.b sinetable(pc,d0.w),d1
- move.b 23(a5),d0
- and.w #$000f,d0
- mulu d0,d1
- lsr.w #6,d1
- move.w 8(a5),d5
- tst.b 22(a5)
- bmi.s subvib
- add.w d1,d5
- bra.s nsubvib
- subvib: sub.w d1,d5
- nsubvib: move.b 23(a5),d0
- lsr.b #2,d0
- and.b #$3c,d0
- add.b d0,22(a5)
- bra.w newvals
- sinetable: dc.b $00,$18,$31,$4a,$61,$78,$8d,$a1,$b4,$c5,$d4,$e0,$eb,$f4,$fa,$fd
- dc.b $ff,$fd,$fa,$f4,$eb,$e0,$d4,$c5,$b4,$a1,$8d,$78,$61,$4a,$31,$18
- ; *********************************************************
- nofx04: cmp.b #$0f,d6
- bne.w nofx0f
- ; **************************************** Effect 0F ******
- fx0f: cmp.b #$ff,d4
- bne.s no0fff
- move.w d7,d0
- bsr.w _ChannelOff
- bra.w endl
- no0fff: cmp.b #$f1,d4
- bne.s no0ff1
- cmp.b #3,50(a6)
- bne.w endl
- bra.s playfxnote
- no0ff1: cmp.b #$f2,d4
- bne.s no0ff2
- cmp.b #3,50(a6)
- bne.w endl
- bra.s playfxnote
- no0ff2: cmp.b #$f3,d4
- bne.s no0ff3
- move.b 50(a6),d0
- and.b #2+4,d0 ;is 2 or 4
- beq.s endl
- playfxnote: clr.w d0
- move.b 1(a5),d0
- asl.w #3,d0 ;get address of this sample's data
- lea 0(a4,d0.w),a3 ;a3 contains now address of it
- move.w d7,d0 ;track # to d0...
- clr.w d1
- move.b (a5),d1 ;get note # of previous note
- clr.w d2
- move.b 2(a5),d2 ;get previous volume
- clr.w d3
- move.b 1(a5),d3 ;and prev. sample #
- bsr _SoitaNuotti
- bra.s endl
- no0ff3: cmp.b #$f8,d4
- beq.s filteroff
- cmp.b #$f9,d4
- bne.s endl
- bclr #1,$bfe001
- bra.s endl
- filteroff: bset #1,$bfe001
- bra.s endl
- ; *********************************************************
- nofx0f: cmp.b #$0c,d6
- bne.s endl
- newvals: tst.w d5 ;now: do the effects!!!
- bne.s nooldper
- move.w 8(a5),d5 ;no new period specified: get the old
- nooldper: movea.l 10(a5),a1 ;get channel address
- move.w d5,ac_per(a1) ;push period
- clr.w d5
- IFNE DIM
- tst.w dimval
- bne.s endl
- ENDC
- move.b 2(a5),d5 ;get volume
- move.w d5,ac_vol(a1) ;and push it
- endl: addq.b #1,d7 ;increment channel number
- cmp.w numtracks(pc),d7 ;all channels done???
- blt.w trloop1 ;not yet!!!
-
- bsr _StartDMA ;turn on DMA
- exitint: movem.l (sp)+,d2-d7/a2-a6
- rts
- _SetTempo: tst.b allok
- beq.s exstempo
- movea.l currentmodule(pc),a0
- movea.l 8(a0),a0
- move.b d0,765(a0)
- cmp.b #10,d0 ;If tempo <= 10, use SoundTracker tempo
- bhi.s calctempo
- subq.b #1,d0
- move.b d0,769(a0)
- lsl.w #1,d0
- move.w sttempo+2(pc,d0.w),d1
- bra.s pushtempo
- calctempo: move.l #470000,d1
- divu d0,d1
- pushtempo: move.b d1,$bfe401 ;and set the CIA timer
- lsr.w #8,d1
- move.b d1,$bfe501
- exstempo: rts ; vv-- These values are the SoundTracker tempos (approx.)
- sttempo: dc.w $0f00,2417,4833,7250,9666,12083,14500,16916,19332,21436,24163
-
- IFNE MIDI
- midifx: cmp.b #1,d6
- bne.s nomidi01fx
- lea prevmidipbend(pc),a0
- clr.w d1
- move.b 3(a5),d1 ;get previous midi channel
- lsl.w #1,d1 ;UWORD index
- tst.b d4 ;x100??
- beq.s resetpbend
- move.w 0(a0,d1.w),d0 ;get previous pitch bend
- lsl.w #3,d4 ;multiply bend value by 8
- add.w d4,d0
- cmp.w #$3fff,d0
- bls.s bendpitch
- move.w #$3fff,d0
- bendpitch: move.w d0,0(a0,d1.w) ;save current pitch bend
- lsr.b #1,d1 ;back to UBYTE
- or.b #$e0,d1
- lea noteondata(pc),a0
- move.b d1,(a0) ;midi command & channel
- move.b d0,1(a0) ;lower value
- and.b #$7f,1(a0) ;clear bit 7
- lsr.w #7,d0
- and.b #$7f,d0 ;clr bit 7
- move.b d0,2(a0) ;higher 7 bits
- moveq.l #3,d0
- bsr.w _AddMIDIData
- bra.w endl
- nomidi01fx: cmp.b #2,d6
- bne.s nomidi02fx
- lea prevmidipbend(pc),a0
- clr.w d1
- move.b 3(a5),d1
- lsl.w #1,d1
- tst.b d4
- beq.s resetpbend ;x200??
- move.w 0(a0,d1.w),d0
- lsl.w #3,d4
- sub.w d4,d0
- bpl.s bendpitch ;not under 0
- clr.w d0
- bra.s bendpitch
- resetpbend: tst.b 50(a6)
- bne.w endl
- move.w #$2000,d0
- bra.s bendpitch
- nomidi02fx: cmp.b #$04,d6
- bne.s nomidi04fx
- moveq #$01,d0
- bra.s pushctrldata
- nomidi04fx: cmp.b #$0e,d6 ;with MIDI, this is "pan", when
- bne.s nomidi0efx ;values are 0 - $7f
- moveq #$0a,d0
- pushctrldata: tst.b 50(a6) ;do it only once in a note
- bne.w endl ;(when counter = 0)
- lea noteondata(pc),a0 ;push "control change" data,
- move.b 3(a5),(a0) ;d0 = 1. databyte, d4 = 2. db
- or.b #$b0,(a0)
- move.b d0,1(a0)
- move.b d4,2(a0)
- bmi.w endl ;0 - $7f!!
- moveq.l #3,d0
- bsr.w _AddMIDIData
- bra.w endl
- nomidi0efx: cmp.b #$0f,d6
- bne.w endl
- cmp.b #$fa,d4 ;hold pedal ON
- bne.s nomffa
- moveq #$40,d0
- moveq #$7f,d4
- bra.s pushctrldata
- nomffa: cmp.b #$fb,d4 ;hold pedal OFF
- bne.s nomffb
- moveq #$40,d0
- moveq #$00,d4
- bra.s pushctrldata
- nomffb: bra.w fx0f
- ENDC
-
- DoArpeggio: ; begin note in d1, note num returned in d4
- move.b 50(a6),d0
- tst.b d0
- beq.s arpg03
- cmp.b #3,d0
- bne.s arpgn03
- arpg03: and.b #$0f,d4 ;counter = 0 or 3: get last number
- add.b d1,d4 ;add it to note number
- rts
- arpgn03: cmp.b #1,d0
- beq.s arpg14
- cmp.b #4,d0
- bne.s arpgn14
- arpg14: lsr.b #4,d4 ;counter = 1 or 4: get the first number
- add.b d1,d4 ;add to prev. note
- rts
- arpgn14: move.b d1,d4 ;2 or 5: the previous note
- cmdrts: rts
-
- IFNE MIDI
- _ResetMIDI: tst.b allok
- beq.s cmdrts ;the nearest "rts"
- movem.l d2/a2,-(sp)
- lea prevmidicpres(pc),a0
- clr.l (a0)+ ;force presets to be set again
- clr.l (a0)+ ;(clear prev. preset numbers)
- clr.l (a0)+
- clr.l (a0)+
- clr.b lastcmdbyte
- lea midiresd(pc),a2
- move.b #$e0,(a2) ;reset pitchbenders & mod. wheel
- move.b #$b0,3(a2)
- moveq.l #15,d2
- respbendl: movea.l a2,a0
- moveq.l #6,d0
- bsr.w _AddMIDIData
- addq.b #1,(a2)
- addq.b #1,3(a2)
- dbf d2,respbendl
- lea prevmidipbend(pc),a2
- moveq.l #15,d2
- resprevpbends: move.w #$2000,(a2)+
- dbf d2,resprevpbends
- movem.l (sp)+,d2/a2
- rts
- midiresd: dc.b $e0,$00,$40,$b0,$01,$00
- ENDC
-
- getinsdata: clr.l d2
- move.w 4(a0),d0 ;Soitin-struct in a0, instr#<<1: d3
- bne.s iff5or3oct ;note # in d1 (0 - ...)
- move.l a0,d0
- lea periods(pc),a0
- lsl.b #1,d1
- move.w 0(a0,d1.w),d5 ;put period to d5
- move.l d0,a0
- addq.l #6,d0 ;Skip structure
- move.l (a0),d1 ;length
- move.w (a3),d2
- move.w 2(a3),d3
- rts
- iff5or3oct: movem.l a1/d6-d7,-(sp)
- clr.l d7
- move.w d1,d7
- divu #12,d7 ;octave #
- move.l d7,d5
- swap d5 ;note number in this oct (0-11) is in d5
- move.l (a0),d1
- cmp.b #2,d0
- bne.s no3oct
- addq.l #6,d7
- divu #7,d1 ;get length of the 1st octave
- bra.s no5oct
- no3oct: divu #31,d1 ;get length of the 1st octave (5 octaves)
- no5oct: move.l d1,d0 ;d0 and d1 = length of the 1st oct
- move.w (a3),d2
- move.w 2(a3),d3
- clr.w d6
- move.b shiftcnt(pc,d7.w),d6
- lsl.w d6,d2
- lsl.w d6,d3
- lsl.w d6,d1
- move.b mullencnt(pc,d7.w),d6
- mulu d6,d0 ;offset of this oct from 1st oct
- add.l a0,d0 ;add base address to offset
- addq.l #6,d0 ;skip structure
- lea periods(pc),a1
- add.b octstart(pc,d7.w),d5
- lsl.b #1,d5
- move.w 0(a1,d5.w),d5
- movem.l (sp)+,a1/d6-d7
- rts ;returns period in d5
- shiftcnt: dc.b 4,3,2,1,1,0,2,2,1,1,0,0
- mullencnt: dc.b 15,7,3,1,1,0,3,3,1,1,0,0
- octstart: dc.b 12,12,12,12,24,24,0,12,12,24,24,36
-
- _AudioInit: movem.l a6/d2,-(sp)
- clr.l d2
- movea.l 4,a6
- ; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ alloc signal bit
- addq.l #1,d2
- st.l d0 ; -1
- jsr -$14a(a6) ;AllocSignal()
- tst.b d0
- bmi.w initerr
- move.b d0,sigbitnum
- ; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ prepare IORequest
- lea allocport(pc),a1
- move.b d0,15(a1) ;set mp_SigBit
- move.l a1,-(sp)
- suba.l a1,a1
- jsr -$126(a6) ;FindTask(0)
- move.l (sp)+,a1
- move.l d0,16(a1) ;set mp_SigTask
- lea reqlist(pc),a0
- move.l a0,(a0) ;NEWLIST begins...
- addq.l #4,(a0)
- clr.l 4(a0)
- move.l a0,8(a0) ;NEWLIST ends...
- ; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ open audio.device
- addq.l #1,d2
- lea allocreq(pc),a1
- lea audiodevname(pc),a0
- clr.l d0
- clr.l d1
- movea.l 4,a6
- jsr -$1bc(a6) ;OpenDevice()
- tst.l d0
- bne.s initerr
- st.b audiodevopen
- ; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ open ciaa.resource
- addq.l #1,d2
- clr.l d0
- lea ciaaname(pc),a1
- jsr -$1f2(a6) ;OpenResource()
- tst.l d0
- beq.s initerr
- move.l d0,_ciaaresource
- ; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ attach interrupt
- addq.l #1,d2
- move.l d0,a6
- lea timerinterrupt(pc),a1
- clr.l d0 ;Bit number 0: Timer A
- jsr -$6(a6) ;AddICRVector
- tst.l d0
- bne.s initerr
- and.b #%10000000,$bfee01
- st.b timeropen
- clr.l d0
- initret: movem.l (sp)+,a6/d2
- rts
- initerr: move.l d2,d0
- bra.s initret
-
- _AudioRem: move.l a6,-(sp)
- tst.b timeropen
- beq.s rem1
- ; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ remove interrupt
- move.l _ciaaresource(pc),a6
- lea timerinterrupt(pc),a1
- clr.l d0 ;Bit number 0: Timer A
- jsr -$c(a6) ;RemICRVector
- ;There is no CloseResource(). I'm not sure if I should use CloseLibrary()??
- clr.b timeropen
- rem1: movea.l 4,a6
- tst.b audiodevopen
- beq.s rem2
- move.w #$000f,$dff096 ;stop audio DMA
- ; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ close audio.device
- lea allocreq(pc),a1
- jsr -$1c2(a6) ;CloseDevice()
- clr.b audiodevopen
- rem2: clr.l d0
- move.b sigbitnum(pc),d0
- bmi.s rem3
- ; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ free signal bit
- jsr -$150(a6) ;FreeSignal()
- move.b #-1,sigbitnum
- rem3: move.l (sp)+,a6
- rts
-
- IFNE MIDI
-
- _GetSerial: move.l a6,-(sp) ;Get serial port for MIDI
- bsr.s GetSer2
- tst.l d0 ;got the port??
- beq.s rgser ;yes
- movea.l 4,a6 ;no..try to flush serial.device:
- jsr -$84(a6) ;Forbid
- lea $15e(a6),a0 ;ExecBase->DeviceList
- lea serdev(pc),a1 ;"serial.device"
- jsr -$114(a6) ;FindName
- tst.l d0
- beq.s serdnotf ;no serial.device!!
- move.l d0,a1
- jsr -$1b6(a6) ;RemDevice
- serdnotf: jsr -$8a(a6) ;and Permit
- bsr.s GetSer2 ;now try it again...
- rgser: move.l (sp)+,a6
- rts
-
- GetSer2: move.l 4,a6
- clr.l d0
- lea miscresname(pc),a1
- jsr -$1f2(a6) ;OpenResource()
- move.l d0,miscresbase
- tst.l d0
- beq.s gserror
- move.l d0,a6
- lea medname(pc),a1
- clr.l d0 ;serial port
- jsr -$6(a6) ;AllocMiscResource()
- tst.l d0
- bne.s gserror
- st.b serportalloc
- clr.w intrson
- move.w $dff01c,d0
- btst #0,d0
- sne.b intrson
- moveq.l #0,d0 ;TBE
- lea serinterrupt(pc),a1
- move.l 4,a6
- jsr -$a2(a6) ;SetIntVector()
- move.l d0,prevtbe
- move.w #$8001,$dff09a ;TBE on!!
- move.w #114,$dff032 ;set baud rate (SERPER)
- moveq #0,d0
- retgs: rts
- gserror: st d0
- rts
-
- intrson: dc.b 0,0
-
- _FreeSerial: move.l a6,-(sp)
- tst.l miscresbase
- beq.s retfs
- tst.b serportalloc
- beq.s retfs
- move.w #$0001,$dff09a ;disable TBE
- movea.l prevtbe(pc),a1
- moveq.l #0,d0
- movea.l 4,a6
- jsr -$a2(a6) ;SetIntVector()
- clr.b serportalloc
- tst.b intrson
- beq.s notbebackon
- move.w #$8001,$dff09a
- notbebackon: movea.l miscresbase(pc),a6
- clr.l d0 ;serial port
- jsr -$c(a6) ;FreeMiscResource()
- clr.b lastcmdbyte
- retfs: move.l (sp)+,a6
- rts
-
- prevtbe: dc.l 0
-
- SerIntHandler: move.w #$4000,$9a(a0) ;disable...
- addq.b #1,$126(a6)
- move.w #1,$9c(a0) ;clear intreq bit
- move.b bytesinbuff(pc),d0
- beq.s exsih ;buffer empty
- movea.l 4(a1),a5 ;get buffer read pointer
- move.w #$100,d1 ;Stop bit
- move.b (a5),d1 ;get byte
- move.w d1,$30(a0) ;and push it out!! (SERDAT)
- addq.l #1,a5 ;add 1
- cmpa.l a1,a5 ;shall we reset ptr??
- bne.s norrbuffptr ;not yet..
- lea sendbuffer(pc),a5
- norrbuffptr: subq.b #1,d0 ;one less bytes in buffer
- move.b d0,bytesinbuff ;remember it
- move.l a5,4(a1) ;push new read pointer back
- exsih: subq.b #1,$126(a6)
- bge.s exsih0
- move.w #$c000,$9a(a0)
- exsih0: rts
-
- _AddMIDIData: tst.b serportalloc
- beq.s retamd
- movem.l a2/a6,-(sp)
- movea.l 4,a6
- move.w #$4000,$dff09a ;Disable interrupts
- addq.b #1,$126(a6) ;ExecBase->IDNestCnt
- move.b bytesinbuff(pc),d1
- bne.s noTBEreq
- move.w #$8001,$dff09c ;request TBE
- noTBEreq: lea buffptr(pc),a2 ;end of buffer (ptr)
- movea.l (a2),a1 ;buffer pointer
- adddataloop: move.b (a0)+,d1 ;get byte
- bpl.s norscheck ;this isn't a status byte
- cmp.b #$ef,d1 ;forget system messages
- bhi.s norscheck
- cmp.b lastcmdbyte(pc),d1 ;same as previos status byte??
- beq.s samesb ;yes, skip
- move.b d1,lastcmdbyte ;no, don't skip but remember!!
- norscheck: move.b d1,(a1)+ ;push it to midi send buffer
- addq.b #1,bytesinbuff
- samesb: cmpa.l a2,a1 ;end of buffer??
- bne.s noresbuffptr ;no, no!!
- lea sendbuffer(pc),a1 ;better reset it to avoid trashing
- noresbuffptr: subq.b #1,d0
- bne.s adddataloop
- move.l a1,(a2) ;push new buffer ptr back
- overflow: subq.b #1,$126(a6)
- bge.s retamd1
- move.w #$c000,$dff09a ;enable interrupts again
- retamd1: movem.l (sp)+,a2/a6
- retamd: rts
- ENDC
-
- xdef _InitPlayer
- xdef _PlayModule
- xdef _ContModule
- xdef _StopPlayer
- xdef _RemPlayer
- IFNE DIM
- xdef _DimOffPlayer
- ENDC
- xdef _SetTempo
-
- _InitPlayer: move.l a6,-(sp)
- lea filterpos(pc),a0
- clr.b (a0)
- btst #1,$bfe001
- sne.b (a0)
- IFNE MIDI
- bsr.w _GetSerial
- tst.l d0
- bne.s iperror
- ENDC
- bsr.w _AudioInit
- tst.l d0
- bne.s iperror
- move.l 4,a6
- moveq #8,d0
- move.l #$10002,d1
- jsr -$c6(a6)
- tst.l d0
- beq.s iperror
- move.l d0,chipzero
- IFNE MIDI
- moveq.l #5,d0 ;INTB_VERTB
- lea vbinterrupt(pc),a1
- jsr -$a8(a6) ;AddIntServer()
- move.b #1,intserv
- ENDC
- st.b allok
- moveq.l #6,d0
- bsr.w _SetTempo ;default tempo
- clr.l d0 ;Init OK
- xip: move.l (sp)+,a6
- rts
-
- iperror: bsr.s _RemPlayer ;free all stuff
- moveq #-1,d0
- bra.s xip
-
- _RemPlayer: move.l a6,-(sp)
- move.l 4,a6
- lea currentmodule(pc),a0
- tst.l (a0)
- beq.s nostpplr
- movea.l (a0),a0
- tst.w 40(a0)
- beq.s nostpplr
- bsr.w _StopPlayer
- nostpplr: lea allok(pc),a0
- clr.b (a0)+
- bclr #1,$bfe001 ;filter back on
- move.b (a0),d0 ;prev. filter??
- and.b #2,d0 ;only leave the filter bit
- or.b d0,$bfe001
- lea chipzero(pc),a0
- movea.l (a0),a1
- clr.l (a0)
- move.l a1,d0
- beq.s nofreecz
- moveq #8,d0
- jsr -$d2(a6) ;FreeMem()
- nofreecz: bsr.w _AudioRem
- IFNE MIDI
- tst.b intserv
- beq.s noremvbis
- moveq.l #5,d0 ;INTB_VERTB
- lea vbinterrupt(pc),a1
- jsr -$ae(a6) ;RemIntServer()
- clr.b intserv
- noremvbis: bsr.w _FreeSerial
- ENDC
- move.l (sp)+,a6
- xremp: rts
-
- _PlayModule: tst.b allok
- beq.s xremp
- move.l a0,d0
- bne.s newcmod
- lea currentmodule(pc),a0
- tst.l (a0) ;try old module
- beq.w xpmod3
- movea.l (a0),a0
- newcmod: lea 40(a0),a1
- clr.l (a1)+ ;reset everything
- clr.l (a1)+
- clr.w (a1)
- not.w (a1)+
- move.b #$05,(a1)
- movea.l 8(a0),a1
- IFNE DIM
- clr.w dimval
- ENDC
- btst #0,767(a1) ;filter??
- bne.s filteron
- bset #1,$bfe001
- bra.s _ContModule
- filteron: bclr #1,$bfe001
- _ContModule: tst.b allok
- beq.s xpmod3
- move.l a6,-(sp)
- movea.l 4,a6
- move.w #$4000,$dff09a ;please don't disturb!!!
- addq.b #1,$126(a6)
- move.l a0,d0
- bne.s newcmod2
- lea currentmodule(pc),a0
- tst.l (a0)
- beq.s exitpmod
- movea.l (a0),a0
- newcmod2: tst.b timeropen
- beq.s exitpmod
- move.w 46(a0),d1
- movea.l 8(a0),a1
- move.w 764(a1),d0
- IFNE DIM
- move.b 786(a1),dimstart
- ENDC
- adda.w d1,a1
- move.b 508(a1),43(a0) ;init pblock
- move.l a0,currentmodule
- move.w #2,40(a0) ;pstate = play song
- bsr.w _SetTempo
- or.b #1,$bfee01
- move.w #$000f,$dff096
- exitpmod: subq.b #1,$126(a6)
- bge.s xpmod2
- move.w #$c000,$dff09a ;enable interrupts again
- xpmod2: move.l (sp)+,a6
- xpmod3: rts
-
- _StopPlayer: tst.b allok
- beq.s stpplrend
- tst.l currentmodule
- beq.s nocurrm
- movea.l currentmodule(pc),a0
- clr.w 40(a0) ;the interrupt will stop the timer
- nocurrm:
- IFNE DIM
- clr.w dimval
- ENDC
- IFNE MIDI
- move.b #$af,stpdata
- stpplrloop: lea stpdata(pc),a0
- addq.b #1,(a0)
- cmp.b #$bf,(a0)
- bhi.s stpplrend
- moveq.l #3,d0
- bsr.w _AddMIDIData
- bra.s stpplrloop
- ENDC
- stpplrend: rts
-
- IFNE DIM
- _DimOffPlayer: tst.b allok
- beq.s dimnocm
- tst.w d0
- beq.s dimstp
- moveq #0,d1
- move.b dimstart(pc),d1
- lsl.l #7,d1 ;* 128
- move.w d1,dimval
- divu d0,d1
- move.w d1,dimstep
- dimnocm: rts
- dimstp: bsr.s _StopPlayer
- rts
- ENDC
-
- IFNE MIDI
- VBlankHandler: subq.b #1,(a1)
- bne.s exitvblank
- move.b #15,(a1)
- moveq.l #1,d0
- lea 1(a1),a0
- bsr.w _AddMIDIData
- exitvblank moveq.l #0,d0
- rts
-
- actsens: dc.b 0,$FE
- intserv: dc.b 0
- stpdata: dc.b 0,$7b,0
-
- sendbuffer: ds.b 128
- buffptr: dc.l sendbuffer
- readbuffptr: dc.l sendbuffer
- miscresbase: dc.l 0
- lastcmdbyte: dc.b 0
- ENDC
- even
- IFNE MIDI
- preschgdata: dc.b 0,0
- noteondata: dc.l 0
- ENDC
- audiodevopen: dc.b 0
- timeropen: dc.b 0
- IFNE DIM
- dimval: dc.w 0
- dimstep: dc.w 0
- dimstart: dc.b 0
- ENDC
- IFNE MIDI
- serportalloc: dc.b 0
- bytesinbuff: dc.b 0
- ENDC
- sigbitnum: dc.b -1
- allok: dc.b 0
- filterpos: dc.b 0
- even
- timerinterrupt: dc.w 0,0,0,0,0
- dc.l timerintname,0,_IntHandler
- IFNE MIDI
- serinterrupt: dc.w 0,0,0,0,0
- dc.l serintname,buffptr,SerIntHandler
- vbinterrupt: dc.w 0,0,0,0,0,
- dc.l vbintname,actsens,VBlankHandler
- ENDC
- allocport: dc.l 0,0 ;succ, pred
- dc.b 4,0 ;NT_MSGPORT
- dc.l 0 ;name
- dc.b 0,0 ;flags = PA_SIGNAL
- dc.l 0 ;task
- reqlist: dc.l 0,0,0 ;list head, tail and tailpred
- dc.b 5,0
- allocreq: dc.l 0,0
- dc.b 5,127 ;NT_MESSAGE, use maximum priority (127)
- dc.l 0,allocport ;name, replyport
- dc.w 68 ;length
- dc.l 0 ;io_Device
- dc.l 0 ;io_Unit
- dc.w 0 ;io_Command
- dc.b 0,0 ;io_Flags, io_Error
- dc.w 0 ;ioa_AllocKey
- dc.l sttempo ;ioa_Data
- dc.l 1 ;ioa_Length
- dc.w 0,0,0 ;ioa_Period, Volume, Cycles
- dc.w 0,0,0,0,0,0,0,0,0,0 ;ioa_WriteMsg
- ciaaname: dc.b 'ciaa.resource',0
- timerintname: dc.b 'Player: TimerInterrupt',0
- IFNE MIDI
- serintname: dc.b 'Player: SerialInterrupt',0
- vbintname: dc.b 'Player: VBlankInterrupt',0
- ENDC
- audiodevname: dc.b 'audio.device',0
- IFNE MIDI
- miscresname: dc.b 'misc.resource',0
- serdev: dc.b 'serial.device',0
- ENDC
- medname: dc.b 'MED player routine',0 ;yeah, our name
- _ciaaresource: dc.l 0
- periods: 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
- dc.w 214,202,190,180,170,160,151,143,135,127,120,113
- dc.w 214,202,190,180,170,160,151,143,135,127,120,113
- dc.w 214,202,190,180,170,160,151,143,135,127,120,113
- currentmodule: dc.l 0
- chipzero: dc.l 0
- end
-