2 Copyright 2010, The AROS Development Team. All rights reserved.
9 * by Nexus Development 2003
10 * coded by Emanuele Cesaroni
18 #include <exec/errors.h>
19 #include <exec/devices.h>
20 #include <devices/audio.h>
21 #include <devices/ahi.h>
22 #include <clib/alib_protos.h>
23 #include <proto/exec.h>
26 #define ADIOB_REPLYDEV 0
27 #define ADIOF_REPLYDEV (1<<0)
30 #define DEVF_DELEXP (1<<0)
38 //////////////////////////////////////////////////////////////////////////////
39 //////////////////////////////////////////////////////////////////////////////
40 //////////////////////////////////////////////////////////////////////////////
44 #define STOLEN_SIG SIGBREAKF_CTRL_C // The stoolen signal...
45 #define PROCESS_STACK 160000
50 #define MEM_TYPE MEMF_PUBLIC|MEMF_CLEAR // the mem i will alloc. Do not modify the list needs a CLEAR.
52 // Structures of ESYSTEM list of nodes
55 struct enode
*prec
; // Previous in list.
56 struct enode
*next
; // Next in list.
57 unsigned long int size
; // Total size of this struct. So sizeof(ENODE) + the size asked during enode_AllocNode().
58 unsigned long int name
; // A value (used as unique name) here freely usable for system researchs.
59 signed char pri
; // The priority used by enode_Enqueue(). It is freely usable before add that node into a list -127 to 127.
60 signed char dummy_b
; // Not used. Align.
61 signed short dummy_w
; // Not used. Align to long.
63 typedef struct enode ENODE
;
68 struct enode first_node
;
69 struct enode last_node
;
70 struct enode
*firstnode
; // This pointer is the ELIST pointer!!!
71 struct enode
*lastnode
;
73 typedef struct elist ELIST
;
75 // Input value for enode_AllocNode()
76 #define ENODE_NONAME 0
77 #define ENODE_NOBODY 0
79 // Quitting mode for enode_FreeList() asked in enode_AllocList().
80 #define ELIST_FREE 0 // Ask to enode_AllocList when enode_FreeList is called to free the enodes the list has.
81 #define ELIST_SIMPLE 1 // No free the nodes they will be freed manually.
82 #define ELIST_EMPTY 0 // Ask this to enode_AllocList() to get an empty list.
86 ELIST
*es_tasklist
; // The task list to intercept them at each BeginIO.
87 struct SignalSemaphore es_devsem
; // the semaphore used by the device.
89 typedef struct EmaSys ESYS
;
96 struct Task
*ts_slavetask
;
97 struct IOAudio
*ts_initio
; // The IOAudio used to init the slave process.
98 struct Task
*ts_opentask
; // The task which activate the slave process.
99 struct Task
*ts_calltask
; // The task which is calling some commands as CMD_FLUSH.
101 typedef struct TaskSys TSYS
;
106 // Some extra commands.
107 #define CMD_ABORTIO 1000 // This is my cmd for ioaborting.
108 #define CMD_CLOSE 1001 // This is my cmd for closing slave process.
110 #define UNIT_STOP 1 << 0 // This unit is stopped;
114 // Init system functions
115 BOOL
InitESYS( VOID
);
116 VOID
FreeESYS( VOID
);
118 // Init and end slave process routines.
119 BOOL
InitSLAVE(struct IOAudio
*ioaudio
);
120 VOID
FreeSLAVE(struct IOAudio
*ioaudio
);
122 // The main slave process.
123 VOID
TaskBody( VOID
);
125 // Protos for the ESYSTEM
126 ENODE
*enode_AllocNode(unsigned long int nodesize
, unsigned long int name
);
127 VOID
enode_FreeNode(ENODE
*thenode
);
128 ELIST
*enode_AllocList(unsigned long int toalloc
, unsigned long int mode
);
129 VOID
enode_FreeList(ELIST
*thelist
);
130 VOID
enode_AddHead(ELIST
*thelist
, ENODE
*thenode
);
131 ENODE
*enode_RemHead(ELIST
*thelist
);
132 VOID
enode_AddTail(ELIST
*thelist
, ENODE
*thenode
);
133 ENODE
*enode_RemTail(ELIST
*thelist
);
134 VOID
enode_Remove(ENODE
*thenode
);
135 ENODE
*enode_FindNode(ELIST
*thelist
, unsigned long int name
);
136 ELIST
*enode_FindListNode(ENODE
*thenode
);
137 VOID
enode_Insert(ELIST
*thelist
, ENODE
*insert
, ENODE
*before
);
138 VOID
enode_Enqueue(ELIST
*thelist
, ENODE
*thenode
);
139 ENODE
*enode_GetHeadNode(ELIST
*thelist
);
140 ENODE
*enode_GetTailNode(ELIST
*thelist
);
141 ENODE
*enode_GetNextNode(ELIST
*thelist
, ENODE
*thenode
);
142 ENODE
*enode_GetPrecNode(ELIST
*thelist
, ENODE
*thenode
);
144 // This the structure which represent an audio unit.
147 struct AHIRequest eu_ahireq
; // An ahi request ready to be used.
148 struct MsgPort
*eu_port
; // My port.
149 WORD eu_allockey
; // The allok key for this unit.
150 BYTE eu_pri
; // The priority for this unit.
151 UBYTE eu_id
; // Number of port, from 0 to 3.
152 UBYTE eu_status
; // The state.
153 ULONG eu_freq
; // used by ahi the freq.
154 ULONG eu_volume
; // used by ahi the volume.
155 ULONG eu_len
; // used by ahi as the lenght.
156 UBYTE
*eu_data
; // used as data by ahi.
157 UWORD eu_cycles
; // The cycles.
158 UWORD eu_savecycles
; // The cycles (save value).
159 UWORD eu_actcycles
; // The cycles (actual value).
160 ULONG eu_repfreq
; // used by ahi the freq when infinite loop.
161 ULONG eu_repvolume
; // used by ahi the volume when infinite loop.
162 ULONG eu_replen
; // used by ahi as the lenght when infinite loop.
163 UBYTE
*eu_repdata
; // used as data by ahi when infinite loop.
164 ULONG eu_clock
; // The clock costant.
165 struct IOAudio
*eu_audioio
; // The audioio which is the pre-cache.
166 struct IOAudio
*eu_usingme
; // The one which is effectively running on unit.
167 struct List eu_writewaitlist
; // The list with all the IOAudio under writing (both precached or effective).
168 struct List eu_waitcyclelist
; // The list with all the IOAudio under waitcycle command.
170 typedef struct emaunit EUNIT
;
172 // This is a general structure for the task with all the necessary to go.
175 ENODE et_node
; // The node of this structure.
176 WORD et_key
; // The actual key.
177 UBYTE et_unitmask
; // A bit 1 is a unit under use.
178 struct List et_allocatelist
; // The list with the IOAudio waitng for allocate.
179 UWORD et_allocated
; // This is the counter of the one in allocatelist.
180 struct GfxBase
*et_gfxbase
; // Graph library base.
181 ULONG et_clock
; // Clock costant for PAL or NTSC
182 struct MsgPort
*et_portunit0
; // Channel 0.
183 struct MsgPort
*et_portunit1
; // Channel 1.
184 struct MsgPort
*et_portunit2
; // Channel 2.
185 struct MsgPort
*et_portunit3
; // Channel 3.
186 struct MsgPort
*et_portunits
; // All channels.
187 struct MsgPort
*et_portahi
; // Used to communicate with ahi.device.
188 struct AHIRequest
*et_openahireq
; // Used to open the device and to get the device's data.
189 EUNIT
*et_units
[4]; // The units.
190 struct MsgPort
*et_ports
[4]; // Here copied the unit msgport form 0 to 3.
191 struct Task
*et_slavetask
; // Here the pointer to the slave process.
193 typedef struct etask ETASK
;
195 EUNIT
*init_EUnit(ETASK
*estruct
, UBYTE channel
, struct MsgPort
*myport
);
196 VOID
free_EUnit(ETASK
*estruct
, EUNIT
*unit
);
198 ETASK
*global_eta
; // For now this is used by the device to find the etask structure.
201 // Protos of commands which are called form the slave process.
202 VOID
_CMD_WRITE(struct IOAudio
*audioio
, ETASK
*eta
, EUNIT
*unit
);
203 VOID
_CMD_RESET(struct IOAudio
*audioio
, ETASK
*eta
);
204 VOID
_CMD_READ(struct IOAudio
*audioio
, ETASK
*eta
);
205 VOID
_CMD_STOP(struct IOAudio
*audioio
, ETASK
*eta
);
206 VOID
_CMD_START(struct IOAudio
*audioio
, ETASK
*eta
);
207 VOID
_CMD_UPDATE(struct IOAudio
*audioio
, ETASK
*eta
);
208 VOID
_CMD_CLEAR(struct IOAudio
*audioio
, ETASK
*eta
);
209 VOID
_ADCMD_WAITCYCLE(struct IOAudio
*audioio
, ETASK
*eta
);
210 VOID
_ADCMD_PERVOL(struct IOAudio
*audioio
, ETASK
*eta
);
211 VOID
_ADCMD_ALLOCATE(struct IOAudio
*audioio
, ETASK
*eta
);
212 VOID
_ADCMD_FREE(struct IOAudio
*audioio
, ETASK
*eta
);
213 VOID
_ADCMD_SETPREC(struct IOAudio
*audioio
, ETASK
*eta
);
214 VOID
_ADCMD_FINISH(struct IOAudio
*audioio
, ETASK
*eta
);
215 VOID
_ADCMD_LOCK(struct IOAudio
*audioio
, ETASK
*eta
);
217 VOID
_CMD_FLUSH(struct IOAudio
*audioio
, ETASK
*eta
);
218 VOID
_CMD_ABORTIO(struct IOAudio
*audioio
, ETASK
*eta
);
219 VOID
_CMD_CLOSE(struct IOAudio
*audioio
, ETASK
*eta
);
221 // Protos of commands called by the device.
222 VOID
audio_ALLOCATE(struct IOAudio
*audioio
);
223 VOID
audio_FREE(struct IOAudio
*audioio
);
224 VOID
audio_LOCK(struct IOAudio
*audioio
);
225 VOID
audio_FINISH(struct IOAudio
*audioio
);
226 VOID
audio_PERVOL(struct IOAudio
*audioio
);
227 VOID
audio_SETPREC(struct IOAudio
*audioio
);
228 VOID
audio_WAITCYCLE(struct IOAudio
*audioio
);
229 VOID
audio_READ(struct IOAudio
*audioio
);
230 VOID
audio_WRITE(struct IOAudio
*audioio
);
231 VOID
audio_UPDATE(struct IOAudio
*audioio
);
232 VOID
audio_CLEAR(struct IOAudio
*audioio
);
233 VOID
audio_STOP(struct IOAudio
*audioio
);
234 VOID
audio_FLUSH(struct IOAudio
*audioio
);
235 VOID
audio_RESET(struct IOAudio
*audioio
);
236 VOID
audio_START(struct IOAudio
*audioio
);
238 VOID
audio_ABORTIO(struct IOAudio
*audioio
, ETASK
*eta
);
239 VOID
audio_CLOSE(struct IOAudio
*audioio
, ETASK
*eta
);
241 // Protos of some utils.
242 VOID
ReplyWaitCycles(EUNIT
*unit
, ETASK
*eta
);
243 VOID
UnitCopyData(EUNIT
*unit
, struct IOAudio
*audioio
);
244 VOID
UnitAHIPerVol(EUNIT
*unit
, struct IOAudio
*audioio
);
245 VOID
UnitInitAhi(EUNIT
*unit
);
246 VOID
UnitInitRepAhi(EUNIT
*unit
);
247 VOID
FlushUnit(EUNIT
*unit
);
248 VOID
ResetUnit(EUNIT
*unit
);
249 VOID
ReAllocateUnits(ETASK
*eta
);
251 #endif /* LIBDATA_H */