revert between 56095 -> 55830 in arch
[AROS.git] / workbench / devs / AHI / Drivers / ac97 / ac97-playslave.c
blobf6494072970dbf135b0d464667b83b05782489f7
2 #define DEBUG 1
3 #include <aros/debug.h>
5 #include <asm/io.h>
6 #include <devices/ahi.h>
7 #include <libraries/ahi_sub.h>
9 #include "DriverData.h"
10 #include "library.h"
12 #define dd ((struct AC97Data *) AudioCtrl->ahiac_DriverData)
14 /******************************************************************************
15 ** The slave process **********************************************************
16 ******************************************************************************/
18 #undef SysBase
20 void Slave( struct ExecBase* SysBase );
22 #if defined( __AROS__ )
24 #include <aros/asmcall.h>
26 AROS_UFH3(void, SlaveEntry,
27 AROS_UFHA(STRPTR, argPtr, A0),
28 AROS_UFHA(ULONG, argSize, D0),
29 AROS_UFHA(struct ExecBase *, SysBase, A6))
31 AROS_USERFUNC_INIT
32 Slave( SysBase );
33 AROS_USERFUNC_EXIT
36 #else
38 void SlaveEntry(void)
40 struct ExecBase* SysBase = *((struct ExecBase**) 4);
42 Slave( SysBase );
44 #endif
46 struct BufferDescriptor {
47 APTR pointer;
48 ULONG length;
51 void
52 Slave( struct ExecBase* SysBase )
54 struct AHIAudioCtrlDrv* AudioCtrl;
55 struct DriverBase* AHIsubBase;
56 struct ac97Base* ac97Base;
57 BOOL running, firstTime = TRUE;
58 ULONG signals;
60 AudioCtrl = (struct AHIAudioCtrlDrv*) FindTask( NULL )->tc_UserData;
61 AHIsubBase = (struct DriverBase*) dd->ahisubbase;
62 ac97Base = (struct ac97Base*) AHIsubBase;
64 dd->slavesignal = AllocSignal( -1 );
66 // outb(0x1e, (IPTR)ac97Base->dmabase + PO_CR);
67 // outl(ac97Base->PCM_out, (IPTR)ac97Base->dmabase + PO_BDBAR);
69 D(bug("[AHI:AC97] %s: SR=%04x CR=%02x CIV=%02x LVI=%02x\n", __func__,
70 inw((IPTR)ac97Base->dmabase + ac97Base->off_po_sr),
71 inb((IPTR)ac97Base->dmabase + PO_CR),
72 inb((IPTR)ac97Base->dmabase + PO_CIV),
73 inb((IPTR)ac97Base->dmabase + PO_LVI)));
75 if( dd->slavesignal != -1 )
77 // Everything set up. Tell Master we're alive and healthy.
79 Signal( (struct Task*) dd->mastertask,
80 1L << dd->mastersignal );
82 running = TRUE;
84 SetTaskPri(FindTask(NULL), 127);
86 int tail = (inb((IPTR)ac97Base->dmabase + PO_CIV) + 1) & 0x1f;
88 while( running )
90 signals = SetSignal(0L,0L);
92 if( signals & ( SIGBREAKF_CTRL_C | (1L << dd->slavesignal) ) )
94 running = FALSE;
96 else
98 int i,j;
99 #if defined(__AROS__) && (__WORDSIZE==64)
100 int bufSize = 0;
101 APTR buffPtr = NULL;
102 #endif
103 ULONG buff;
105 CallHookPkt( AudioCtrl->ahiac_PlayerFunc, AudioCtrl, NULL );
106 CallHookPkt( AudioCtrl->ahiac_MixerFunc, AudioCtrl, dd->mixbuffer );
108 i = AudioCtrl->ahiac_BuffSamples << 1;
109 i <<= ac97Base->size_shift; /* For SIS 7012 size must be in bytes */
110 j = tail;
111 #if defined(__AROS__) && (__WORDSIZE==64)
112 if (((IPTR)dd->mixbuffer > 0xFFFFFFFF) || (((IPTR)dd->mixbuffer + i) > 0xFFFFFFFF))
114 bufSize = i;
115 buffPtr = AllocPooled(ac97Base->buffer, i);
116 CopyMem(dd->mixbuffer, buffPtr, i);
117 buff = (ULONG)(IPTR)buffPtr;
119 else
120 #endif
121 buff = (ULONG)(IPTR)dd->mixbuffer;
122 while (i > 0)
124 D(bug("[AHI:AC97] %s: Playing sample @ %p\n", __func__, (IPTR)buff));
125 ac97Base->PCM_out[j].sample_address = buff;
126 ac97Base->PCM_out[j].sample_size = (i > 65532) ? 65532 : i;
128 i -= ac97Base->PCM_out[j].sample_size;
129 buff += ac97Base->PCM_out[j].sample_size
130 << (1 - ac97Base->size_shift); /* SIS 7012: size already in bytes */
131 j++;
132 tail++;
133 tail &= 0x1f;
134 j &= 0x1f;
136 ac97Base->PCM_out[(j-1) & 0x1f].sample_size |= 0x80000000;
138 D(bug("playing audio from %x (size %d, buffer %d)\n",
139 dd->mixbuffer, AudioCtrl->ahiac_BuffSamples, j-1));
141 D(bug("SR=%08x ",inl((IPTR)ac97Base->dmabase + PO_CIV)));
143 // outw(4, (IPTR)ac97Base->dmabase + ac97Base->off_po_sr);
144 outb((j-1) & 0x1f, (IPTR)ac97Base->dmabase + PO_LVI);
145 if (firstTime)
147 outb(0x11, (IPTR)ac97Base->dmabase + PO_CR);
148 /* Enable busmaster + interrupt on completion */
149 firstTime = FALSE;
152 // outw(0x1c, (IPTR)ac97Base->dmabase + ac97Base->off_po_sr);
153 // D(bug("SR=%04x ",inw((IPTR)ac97Base->dmabase + ac97Base->off_po_sr)));
154 // while (!(inw((IPTR)ac97Base->dmabase + ac97Base->off_po_sr) & 8)) {
155 // D(bug("SR=%04x ",inw((IPTR)ac97Base->dmabase + ac97Base->off_po_sr)));
157 D(bug("[AHI:AC97] %s: Waiting for int...", __func__));
158 Wait(SIGBREAKF_CTRL_E);
159 D(bug("[AHI:AC97] %s: Got it\n", __func__));
161 // }
162 // D(bug("SR=%04x\n",inw((IPTR)ac97Base->dmabase + ac97Base->off_po_sr)));
163 // outw(inw((IPTR)ac97Base->dmabase + ac97Base->off_po_sr), (IPTR)ac97Base->dmabase + ac97Base->off_po_sr);
165 // ac97Base->PCM_out
166 // The mixing buffer is now filled with AudioCtrl->ahiac_BuffSamples
167 // of sample frames (type AudioCtrl->ahiac_BuffType). Send them
168 // to the sound card here.
169 #if defined(__AROS__) && (__WORDSIZE==64)
170 if (buffPtr)
171 FreePooled(ac97Base->buffer, buffPtr, bufSize);
172 #endif
177 outb(0, (IPTR)ac97Base->dmabase + PO_CR);
178 FreeSignal( dd->slavesignal );
179 dd->slavesignal = -1;
181 Forbid();
183 // Tell the Master we're dying
185 Signal( (struct Task*) dd->mastertask,
186 1L << dd->mastersignal );
188 dd->slavetask = NULL;
190 // Multitasking will resume when we are dead.