From c417cd0964521347c0d9bcabcad38430fa8b29eb Mon Sep 17 00:00:00 2001 From: Toni Wilen Date: Sat, 21 Aug 2021 20:14:18 +0300 Subject: [PATCH] Unfinished UAESND AHI driver added. --- uaesnd_ahi.s | 1322 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1322 insertions(+) create mode 100644 uaesnd_ahi.s diff --git a/uaesnd_ahi.s b/uaesnd_ahi.s new file mode 100644 index 00000000..545e5d74 --- /dev/null +++ b/uaesnd_ahi.s @@ -0,0 +1,1322 @@ + + ; 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 ; µ- 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 "© 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: -- 2.47.3