Check for SYS/GL during library init. Reason is that
[AROS.git] / workbench / devs / AHI / Drivers / Wavetools / wavetools_audio.a
blobc7ea60aec1432c5a34966c2d259d6b9f50811b2e
1 ; Modified to compile with snma
2 ; compile: snma wavetools_audio.s OBJ AHI/wavetools.audio
3 ; (have snma create executables)
5 ;*** ScR ***
7 ;*** NOTES ***
10 DMA_LENGTH EQU 2021
12 ;------------
13 ; incdir include:
15 include exec/types.i
16 include macros.i ; general macros
18 include exec/exec.i
19 include dos/dos.i
20 include dos/dostags.i
21 include utility/utility.i
22 include utility/hooks.i
24 ; Library Vector Offsets
25 include lvo/exec_lib.i
26 include lvo/dos_lib.i
27 include lvo/utility_lib.i
29 include devices/ahi.i
30 include libraries/ahi_sub.i
31 include devices/dad_audio.i
32 include lvo/ahi_sub_lib.i
34 ; * wtBase (private)
35 STRUCTURE wtBase,LIB_SIZE
36 UBYTE wtb_Flags
37 UBYTE wtb_Pad1
38 UWORD wtb_Pad2
39 APTR wtb_SysLib
40 ULONG wtb_SegList
41 APTR wtb_DosLib
42 APTR wtb_UtilLib
43 LABEL wtBase_SIZEOF
45 ; * wavetools (private) ahiac_DriverData points to this structure.
46 STRUCTURE wavetools,0
47 UBYTE wt_Flags
48 UBYTE wt_Pad1
49 BYTE wt_MasterSignal
50 BYTE wt_RecMasterSignal
51 BYTE wt_SlaveSignal
52 BYTE wt_RecSlaveSignal
53 UWORD wt_Pad2
54 APTR wt_MasterTask
55 APTR wt_RecMasterTask
56 APTR wt_SlaveTask
57 APTR wt_RecSlaveTask
58 APTR wt_dadport
59 APTR wt_recdadport
60 APTR wt_dadioreq
61 APTR wt_recdadioreq
62 ULONG wt_daddev
63 ULONG wt_recdaddev
64 APTR wt_RecBuffer
65 APTR wt_RecordMsg
66 APTR wt_DMAbuffer1
67 APTR wt_DMAbuffer2
68 LONG wt_InputVolume ; through put volume?
69 LONG wt_OutputVolume ; replay volume
70 LONG wt_InputGain
72 ULONG wt_DBflag
74 APTR wt_SoftInt
76 LABEL wt_SoftIntData
77 APTR wt_PlayerHook
78 ULONG wt_Reserved
79 APTR wt_AudioCtrlP
80 FPTR wt_PlayerEntry ;wt_PlayerHook->h_Entry
82 ULONG wt_LoopTimes
83 APTR wt_MixHook
84 APTR wt_Mixbuffer
85 APTR wt_AudioCtrlM
86 FPTR wt_MixEntry ;wt_MixHook->h_Entry
88 APTR wt_DMAbuffer ;current buffer
89 APTR wt_DMAlength ;length
91 LABEL wavetools_SIZEOF
93 Start:
94 moveq #-1,d0
95 rts
97 VERSION EQU 2
98 REVISION EQU 1
99 DATE MACRO
100 dc.b "15.02.97"
101 ENDM
102 VERS MACRO
103 dc.b "wavetools 2.11"
104 ENDM
105 VSTRING MACRO
106 VERS
107 dc.b " ("
108 DATE
109 dc.b ")",13,10,0
110 ENDM
111 VERSTAG MACRO
112 dc.b 0,"$VER: "
113 VERS
114 dc.b " ("
115 DATE
116 dc.b ")",0
117 ENDM
119 RomTag:
120 DC.W RTC_MATCHWORD
121 DC.L RomTag
122 DC.L EndCode
123 DC.B RTF_AUTOINIT
124 DC.B VERSION ;version
125 DC.B NT_LIBRARY
126 DC.B 0 ;pri
127 DC.L LibName
128 DC.L IDString
129 DC.L InitTable
131 LibName: dc.b "wavetools.audio",0
132 IDString: VSTRING
133 dosName: DOSNAME
134 utilName: UTILITYNAME
136 cnop 0,2
138 InitTable:
139 DC.L wtBase_SIZEOF
140 DC.L funcTable
141 DC.L dataTable
142 DC.L initRoutine
144 funcTable:
145 dc.l Open
146 dc.l Close
147 dc.l Expunge
148 dc.l Null
150 dc.l AHIsub_AllocAudio
151 dc.l AHIsub_FreeAudio
152 dc.l AHIsub_Disable
153 dc.l AHIsub_Enable
154 dc.l AHIsub_Start
155 dc.l AHIsub_Update
156 dc.l AHIsub_Stop
157 dc.l AHIsub_SetVol
158 dc.l AHIsub_SetFreq
159 dc.l AHIsub_SetSound
160 dc.l AHIsub_SetEffect
161 dc.l AHIsub_LoadSound
162 dc.l AHIsub_UnloadSound
163 dc.l AHIsub_GetAttr
164 dc.l AHIsub_HardwareControl
165 dc.l -1
167 dataTable:
168 INITBYTE LN_TYPE,NT_LIBRARY
169 INITLONG LN_NAME,LibName
170 INITBYTE LIB_FLAGS,LIBF_SUMUSED!LIBF_CHANGED
171 INITWORD LIB_VERSION,VERSION
172 INITWORD LIB_REVISION,REVISION
173 INITLONG LIB_IDSTRING,IDString
174 DC.L 0
176 initRoutine:
177 ;movem.l d1/a0/a1/a5/a6,-(sp)
178 mpush d1/a0/a1/a5/a6
179 move.l d0,a5
180 move.l a6,wtb_SysLib(a5)
181 move.l a0,wtb_SegList(a5)
182 lea dosName(pc),a1
183 moveq #37,d0
184 call OpenLibrary
185 move.l d0,wtb_DosLib(a5)
186 bne.b .dosOK
187 ALERT AG_OpenLib!AO_DOSLib
188 moveq #0,d0
189 bra.b .exit
190 .dosOK
191 lea utilName(pc),a1
192 moveq #37,d0
193 call OpenLibrary
194 move.l d0,wtb_UtilLib(a5)
195 bne.b .utilOK
196 ALERT AG_OpenLib!AO_UtilityLib
197 moveq #0,d0
198 bra.b .exit
199 .utilOK
200 move.l a5,d0
201 .exit
202 ;movem.l (sp)+,d1/a0/a1/a5/a6
203 mpop d1/a0/a1/a5/a6
206 Open:
207 addq.w #1,LIB_OPENCNT(a6)
208 bclr.b #LIBB_DELEXP,wtb_Flags(a6)
209 move.l a6,d0
212 Close:
213 moveq #0,d0
214 subq.w #1,LIB_OPENCNT(a6)
215 bne.b .exit
216 btst.b #LIBB_DELEXP,wtb_Flags(a6)
217 beq.b .exit
218 bsr.b Expunge
219 .exit
222 Expunge:
223 ;movem.l d1/d2/a0/a1/a5/a6,-(sp)
224 mpush d1/d2/a0/a1/a5/a6
225 move.l a6,a5
226 move.l wtb_SysLib(a5),a6
227 tst.w LIB_OPENCNT(a5)
228 beq.b .notopen
229 bset.b #LIBB_DELEXP,wtb_Flags(a5)
230 moveq #0,d0
231 bra.b .Expunge_end
232 .notopen
233 move.l wtb_DosLib(a5),a1
234 call CloseLibrary
235 move.l wtb_UtilLib(a5),a1
236 call CloseLibrary
238 move.l wtb_SegList(a5),d2
239 move.l a5,a1
240 call Remove
242 moveq #0,d0
243 move.l a5,a1
244 move.w LIB_NEGSIZE(a5),d0
245 sub.l d0,a1
246 add.w LIB_POSSIZE(a5),d0
247 call FreeMem
248 move.l d2,d0
249 .Expunge_end
250 ;movem.l (sp)+,d1/d2/a0/a1/a5/a6
251 ;mpop
252 mpop d1/d2/a0/a1/a5/a6
255 Null:
256 moveq #0,d0
259 ;* result = AHIsub_AllocAudio( tagList, AudioCtrl );
260 ;* D0 A1 A2
262 AHIsub_AllocAudio:
263 mpush d2-d7/a2-a6
264 move.l a6,a5
265 move.l wtb_SysLib(a5),a6
267 move.l #wavetools_SIZEOF,d0
268 move.l #MEMF_PUBLIC|MEMF_CLEAR,d1
269 call AllocVec
270 move.l d0,ahiac_DriverData(a2)
271 beq.w .error_nowavetools
272 move.l d0,a3
274 ;* try allocate dad_audio.device
275 moveq #0,d2
276 moveq #0,d3
277 moveq #-1,d4
278 call CreateMsgPort
279 move.l d0,d2
280 beq.b .err2
281 move.l d0,a0
282 moveq #IOSTD_SIZE,d0
283 call CreateIORequest
284 move.l d0,d3
285 beq.b .err1
286 lea dadname(pc),a0
287 moveq #0,d0
288 move.l d3,a1
289 moveq #0,d1
290 call OpenDevice
291 move.l d0,d4
292 move.l d3,a1
293 call CloseDevice
294 move.l d3,a0
295 call DeleteIORequest
296 .err1
297 move.l d2,a0
298 call DeleteMsgPort
299 .err2
300 tst.l d4
301 bne.w .error_nodevice
303 move.l #-1,wt_daddev(a3)
304 move.b #-1,wt_MasterSignal(a3)
305 move.b #-1,wt_SlaveSignal(a3)
306 move.l a2,wt_AudioCtrlP(a3) ;player Hook
307 move.l a2,wt_AudioCtrlM(a3) ;mixer Hook
309 ;* find closest frequency
310 move.l ahiac_MixFreq(a2),d0
311 bsr findfreq
312 move.l d0,ahiac_MixFreq(a2) ;store actual freq
314 moveq #IS_SIZE,d0
315 move.l #MEMF_PUBLIC!MEMF_CLEAR,d1
316 call AllocVec
317 move.l d0,wt_SoftInt(a3)
318 beq.b .error_nointmem
320 move.l d0,a0
321 move.b #NT_INTERRUPT,LN_TYPE(a0)
322 lea LibName(pc),a1
323 move.l a1,LN_NAME(a0)
324 lea SoftInt_Dummy(pc),a1
325 move.l a1,IS_CODE(a0)
326 lea wt_SoftIntData(a3),a1
327 move.l a1,IS_DATA(a0)
329 ;* Set default output volume
330 move.l #$10000,wt_OutputVolume(a3)
332 moveq #AHISF_CANRECORD|AHISF_KNOWSTEREO|AHISF_MIXING|AHISF_TIMING,d0
333 .exit
334 ;mpop
335 mpop d2-d7/a2-a6
337 .error_nointmem
338 .error_nodevice
339 .error_nowavetools
340 moveq #AHISF_ERROR,d0
341 bra.b .exit
343 ;in:
344 ;* d0 Frequency
345 ;out:
346 ;* d0 New frequency
347 findfreq:
348 lea freqlist(pc),a0
349 cmp.l (a0),d0
350 bhi.b .findfreq
351 move.l (a0),d0
352 bra.b .2
353 .findfreq
354 cmp.l (a0)+,d0
355 bhi.b .findfreq
356 move.l -4(a0),d1
357 sub.l d0,d1
358 sub.l -8(a0),d0
359 cmp.l d1,d0
360 bhs.b .1
361 move.l -8(a0),d0
362 bra.b .2
364 move.l -4(a0),d0
368 freqlist:
369 dc.l DADFREQ_17640
370 dc.l DADFREQ_19200
371 dc.l DADFREQ_22050
372 dc.l DADFREQ_24000
373 dc.l DADFREQ_29400
374 dc.l DADFREQ_32000
375 dc.l DADFREQ_44100
376 dc.l DADFREQ_48000
377 dc.l -1
379 ;* AHIsub_FreeAudio( AudioCtrl );
380 ;* A2
382 AHIsub_FreeAudio:
383 mpush d2-d7/a2-a6
385 move.l a6,a5
386 move.l wtb_SysLib(a5),a6
388 move.l ahiac_DriverData(a2),d0
389 beq.b .nodriverdata
390 move.l d0,a3
392 move.l wt_SoftInt(a3),a1
393 clr.l wt_SoftInt(a3)
394 call FreeVec
396 move.l ahiac_DriverData(a2),a1
397 clr.l ahiac_DriverData(a2)
398 call FreeVec
399 .nodriverdata
400 moveq #0,d0
401 mpop d2-d7/a2-a6
402 ;mpop
406 ;* AHIsub_Disable( AudioCtrl );
407 ;* A2
409 AHIsub_Disable:
410 mpush a5/a6
411 move.l a6,a5
412 move.l wtb_SysLib(a5),a6
413 call Forbid ; Lame, but it works.
414 mpop a5/a6
417 ;* AHIsub_Enable( AudioCtrl );
418 ;* A2
420 AHIsub_Enable:
421 mpush a5/a6
422 move.l a6,a5
423 move.l wtb_SysLib(a5),a6
424 call Permit ; Lame, but it works.
425 mpop a5/a6
428 ;* error = AHIsub_Start( Flags, AudioCtrl );
429 ;* D0 D0 A2
431 AHIsub_Start:
432 mpush d2-d7/a2-a6
434 move.l a6,a5
435 move.l wtb_SysLib(a5),a6
436 move.l ahiac_DriverData(a2),a3
438 move.l d0,d7
439 btst #AHISB_PLAY,d7
440 beq.b .noplay
442 exg.l a5,a6
443 moveq #AHISF_PLAY,d0
444 call AHIsub_Stop
445 call AHIsub_Update ;fill variables
446 exg.l a5,a6
448 move.l ahiac_BuffSize(a2),d0
449 move.l #MEMF_PUBLIC|MEMF_CLEAR,d1
450 call AllocVec
451 move.l d0,wt_Mixbuffer(a3)
452 beq.b .error_nomixmem
454 move.l ahiac_MaxBuffSamples(a2),d0
455 lsl.l #2,d0 ;16bit+Stereo
456 move.l d0,d2
457 move.l #MEMF_24BITDMA!MEMF_PUBLIC|MEMF_CLEAR,d1
458 call AllocVec
459 move.l d0,wt_DMAbuffer1(a3)
460 beq.b .error_nodmamem
462 move.l d2,d0
463 move.l #MEMF_24BITDMA!MEMF_PUBLIC|MEMF_CLEAR,d1
464 call AllocVec
465 move.l d0,wt_DMAbuffer2(a3)
466 beq.b .error_nodmamem
468 bsr.b PlayStart
469 tst.l d0
470 bne.b .error
472 .noplay
473 btst #AHISB_RECORD,d7
474 beq.b .norecord
475 moveq #AHISF_PLAY,d0
477 exg.l a5,a6
478 moveq #AHISF_PLAY|AHISF_RECORD,d0
479 call AHIsub_Stop
480 exg.l a5,a6
482 bsr.w RecStart
483 tst.l d0
484 bne.b .error
486 .norecord
487 moveq #AHIE_OK,d0
488 .exit
489 mpop d2-d7/a2-a6
490 ;mpop
492 .error_nodmamem
493 .error_nomixmem
494 moveq #AHIE_NOMEM,d0
495 .error
496 bra.b .exit
498 PlayStart:
499 ;* create audio playback process
500 moveq #-1,d0
501 call AllocSignal
502 move.b d0,wt_MasterSignal(a3)
503 cmp.b #-1,d0
504 beq.w .error_nosignal
505 suba.l a1,a1
506 call FindTask
507 move.l d0,wt_MasterTask(a3)
509 ;* This is just a trick to make it possible to send the slave an argument.
510 moveq #.size,d0
511 move.l #MEMF_PUBLIC|MEMF_CLEAR,d1
512 call AllocVec
513 tst.l d0
514 beq.b .error_noaudioproc
515 move.l d0,a1
517 lea .kicker(pc),a0
518 moveq #.size-1,d1
519 .copykicker
520 move.b (a0)+,(a1)+
521 dbf d1,.copykicker
523 move.l d0,a1
524 move.l a2,.audioctrl(a1)
525 lea .codestart(a1),a0
526 move.l a0,.entry(a1)
528 move.l wt_SoftInt(a3),a0
529 move.l ahiac_Flags(a2),d0
530 and.l #AHIACF_STEREO,d0
531 beq.b .mono
532 move.l #SoftInt_Stereo,IS_CODE(a0)
533 bra.b .1
534 .mono
535 move.l #SoftInt_Mono,IS_CODE(a0)
538 mpush a1
539 call CacheClearU
540 mpop a1
542 move.l wtb_DosLib(a5),a6
543 move.l a1,d1
544 call CreateNewProc
545 move.l d0,wt_SlaveTask(a3)
546 beq.b .error_noaudioproc
548 ; Wait for slave to allocate and store a signal (or die if error).
549 move.l wtb_SysLib(a5),a6
550 moveq #0,d0
551 move.b wt_MasterSignal(a3),d1
552 bset d1,d0
553 call Wait
554 moveq #AHIE_OK,d0
556 .error_noaudioproc
557 .error_nolocalvar
558 .error_nosignal
559 moveq #AHIE_NOMEM,d0
562 .kicker:
563 dc.l NP_Entry
564 .entry EQU *-.kicker
565 dc.l Dummy
566 dc.l NP_Priority,127
567 dc.l NP_Name,LibName
568 dc.l TAG_DONE
570 .codestart EQU *-.kicker
571 lea .kicker(pc),a1 ;a1 points to allocated kicker
572 .audioctrl EQU *+2-.kicker
573 ;lea Dummy,a2 ;a2 points to current AudioCtrl structure
574 dc.w $45F9 ; ADDED: opcode(LEA xxx,a2)
575 dc.l Dummy
576 ;jmp audioproc_play ; ADDED: (PC) on lea Dummy... and jmp audio...
577 dc.w $4EF9 ; ADDED: opcode(jmp)
578 dc.l audioproc_play ; absolute
579 .size EQU *-.kicker
581 RecStart:
582 ;* create audio record process
583 moveq #-1,d0
584 call AllocSignal
585 move.b d0,wt_RecMasterSignal(a3)
586 cmp.b #-1,d0
587 beq.b .error_nosignal
588 suba.l a1,a1
589 call FindTask
590 move.l d0,wt_RecMasterTask(a3)
592 ;* This is just a trick to make it possible to send the slave an argument.
593 moveq #.size,d0
594 move.l #MEMF_PUBLIC|MEMF_CLEAR,d1
595 call AllocVec
596 tst.l d0
597 beq.b .error_noaudioproc
598 move.l d0,a1
600 lea .kicker(pc),a0
601 moveq #.size-1,d1
602 .copykicker
603 move.b (a0)+,(a1)+
604 dbf d1,.copykicker
606 move.l d0,a1
607 move.l a2,.audioctrl(a1)
608 lea .codestart(a1),a0
609 move.l a0,.entry(a1)
611 mpush a1
612 call CacheClearU
613 mpop a1
615 move.l wtb_DosLib(a5),a6
616 move.l a1,d1
617 call CreateNewProc
618 move.l d0,wt_RecSlaveTask(a3)
619 beq.b .error_noaudioproc
621 ; Wait for slave to allocate and store a signal (or die if error).
622 move.l wtb_SysLib(a5),a6
623 moveq #0,d0
624 move.b wt_RecMasterSignal(a3),d1
625 bset d1,d0
626 call Wait
627 moveq #AHIE_OK,d0
629 .error_noaudioproc
630 .error_nolocalvar
631 .error_nosignal
632 moveq #AHIE_NOMEM,d0
635 ;*** 'kicker'
636 .kicker:
637 dc.l NP_Entry
638 .entry EQU *-.kicker
639 dc.l Dummy
640 dc.l NP_Priority,127
641 dc.l NP_Name,LibName
642 dc.l TAG_DONE
644 .codestart EQU *-.kicker
645 lea .kicker(pc),a1 ;a1 points to allocated kicker
646 .audioctrl EQU *+2-.kicker
647 ;lea Dummy(PC),a2 ;a2 points to current AudioCtrl structure
648 dc.w $45F9 ; ADDED: opcode(LEA xx,a2)
649 dc.l Dummy ;
650 dc.w $4EF9 ; ADDED: opcode(jmp)
651 dc.l audioproc_record ; absolute
652 ;jmp audioproc_record
653 .size EQU *-.kicker
656 Dummy:
659 ;* AHIsub_Update( flags, audioctrl );
660 ;* D0 A2
662 AHIsub_Update:
663 mpush d2-d7/a2-a6
665 call AHIsub_Disable ;make sure we don't get an interrupt
666 ;while updating our local variables
667 move.l ahiac_DriverData(a2),a3
669 move.l ahiac_PlayerFunc(a2),a0
670 move.l a0,wt_PlayerHook(a3)
671 move.l h_Entry(a0),wt_PlayerEntry(a3)
673 move.l ahiac_BuffSamples(a2),d0
674 move.l d0,wt_LoopTimes(a3) ;See audioproc.
675 lsl.l #2,d0
676 move.l d0,wt_DMAlength(a3)
678 move.l ahiac_MixerFunc(a2),a0
679 move.l a0,wt_MixHook(a3)
680 move.l h_Entry(a0),wt_MixEntry(a3)
682 call AHIsub_Enable
683 moveq #0,d0
684 mpop d2-d7/a2-a6
685 ;mpop
689 ;* AHIsub_Stop(Flags, AudioCtrl );
690 ;* D0 A2
692 AHIsub_Stop:
693 mpush d2-d7/a2-a6
695 move.l a6,a5
696 move.l wtb_SysLib(a5),a6
697 move.l ahiac_DriverData(a2),a3
699 move.l d0,d7 ;save flags
700 btst #AHISB_PLAY,d7
701 beq.b .noplaystop
703 ; Signal slave to quit
704 move.l wt_SlaveTask(a3),d0
705 beq.b .noslave
706 move.l d0,a1
707 moveq #0,d0
708 move.b wt_SlaveSignal(a3),d1
709 bset d1,d0
710 call Signal
711 ; Wait for slave to die
712 moveq #0,d0
713 move.b wt_MasterSignal(a3),d1
714 bset d1,d0
715 call Wait
716 .noslave
717 moveq #0,d0
718 move.b wt_MasterSignal(a3),d0 ;-1 is ok
719 move.b #-1,wt_MasterSignal(a3)
720 call FreeSignal
722 move.l wt_DMAbuffer1(a3),d0
723 beq.b .nodmamem1
724 move.l d0,a1
725 call FreeVec
726 clr.l wt_DMAbuffer1(a3)
727 .nodmamem1
728 move.l wt_DMAbuffer2(a3),d0
729 beq.b .nodmamem2
730 move.l d0,a1
731 call FreeVec
732 clr.l wt_DMAbuffer2(a3)
733 .nodmamem2
734 move.l wt_Mixbuffer(a3),d0
735 beq.b .nomixmem
736 move.l d0,a1
737 call FreeVec
738 clr.l wt_Mixbuffer(a3)
739 .nomixmem
741 .noplaystop
742 btst #AHISB_RECORD,d7
743 beq.b .norecstop
745 ; Signal record slave to quit
746 move.l wt_RecSlaveTask(a3),d0
747 beq.b .norecslave
748 move.l d0,a1
749 moveq #0,d0
750 move.b wt_RecSlaveSignal(a3),d1
751 bset d1,d0
752 call Signal
753 ; Wait for record slave to die
754 moveq #0,d0
755 move.b wt_RecMasterSignal(a3),d1
756 bset d1,d0
757 call Wait
758 .norecslave
759 moveq #0,d0
760 move.b wt_RecMasterSignal(a3),d0 ;-1 is ok
761 move.b #-1,wt_RecMasterSignal(a3)
762 call FreeSignal
763 .norecstop
764 moveq #0,d0
765 mpop d2-d7/a2-a6
766 ;mpop
769 AHIsub_SetVol:
770 AHIsub_SetFreq:
771 AHIsub_SetSound:
772 AHIsub_SetEffect:
773 AHIsub_LoadSound:
774 AHIsub_UnloadSound:
775 moveq #AHIS_UNKNOWN,d0
778 ;in:
779 ;* d1 wt_OutputVolume
780 ;* a2 audioctrl
781 ;out:
782 ;* d0 Wavetools outout damp value
783 volume2damp:
784 ;* translate linear to wavetools output damp value
786 moveq #DADCONST_MAXDAMP,d0 ;DADCONST_MAXDAMP
787 lea .volumelist(pc),a0
788 .loop
789 cmp.l (a0)+,d1
790 bls.b .exit
791 subq.l #1,d0
792 bpl.b .loop
793 .exit
794 and.l #DADCONST_MAXDAMP,d0 ;just security
797 ; 32 values
798 .volumelist
799 dc.l 1,2,3,4,6,8,12,16,23,33,46,66,93,131,185,261,369,521,735,1039
800 dc.l 1467,2072,2927,4135,5841,8250,11654,16462,23253,32846,46396
801 dc.l 65536
805 ;lineargain2decibel:
806 ; translate linear gain to wavetools gain
807 ; in:
808 ; d1 wt_InputGain
809 ; out:
810 ; d0 Wavetools input Gain Value
812 ; moveq #0,d0 ; no gain
813 ; lea .gainlist(pc),a0
814 ;.loop
815 ; cmp.l (a0)+,d1
816 ; bls.b .exit ; use the larger value
817 ; add.l #1,d0 ; increase gain
818 ; bpl.b .loop
819 ;.exit
820 ; and.l #DADCONST_MAXGAIN,d0 ;just security
821 ; rts
822 ; Just made the database half size
823 ; 16 values
824 .gainlist
825 dc.l 1,3,8,16,33,66,131,261,521,1039
826 dc.l 2072,4135,8250,16462,32846
827 dc.l 65536
830 lineargain2decibel:
831 ; 15 Feb 1997 bugfix
832 ; translate linear gain to wavetools gain
833 ; in:
834 ; d1 wt_InputGain
835 ; out:
836 ; d0 Wavetools input Gain Value
837 ; method:
838 ; search list for a value larger than the suggested value
839 ; start search with lowest possible value ($10000)
841 moveq #0,d0 ; start with no gain
842 lea .posboundaries(pc),a0 ;
843 .loop
844 cmp.l (a0)+,d1
845 ble.b .exit ; use the larger/equal value
846 add.l #1,d0 ; increase gain
847 cmp.l #15,d0 ; max value is 15
848 bls.b .loop ; jump if less than 15
849 .exit
850 and.l #DADCONST_MAXGAIN,d0 ;just security
853 ;From toccata drivern 15 Feb 1997, 16 values
854 .posboundaries
855 dc.l 65536,77889,92572,110022,130761,155410,184705,219522,260903
856 dc.l 310084,368536,438005,520570,618699,735326,873936
860 ;* AHIsub_GetAttr( attribute, argument, default, taglist, audioctrl );
861 ;* D0 D0 D1 D2 A1 a2
863 AHIsub_GetAttr:
864 cmp.l #AHIDB_Bits,d0
865 bne.b .not_bits
866 moveq #16,d0
867 bra.w .exit
868 .not_bits
869 cmp.l #AHIDB_Frequencies,d0
870 bne.b .not_freqs
871 moveq #8,d0
872 bra.w .exit
873 .not_freqs
874 cmp.l #AHIDB_Frequency,d0
875 bne.b .not_freq
876 add.l d1,d1
877 add.l d1,d1
878 lea freqlist(pc),a0
879 move.l (a0,d1.l),d0
880 bra.w .exit
881 .not_freq
882 cmp.l #AHIDB_Index,d0
883 bne.b .not_index
884 move.l d1,d0
885 bsr.w findfreq
886 move.l d0,d1
887 moveq #0,d0
888 lea freqlist(pc),a0
889 .index_loop
890 cmp.l (a0)+,d1
891 beq.w .exit
892 addq.l #1,d0
893 bra.b .index_loop
894 .not_index
895 cmp.l #AHIDB_Author,d0
896 bne.b .not_author
897 lea .author(pc),a0
898 move.l a0,d0
899 bra.w .exit
900 .not_author
901 cmp.l #AHIDB_Copyright,d0
902 bne.b .not_copyright
903 lea .copyright(pc),a0
904 move.l a0,d0
905 bra.w .exit
906 .not_copyright
907 cmp.l #AHIDB_Version,d0
908 bne.b .not_version
909 lea IDString(pc),a0
910 move.l a0,d0
911 bra.w .exit
912 .not_version
913 cmp.l #AHIDB_MaxRecordSamples,d0
914 bne.b .not_maxrecsamples
915 move.l #DMA_LENGTH,d0
916 bra.w .exit
917 .not_maxrecsamples
918 cmp.l #AHIDB_Realtime,d0
919 bne.b .not_realtime
920 moveq #TRUE,d0
921 bra.w .exit
922 .not_realtime
923 cmp.l #AHIDB_Record,d0
924 bne.b .not_record
925 moveq #TRUE,d0
926 bra.w .exit
927 .not_record
928 cmp.l #AHIDB_FullDuplex,d0
929 bne.b .not_fullduplex
930 moveq #FALSE,d0
931 bra.w .exit
932 .not_fullduplex
933 cmp.l #AHIDB_Inputs,d0
934 bne.b .not_inputs
935 moveq #1,d0
936 bra.w .exit
937 .not_inputs
938 cmp.l #AHIDB_Input,d0
939 bne.b .not_input
940 lea .line(pc),a0 ;only one source
941 move.l a0,d0
942 bra.w .exit
943 .not_input
944 cmp.l #AHIDB_Outputs,d0
945 bne.b .not_outputs
946 moveq #1,d0
947 bra.w .exit
948 .not_outputs
949 cmp.l #AHIDB_Output,d0
950 bne.b .not_output
951 lea .line(pc),a0 ;only one destination
952 move.l a0,d0
953 bra.w .exit
954 .not_output
955 cmp.l #AHIDB_MinMonitorVolume,d0
956 bne.b .not_minmonvol
957 moveq #0,d0
958 bra.w .exit
959 .not_minmonvol
960 cmp.l #AHIDB_MaxMonitorVolume,d0
961 bne.b .not_maxmonvol
962 move.l #$10000,d0
963 bra.b .exit
964 .not_maxmonvol
965 cmp.l #AHIDB_MinOutputVolume,d0
966 bne.b .not_minoutvol
967 moveq #0,d0
968 bra.b .exit
969 .not_minoutvol
970 cmp.l #AHIDB_MaxOutputVolume,d0
971 bne.b .not_maxoutvol
972 move.l #$10000,d0
973 bra.b .exit
974 .not_maxoutvol
975 cmp.l #AHIDB_MaxInputGain,d0 ;NEW 06 Jan 1997
976 bne.b .not_maxgain ;BUGFIX 15 Feb 1997
977 move.l #$000d55d0,d0 ; 13.335<<16 == +22.5 dB
978 bra.b .exit
979 .not_maxgain
980 cmp.l #AHIDB_MinInputGain,d0 ;NEW 06 Jan 1997
981 bne.b .not_mingain
982 move.l #$10000,d0 ;NEW 15 Feb 1997
983 bra.b .exit
984 .not_mingain
986 ;* Unknown attribute, return default.
987 move.l d2,d0
988 .exit
990 .author
991 dc.b "Martin 'Leviticus' Blom",0
992 .copyright
993 dc.b "Public Domain",0
994 .line
995 dc.b "Line",0
996 even
999 ;* AHIsub_HardwareControl( attribute, argument, audioctrl );
1000 ;* D0 D0 D1 A2
1002 AHIsub_HardwareControl:
1003 cmp.l #AHIC_MonitorVolume,d0
1004 bne.b .dontsetmonvol
1005 move.l ahiac_DriverData(a2),a1
1006 move.l d1,wt_InputVolume(a1)
1007 bra.b .exit
1008 .dontsetmonvol
1009 cmp.l #AHIC_MonitorVolume_Query,d0
1010 bne.b .dontgetmonvol
1011 move.l ahiac_DriverData(a2),a1
1012 move.l wt_InputVolume(a1),d0
1013 bra.b .quit
1014 .dontgetmonvol
1015 cmp.l #AHIC_OutputVolume,d0
1016 bne.b .dontsetvol
1017 move.l ahiac_DriverData(a2),a1
1018 move.l d1,wt_OutputVolume(a1)
1019 bra.b .exit
1020 .dontsetvol
1021 cmp.l #AHIC_OutputVolume_Query,d0
1022 bne.b .dontgetvol
1023 move.l ahiac_DriverData(a2),a1
1024 move.l wt_OutputVolume(a1),d0
1025 bra.b .quit
1026 .dontgetvol
1027 cmp.l #AHIC_InputGain,d0
1028 bne.b .dontsetgain
1029 move.l ahiac_DriverData(a2),a1
1030 move.l d1,wt_InputGain(a1)
1031 bra.b .exit
1032 .dontsetgain ;NEW
1033 cmp.l #AHIC_InputGain_Query,d0
1034 bne.b .dontgetgain
1035 move.l ahiac_DriverData(a2),a1
1036 move.l wt_InputGain(a1),d0
1037 bra.b .quit
1038 .dontgetgain
1039 moveq #FALSE,d0
1040 .quit
1042 .exit
1043 moveq #TRUE,d0
1045 ;*****************************************************************************
1047 ;in:
1048 ;* a1 ptr to 'kicker'
1049 ;* a2 AudioCtrl
1050 audioproc_play:
1051 move.l ahiac_DriverData(a2),a5
1052 move.l 4.w,a6
1053 call FreeVec
1055 moveq #-1,d0
1056 call AllocSignal
1057 move.b d0,wt_SlaveSignal(a5)
1058 cmp.b #-1,d0
1059 beq.w .error_nosignal
1061 ;* allocate dad_audio.device
1062 call CreateMsgPort
1063 move.l d0,wt_dadport(a5)
1064 beq.w .error_noport
1065 move.l d0,a0
1066 moveq #IOSTD_SIZE,d0
1068 call CreateIORequest
1069 move.l d0,wt_dadioreq(a5)
1070 beq.w .error_noioreq
1072 lea dadname(pc),a0
1073 moveq #0,d0
1074 move.l wt_dadioreq(a5),a1
1075 moveq #0,d1
1076 call OpenDevice
1077 move.l d0,wt_daddev(a5)
1078 bne.w .error_nodaddev
1080 ;* initialize the board
1081 move.l wt_dadioreq(a5),a1
1082 move.l #DADF_SETFLAG|DADF_INIT,IO_DATA(a1)
1083 clr.l IO_LENGTH(a1)
1084 clr.l IO_OFFSET(a1)
1085 move.w #DADCMD_INIT2,IO_COMMAND(a1)
1086 call DoIO
1088 move.l wt_dadioreq(a5),a1
1089 move.l ahiac_MixFreq(a2),IO_DATA(a1)
1090 clr.l IO_LENGTH(a1)
1091 clr.l IO_OFFSET(a1)
1092 move.w #DADCMD_REPLAYFREQ,IO_COMMAND(a1)
1093 call DoIO
1095 move.l wt_MasterTask(a5),a1
1096 moveq #0,d0
1097 move.b wt_MasterSignal(a5),d1
1098 bset d1,d0
1099 call Signal ;Tell master we're alive and kicking!
1101 .again
1102 ;*** Set Volume
1103 move.l wt_OutputVolume(a5),d1 ;default is $10000 (see alloc function)
1104 bsr.w volume2damp
1105 move.l wt_dadioreq(a5),a1
1106 move.l d0,IO_DATA(a1)
1107 clr.l IO_LENGTH(a1)
1108 clr.l IO_OFFSET(a1)
1109 move.w #DADCMD_OUTPUTDAMP,IO_COMMAND(a1)
1110 call DoIO
1112 not.l wt_DBflag(a5)
1113 beq.b .1
1114 move.l wt_DMAbuffer1(a5),wt_DMAbuffer(a5)
1115 bra.b .2
1117 move.l wt_DMAbuffer2(a5),wt_DMAbuffer(a5)
1120 move.l wt_SoftInt(a5),a1
1121 call Cause
1123 move.l wt_dadioreq(a5),a1
1124 call WaitIO
1126 moveq #0,d0
1127 moveq #0,d1
1128 call SetSignal
1129 move.b wt_SlaveSignal(a5),d1
1130 btst d1,d0
1131 bne.b .quit
1133 move.l wt_dadioreq(a5),a1
1134 move.l wt_DMAbuffer(a5),IO_DATA(a1)
1135 move.l wt_DMAlength(a5),IO_LENGTH(a1)
1136 clr.l IO_OFFSET(a1)
1137 move.w #CMD_WRITE,IO_COMMAND(a1)
1138 call DoIO ; changed SendIO to DoIO
1139 bra.b .again
1140 .quit
1141 .error_noport
1142 .error_noioreq
1143 .error_nodaddev
1144 .error_nosignal
1145 clr.l wt_SlaveTask(a5)
1146 moveq #0,d0
1147 move.b wt_SlaveSignal(a5),d0 ;-1 is ok
1148 move.b #-1,wt_SlaveSignal(a5)
1149 call FreeSignal
1151 tst.l wt_daddev(a5)
1152 bne.b .nodaddev
1154 move.l wt_dadioreq(a5),a1
1155 move.l #DADCONST_MAXDAMP,IO_DATA(a1) ;zero volume
1156 clr.l IO_LENGTH(a1)
1157 clr.l IO_OFFSET(a1)
1158 move.w #DADCMD_OUTPUTDAMP,IO_COMMAND(a1)
1159 call DoIO
1161 move.l wt_dadioreq(a5),a1
1162 move.l #-1,wt_daddev(a5)
1163 call CloseDevice
1164 .nodaddev
1165 move.l wt_dadioreq(a5),a0
1166 clr.l wt_dadioreq(a5)
1167 call DeleteIORequest
1168 .noaudioreq
1169 move.l wt_dadport(a5),a0
1170 clr.l wt_dadport(a5)
1171 call DeleteMsgPort
1172 .noaudioport
1173 move.l wt_MasterTask(a5),a1
1174 moveq #0,d0
1175 move.b wt_MasterSignal(a5),d1
1176 bset d1,d0
1177 call Signal
1181 SoftInt_Dummy:
1184 * d0 scratch
1185 * d1 scratch
1186 * a0 scratch
1187 * a1 wt_SoftIntData
1188 * a5 scratch
1189 SoftInt_Mono:
1190 mpush a2/a3
1191 move.l a1,a5
1192 movem.l (a5)+,a0/a1/a2/a3
1193 jsr (a3) ;call Player Hook
1194 movem.l (a5),d0/a0/a1/a2/a3/a5
1195 jsr (a3) ;call Mixer Hook
1197 ;* transfer buffer (unrolled)
1198 lsr.w #1,d0
1199 bcs.b .3
1200 subq.w #1,d0
1201 .loop
1202 move.w (a1),(a5)+
1203 move.w (a1)+,(a5)+
1205 move.w (a1),(a5)+
1206 move.w (a1)+,(a5)+
1207 dbf d0,.loop
1208 mpop a2/a3
1211 ;* d0 scratch
1212 ;* d1 scratch
1213 ;* a0 scratch
1214 ;* a1 wt_SoftIntData
1215 ;* a5 scratch
1216 SoftInt_Stereo:
1217 mpush a2/a3
1218 move.l a1,a5
1219 movem.l (a5)+,a0/a1/a2/a3
1220 jsr (a3) ;call Player Hook
1221 movem.l (a5),d0/a0/a1/a2/a3/a5
1222 jsr (a3) ;call Mixer Hook
1224 ;* transfer buffer (unrolled)
1225 lsr.w #1,d0
1226 bcs.b .3
1227 subq.w #1,d0
1228 .loop
1229 move.l (a1)+,(a5)+
1231 move.l (a1)+,(a5)+
1232 dbf d0,.loop
1233 mpop a2/a3
1236 ;in:
1237 ;* a1 ptr to 'kicker'
1238 ;* a2 AudioCtrl
1239 audioproc_record:
1240 move.l ahiac_DriverData(a2),a5
1241 move.l 4.w,a6
1242 call FreeVec
1244 moveq #-1,d0
1245 call AllocSignal
1246 move.b d0,wt_RecSlaveSignal(a5)
1247 cmp.b #-1,d0
1248 beq.w .error
1250 moveq #AHIRecordMessage_SIZEOF,d0
1251 move.l #MEMF_24BITDMA|MEMF_PUBLIC|MEMF_CLEAR,d1
1252 call AllocVec
1253 move.l d0,wt_RecordMsg(a5)
1254 beq.w .error
1256 ;* allocate dad_audio.device
1257 call CreateMsgPort
1258 move.l d0,wt_recdadport(a5)
1259 beq.w .error
1260 move.l d0,a0
1261 moveq #IOSTD_SIZE,d0
1263 call CreateIORequest
1264 move.l d0,wt_recdadioreq(a5)
1265 beq.w .error
1267 lea dadname(pc),a0
1268 moveq #0,d0
1269 move.l wt_recdadioreq(a5),a1
1270 moveq #0,d1
1271 call OpenDevice
1272 move.l d0,wt_recdaddev(a5)
1273 bne.w .error
1275 ;* initialize the board
1276 move.l wt_recdadioreq(a5),a1
1277 move.l #DADF_SETFLAG|DADF_INIT,IO_DATA(a1)
1278 clr.l IO_LENGTH(a1)
1279 clr.l IO_OFFSET(a1)
1280 move.w #DADCMD_INIT2,IO_COMMAND(a1)
1281 call DoIO
1283 move.l wt_recdadioreq(a5),a1
1284 move.l ahiac_MixFreq(a2),IO_DATA(a1)
1285 clr.l IO_LENGTH(a1)
1286 clr.l IO_OFFSET(a1)
1287 move.w #DADCMD_SAMPLEFREQ,IO_COMMAND(a1)
1288 call DoIO
1290 move.l wt_recdadioreq(a5),a1
1291 move.l ahiac_MixFreq(a2),IO_DATA(a1)
1292 clr.l IO_LENGTH(a1)
1293 clr.l IO_OFFSET(a1)
1294 move.w #DADCMD_REPLAYFREQ,IO_COMMAND(a1)
1295 call DoIO
1297 ;input gain
1298 move.l wt_recdadioreq(a5),a1
1299 move.l wt_InputGain(a5),d1
1300 bsr lineargain2decibel ;translate gain value
1301 move.l d0,IO_DATA(a1)
1302 clr.l IO_LENGTH(a1)
1303 clr.l IO_OFFSET(a1)
1304 move.w #DADCMD_INPUTGAIN,IO_COMMAND(a1)
1305 call DoIO
1307 move.l wt_recdadioreq(a5),a1
1308 clr.l IO_DATA(a1)
1309 clr.l IO_LENGTH(a1)
1310 move.l #DAD_BUFFER_SETUP,IO_OFFSET(a1)
1311 move.w #DADCMD_BUFFER,IO_COMMAND(a1)
1312 call DoIO
1313 ; Hardcoded value used, since ahi.device must know the size
1314 ;of the record buffer.
1316 move.l #DMA_LENGTH*4,d7
1317 move.l d7,d0
1318 move.l #MEMF_CLEAR|MEMF_CHIP|MEMF_PUBLIC,d1
1319 call AllocVec
1320 move.l d0,wt_RecBuffer(a5)
1321 beq.w .error
1323 move.l wt_RecMasterTask(a5),a1
1324 moveq #0,d0
1325 move.b wt_RecMasterSignal(a5),d1
1326 bset d1,d0
1327 call Signal ;Tell Master we're alive and kicking!
1329 .again
1330 ;*** Set Volume
1331 move.l wt_InputVolume(a5),d1
1332 bsr.w volume2damp
1333 move.l wt_recdadioreq(a5),a1
1334 move.l d0,IO_DATA(a1)
1335 clr.l IO_LENGTH(a1)
1336 clr.l IO_OFFSET(a1)
1337 move.w #DADCMD_OUTPUTDAMP,IO_COMMAND(a1)
1338 call DoIO
1340 ;*** Read
1341 move.l wt_recdadioreq(a5),a1
1342 move.l wt_RecBuffer(a5),IO_DATA(a1)
1343 move.l d7,IO_LENGTH(a1)
1344 move.l #-1,IO_OFFSET(a1)
1345 move.w #CMD_READ,IO_COMMAND(a1)
1346 call DoIO ;copy internal buffer to RecBuffer
1348 move.l wt_recdadioreq(a5),a1
1349 clr.l IO_DATA(a1)
1350 move.l IO_ACTUAL(a1),IO_LENGTH(a1)
1351 move.l #DAD_BUFFER_SWITCH,IO_OFFSET(a1)
1352 move.w #DADCMD_BUFFER,IO_COMMAND(a1)
1353 call DoIO ;swap internal buffers
1355 ;*** Call Hook
1356 move.l ahiac_SamplerFunc(a2),a0
1357 move.l h_Entry(a0),a3
1358 move.l wt_RecordMsg(a5),a1
1359 move.l wt_RecBuffer(a5),ahirm_Buffer(a1)
1360 move.l d7,d0
1361 lsr.l #2,d0
1362 move.l d0,ahirm_Length(a1)
1363 move.l #AHIST_S16S,ahirm_Type(a1)
1364 jsr (a3)
1366 ;*** Exit?
1367 moveq #0,d0
1368 moveq #0,d1
1369 call SetSignal
1370 move.b wt_RecSlaveSignal(a5),d1
1371 btst d1,d0
1372 beq.w .again
1373 .error
1374 move.l wt_RecBuffer(a5),d0
1375 beq.b .nobuffer
1376 move.l d0,a1
1377 clr.l wt_RecBuffer(a5)
1378 call FreeVec
1379 .nobuffer
1380 clr.l wt_RecSlaveTask(a5)
1381 moveq #0,d0
1382 move.b wt_RecSlaveSignal(a5),d0 ;-1 is ok
1383 move.b #-1,wt_RecSlaveSignal(a5)
1384 call FreeSignal
1386 tst.l wt_recdaddev(a5)
1387 bne.b .nodaddev
1389 move.l wt_recdadioreq(a5),a1
1390 move.l #-1,wt_recdaddev(a5)
1391 call CloseDevice
1392 .nodaddev
1393 move.l wt_recdadioreq(a5),a0
1394 clr.l wt_recdadioreq(a5)
1395 call DeleteIORequest
1396 .noaudioreq
1397 move.l wt_recdadport(a5),a0
1398 clr.l wt_recdadport(a5)
1399 call DeleteMsgPort
1400 .noaudioport
1401 move.l wt_RecMasterTask(a5),a1
1402 moveq #0,d0
1403 move.b wt_RecMasterSignal(a5),d1
1404 bset d1,d0
1405 call Signal
1407 dadname:
1408 DAD_DEVICENAME
1409 versiontag:
1410 VERSTAG
1411 even
1412 EndCode: