home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Audio 4.94 - Over 11,000 Files
/
audio-11000.iso
/
amiga
/
midi
/
med210.lhw
/
in.adf
/
Source
/
med210src.lzh
/
med-player.a
< prev
next >
Wrap
Text File
|
1990-07-14
|
36KB
|
1,331 lines
; MED V2.10 - ⌐ 1989, 1990 by Teijo Kinnunen
; med-player.a - konekielinen soittorutiini
; the machine language player routine
ac_ptr EQU $00
ac_len EQU $04
ac_per EQU $06
ac_vol EQU $08
T03SZ EQU 24
T415SZ EQU 8
xdef _GetSerial
xdef _FreeSerial
xdef _AddMIDIData
xdef _AudioInit
xdef _AudioRem
xdef _ChannelOff
xdef _SetTempo
xdef _ResetMIDI
xref _song
xref _PiirraPylvas
xref _sample
xref _trackon
xref _zeroptr
xref _periodit
xref _specialupd
xref _counter
xref DrawEqualizer
xref ClrChanDisp
xref SetDisp1
xref SetDisp2
xref SetDisp3
section "text",code
EVEN
_ChannelOff: ;d0 = channel #
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
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: cmp.b #4,d0
bge.s notamigatrk
moveq.l #1,d1
lsl.w d0,d1
move.w d1,$dff096
jsr ClrChanDisp(pc)
notamigatrk: rts
; track # = d7, note vol = d0, song = a4
GetRelVol: clr.w d1
clr.w d2
move.b 3330(a4),d1 ;master volume
lea 3314(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
lea _sample,a0 ;Is this instrument in mem?
move.w d3,d7
lsl.w #2,d7 ;d7 = instr.num << 2
tst.l 0(a0,d7.w)
bne.s inmem
tst.b 44(a3) ;is MIDI channel set
beq.w retsn2 ; NO!!!
inmem: lea _trackon,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 3290(a4),d1 ;add play transpose
add.b 47(a3),d1 ;and instr. transpose
jsr DrawEqualizer(pc)
cmp.b #4,d0
bge.s nodmaoff ;track #á>= 4: not an Amiga channel
jsr ClrChanDisp(pc)
move.w d4,$dff096 ;stop this channel (dmacon)
nodmaoff: 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 44(a3)
bne.w handleMIDInote
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
lea _sample,a0 ;get the address of...
movea.l 0(a0,d7.w),a0 ;...this instrument
lsl.w #1,d3
move.w d0,d4 ;d4 = track number
bsr.w getinsdata
move.l d0,ac_ptr(a1) ;put it in ac_ptr
move.w (sp),d6 ;volume
jsr SetDisp1(pc)
cmp.w #1,d3
bhi.s repeat
move.l _zeroptr,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
jsr SetDisp2(pc)
move.w d5,8(a5)
move.w (sp),ac_vol(a1) ;volume
lsr.w #2,d7 ;d7 is now instr. number again
drawcol: move.w d7,d0 ;to d0
cmp.b #31,d0
bge.s nodraw
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 3291(a4),d0 ;flags
btst #1,d0 ;jumping ??
beq.s retsn2 ;no...
btst #2,d0 ;with instruments
bne.s retsn2 ;no......
move.l 3294(a4),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)+,d3-d7
rts
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 44(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 45(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 drawcol
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
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
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
; 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
t415d: ds.b 8*12 ;8 bytes * 12 tracks = 96 bytes
trackdataptrs: dc.l t03d,t03d+T03SZ,t03d+2*T03SZ,t03d+3*T03SZ
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
nextblock: dc.b 0
animpause: dc.b 1
numtracks: dc.b 0,0
xref _pstate
xref _pblock
xref _lohko
xref _pline
xref _actplayline
xref _pseqnum
xref _blocks
xref _updscrflag
xref _maintsk
xref _updscrmsk
xref _tempo
xref _sprptr
xref _hyppymsk
xref _keybnote
_IntHandler:
movem.l d2-d7/a2-a5,-(sp)
tst.b _keybnote ;Do we have to play note from keyboard
beq.s nokbnote ;no...just normal playing
lea _keybnote,a1 ;get the address of the structure
lea _song,a4 ;and the song
lea 4(a4),a3 ;ptr to sample structures
clr.w dmaonmsk
moveq.l #0,d0
moveq.l #0,d1
moveq.l #0,d2
moveq.l #0,d3
clr.w d7
move.b 3(a1),d7 ;get all these values from
move.b d7,d0
lsl.b #2,d0
movea.l trackdataptrs(pc,d0.w),a5
move.b 2(a1),d3
move.w d3,d4
mulu #48,d4
adda.w d4,a3
move.b 46(a3),d0
bsr.w GetRelVol
move.b d0,d2
move.b d7,d0
move.b 1(a1),d1 ;the command structure
clr.b (a1) ;clear the play note flag
bsr _SoitaNuotti ;and play the note finally
bsr _StartDMA
bra.s notplaying ;exit
nokbnote: tst.w _pstate ;are we playing
bne.s playing ;yes, we are
movea.l craddr(pc),a0
bclr #0,(a0) ;no...stop the timer
move.b #$05,_counter
clr.b animcnt
move.l frame+36(pc),_sprptr
bra.w sigjump
notplaying: movem.l (sp)+,d2-d7/a2-a5 ;exit interrupt
rts
playing: clr.w dmaonmsk
lea _song,a4
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
; --- new note!! first get address of current block
lea _lohko,a0 ;a2 = address of 1st block's address
move.w _pblock,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 _actplayline,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,_pstate ;play block or play song
bne.s nonewseq ;play block only...
cmp.b #$01,nextblock
beq.s posjump
addq.w #1,_pseqnum ;advance sequence number
posjump: move.w 3030(a4),d0 ;get the highest seq number
move.w _pseqnum,d1 ;and current seq number
cmp.w d0,d1 ;is this the highest seq number
blt.s nostartagain ;no
clr.w _pseqnum ;yes: play song again
clr.w d1 ;...forever!!!
nostartagain: clr.w d0
lea 3032(a4),a1 ;offset of sequence table
move.b 0(a1,d1.w),d0 ;get number of the block
move.w d0,_pblock ;and put it to block number var
clr.w d1
move.b _blocks,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,_pblock ;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),_pline
tst.w _updscrflag ;screen updating on??
beq.s noscrupd ;no
movea.l _maintsk,a1 ;ask the main task to update screen
move.l _updscrmsk,d0
jsr -$144(a6) ;Signal()
; --- now start to play it
noscrupd: clr.b _counter
clr.l d7 ;number of track
move.b (a2),numtracks+1 ;save #áof tracks
lea 36(a2),a2 ;skip block header...
move.w numtracks(pc),d3
mulu #3,d3
move.w _pline,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
lea 4(a4),a3 ;skip "MED\x04"
mulu #48,d0 ;get address of this sample's data
adda.w d0,a3 ;a3 contains now address of it
moveq.l #0,d0
; ---------------- get volume and make it relative (0 - 100 %)
move.b 46(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 _pstate
or.b #2,_specialupd
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 _periodit,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
btst #4,3291(a4) ;look at flags
bne.s volhex
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
volhex: 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 3030(a4),d0 ;test the song length
bhi.s noeffect
move.w d0,_pseqnum
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 _periodit,a0
add.b 3290(a4),d5 ;play transpose
clr.w d0
move.b 1(a5),d0
mulu #48,d0
add.b 51(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
lea 4(a4),a3 ;skip "MED\x04"
mulu #48,d3 ;get address of this sample's data
adda.w d3,a3 ;a3 contains now address of it
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
tst.b 6(a5) ;first: is it MIDI??
bne.w midifx
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,3291(a4)
beq.s nost1
move.b 3293(a4),d0
cmp.b _counter,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,3291(a4)
beq.s nost2
move.b 3293(a4),d0
cmp.b _counter,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 3290(a4),d4 ;add play transpose
clr.w d0
move.b 1(a5),d0 ;prev. instr #
mulu #48,d0 ;get address of this sample's data
add.b 51(a4,d0.w),d4 ;add instrument 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
beq.s fx0d
cmp.b #$0a,d6
bne.s nofx0d
; **************************************** Effect 0D/0A ***
fx0d: btst #5,3291(a4)
beq.s nostD
move.b 3293(a4),d0
cmp.b _counter,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
move.b d0,d1
bra dispvolchng
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)
move.b d0,d1
bra.w dispvolchng
; *********************************************************
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,_counter ;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,3291(a4)
beq.s nost3
move.b 3293(a4),d0
cmp.b _counter,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 _counter
bne.w endl
move.b 2(a5),d1
dispvolchng: move.w d7,d0
ext.w d1
jsr SetDisp3(pc)
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,_counter
bne.w endl
bra.s playfxnote
no0ff1: cmp.b #$f2,d4
bne.s no0ff2
cmp.b #3,_counter
bne.w endl
bra.s playfxnote
no0ff2: cmp.b #$f3,d4
bne.s no0ff3
move.b _counter,d0
and.b #2+4,d0 ;is 2 or 4
beq.s endl
playfxnote: lea 4(a4),a3 ;skip "MED\x04"
clr.w d0
move.b 1(a5),d0
mulu #48,d0 ;get address of this sample's data
adda.w d0,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 ;f8 = filter off
beq.s filteroff
cmp.b #$f9,d4 ;f9 = filter on
bne.s endl
bclr #1,$bfe001
bra.s setfiltspcupd
filteroff: bset #1,$bfe001
setfiltspcupd: or.b #1,_specialupd
bra.s endl
; *********************************************************
nofx0f: cmp.b #$0c,d6
bne.s endl
newvals: tst.w d5 ;now: do the effects!!!
beq.s oldper
move.w d7,d4
jsr SetDisp2(pc)
bra.s nooldper
oldper: 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
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
move.b 3291(a4),d0 ;get the flags
btst #1,d0 ;is Topi's jumping on ???
beq.s exitint ;no
lea animcnt(pc),a1
lea animpause(pc),a2
btst #2,d0 ;every 8th note ???
beq.s no8th
moveq #7,d0
and.w _pline,d0 ;is this 8th note ??
bne.s no8th ;no...
tst.b (a1)
bne.s no8th
tst.w _pstate
beq.s no8th
move.b #1,(a1)
no8th: tst.b (a1)
beq.s exitint
addq.b #1,(a2) ;Handles all animation
cmp.b #2,(a2)
blt.s exitint
cmp.b #10,(a1)
bne.s nojumpend
clr.b (a1)
move.b #1,(a2)
bra.s exitint
nojumpend: clr.w d0
move.b (a1),d0
addq.b #1,(a1)
lsl.w #2,d0
lea frame(pc),a1
move.l 0(a1,d0.w),_sprptr
tst.w _updscrflag
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 (a2)
exitint: movem.l (sp)+,d2-d7/a2-a5
rts
_SetTempo: move.w d0,_tempo
cmp.b #10,d0 ;If tempo <= 10, use SoundTracker tempo
bhi.s calctempo
subq.b #1,d0
move.b d0,_song+3293
lsl.w #1,d0
move.w sttempo+2(pc,d0.w),d1
bra.s pushtempo
calctempo: move.l #470000,d1
divu d0,d1
pushtempo: movea.l craddr+4(pc),a0
move.b d1,(a0) ;and set the CIA timer
lsr.w #8,d1
movea.l craddr+8(pc),a0
move.b d1,(a0)
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 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 _counter
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 _counter ;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 ;I said 0 - $7f!!! (for future compability)
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
DoArpeggio: ; begin note in d1, note num returned in d4
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
_ResetMIDI: 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
even
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
move.w 40(a3),d2
move.w 42(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 40(a3),d2
move.w 42(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 _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
lea craddr(pc),a0
move.l #$bfee01,(a0)+
move.l #$bfe401,(a0)+
move.l #$bfe501,(a0)+
and.b #%10000000,$bfee01
st.b timeropen
clr.w _pstate
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
moveq.l #0,d0
jsr -$c(a6) ;RemICRVector
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(pc),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
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: movea.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
btst #11,d0
sne.b intrson+1
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
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 #$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()
move.w #$8000,d0
tst.b intrson
beq.s nofsstbe
bset #0,d0
nofsstbe: tst.b intrson+1
beq.s nofssrbf
bset #11,d0
nofssrbf: move.w d0,$dff09a ;set RBF & TBE to their prev. values
movea.l miscresbase(pc),a6
clr.l d0 ;serial port
jsr -$c(a6) ;FreeMiscResource()
clr.b serportalloc
clr.b lastcmdbyte
retfs: move.l (sp)+,a6
rts
prevtbe: dc.l 0
prevrbf: dc.l 0
xref _recmidi
xref _recmidimsk
xref _recvol
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
move.b 2(a1),_recvol
movea.l _maintsk,a1
move.l _recmidimsk,d0
jsr -$144(a6) ;Signal()
nosrec: rts
recmidi: dc.b 0,0,0,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
sendbuffer: ds.b 128
buffptr: dc.l sendbuffer
readbuffptr: dc.l sendbuffer
miscresbase: dc.l 0
lastcmdbyte: dc.b 0
even
preschgdata: dc.b 0,0
noteondata: dc.l 0
audiodevopen: dc.b 0
timeropen: dc.b 0
serportalloc: dc.b 0
bytesinbuff: dc.b 0
sigbitnum: dc.b -1
even
craddr: dc.l 0
dc.l 0 ;tloaddr
dc.l 0 ;thiaddr
timerinterrupt: dc.w 0,0,0,0,0
dc.l timerintname,0,_IntHandler
serinterrupt: dc.w 0,0,0,0,0
dc.l serintname,buffptr,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, 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 'MEDTimerInterrupt',0
serintname: dc.b 'MEDSerialInterrupt',0
rbfintname: dc.b 'MEDSerialRBFInt',0
audiodevname: dc.b 'audio.device',0
miscresname: dc.b 'misc.resource',0
serdev: dc.b 'serial.device',0
medname: dc.b 'MED',0 ;yeah, our name
end