home *** CD-ROM | disk | FTP | other *** search
Text File | 1990-04-03 | 27.0 KB | 1,018 lines |
- ; MED - by Teijo Kinnunen, 1989, 1990
- ; med-player.a - the player routine
- custom EQU $dff000
- dmacon EQU $096
- aud0 EQU $0A0
- aud1 EQU $0B0
- aud2 EQU $0C0
- aud3 EQU $0D0
- ac_ptr EQU $00
- ac_len EQU $04
- ac_per EQU $06
- ac_vol EQU $08
- xdef _GetSerial
- xdef _FreeSerial
- xdef _AddMIDIData
- xdef _AudioInit
- xdef _AudioRem
- xdef _ChannelOff
- xdef _SetTempo
- xref _tamakappale
- xref _PiirraPylvas
- xref _soitin
- xref _aanipaalla
- xref _zeroptr
- xref _periodit
- xref _specialupd
- xref _counter
- xref DrawEqualizer
-
- section "text",code
- EVEN
- dc.b ' MEDPlayer is here!!!:'
- waithwnum: dc.l 500
- newaptr: dc.l 0,0,0,0
- newalen: dc.w 0,0,0,0
- audaddr: dc.l custom+aud0,custom+aud1,custom+aud2,custom+aud3
-
- _ChannelOff: ;d0 = channel #
- lea prevmidinote,a0 ;first: is it MIDI??
- move.b 0(a0,d0.w),d1
- beq.s notcomidi ;not midi note
- clr.b 0(a0,d0.w)
- clr.l noteondata ; new midi msg
- move.b d1,noteondata+1
- lea prevmidichan,a0
- move.b 0(a0,d0.w),noteondata ;prev midi channel
- or.b #$80,noteondata ;note off
- lea noteondata,a0
- moveq.l #3,d0
- bra.w _AddMIDIData
- notcomidi: cmp.b #4,d0
- bge.s notamigatrk
- moveq.l #1,d1
- lsl.w d0,d1
- move.w d1,$dff096
- notamigatrk: rts
- _SoitaNuotti: ;d0 = trk #, d1 = note #, d2 = vol, d3 = instr #
- movem.l a2-a3/d3-d7,-(sp) ;All right, let's start!!
- move.w d2,-(sp)
- clr.l d4
- bset d0,d4 ;d4 is mask for this channel
- lea _soitin,a0 ;Is this instrument in mem?
- lsl.w #2,d3 ;d3 = instr.num << 2
- tst.l 0(a0,d3.w)
- bne.s inmem
- lsr.w #2,d3
- lea _tamakappale+1574,a0
- tst.b 0(a0,d3.w) ;is MIDI channel set
- beq.w retsn2 ; NO!!!
- lsl.w #2,d3
- inmem: lsr.w #1,d3 ;d3 = instr. num << 1
- lea _aanipaalla,a0 ;Is this track on??
- lsl.w #1,d0 ;d0 = track num << 1
- tst.w 0(a0,d0.w)
- beq.w retsn2 ; NO!!!!!!
- lsr.w #1,d0
- add.b _tamakappale+1550,d1 ;add play transpose
- bgt.s notenot2low
- add.b #12,d1 ;note was too low, octave up
- bra.s endpttest
- notenot2low: cmp.b #63,d1
- ble.s endpttest
- sub.b #12,d1 ;note was too high, octave down
- endpttest: jsr DrawEqualizer(pc)
- cmp.b #4,d0
- bge.s nodmaoff ;track #á>= 4: not an Amiga channel
- move.w d4,$dff096 ;stop this channel (dmacon)
- nodmaoff: lea prevmidinote,a0
- move.b 0(a0,d0.w),d6 ;get prev. midi note
- beq.s noprevmidi
- clr.b 0(a0,d0.w)
- move.b d6,noteondata+1
- lea prevmidichan,a0
- move.b 0(a0,d0.w),noteondata ;prev midi channel
- or.b #$80,noteondata ;note off
- lea noteondata,a0
- clr.b 2(a0) ;clear volume
- movem.l d0-d1,-(sp)
- moveq.l #3,d0
- bsr.w _AddMIDIData
- movem.l (sp)+,d0-d1
- noprevmidi: lea _tamakappale+1574,a1
- lsr.w #1,d3
- tst.b 0(a1,d3.w)
- bne.w handleMIDInote
- cmp.b #4,d0 ;test track # again
- bge.w retsn2 ;no Amiga instruments in tracks > 3
- or.w d4,dmaonmsk
- subq.b #1,d1
- lsl.w #1,d0
- lsl.w #1,d3
- lea newalen(pc),a2
- clr.w 0(a2,d0.w)
- move.w d0,d6
- lsl.w #1,d6 ;d6 = channel num << 2
- move.w d3,d7
- lsl.w #1,d7 ;d7 = instr. num << 2
- lea audaddr,a1
- movea.l 0(a1,d6.w),a1 ;base of this channel's regs
- lea newaptr(pc),a3 ;a3 = address of newaptr
- lea _soitin,a2 ;get the address of...
- move.l 0(a2,d7.w),d5 ;...this instrument
- move.l d5,a0
- bsr.w getinsdata
- move.l d0,ac_ptr(a1) ;put it in ac_ptr
- cmp.w #2,d3
- bls.s norepeat
-
- add.l d2,d0 ;d0 = starting address of repeat
- move.l d0,0(a3,d6.w) ;remember!! (move to newaptr)
- lsr.w #1,d3 ;shift right
- lsr.w #1,d6
- move.w d3,16(a3,d6.w) ;remember too (newalen)
- lsr.w #1,d2 ;shift
- beq.s begin0 ;rep. start < 2
- move.w d2,ac_len(a1) ;move repeat to hardware
- bra.s retsn1
- begin0: move.w d3,ac_len(a1)
- bra.s retsn1
-
- norepeat: move.l _zeroptr,0(a3,d6.w) ;pointer of zero word
- lea newalen(pc),a3
- lsr.w #1,d6
- move.w #1,0(a3,d6.w) ;length: 1 word
- lsr.l #1,d1 ;shift length right
- move.w d1,ac_len(a1) ;and put to custom chip
-
- retsn1: move.w d5,ac_per(a1) ;getinsdata puts period to d5
- lea prevper(pc),a0
- move.w d5,0(a0,d6.w)
- move.w (sp),ac_vol(a1) ;volume
- lsr.w #2,d7 ;d7 is now instr. number again
- drawcol: move.w d7,d0 ;to d0
- subq.w #1,d0 ;number of column
- clr.l d1
- move.w (sp),d1 ;volume (height) to d1
- lsr.b #1,d1 ;to range 0 - 32
- and.b #$fe,d1 ;must be even
- beq.s nodraw ;volume = 1, don't draw
- jsr _PiirraPylvas(pc) ;draw it
- nodraw: move.b _tamakappale+1551,d0 ;flags
- btst #1,d0 ;jumping ??
- beq.s retsn2 ;no...
- btst #2,d0 ;with instruments
- bne.s retsn2 ;no......
- move.l _tamakappale+1554,d0 ;yes!!!, get instr. mask
- lsr.l d7,d0 ;set this instr. to bit #0
- btst #0,d0 ;and test it
- beq.s retsn2 ;no jump with this instr
- move.b #1,animcnt ;init animation counter
- retsn2: addq.l #2,sp ;forget volume
- movem.l (sp)+,a2-a3/d3-d7
- rts
-
- handleMIDInote:
- add.b #23,d1 ;2 octaves higher and -1
- move.b d1,noteondata+1 ;MIDI msg note #
- lea prevmidinote(pc),a0
- move.b d1,0(a0,d0.w) ;save this note number
- move.b d2,d4 ;temporary save the volume
- subq.b #1,d2 ;if 64 => 63
- lsl.b #1,d2 ;volume 0 - 63 => 0 - 127
- bclr #7,d2 ;be sure that bit 7 is clear
- move.b d2,noteondata+2 ;MIDI msg volume
- clr.w d1
- move.b 0(a1,d3.w),d1 ;get midi chan of this instrument
- subq.b #1,d1 ;from 1-16 to 0-15
- lea prevmidichan(pc),a0
- move.b d1,0(a0,d0.w) ;save to prev midi channel
- move.b #$90,noteondata ;MIDI: Note on
- or.b d1,noteondata ;MIDI msg Note on & channel
- move.b 32(a1,d3.w),d2 ;get preset #
- beq.s nochgpres ;zero = no preset
- lea prevmchpreset(pc),a0
- move.b 0(a0,d1.w),d0
- cmp.b d2,d0 ;is this previous preset ??
- beq.s nochgpres ;yes...no need to change
- move.b #$c0,preschgdata
- or.b d1,preschgdata
- move.b d2,0(a0,d1.w) ;save preset to prevmchpreset
- subq.b #1,d2
- move.b d2,preschgdata+1
- lea preschgdata,a0
- moveq.l #5,d0
- bra.s preschanged
- nochgpres: moveq.l #3,d0
- lea noteondata,a0
- preschanged: bsr.w _AddMIDIData
- move.w d3,d7
- bra.w drawcol
-
- _StartDMA: ;This small routine turns on audio DMA
- move.w dmaonmsk,d0 ;dmaonmsk contains the mask of
- beq.s retsdma ;the channels that must be turned on
- bset #15,d0 ;DMAF_SETCLR: set these bits in dmacon
- move.l waithwnum,d1
- waithw0: dbf d1,waithw0
- move.w d0,custom+dmacon ;do that!!!
- move.l waithwnum,d1
- waithw1: dbf d1,waithw1
- lsr.b #1,d0 ;finally, push new ptrs to audio hw regs
- bcc.s pushch1
- move.l newaptr(pc),custom+aud0+ac_ptr
- move.w newalen(pc),custom+aud0+ac_len
- pushch1: lsr.b #1,d0
- bcc.s pushch2
- move.l newaptr+4(pc),custom+aud1+ac_ptr
- move.w newalen+2(pc),custom+aud1+ac_len
- pushch2: lsr.b #1,d0
- bcc.s pushch3
- move.l newaptr+8(pc),custom+aud2+ac_ptr
- move.w newalen+4(pc),custom+aud2+ac_len
- pushch3: lsr.b #1,d0
- bcc.s retsdma
- move.l newaptr+12(pc),custom+aud3+ac_ptr
- move.w newalen+6(pc),custom+aud3+ac_len
- retsdma: rts
-
- xref _mouse1
- xref _mouse2
- xref _mouse3
- xref _mouse4
- xref _mouse5
- frame: dc.l 0,_mouse2,_mouse3,_mouse4,_mouse5,_mouse5,_mouse4,_mouse3
- dc.l _mouse2,_mouse1,0
- dmaonmsk: dc.w 0
- animcnt: dc.b 0,0
- prevmidinote: dc.b 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
- prevmidichan: dc.b 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
- prevpitchbend: dc.w $2000,$2000,$2000,$2000,$2000,$2000,$2000,$2000
- dc.w $2000,$2000,$2000,$2000,$2000,$2000,$2000,$2000
- prevmchpreset: dc.b 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;previous preset
- prevper: dc.w 0,0,0,0
- prevnote: dc.b 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
- previnstr: dc.b 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
- prevvol: dc.b 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
- effect: dc.b 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
- effectqual: dc.b 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
- nextblock: dc.b 0
- animpause: dc.b 1
- numtracks: dc.b 0,0
- xref _soittotila
- xref _soittolohko
- xref _lohko
- xref _soittorivi
- xref _soittolohkonnum
- xref _lohkoja
- xref _naytonpaivitys
- xref _maintsk
- xref _nayttomsk
- xref _tempo
- xref _sprptr
- xref _hyppymsk
- xref _komento
- _IntHandler:
- movem.l d2-d7/a2-a4,-(sp)
- cmp.w #5,_komento ;Do we have to play note from keyboard
- bne.s nokbnote ;no...just normal playing
- lea _komento,a1 ;get the address of the structure
- lea _tamakappale+1284,a2 ;and the song
- clr.w dmaonmsk
- clr.w d0
- clr.w d1
- move.b 8(a1),d0 ;get all these values from
- move.b 5(a1),d1 ;the command structure
- move.w 6(a1),d3
- clr.w d2
- move.b 0(a2,d3.w),d2
- clr.w (a1) ;clear the command word
- bsr _SoitaNuotti ;and play the note finally
- bsr _StartDMA
- bra.s notplaying ;exit
- nokbnote: tst.w _soittotila ;are we playing
- bne.s playing ;yes, we are
- bclr.b #0,$bfee01 ;no...stop the timer
- move.b #$05,_counter
- clr.b animcnt
- move.l frame+36,_sprptr
- bra.w sigjump
- notplaying: movem.l (sp)+,d2-d7/a2-a4 ;exit interrupt
- rts
- playing: clr.w dmaonmsk
- add.b #1,_counter
- cmp.b #6,_counter ;if counter = 6: new note and fx
- bne.w nonewnote ;if counter is not 6: just do fx
- clr.b _counter ;new note!!!
- clr.l d7 ;number of track
- lea _lohko,a2 ;a2 = address of 1st block's address
- move.w _soittolohko,d2
- lsl.w #2,d2 ;shift to longword index
- movea.l 0(a2,d2.w),a2 ;get the pointer of the block
- move.b (a2),numtracks+1 ;save #áof tracks
- addq.l #4,a2 ;skip...
- move.w numtracks,d3
- mulu #3,d3
- move.w _soittorivi,d2
- mulu d2,d3
- adda.l d3,a2 ;a2 = address of this line
- lea prevnote(pc),a3
- lea _tamakappale,a4
- trloop0: clr.w d5
- 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
- lea effectqual(pc),a1
- move.b d6,0(a1,d7.w) ;save the fx numbers
- clr.b d4 ;d4 is a flag: if set, instr. is
- btst #7,d5 ;in range G-V. If clr, it's 1-F.
- beq.s nogtov ;In the song, if bit #7 is set in
- bclr #7,d5 ;note number byte, it's G-V
- st.b d4 ;this instrument is in range G-V
- nogtov: 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)
- beq.s noinstnum ;no. It's 0!!!
- 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: lea previnstr(pc),a1
- move.b d0,0(a1,d7.w) ;remember instr. number!
- lea prevvol(pc),a1
- add.w #1284,d0 ;offset of volumes in song struct
- move.b 0(a4,d0.w),0(a1,d7.w) ;vol of this instr to prevvol
- noinstnum: move.w d6,d0 ;effect again...
- lsr.w #8,d0
- and.b #$0f,d0 ;now check only the effect part
- lea effect(pc),a1
- move.b d0,0(a1,d7.w) ;save the effect number
- beq.s noeffect ;no effect
- cmp.b #$0f,d0 ;yes effect...is it Tempo???
- bne.s not0f ;not Tempo
- 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
- clr.l d0 ;will happen!!!
- move.b d6,d0
- bsr _SetTempo ;change The Tempo
- bra.s noeffect
- fx0fspecial: cmp.b #$f2,d6 ; | rest - play | SpecialFX#2: no note..yet
- bne.s isfxfe ;not SpecFX2
- move.b d5,(a3) ;Yes!!! Save the note number
- clr.w d5 ; clear the number for awhile
- bra.s noeffect
- isfxfe: cmp.b #$fe,d6
- bne.s noeffect
- clr.w _soittotila
- or.b #2,_specialupd
- bra.s noeffect
- fx0fchgblck: st.b nextblock ;next block????...YES!!!! (F00)
- bra.s noeffect
- not0f: cmp.b #$0c,d0 ;new volume???
- bne.s noeffect ;NO!!!!!!!!!!!!!!!!!!!!!!
- move.b d6,d0
- lsr.b #4,d0 ;Strange code begins now
- mulu #10,d0
- move.b d6,d1
- and.b #$0f,d1
- add.b d1,d0 ;strange code ends now: d0 is vol
- cmp.b #64,d0
- bls.s novolov64
- moveq.l #64,d0
- novolov64 lea prevvol(pc),a1
- move.b d0,0(a1,d7.w) ;and save it....
- noeffect: tst.b d5 ;Now we'll check if we have to play a note
- beq.s endtrkloop ;no.
- move.b d5,(a3)
- move.w d7,d0
- move.w d5,d1
- clr.w d2
- clr.w d3
- lea previnstr(pc),a1
- move.b 0(a1,d7.w),d3
- lea prevvol(pc),a1
- move.b 0(a1,d7.w),d2 ;get volume
- bsr _SoitaNuotti ;play it!!!!!!!!!!!
- endtrkloop: addq.l #1,a3 ;a3 = pointer to prev. note #
- addq.l #1,d7
- cmp.w numtracks,d7
- blt.w trloop0
-
- add.w #1,_soittorivi ;very important!!! advance line!!
- cmp.w #63,_soittorivi ;important too!!! advance block??
- bgt.s chgblock ;yes!!!
- tst.b nextblock ;command F00 ??
- beq.s nochgblock ;no, don't change block
- chgblock: clr.w _soittorivi ;clear line number
- cmp.w #2,_soittotila ;play block or play song
- bne.s nonewseq ;play block only...
- add.w #1,_soittolohkonnum ;advance sequence number
- move.w 1546(a4),d0 ;get the highest seq number
- move.w _soittolohkonnum,d1 ;and current seq number
- cmp.w d0,d1 ;is this the highest seq number
- blt.s nostartagain ;no
- clr.w _soittolohkonnum ;yes: play song again
- clr.w d1 ;...forever!!!
- nostartagain: clr.w d0
- lea 1446(a4),a1 ;offset of sequence table
- move.b 0(a1,d1.w),d0 ;get number of the block
- move.w d0,_soittolohko ;and put it to block number var
- move.w _lohkoja,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 nonewseq ;no
- move.w d1,_soittolohko ;yes..then play just the last block
- nonewseq: clr.b nextblock ;clear this if F00 set it
- nochgblock: tst.w _naytonpaivitys ;screen updating on??
- beq.s nonewnote ;no
- movea.l _maintsk,a1 ;ask the main task to update screen
- move.l _nayttomsk,d0
- jsr -$144(a6) ;Signal()
- nonewnote:
- ; *********************** This code produces the effects **
- clr.l d7 ;clear track count
- lea prevper(pc),a3
- lea prevvol(pc),a4
- trloop1: clr.w d5
- lea effect,a1
- clr.w d4
- move.b 0(a1,d7.w),d6 ;get the fx number
- lea effectqual,a1
- move.b 0(a1,d7.w),d4 ;and the last 2 #'s
- lea prevmidinote,a0 ;first: is it MIDI??
- tst.b 0(a0,d7.w)
- bne.w midifx
- cmp.b #1,d6 ;effect #1
- bne.s nofx01
- ; **************************************** Effect 01 ******
- cmp.w #5,_tamakappale+1552
- bne.s nost1
- tst.b _counter
- beq newvals
- nost1: sub.w d4,(a3) ;slide it up!!!
- cmp.w #113,(a3) ;too high???
- bge newvals
- move.w #113,(a3) ;yes, too high!!!
- bra newvals
- ; *********************************************************
- nofx01: cmp.b #2,d6
- bne.s nofx02
- ; **************************************** Effect 02 ******
- cmp.w #5,_tamakappale+1552
- bne.s nost2
- tst.b _counter
- beq newvals
- nost2: add.w d4,(a3) ;slide it down!!!!!!!!!
- cmp.w #856,(a3) ;too low??
- ble newvals
- move.w #856,(a3) ;too low.
- bra newvals
- ; *********************************************************
- nofx02: tst.b d6
- bne.s nofx00
- ; **************************************** Effect 00 ******
- tst.b d4 ;both fxqualifiers are 0s: no arpeggio!!
- beq.w endl
- lea prevnote,a1
- bsr.w DoArpeggio
- subq.b #1,d4 ;-1 to make it 0 - 127
- add.b _tamakappale+1550,d4 ;add play transpose
- lsl.b #1,d4 ;shift to make index for UWORD
- lea _periodit,a1
- move.w 0(a1,d4.w),d5
- bra.w newvals
- ; *********************************************************
- nofx00: cmp.b #$0d,d6
- bne.s nofx0d
- ; **************************************** Effect 0D ******
- move.b d4,d1
- move.b (a4),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,(a4) ;put new vol back
- bra 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,(a4)
- bra newvals
- ; *********************************************************
- nofx0d: cmp.b #3,d6
- bne.s nofx03
- ; **************************************** Effect 03 ******
- move.w (a3),d5 ;this is very simple: get the old period
- cmp.b #3,_counter ;and..
- bge.w newvals ;if counter < 3
- sub.w d4,d5 ;subtract effect qualifier
- bra.w newvals
- ; *********************************************************
- nofx03: cmp.b #$0f,d6
- bne.s 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,_counter
- bne.s newvals
- bra.s playfxnote
- no0ff1: cmp.b #$f2,d4
- bne.s no0ff2
- cmp.b #3,_counter
- bne.s newvals
- bra.s playfxnote
- no0ff2: cmp.b #$f3,d4
- bne.s endl
- move.b _counter,d0
- and.b #2+4,d0 ;is 2 or 4
- beq.s newvals
- playfxnote: move.w d7,d0 ;track # to d0...
- lea prevnote(pc),a1
- clr.w d1
- move.b 0(a1,d7.w),d1 ;get note # of previous note
- clr.w d2
- move.b (a4),d2 ;get previous volume
- lea previnstr(pc),a1
- clr.w d3
- move.b 0(a1,d7.w),d3
- bsr _SoitaNuotti
- bra.s endl
- ; *********************************************************
- nofx0f: cmp.b #$0e,d6
- bne.s nofx0e
- fx0e: or.b #1,_specialupd
- tst.b d4
- bne.s filteroff
- bclr #1,$bfe001
- bra.s endl
- filteroff: bset #1,$bfe001
- bra.s endl
- nofx0e: cmp.b #$0c,d6
- bne.s endl
- newvals: tst.w d5 ;now: do the effects!!!
- bne.s nonewper
- move.w (a3),d5 ;no new period specified: get the old
- nonewper: move.w d7,d4 ;channel number to d4
- lsl.w #2,d4 ;and shift it to make it a longword index
- lea audaddr,a1
- movea.l 0(a1,d4.w),a1
- move.w d5,ac_per(a1)
- clr.w d5
- move.b (a4),d5
- move.w d5,ac_vol(a1)
- endl: addq.l #2,a3 ;inc pointer to previous period value
- addq.l #1,a4 ;and previous volume
- addq.l #1,d7 ;increment channel number
- cmp.w numtracks,d7 ;all channels done???
- blt.w trloop1 ;not yet!!!
-
- bsr _StartDMA ;turn on DMA
- move.b _tamakappale+1551,d0 ;get the flags
- btst #1,d0 ;is Topi's jumping on ???
- beq.w exitint ;no
- btst #2,d0 ;every 8th note ???
- beq.s no8th
- move.w #$0007,d0
- and.w _soittorivi,d0 ;is this 8th note ??
- bne.s no8th ;no...
- tst.b animcnt
- bne.s no8th
- tst.w _soittotila
- beq.s no8th
- move.b #1,animcnt
- no8th: tst.b animcnt
- beq.s exitint
- add.b #1,animpause ;Handles all animation
- cmp.b #2,animpause
- blt.s exitint
- cmp.b #10,animcnt
- bne.s nojumpend
- clr.b animcnt
- move.b #1,animpause
- bra.s exitint
- nojumpend: clr.w d0
- move.b animcnt,d0
- add.b #1,animcnt
- lsl.w #2,d0
- lea frame(pc),a1
- move.l 0(a1,d0.w),_sprptr
- tst.w _naytonpaivitys
- beq.s exitint
- sigjump: movea.l _maintsk,a1 ;and asks the main task to...
- move.l _hyppymsk,d0 ;...SetPointer() !!!!!
- jsr -$144(a6) ;Signal()
- clr.b animpause
- exitint: movem.l (sp)+,d2-d7/a2-a4
- rts
- _SetTempo: move.w d0,_tempo
- cmp.b #10,d0 ;If tempo <= 10, use SoundTracker tempo
- bhi.s calctempo
- lea sttempo(pc),a1
- lsl.w #1,d0
- move.w 0(a1,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
- or.b #4,_specialupd
- rts ; vv-- These values are the SoundTracker tempos (approx.)
- sttempo: dc.w $0f00,2417,4833,7250,9666,12083,14500,16916,19332,21436,24163
-
- midifx: cmp.b #1,d6
- bne.s nomidi01fx
- lea prevmidichan,a1
- lea prevpitchbend,a0
- clr.w d1
- move.b 0(a1,d7.w),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,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 prevmidichan,a1
- lea prevpitchbend,a0
- clr.w d1
- move.b 0(a1,d7.w),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
- nomidi02fx: cmp.b #$0f,d6
- beq.w fx0f
- cmp.b #$0e,d6
- bne.w endl
- bra.w fx0e
- resetpbend: tst.b _counter
- bne.w endl
- move.w #$2000,d0
- bra.s bendpitch
-
- DoArpeggio: ; beginning note table in a1, note num returned in d4
- move.b 0(a1,d7.w),d1 ;d1 = # of previous note played
- move.b _counter,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
- rts
-
- 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 _periodit,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
- lea _tamakappale+1316,a0
- move.w 0(a0,d3.w),d2
- move.w 64(a0,d3.w),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
- lea _tamakappale+1316,a1
- move.w 0(a1,d3.w),d2
- move.w 64(a1,d3.w),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 _periodit,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
-
- xref _ciaaresource
- xref _maintsk
-
- _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 _maintsk,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.b 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
- move.l #%10000001,d0
- jsr -$12(a6) ;AbleICR()
- st.b timeropen
- clr.w _soittotila
- 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,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()??
- 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()
- rem2: clr.l d0
- move.b sigbitnum,d0
- bmi.s rem3
- ; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ free signal bit
- jsr -$150(a6) ;FreeSignal()
- rem3: move.l (sp)+,a6
- rts
-
- _GetSerial: move.l a6,-(sp) ;Get serial port for MIDI
- 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
- moveq.l #0,d0 ;TBE
- lea serinterrupt(pc),a1
- move.l 4,a6
- jsr -$a2(a6) ;SetIntVector()
- move.l d0,prevtbe
- moveq.l #11,d0 ;RBF
- lea rbfinterrupt(pc),a1
- jsr -$a2(a6) ;SetIntVector()
- move.l d0,prevrbf
- move.w #$8001,$dff09a ;TBE on!!
- move.w #114,$dff032 ;set baud rate (SERPER)
- clr.l d0
- retgs: move.l (sp)+,a6
- rts
- gserror: st d0
- bra.s retgs
-
- _FreeSerial: move.l a6,-(sp)
- tst.l miscresbase
- beq.s retfs
- tst.b serportalloc
- beq.s retfs
- move.w #$0801,$dff09a ;disable RBF & TBE
- movea.l prevtbe(pc),a1
- moveq.l #0,d0
- movea.l 4,a6
- jsr -$a2(a6) ;SetIntVector()
- movea.l prevrbf(pc),a1
- moveq.l #11,d0
- jsr -$a2(a6) ;SetIntVector()
- movea.l miscresbase(pc),a6
- clr.l d0 ;serial port
- jsr -$c(a6) ;FreeMiscResource()
- clr.b serportalloc
- retfs: move.l (sp)+,a6
- rts
-
- prevtbe: dc.l 0
- prevrbf: dc.l 0
- xref _recmidi
- xref _recmidimsk
-
- RBFIntHandler: move.w $18(a0),d0 ;SERDATR
- move.w #$0800,$9c(a0) ;clr intreq
- btst #7,d0 ;status??
- beq.s nostatus
- move.b d0,(a1)
- move.b #$1,3(a1)
- rts
- nostatus: clr.w d1
- move.b 3(a1),d1
- move.b d0,0(a1,d1.w)
- addq.b #1,d1
- cmp.b #3,d1
- bge.s sigmidirec
- move.b d1,3(a1)
- rts
- sigmidirec: move.b #$1,3(a1)
- and.b #$f0,(a1)
- cmp.b #$90,(a1)
- bne.s nosrec
- move.b 1(a1),_recmidi
- movea.l _maintsk,a1
- move.l _recmidimsk,d0
- jsr -$144(a6) ;Signal()
- nosrec: rts
- recmidi: dc.b 0,0,0,0
-
- SerIntHandler: move.w #1,$9c(a0) ;clear intreq bit
- clr.l d0
- move.b bytesinbuff(pc),d0
- beq.s exsih ;buffer empty
- move.w #$100,d1 ;Stop bit
- move.b sendbuffer(pc),d1
- move.w d1,$30(a0) ;SERDAT
- move.w #$4000,$9a(a0) ;NO ONE may stop us!!!
- addq.b #1,$126(a6)
- lea sendbuffer(pc),a5
- shiftdataloop: subq.b #1,d0 ;shift serial buffer 1 byte left
- beq.s endshiftloop
- move.b (a1)+,(a5)+ ;a1 = is_Data = sendbuffer + 1
- bra.s shiftdataloop
- endshiftloop: subq.b #1,bytesinbuff
- subq.b #1,$126(a6)
- bge.s exsih
- move.w #$c000,$9a(a0)
- exsih: rts
-
- _AddMIDIData: tst.b serportalloc
- beq.s retamd
- movem.l d2/a6,-(sp)
- movea.l 4,a6
- move.w #$4000,$dff09a ;No interrupts...
- addq.b #1,$126(a6)
- clr.w d1
- clr.b d2
- move.b bytesinbuff(pc),d1
- seq.b d2
- add.b d0,d1
- cmp.b #127,d1
- bgt.s overflow ;sorry, can't do anything.
- move.b d1,bytesinbuff
- sub.b d0,d1
- lea sendbuffer(pc,d1.w),a1
- adddataloop: move.b (a0)+,(a1)+
- subq.b #1,d0
- bne.s adddataloop
- overflow: subq.b #1,$126(a6)
- bge.s nointena
- move.w #$c000,$dff09a
- nointena: tst.b d2
- beq.s nonewtbe
- move.w #$8001,$dff09c ;request TBE
- nonewtbe: movem.l (sp)+,d2/a6
- retamd: rts
-
- sendbuffer: ds.b 128
- miscresbase: dc.l 0
- noteondata: dc.l 0
- audiodevopen: dc.b 0
- timeropen: dc.b 0
- serportalloc: dc.b 0
- bytesinbuff: dc.b 0
- preschgdata: dc.b 0,0
- pbendresdata: dc.b $e0,$00,$40 ;for fast pitch bend resetting
- sigbitnum: dc.b -1
- timerinterrupt: dc.w 0,0,0,0,0
- dc.l timerintname,0,_IntHandler
- serinterrupt: dc.w 0,0,0,0,0
- dc.l serintname,sendbuffer+1,SerIntHandler
- rbfinterrupt: dc.w 0,0,0,0,0
- dc.l rbfintname,recmidi,RBFIntHandler
- 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, 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 'MEDTimerInterrupt',0
- serintname: dc.b 'MEDSerialInterrupt',0
- rbfintname: dc.b 'MEDSerialRBFInt',0
- audiodevname: dc.b 'audio.device',0
- miscresname: dc.b 'misc.resource',0
- medname: dc.b 'MED',0 ;yeah, our name
- end
-