mirror of
https://github.com/LIV2/WinUAE.git
synced 2025-12-06 00:12:52 +00:00
1323 lines
21 KiB
ArmAsm
1323 lines
21 KiB
ArmAsm
|
||
; Amiga-side full featured AHI driver for WinUAE 4.3.1+ UAESND sound board.
|
||
; by Toni Wilen (c) 2019-2020
|
||
|
||
; License: GPL version 2 or any later version.
|
||
|
||
incdir sys:programming/asm/includes/
|
||
|
||
include exec/exec.i
|
||
include exec/exec_lib.i
|
||
include exec/libraries.i
|
||
include exec/ports.i
|
||
include devices/ahi.i
|
||
include libraries/ahi_sub.i
|
||
include libraries/configregs.i
|
||
include libraries/configvars.i
|
||
include utility/hooks.i
|
||
include hardware/intbits.i
|
||
include utility/utility.i
|
||
include utility/hooks.i
|
||
|
||
DEBUG EQU 1
|
||
DEBUG_ADDR EQU $bfff00
|
||
|
||
VERSION EQU 4
|
||
REVISION EQU 1
|
||
VERSION_STRUCT EQU 1
|
||
|
||
call MACRO
|
||
jsr _LVO\1(a6)
|
||
ENDM
|
||
|
||
STRUCTURE UAESNDHW,$80
|
||
ULONG base_uae_version
|
||
UWORD base_snd_version
|
||
UWORD base_snd_revision
|
||
ULONG base_frequency
|
||
UBYTE base_max_channels
|
||
UBYTE base_max_actual_channels
|
||
UBYTE base_max_streams
|
||
UBYTE base_pad1
|
||
ULONG base_ram_offset
|
||
ULONG base_ram_size
|
||
STRUCT base_reserved1,$48
|
||
ULONG base_stream_allocate
|
||
ULONG base_stream_latch
|
||
ULONG base_stream_unlatch
|
||
ULONG base_pad2
|
||
ULONG base_stream_enable
|
||
ULONG base_stream_intena
|
||
ULONG base_stream_intreq
|
||
|
||
STRUCTURE UAESNDSet,0
|
||
UWORD set_flags
|
||
UWORD set_format
|
||
APTR set_pointer
|
||
ULONG set_length
|
||
ULONG set_frequency
|
||
APTR set_repeat_pointer
|
||
ULONG set_repeat_length
|
||
UWORD set_repeat_count
|
||
UWORD set_volume
|
||
APTR set_next_pointer
|
||
UBYTE set_channels
|
||
UBYTE set_type
|
||
UBYTE set_intena
|
||
UBYTE set_mask
|
||
UWORD set_hpan
|
||
UWORD set_dpan
|
||
APTR set_pointer_original
|
||
ULONG set_length_original
|
||
; extra
|
||
ULONG set_offset
|
||
UWORD set_sample_size
|
||
LABEL UAESNDSet_SIZEOF
|
||
|
||
STREAM_START = $100
|
||
STREAM_OFFSET = $100
|
||
|
||
STRUCTURE UAESNDStream,0
|
||
STRUCT UAESNDSetCurrent,$40
|
||
STRUCT UAESNDSetLatched,$40
|
||
APTR stream_sample_pointer
|
||
UBYTE stream_pad01
|
||
UBYTE stream_pad02
|
||
UBYTE stream_pad03
|
||
UBYTE stream_intreq
|
||
UBYTE stream_pad04
|
||
UBYTE stream_pad05
|
||
UBYTE stream_pad06
|
||
UBYTE stream_alt_intreq
|
||
UBYTE stream_pad07
|
||
UBYTE stream_pad08
|
||
UBYTE stream_pad09
|
||
UBYTE stream_master_intena
|
||
UBYTE stream_pad10
|
||
UBYTE stream_pad11
|
||
UBYTE stream_pad12
|
||
UBYTE stream_status
|
||
ULONG stream_timer1_frequency
|
||
ULONG stream_pad13
|
||
ULONG stream_pad14
|
||
APTR stream_sample_pointer_imm
|
||
|
||
STRUCTURE sound,0
|
||
APTR so_Address
|
||
ULONG so_Length
|
||
UWORD so_Type
|
||
UWORD so_Samplesize
|
||
LABEL sound_SIZEOF
|
||
|
||
STRUCTURE channel,0
|
||
APTR ch_set_current
|
||
STRUCT ch_UAESNDSet1,UAESNDSet_SIZEOF
|
||
STRUCT ch_SndMsg,AHISoundMessage_SIZEOF
|
||
LABEL channel_SIZEOF
|
||
|
||
STRUCTURE UAESNDBase,LIB_SIZE
|
||
UBYTE ub_Flags
|
||
UBYTE ub_Pad1
|
||
UWORD ub_Pad2
|
||
APTR ub_SysLib
|
||
ULONG ub_SegList
|
||
ULONG ub_Base
|
||
APTR ub_ConfigDev
|
||
APTR ub_UtilBase
|
||
LABEL UAESNDBase_SIZEOF
|
||
|
||
STRUCTURE UAESND,0
|
||
ULONG p_Base
|
||
APTR p_UAESNDBase
|
||
UWORD p_DisableCount
|
||
BOOL p_intadded
|
||
APTR p_AudioCtrl
|
||
ULONG p_SoundSize
|
||
APTR p_Sounds
|
||
APTR p_Channels
|
||
ULONG p_ChannelSize
|
||
ULONG p_DriverDataSize
|
||
APTR p_ChannelInfo
|
||
UWORD p_StreamCnt
|
||
UWORD p_Pad1
|
||
STRUCT p_Interrupt,IS_SIZE
|
||
LABEL UAESND_SIZEOF
|
||
|
||
Start:
|
||
moveq #-1,d0
|
||
rts
|
||
|
||
RomTag:
|
||
DC.W RTC_MATCHWORD
|
||
DC.L RomTag
|
||
DC.L EndCode
|
||
DC.B RTF_AUTOINIT
|
||
DC.B 4 ;version
|
||
DC.B NT_LIBRARY
|
||
DC.B 0 ;pri
|
||
DC.L LibName
|
||
DC.L IDString
|
||
DC.L InitTable
|
||
|
||
LibName:
|
||
dc.b "uaesnd.audio",0
|
||
dc.b "$VER:"
|
||
IDString:
|
||
dc.b "uaesnd.audio 4.1 (11.04.2020)",0
|
||
cnop 0,4
|
||
|
||
InitTable:
|
||
DC.L UAESNDBase_SIZEOF
|
||
DC.L funcTable
|
||
DC.L dataTable
|
||
DC.L initRoutine
|
||
|
||
funcTable:
|
||
dc.l Open
|
||
dc.l Close
|
||
dc.l Expunge
|
||
dc.l Null
|
||
|
||
dc.l AHIsub_AllocAudio
|
||
dc.l AHIsub_FreeAudio
|
||
dc.l AHIsub_Disable
|
||
dc.l AHIsub_Enable
|
||
dc.l AHIsub_Start
|
||
dc.l AHIsub_Update
|
||
dc.l AHIsub_Stop
|
||
dc.l AHIsub_SetVol
|
||
dc.l AHIsub_SetFreq
|
||
dc.l AHIsub_SetSound
|
||
dc.l AHIsub_SetEffect
|
||
dc.l AHIsub_LoadSound
|
||
dc.l AHIsub_UnloadSound
|
||
dc.l AHIsub_GetAttr
|
||
dc.l AHIsub_HardwareControl
|
||
dc.l -1
|
||
|
||
dataTable:
|
||
INITBYTE LN_TYPE,NT_LIBRARY
|
||
INITLONG LN_NAME,LibName
|
||
INITBYTE LIB_FLAGS,LIBF_SUMUSED|LIBF_CHANGED
|
||
INITWORD LIB_VERSION,VERSION
|
||
INITWORD LIB_REVISION,REVISION
|
||
INITLONG LIB_IDSTRING,IDString
|
||
DC.L 0
|
||
|
||
IFD DEBUG=1
|
||
debugreturn
|
||
move.l d0,DEBUG_ADDR
|
||
move.l #debug_return,DEBUG_ADDR+4
|
||
rts
|
||
debug_return
|
||
dc.b "-> %x\n",0
|
||
even
|
||
ENDC
|
||
|
||
IFD DEBUG=1
|
||
debug_setvol
|
||
dc.b "SetVol(%u,%x,%x,%p,%x)\n",0
|
||
even
|
||
ENDC
|
||
|
||
; UWORD channel D0
|
||
; Fixed volume D1
|
||
; sposition pan D2
|
||
; struct AHIAudioCtrlDrv* A2
|
||
; ULONG Flags D3
|
||
|
||
AHIsub_SetVol
|
||
movem.l d2/a2,-(sp)
|
||
|
||
IFD DEBUG=1
|
||
lea DEBUG_ADDR,a0
|
||
move.w d0,(a0)
|
||
move.l d1,(a0)
|
||
move.l d2,(a0)
|
||
move.l a2,(a0)
|
||
move.l d3,(a0)
|
||
move.l #debug_setvol,4(a0)
|
||
ENDC
|
||
|
||
move.l ahiac_DriverData(a2),a2
|
||
|
||
move.w d0,d2
|
||
mulu #channel_SIZEOF,d0
|
||
move.l p_Channels(a2),a1
|
||
add.l d0,a1
|
||
asr.l #1,d1
|
||
bpl.s .pos
|
||
neg.l d1
|
||
.pos
|
||
cmp.l #32767,d1
|
||
bcs.s .large
|
||
move.w #32767,d1
|
||
.large
|
||
move.l ch_set_current(a1),a0
|
||
move.w d1,set_volume(a0)
|
||
|
||
btst #AHISB_IMM,d3
|
||
beq.s .noimm
|
||
|
||
move.l p_Base(a2),a0
|
||
mulu #STREAM_OFFSET,d2
|
||
add.l d2,a0
|
||
move.w d1,STREAM_START+UAESNDSetCurrent+set_volume(a0)
|
||
|
||
.noimm
|
||
movem.l (sp)+,d2/a2
|
||
moveq #0,d0
|
||
|
||
IFD DEBUG=1
|
||
bsr debugreturn
|
||
ENDC
|
||
|
||
rts
|
||
|
||
IFD DEBUG=1
|
||
debug_setfreq
|
||
dc.b "SetFreq(%u,%x,%p,%x)\n",0
|
||
even
|
||
ENDC
|
||
|
||
; UWORD channel D0
|
||
; ULONG freq D1
|
||
; struct AHIAudioCtrlDrv* A2
|
||
; ULONG Flags D2
|
||
|
||
AHIsub_SetFreq
|
||
movem.l d3/a2,-(sp)
|
||
|
||
IFD DEBUG=1
|
||
lea DEBUG_ADDR,a0
|
||
move.w d0,(a0)
|
||
move.l d1,(a0)
|
||
move.l d2,(a0)
|
||
move.l d2,(a0)
|
||
move.l #debug_setfreq,4(a0)
|
||
ENDC
|
||
|
||
move.l ahiac_DriverData(a2),a2
|
||
|
||
move.w d0,d3
|
||
mulu #channel_SIZEOF,d0
|
||
move.l p_Channels(a2),a1
|
||
add.l d0,a1
|
||
asl.l #8,d1
|
||
|
||
move.l ch_set_current(a1),a0
|
||
move.l d1,set_frequency(a0)
|
||
|
||
btst #AHISB_IMM,d2
|
||
beq.s .noimm
|
||
|
||
move.l p_Base(a2),a0
|
||
mulu #STREAM_OFFSET,d3
|
||
add.l d3,a0
|
||
move.l d1,STREAM_START+UAESNDSetCurrent+set_frequency(a0)
|
||
|
||
.noimm
|
||
movem.l (sp)+,d3/a2
|
||
moveq #0,d0
|
||
|
||
IFD DEBUG=1
|
||
bsr debugreturn
|
||
ENDC
|
||
|
||
rts
|
||
|
||
IFD DEBUG=1
|
||
debug_setsound
|
||
dc.b "SetSound(%u,%u,%x,%d,%p,%x)\n",0
|
||
even
|
||
ENDC
|
||
|
||
; UWORD channel D0
|
||
; UWORD sound D1
|
||
; ULONG offset D2
|
||
; LONG length D3
|
||
; struct AHIAudioCtrlDrv* A2
|
||
; ULONG Flags D4
|
||
|
||
AHIsub_SetSound
|
||
movem.l d2-d5/a2-a5,-(sp)
|
||
|
||
IFD DEBUG=1
|
||
lea DEBUG_ADDR,a0
|
||
move.w d0,(a0)
|
||
move.w d1,(a0)
|
||
move.l d2,(a0)
|
||
move.l d3,(a0)
|
||
move.l a2,(a0)
|
||
move.l d4,(a0)
|
||
move.l #debug_setsound,4(a0)
|
||
ENDC
|
||
|
||
move.l ahiac_DriverData(a2),a3
|
||
|
||
move.w d0,d5
|
||
mulu #channel_SIZEOF,d0
|
||
move.l p_Channels(a3),a1
|
||
add.l d0,a1
|
||
move.l ch_set_current(a1),a4
|
||
|
||
move.l p_Base(a3),a5
|
||
add.w #STREAM_START,a5
|
||
mulu #STREAM_OFFSET,d5
|
||
add.l d5,a5
|
||
|
||
cmp.w #AHI_NOSOUND,d1
|
||
bne.s .sound_ok
|
||
moveq #0,d2
|
||
moveq #0,d3
|
||
lea empty_sound(pc),a2
|
||
bra.s .update_channel
|
||
|
||
.sound_ok
|
||
move.w d1,d0
|
||
mulu #sound_SIZEOF,d0
|
||
move.l p_Sounds(a3),a2
|
||
add.l d0,a2
|
||
tst.l d3
|
||
bne.s .length_ok
|
||
move.l so_Length(a2),d3
|
||
.length_ok
|
||
|
||
.update_channel
|
||
|
||
move.b so_Type+0(a2),set_channels(a4)
|
||
move.b so_Type+1(a2),set_type(a4)
|
||
moveq #0,d0
|
||
move.w so_Samplesize(a2),d0
|
||
move.w d0,set_sample_size(a4)
|
||
mulu.l d0,d2
|
||
move.l d2,set_offset(a4)
|
||
move.l so_Address(a2),d0
|
||
move.l d0,set_repeat_pointer(a4)
|
||
add.l d2,d0
|
||
move.l d0,set_pointer(a4)
|
||
move.l d3,set_length(a4)
|
||
move.w #-1,set_repeat_count(a4)
|
||
move.b #3,set_mask(a4)
|
||
move.l a4,set_next_pointer(a4)
|
||
|
||
bset #0,stream_master_intena(a5)
|
||
|
||
btst #AHISB_IMM,d4
|
||
bne.s .doimm
|
||
|
||
; tell the sound hardware that next set is ready
|
||
; to play when previous one has finished (or has
|
||
; already started looping)
|
||
|
||
move.b #1,stream_status(a5)
|
||
bra.s .noimm
|
||
|
||
.doimm
|
||
|
||
; start stream immediately
|
||
move.l a4,stream_sample_pointer_imm(a5)
|
||
|
||
.noimm
|
||
|
||
movem.l (sp)+,d2-d5/a2-a5
|
||
moveq #0,d0
|
||
|
||
IFD DEBUG=1
|
||
bsr debugreturn
|
||
ENDC
|
||
|
||
rts
|
||
|
||
empty_sound
|
||
dc.l 0,0
|
||
dc.w 0,0
|
||
|
||
IFD DEBUG=1
|
||
debug_seteffect
|
||
dc.b "SetEffect(%p,%p)\n",0
|
||
even
|
||
ENDC
|
||
|
||
; Effect* A0
|
||
; struct AHIAudioCtrlDrv* A2
|
||
|
||
AHIsub_SetEffect
|
||
move.l a3,-(sp)
|
||
|
||
IFD DEBUG=1
|
||
lea DEBUG_ADDR,a1
|
||
move.l a0,(a1)
|
||
move.l a2,(a1)
|
||
move.l #debug_seteffect,4(a1)
|
||
ENDC
|
||
|
||
moveq #AHIE_OK,d1
|
||
move.l ahiac_DriverData(a2),a3
|
||
move.l ahie_Effect(a0),d0
|
||
cmp.l #AHIET_MASTERVOLUME,d0
|
||
bne.s .nmastervolume
|
||
nop
|
||
bra.s .end
|
||
.nmastervolume
|
||
cmp.l #AHIET_CANCEL|AHIET_MASTERVOLUME,d0
|
||
bne.s .nmastervolume_off
|
||
nop
|
||
bra.s .end
|
||
.nmastervolume_off
|
||
cmp.l #AHIET_CHANNELINFO,d0
|
||
bne.s .nchannelinfo
|
||
move.l a0,p_ChannelInfo(a3)
|
||
bra.s .end
|
||
.nchannelinfo
|
||
cmp.l #AHIET_CANCEL|AHIET_CHANNELINFO,d0
|
||
bne.s .nchannelinfo_off
|
||
clr.l p_ChannelInfo(a3)
|
||
bra.s .end
|
||
.nchannelinfo_off
|
||
moveq #AHIE_UNKNOWN,d1
|
||
.end
|
||
move.l (sp)+,a3
|
||
move.l d1,d0
|
||
|
||
IFD DEBUG=1
|
||
bsr debugreturn
|
||
ENDC
|
||
|
||
rts
|
||
|
||
update_playerfunc
|
||
|
||
movem.l a2/a3,-(sp)
|
||
move.l a0,a3
|
||
move.l ahiac_DriverData(a3),a2
|
||
move.l p_Base(a2),a0
|
||
move.l ahiac_PlayerFreq(a3),d0
|
||
cmp.l #$10000,d0
|
||
bcs.s .notfixed
|
||
lsr.l #8,d0
|
||
.notfixed
|
||
bset.b #4,STREAM_START+stream_master_intena(a0)
|
||
move.l d0,STREAM_START+stream_timer1_frequency(a0)
|
||
movem.l (sp)+,a2/a3
|
||
rts
|
||
|
||
; ULONG Flags D0
|
||
; struct AHIAudioCtrlDrv* A2
|
||
|
||
AHIsub_Update
|
||
|
||
move.l a3,-(sp)
|
||
|
||
move.l ahiac_DriverData(a2),a3
|
||
move.l p_Base(a3),a0
|
||
bsr.w uaesnd_disable
|
||
|
||
move.l a2,a0
|
||
bsr.w update_playerfunc
|
||
|
||
move.l p_Base(a3),a0
|
||
bsr.w uaesnd_enable
|
||
|
||
move.l (sp)+,a3
|
||
rts
|
||
|
||
IFD DEBUG=1
|
||
debug_loadsound
|
||
dc.b "LoadSound(%u,%x,%p,%p)\n",0
|
||
even
|
||
ENDC
|
||
|
||
; UWORD Sound D0
|
||
; ULONG Type D1
|
||
; APTR Info A0
|
||
; struct AHIAudioCtrlDrv* A2
|
||
|
||
AHIsub_LoadSound
|
||
movem.l d2/d5/a2/a3,-(sp)
|
||
|
||
IFD DEBUG=1
|
||
lea DEBUG_ADDR,a1
|
||
move.w d0,(a1)
|
||
move.l d1,(a1)
|
||
move.l a0,(a1)
|
||
move.l a2,(a1)
|
||
move.l #debug_loadsound,4(a1)
|
||
ENDC
|
||
|
||
move.l ahiac_DriverData(a2),a3
|
||
|
||
move.l p_Sounds(a3),a2
|
||
mulu #sound_SIZEOF,d0
|
||
add.l d0,a2
|
||
|
||
moveq #AHIE_BADSOUNDTYPE,d5
|
||
cmp.w #AHIST_SAMPLE,d1
|
||
beq.s .sample
|
||
cmp.w #AHIST_DYNAMICSAMPLE,d1
|
||
bne.s .exit
|
||
.sample
|
||
moveq #AHIE_BADSAMPLETYPE,d5
|
||
move.l ahisi_Type(a0),d0
|
||
lea sampletypes(pc),a1
|
||
moveq #-1,d1
|
||
.next
|
||
move.l (a1),d2
|
||
cmp.l d2,d1
|
||
beq.s .exit
|
||
cmp.l d2,d0
|
||
beq.s .samplefound
|
||
addq.l #4+2+2,a1
|
||
bra.s .next
|
||
.samplefound
|
||
|
||
move.w 4(a1),so_Type(a2)
|
||
move.w 6(a1),so_Samplesize(a2)
|
||
move.l ahisi_Address(a0),so_Address(a2)
|
||
move.l ahisi_Length(a0),so_Length(a2)
|
||
moveq #AHIE_OK,d5
|
||
.exit
|
||
move.l d5,d0
|
||
|
||
IFD DEBUG=1
|
||
bsr debugreturn
|
||
ENDC
|
||
|
||
movem.l (sp)+,d2/d5/a2/a3
|
||
rts
|
||
|
||
IFD DEBUG=1
|
||
debug_unloadsound
|
||
dc.b "UnloadSound(%u,%p)\n",0
|
||
even
|
||
ENDC
|
||
|
||
; UWORD Sound D0
|
||
; struct AHIAudioCtrlDrv* A2
|
||
|
||
AHIsub_UnloadSound
|
||
|
||
IFD DEBUG=1
|
||
lea DEBUG_ADDR,a0
|
||
move.w d0,(a0)
|
||
move.l a2,(a0)
|
||
move.l #debug_unloadsound,4(a0)
|
||
ENDC
|
||
|
||
move.l ahiac_DriverData(a2),a0
|
||
move.l p_Sounds(a0),a0
|
||
mulu #sound_SIZEOF,d0
|
||
add.l d0,a0
|
||
clr.w so_Type(a0)
|
||
moveq #0,d0
|
||
|
||
IFD DEBUG=1
|
||
bsr debugreturn
|
||
ENDC
|
||
|
||
rts
|
||
|
||
sampletypes
|
||
dc.l AHIST_M8S
|
||
dc.b 1, 0, 0, 1
|
||
dc.l AHIST_S8S
|
||
dc.b 2, 0, 0, 2
|
||
dc.l AHIST_M16S
|
||
dc.b 1, 1, 0, 2
|
||
dc.l AHIST_S16S
|
||
dc.b 2, 1, 0, 4
|
||
dc.l AHIST_M32S
|
||
dc.b 1, 3, 0, 4
|
||
dc.l AHIST_S32S
|
||
dc.b 2, 3, 0, 8
|
||
dc.l AHIST_L7_1
|
||
dc.b 8, 3, 0, 32
|
||
dc.l -1
|
||
|
||
uaesnd_enable
|
||
move.l base_stream_enable(a0),base_stream_intena(a0)
|
||
rts
|
||
|
||
uaesnd_disable
|
||
clr.l base_stream_intena(a0)
|
||
rts
|
||
|
||
; struct AHIAudioCtrlDrv* A2
|
||
|
||
AHIsub_Disable
|
||
move.l ahiac_DriverData(a2),a0
|
||
addq.w #1,p_DisableCount(a0)
|
||
move.l p_Base(a0),a0
|
||
bsr uaesnd_disable
|
||
rts
|
||
|
||
; struct AHIAudioCtrlDrv* A2
|
||
|
||
AHIsub_Enable
|
||
move.l ahiac_DriverData(a2),a0
|
||
subq.w #1,p_DisableCount(a0)
|
||
bne.s .exit
|
||
move.l p_Base(a0),a0
|
||
bsr uaesnd_enable
|
||
.exit
|
||
rts
|
||
|
||
reset_ch
|
||
move.l p_ChannelSize(a0),d0
|
||
beq.s .res0
|
||
move.l p_Channels(a0),a0
|
||
moveq #channel_SIZEOF,d1
|
||
.res1
|
||
clr.l ch_UAESNDSet1+set_next_pointer(a0)
|
||
sub.l d1,d0
|
||
add.l d1,a0
|
||
bne.s .res1
|
||
.res0
|
||
rts
|
||
|
||
reset_hw
|
||
clr.l base_stream_intena(a0)
|
||
clr.l base_stream_enable(a0)
|
||
clr.l STREAM_START+stream_timer1_frequency(a0)
|
||
rts
|
||
|
||
IFD DEBUG=1
|
||
debug_start
|
||
dc.b "Start(%x,%p)\n",0
|
||
even
|
||
ENDC
|
||
|
||
; ULONG Flags D0
|
||
; struct AHIAudioCtrlDrv* A2
|
||
|
||
AHIsub_Start
|
||
|
||
IFD DEBUG=1
|
||
lea DEBUG_ADDR,a0
|
||
move.l d0,(a0)
|
||
move.l a2,(a0)
|
||
move.l #debug_start,4(a0)
|
||
ENDC
|
||
|
||
move.l ahiac_DriverData(a2),a1
|
||
move.l p_Base(a1),a0
|
||
bsr reset_hw
|
||
|
||
move.l a2,a0
|
||
bsr.w update_playerfunc
|
||
|
||
move.l ahiac_DriverData(a2),a1
|
||
move.l p_Base(a1),a0
|
||
moveq #1,d0
|
||
move.b base_max_streams(a0),d1
|
||
lsl.l d1,d0
|
||
subq.l #1,d0
|
||
move.l d0,base_stream_enable(a0)
|
||
move.l d0,base_stream_intena(a0)
|
||
moveq #AHIE_OK,d0
|
||
|
||
IFD DEBUG=1
|
||
bsr debugreturn
|
||
ENDC
|
||
|
||
rts
|
||
|
||
IFD DEBUG=1
|
||
debug_stop
|
||
dc.b "Stop(%x,%p)\n",0
|
||
even
|
||
ENDC
|
||
|
||
; ULONG Flags D0
|
||
; struct AHIAudioCtrlDrv* A2
|
||
|
||
AHIsub_Stop:
|
||
|
||
IFD DEBUG=1
|
||
lea DEBUG_ADDR,a0
|
||
move.l d0,(a0)
|
||
move.l a2,(a0)
|
||
move.l #debug_stop,4(a0)
|
||
ENDC
|
||
|
||
move.l ahiac_DriverData(a2),a0
|
||
move.l p_Base(a0),a0
|
||
bsr reset_hw
|
||
|
||
move.l ahiac_DriverData(a2),a0
|
||
bsr.w reset_ch
|
||
|
||
moveq #AHIE_OK,d0
|
||
rts
|
||
|
||
IFD DEBUG=1
|
||
debug_allocaudio
|
||
dc.b "AllocAudio(%p,%p)\n",0
|
||
even
|
||
ENDC
|
||
|
||
; struct TagItem* A1
|
||
; struct AHIAudioCtrlDrv* a2
|
||
|
||
AHIsub_AllocAudio
|
||
movem.l d2-d3/d7/a3-a6,-(sp)
|
||
|
||
IFD DEBUG=1
|
||
lea DEBUG_ADDR,a0
|
||
move.l a1,(a0)
|
||
move.l a2,(a0)
|
||
move.l #debug_allocaudio,4(a0)
|
||
ENDC
|
||
|
||
moveq #AHISF_ERROR,d7
|
||
|
||
move.l a6,a5
|
||
move.l a1,d3
|
||
|
||
move.l ub_SysLib(a5),a6
|
||
|
||
move.l #UAESND_SIZEOF,d0
|
||
move.l #MEMF_PUBLIC|MEMF_CLEAR,d1
|
||
call AllocMem
|
||
move.l d0,ahiac_DriverData(a2)
|
||
beq .error
|
||
move.l d0,a3
|
||
|
||
move.l a5,p_UAESNDBase(a3)
|
||
move.l ub_Base(a5),a4
|
||
moveq #0,d0
|
||
move.b base_max_streams(a4),d0
|
||
move.w d0,p_StreamCnt(a3)
|
||
move.l a4,p_Base(a3)
|
||
move.l a2,p_AudioCtrl(a3)
|
||
|
||
moveq #0,d0
|
||
move.b base_max_streams(a4),d0
|
||
cmp.w ahiac_Channels(a2),d0
|
||
bcs .error
|
||
|
||
mulu #channel_SIZEOF,d0
|
||
move.l d0,p_ChannelSize(a3)
|
||
move.l #MEMF_PUBLIC|MEMF_CLEAR,d1
|
||
call AllocMem
|
||
move.l d0,p_Channels(a3)
|
||
beq .error
|
||
|
||
move.l d0,a1
|
||
move.w ahiac_Channels(a2),d1
|
||
subq.w #1,d1
|
||
.setch
|
||
lea ch_UAESNDSet1(a1),a0
|
||
move.l a0,ch_set_current(a1)
|
||
add.w #channel_SIZEOF,a1
|
||
dbf d1,.setch
|
||
|
||
move.w ahiac_Sounds(a2),d0
|
||
mulu.w #sound_SIZEOF,d0
|
||
move.l d0,p_SoundSize(a3)
|
||
move.l #MEMF_PUBLIC|MEMF_CLEAR,d1
|
||
call AllocMem
|
||
move.l d0,p_Sounds(a3)
|
||
beq .error
|
||
|
||
move.l a3,a0
|
||
bsr.w reset_ch
|
||
|
||
move.l a4,a0
|
||
bsr.w reset_hw
|
||
|
||
lea p_Interrupt(a3),a1
|
||
lea interrupt_code(pc),a0
|
||
move.l a0,IS_CODE(a1)
|
||
lea intname(pc),a0
|
||
move.l a0,LN_NAME(a1)
|
||
move.b #NT_INTERRUPT,LN_TYPE(a1)
|
||
move.b #40,LN_PRI(a1)
|
||
move.l a3,IS_DATA(a1)
|
||
moveq #INTB_EXTER,d0
|
||
call AddIntServer
|
||
st p_intadded(a3)
|
||
|
||
move.l a4,a0
|
||
moveq #1,d0
|
||
move.w p_StreamCnt(a3),d1
|
||
lsl.l d1,d0
|
||
subq.l #1,d0
|
||
move.l d0,base_stream_allocate(a0)
|
||
|
||
move.l #AHISF_KNOWSTEREO|AHISF_KNOWHIFI|AHISF_KNOWMULTICHANNEL,d7
|
||
|
||
.error
|
||
move.l d7,d0
|
||
|
||
IFD DEBUG=1
|
||
bsr debugreturn
|
||
ENDC
|
||
|
||
movem.l (sp)+,d2-d3/d7/a3-a6
|
||
rts
|
||
|
||
IFD DEBUG=1
|
||
debug_freeaudio
|
||
dc.b "FreeAudio(%p)\n",0
|
||
even
|
||
ENDC
|
||
|
||
AHIsub_FreeAudio
|
||
movem.l a3/a5/a6,-(sp)
|
||
|
||
IFD DEBUG=1
|
||
lea DEBUG_ADDR,a0
|
||
move.l a2,(a0)
|
||
move.l #debug_freeaudio,4(a0)
|
||
ENDC
|
||
|
||
move.l a6,a5
|
||
move.l ub_SysLib(a5),a6
|
||
move.l ahiac_DriverData(a2),d0
|
||
beq.s .noaudio
|
||
move.l d0,a3
|
||
|
||
tst.b p_intadded(a3)
|
||
beq.s .noint
|
||
lea p_Interrupt(a3),a1
|
||
moveq #INTB_EXTER,d0
|
||
call RemIntServer
|
||
|
||
move.l p_Base(a3),a0
|
||
bsr.w reset_hw
|
||
clr.l base_stream_allocate(a0)
|
||
.noint
|
||
|
||
move.l p_Sounds(a3),d0
|
||
beq.s .nosounds
|
||
move.l d0,a1
|
||
move.l p_SoundSize(a3),d0
|
||
call FreeMem
|
||
.nosounds
|
||
|
||
move.l p_Channels(a3),d0
|
||
beq.s .nochannels
|
||
move.l d0,a1
|
||
move.l p_ChannelSize(a3),d0
|
||
call FreeMem
|
||
.nochannels
|
||
|
||
move.l a3,a1
|
||
move.l p_DriverDataSize(a3),d0
|
||
call FreeMem
|
||
|
||
clr.l ahiac_DriverData(a2)
|
||
|
||
.noaudio
|
||
movem.l (sp)+,a3/a5/a6
|
||
rts
|
||
|
||
IFD DEBUG=1
|
||
debug_getattr
|
||
dc.b "GetAttr(%x,%x,%x,%p,%p)\n",0
|
||
even
|
||
ENDC
|
||
|
||
; ULONG Attribute D0
|
||
; LONG Argument D1
|
||
; LONG DefValue D2
|
||
; struct TagItem* A1
|
||
; struct AHIAudioCtrlDrv* A2
|
||
|
||
AHIsub_GetAttr
|
||
move.l d2,-(sp)
|
||
|
||
IFD DEBUG=1
|
||
lea DEBUG_ADDR,a0
|
||
move.l d0,(a0)
|
||
move.l d1,(a0)
|
||
move.l d2,(a0)
|
||
move.l a1,(a0)
|
||
move.l a2,(a0)
|
||
move.l #debug_getattr,4(a0)
|
||
ENDC
|
||
|
||
cmp.l #AHIDB_Frequency,d0
|
||
bne.s .notfreq
|
||
lea tag_frequencies(pc),a0
|
||
move.l 0(a0,d1.w*4),d2
|
||
bra.s .exit
|
||
.notfreq
|
||
cmp.l #AHIDB_Index,d0
|
||
bne.s .notindex
|
||
lea tag_frequencies(pc),a0
|
||
moveq #0,d2
|
||
.freqnext
|
||
tst.l (a0)
|
||
beq.s .freqexit
|
||
cmp.l (a0)+,d1
|
||
bls.s .exit
|
||
addq.l #1,d2
|
||
bra.s .freqnext
|
||
.freqexit
|
||
moveq #FREQUENCIES-1,d2
|
||
bra.s .exit
|
||
.notindex
|
||
lea GetAttrTags(pc),a0
|
||
.next
|
||
tst.l (a0)
|
||
beq.s .exit
|
||
cmp.l (a0),d0
|
||
addq.l #4+4,a0
|
||
bne.s .next
|
||
move.l -4(a0),d2
|
||
.exit
|
||
move.l d2,d0
|
||
|
||
IFD DEBUG=1
|
||
bsr debugreturn
|
||
ENDC
|
||
|
||
move.l (sp)+,d2
|
||
rts
|
||
|
||
tag_frequencies
|
||
dc.l 4410 ; CD/10
|
||
dc.l 4800 ; DAT/10
|
||
dc.l 5513 ; CD/8
|
||
dc.l 6000 ; DAT/8
|
||
dc.l 7350 ; CD/6
|
||
dc.l 8000 ; <20>- and A-Law, DAT/6
|
||
dc.l 9600 ; DAT/5
|
||
dc.l 11025 ; CD/4
|
||
dc.l 12000 ; DAT/4
|
||
dc.l 14700 ; CD/3
|
||
dc.l 16000 ; DAT/3
|
||
dc.l 17640 ; CD/2.5
|
||
dc.l 18900
|
||
dc.l 19200 ; DAT/2.5
|
||
dc.l 22050 ; CD/2
|
||
dc.l 24000 ; DAT/2
|
||
dc.l 27429
|
||
dc.l 29400 ; CD/1.5
|
||
dc.l 32000 ; DAT/1.5
|
||
dc.l 33075
|
||
dc.l 37800
|
||
dc.l 44100 ; CD
|
||
dc.l 48000 ; DAT
|
||
dc.l 56000
|
||
dc.l 96000
|
||
FREQUENCIES EQU (*-tag_frequencies)>>2
|
||
tag_frequencies_end
|
||
dc.l 0
|
||
|
||
GetAttrTags
|
||
dc.l AHIDB_Bits, 32
|
||
dc.l AHIDB_Frequencies, FREQUENCIES
|
||
dc.l AHIDB_MaxChannels, 8
|
||
dc.l AHIDB_Author, tag_author
|
||
dc.l AHIDB_Copyright, tag_copyright
|
||
dc.l AHIDB_Version, IDString
|
||
dc.l AHIDB_Record, 0
|
||
dc.l AHIDB_Outputs, 1
|
||
dc.l AHIDB_Output, tag_output
|
||
dc.l AHIDB_PingPong, 1
|
||
dc.l AHIDB_Realtime, 1
|
||
dc.l AHIDB_MinOutputVolume, 0
|
||
dc.l AHIDB_MaxOutputVolume, $10000
|
||
dc.l 0
|
||
|
||
tag_author
|
||
dc.b "Toni Wilen",0
|
||
tag_copyright
|
||
dc.b "<EFBFBD> 2020 Toni Wilen",0
|
||
tag_output
|
||
dc.b "UAE",0
|
||
even
|
||
|
||
IFD DEBUG=1
|
||
debug_hardwarecontrol
|
||
dc.b "HardwareControl(%x,%x,%p)\n",0
|
||
even
|
||
ENDC
|
||
|
||
; ULONG Attribute D0
|
||
; LONG Argument D1
|
||
; struct AHIAudioCtrlDrv* A2
|
||
|
||
AHIsub_HardwareControl
|
||
|
||
IFD DEBUG=1
|
||
lea DEBUG_ADDR,a0
|
||
move.l d0,(a0)
|
||
move.l d1,(a0)
|
||
move.l a2,(a0)
|
||
move.l #debug_hardwarecontrol,4(a0)
|
||
ENDC
|
||
|
||
move.l ahiac_DriverData(a2),a0
|
||
move.l p_Base(a0),a0
|
||
|
||
cmp.l #AHIC_MonitorVolume,d0
|
||
bne.s .dontsetmonvol
|
||
nop
|
||
bra.s .done
|
||
.dontsetmonvol
|
||
cmp.l #AHIC_MonitorVolume_Query,d0
|
||
bne.s .dontgetmonvol
|
||
moveq #1,d0
|
||
swap d0
|
||
bra.s .doneout
|
||
.dontgetmonvol
|
||
cmp.l #AHIC_OutputVolume,d0
|
||
bne.s .dontsetoutvol
|
||
lsr.l #1,d1
|
||
nop
|
||
bra.s .done
|
||
.dontsetoutvol
|
||
cmp.l #AHIC_OutputVolume_Query,d0
|
||
bne.s .dontgetoutvol
|
||
|
||
moveq #1,d0
|
||
swap d0
|
||
bra.s .doneout
|
||
.dontgetoutvol
|
||
cmp.l #AHIC_InputGain,d0
|
||
bne.s .dontsetinputgain
|
||
nop
|
||
bra.s .done
|
||
.dontsetinputgain
|
||
cmp.l #AHIC_InputGain_Query,d0
|
||
bne.s .dontgetinputgain
|
||
moveq #1,d0
|
||
swap d0
|
||
bra.s .doneout
|
||
.dontgetinputgain
|
||
cmp.l #AHIC_Input,d0
|
||
bne.s .dontsetinput
|
||
nop
|
||
bra.s .done
|
||
.dontsetinput
|
||
cmp.l #AHIC_Input_Query,d0
|
||
bne.b .dontgetinput
|
||
moveq #0,d0
|
||
bra.s .doneout
|
||
.dontgetinput
|
||
cmp.l #AHIC_Output,d0
|
||
bne.s .dontsetoutput
|
||
nop
|
||
bra.s .done
|
||
.dontsetoutput
|
||
cmp.l #AHIC_Output_Query,d0
|
||
bne.b .dontgetoutput
|
||
moveq #0,d0
|
||
bra.s .doneout
|
||
.dontgetoutput
|
||
moveq #0,d0
|
||
bra.s .doneout
|
||
.done
|
||
moveq #1,d0
|
||
.doneout
|
||
rts
|
||
|
||
; d0.w = channel
|
||
; a0 = AHIAudioCtrlDrv
|
||
callsoundfunc:
|
||
movem.l a2/a6,-(sp)
|
||
move.l a0,a2
|
||
move.l ahiac_SoundFunc(a2),d1
|
||
beq.s .nosoundfunc
|
||
move.l d1,a0
|
||
move.l ahiac_DriverData(a2),a1
|
||
move.l p_Channels(a1),a1
|
||
move.w d0,d1
|
||
mulu #channel_SIZEOF,d1
|
||
add.l d1,a1
|
||
add.w #ch_SndMsg,a1
|
||
move.w d0,(a1)
|
||
ext.l d0
|
||
move.l h_Entry(a0),a6
|
||
jsr (a6)
|
||
.nosoundfunc
|
||
movem.l (sp)+,a2/a6
|
||
rts
|
||
|
||
; a1 = UAESND
|
||
interrupt_code
|
||
move.l p_Base(a1),a0
|
||
move.l base_stream_intreq(a0),d0
|
||
beq.s .notours
|
||
|
||
movem.l d2-d7/a2-a4,-(sp)
|
||
move.l d0,d7
|
||
move.l a1,a5
|
||
move.l p_AudioCtrl(a5),a2
|
||
move.l ahiac_DriverData(a2),a3
|
||
lea STREAM_START(a0),a4
|
||
|
||
moveq #0,d6
|
||
.cont
|
||
btst d6,d7
|
||
beq.s .next
|
||
|
||
; read and clear interrupt status
|
||
move.b stream_intreq(a4),d2
|
||
bpl.s .next
|
||
btst #4,d2
|
||
beq.s .notimer
|
||
|
||
move.l p_ChannelInfo(a3),d0
|
||
beq.s .noci
|
||
move.l d0,a0
|
||
lea ahieci_Offset(a0),a1
|
||
move.w ahieci_Channels(a0),d0
|
||
subq.w #1,d0
|
||
bmi.s .noci
|
||
move.l p_Channels(a3),a6
|
||
move.l a4,a0
|
||
.loop
|
||
move.l set_length_original(a0),d1
|
||
sub.l set_length(a0),d1
|
||
move.l d1,(a1)+
|
||
add.w #STREAM_OFFSET,a0
|
||
dbf d0,.loop
|
||
|
||
move.l p_ChannelInfo(a3),a1
|
||
move.l ahieci_Func(a1),d0
|
||
beq.s .noci
|
||
move.l d0,a0
|
||
move.l h_Entry(a0),a6
|
||
jsr (a6)
|
||
.noci
|
||
|
||
; playerfunc
|
||
move.l ahiac_PlayerFunc(a2),d0
|
||
beq.s .noplayerfunc
|
||
move.l d0,a0
|
||
sub.l a1,a1
|
||
move.l h_Entry(a0),a6
|
||
jsr (a6)
|
||
.noplayerfunc
|
||
|
||
.notimer
|
||
|
||
; sample started interrupt?
|
||
btst #0,d2
|
||
beq.s .next
|
||
|
||
; soundfunc
|
||
move.w d6,d0
|
||
move.l a2,a0
|
||
bsr.w callsoundfunc
|
||
|
||
.next
|
||
add.w #STREAM_OFFSET,a4
|
||
addq.w #1,d6
|
||
cmp.w p_StreamCnt(a3),d6
|
||
bne.s .cont
|
||
|
||
movem.l (sp)+,d2-d7/a2-a4
|
||
moveq #0,d0
|
||
rts
|
||
.notours
|
||
moveq #1,d0
|
||
rts
|
||
|
||
initRoutine:
|
||
movem.l d1/a0/a1/a4/a5/a6,-(sp)
|
||
sub.l a4,a4
|
||
move.l d0,a5
|
||
move.l a6,ub_SysLib(a5)
|
||
move.l a0,ub_SegList(a5)
|
||
|
||
lea utilname(pc),a1
|
||
moveq #0,d0
|
||
call OpenLibrary
|
||
move.l d0,ub_UtilBase(a5)
|
||
beq.s .end
|
||
|
||
lea expname(pc),a1
|
||
moveq #0,d0
|
||
call OpenLibrary
|
||
tst.l d0
|
||
beq.s .end
|
||
move.l d0,a6
|
||
sub.l a0,a0
|
||
move.w #6502,d0
|
||
moveq #2,d1
|
||
jsr -$048(a6) ; FindConfigDev
|
||
move.l d0,ub_ConfigDev(a5)
|
||
move.l a6,a1
|
||
move.l ub_SysLib(a5),a6
|
||
call CloseLibrary
|
||
|
||
move.l ub_ConfigDev(a5),d0
|
||
beq.s .end
|
||
move.l d0,a0
|
||
move.l cd_BoardAddr(a0),ub_Base(a5)
|
||
|
||
move.l a5,a4
|
||
.end
|
||
move.l a4,d0
|
||
movem.l (sp)+,d1/a0/a1/a4/a5/a6
|
||
rts
|
||
|
||
Open:
|
||
addq.w #1,LIB_OPENCNT(a6)
|
||
bclr.b #LIBB_DELEXP,ub_Flags(a6)
|
||
move.l a6,d0
|
||
rts
|
||
|
||
Close:
|
||
moveq #0,d0
|
||
subq.w #1,LIB_OPENCNT(a6)
|
||
bne.b .exit
|
||
btst.b #LIBB_DELEXP,ub_Flags(a6)
|
||
beq.b .exit
|
||
bsr Expunge
|
||
.exit
|
||
rts
|
||
|
||
Expunge:
|
||
movem.l d1/d2/a0/a1/a5/a6,-(sp)
|
||
move.l a6,a5
|
||
move.l ub_SysLib(a5),a6
|
||
tst.w LIB_OPENCNT(a5)
|
||
beq.b .notopen
|
||
bset.b #LIBB_DELEXP,ub_Flags(a5)
|
||
moveq #0,d0
|
||
bra.b .Expunge_end
|
||
.notopen:
|
||
|
||
move.l a5,a1
|
||
call Remove
|
||
|
||
move.l ub_UtilBase(a5),d0
|
||
beq.s .noutil
|
||
move.l d0,a1
|
||
call CloseLibrary
|
||
.noutil
|
||
|
||
move.l ub_SegList(a5),d2
|
||
moveq #0,d0
|
||
move.l a5,a1
|
||
move.w LIB_NEGSIZE(a5),d0
|
||
sub.l d0,a1
|
||
add.w LIB_POSSIZE(a5),d0
|
||
call FreeMem
|
||
|
||
move.l d2,d0
|
||
.Expunge_end
|
||
movem.l (sp)+,d1/d2/a0/a1/a5/a6
|
||
rts
|
||
|
||
Null:
|
||
moveq #0,d0
|
||
rts
|
||
|
||
expname
|
||
dc.b "expansion.library",0
|
||
utilname
|
||
dc.b "utility.library",0
|
||
intname
|
||
dc.b "uaesnd_ahi",0
|
||
cnop 0,4
|
||
|
||
EndCode:
|