- Set a default PCM volume so that something can be heard when driver is
[AROS.git] / workbench / devs / AHI / Drivers / ac97 / ac97-playslave.c
blob56b212d010147b1ac63377a240f28fbe896b24a5
1 #define DEBUG 0
2 #include <aros/debug.h>
3 #include <asm/io.h>
5 #include <config.h>
7 #include <devices/ahi.h>
8 #include <libraries/ahi_sub.h>
10 #include "DriverData.h"
11 #include "library.h"
13 #define dd ((struct AC97Data *) AudioCtrl->ahiac_DriverData)
15 /******************************************************************************
16 ** The slave process **********************************************************
17 ******************************************************************************/
19 #undef SysBase
21 void Slave( struct ExecBase* SysBase );
23 #if defined( __AROS__ )
25 #include <aros/asmcall.h>
27 AROS_UFH3(LONG, SlaveEntry,
28 AROS_UFHA(STRPTR, argPtr, A0),
29 AROS_UFHA(ULONG, argSize, D0),
30 AROS_UFHA(struct ExecBase *, SysBase, A6))
32 AROS_USERFUNC_INIT
33 Slave( SysBase );
34 AROS_USERFUNC_EXIT
37 #else
39 void SlaveEntry(void)
41 struct ExecBase* SysBase = *((struct ExecBase**) 4);
43 Slave( SysBase );
45 #endif
47 struct BufferDescriptor {
48 APTR pointer;
49 ULONG length;
52 void
53 Slave( struct ExecBase* SysBase )
55 struct AHIAudioCtrlDrv* AudioCtrl;
56 struct DriverBase* AHIsubBase;
57 struct ac97Base* ac97Base;
58 BOOL running, firstTime = TRUE;
59 ULONG signals;
61 AudioCtrl = (struct AHIAudioCtrlDrv*) FindTask( NULL )->tc_UserData;
62 AHIsubBase = (struct DriverBase*) dd->ahisubbase;
63 ac97Base = (struct ac97Base*) AHIsubBase;
65 dd->slavesignal = AllocSignal( -1 );
68 // outb(0x1e, ac97Base->dmabase + PO_CR);
69 // outl(ac97Base->PCM_out, ac97Base->dmabase + PO_BDBAR);
71 D(bug("SR=%04x CR=%04x CIV=%02x LVI=%02x\n", inw(ac97Base->dmabase + ac97Base->off_po_sr),
72 inw(ac97Base->dmabase + PO_CR),
73 inb(ac97Base->dmabase + PO_CIV),
74 inb(ac97Base->dmabase + PO_LVI)));
76 if( dd->slavesignal != -1 )
78 // Everything set up. Tell Master we're alive and healthy.
80 Signal( (struct Task*) dd->mastertask,
81 1L << dd->mastersignal );
83 running = TRUE;
85 SetTaskPri(FindTask(NULL), 127);
87 int tail = (inb(ac97Base->dmabase + PO_CIV) + 1) & 0x1f;
89 while( running )
91 signals = SetSignal(0L,0L);
94 if( signals & ( SIGBREAKF_CTRL_C | (1L << dd->slavesignal) ) )
96 running = FALSE;
98 else
100 int i,j;
101 IPTR buff;
102 CallHookPkt( AudioCtrl->ahiac_PlayerFunc, AudioCtrl, NULL );
103 CallHookPkt( AudioCtrl->ahiac_MixerFunc, AudioCtrl, dd->mixbuffer );
105 i = AudioCtrl->ahiac_BuffSamples << 1;
106 i <<= ac97Base->size_shift; /* For SIS 7012 size must be in bytes */
107 j = tail;
108 buff = dd->mixbuffer;
110 while (i > 0)
112 ac97Base->PCM_out[j].sample_address = buff;
113 ac97Base->PCM_out[j].sample_size = (i > 65532) ? 65532 : i;
115 i -= ac97Base->PCM_out[j].sample_size;
116 buff += ac97Base->PCM_out[j].sample_size
117 << (1 - ac97Base->size_shift); /* SIS 7012: size already in bytes */
118 j++;
119 tail++;
120 tail &= 0x1f;
121 j &= 0x1f;
123 ac97Base->PCM_out[(j-1) & 0x1f].sample_size |= 0x80000000;
125 D(bug("playing audio from %x (size %d, buffer %d)\n",
126 dd->mixbuffer, AudioCtrl->ahiac_BuffSamples, j-1));
128 D(bug("SR=%08x ",inl(ac97Base->dmabase + PO_CIV)));
130 // outw(4, ac97Base->dmabase + ac97Base->off_po_sr);
131 outb((j-1) & 0x1f, ac97Base->dmabase + PO_LVI);
132 if (firstTime)
134 outb(0x11, ac97Base->dmabase + PO_CR);
135 /* Enable busmaster + interrupt on completion */
136 firstTime = FALSE;
139 // outw(0x1c, ac97Base->dmabase + ac97Base->off_po_sr);
140 // D(bug("SR=%04x ",inw(ac97Base->dmabase + ac97Base->off_po_sr)));
141 // while (!(inw(ac97Base->dmabase + ac97Base->off_po_sr) & 8)) {
142 // D(bug("SR=%04x ",inw(ac97Base->dmabase + ac97Base->off_po_sr)));
144 D(bug("Waiting for int..."));
145 Wait(SIGBREAKF_CTRL_E);
146 D(bug("Got it\n"));
148 // }
149 // D(bug("SR=%04x\n",inw(ac97Base->dmabase + ac97Base->off_po_sr)));
150 // outw(inw(ac97Base->dmabase + ac97Base->off_po_sr), ac97Base->dmabase + ac97Base->off_po_sr);
152 // ac97Base->PCM_out
153 // The mixing buffer is now filled with AudioCtrl->ahiac_BuffSamples
154 // of sample frames (type AudioCtrl->ahiac_BuffType). Send them
155 // to the sound card here.
160 outb(0, ac97Base->dmabase + PO_CR);
161 FreeSignal( dd->slavesignal );
162 dd->slavesignal = -1;
164 Forbid();
166 // Tell the Master we're dying
168 Signal( (struct Task*) dd->mastertask,
169 1L << dd->mastersignal );
171 dd->slavetask = NULL;
173 // Multitasking will resume when we are dead.