2 Copyright © 2010-2016, The AROS Development Team. All rights reserved.
9 * by Nexus Development 2003
10 * coded by Emanuele Cesaroni
15 #include "audio_intern.h"
17 #include <aros/debug.h>
18 #include <graphics/gfxbase.h>
21 * In CMD_WRITE when more than one bit is set is considered the lowest this keep fastly it.
24 { 0, // 0000 - 0 // This combination is bad.
42 VOID
setup_Units(UBYTE combination
, WORD key
, BYTE pri
, ETASK
*eta
)
45 if (combination
& (1 << 0))
47 ResetUnit(eta
->et_units
[0]);
48 eta
->et_units
[0]->eu_allockey
= key
;
49 eta
->et_units
[0]->eu_pri
= pri
;
50 D(bug("NEWD: Setupped unit %d\n", 0));
53 if (combination
& (1 << 1))
55 ResetUnit(eta
->et_units
[1]);
56 eta
->et_units
[1]->eu_allockey
= key
;
57 eta
->et_units
[1]->eu_pri
= pri
;
58 D(bug("NEWD: Setupped unit %d\n", 1));
61 if (combination
& (1 << 2))
63 ResetUnit(eta
->et_units
[2]);
64 eta
->et_units
[2]->eu_allockey
= key
;
65 eta
->et_units
[2]->eu_pri
= pri
;
66 D(bug("NEWD: Setupped unit %d\n", 2));
69 if (combination
& (1 << 3))
71 ResetUnit(eta
->et_units
[3]);
72 eta
->et_units
[3]->eu_allockey
= key
;
73 eta
->et_units
[3]->eu_pri
= pri
;
74 D(bug("NEWD: Setupped unit %d\n", 3));
77 eta
->et_unitmask
= combination
;
80 VOID
AllocateProc(struct IOAudio
*audioio
, ETASK
*eta
)
82 BYTE
*data
, len
, actual
, pri
;
86 D(bug("NEWD: Arrived ADCMD_ALLOCATE from IOAudio(%x),len=%d,data=%x,key=%d,pri=%d\n",
87 audioio
, audioio
->ioa_Length
, audioio
->ioa_Data
, audioio
->ioa_AllocKey
,
88 audioio
->ioa_Request
.io_Message
.mn_Node
.ln_Pri
));
90 data
= audioio
->ioa_Data
;
91 pri
= audioio
->ioa_Request
.io_Message
.mn_Node
.ln_Pri
;
93 if ((!(key
= audioio
->ioa_AllocKey
)))
95 key
= eta
->et_key
++; /* Always a new key please. */
98 if ((len
= (audioio
->ioa_Length
& 15))) /* If len is > 0 otherwise is ok so returns unit = 0. */
100 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
101 // First control search a combination which doesn't subtract any other just allocated.
105 if ((actual
= *data
++)) /* Actual combination. */
107 D(bug("NEWD: combination %d\n", actual
));
108 if ((actual
& eta
->et_unitmask
) == 0)
110 D(bug("NEWD: after combination %d\n", actual
));
111 setup_Units(actual
, key
, pri
, eta
);
112 audioio
->ioa_Request
.io_Unit
113 = (struct Unit
*) ((IPTR
) actual
);
114 audioio
->ioa_Request
.io_Error
= IONOERROR
;
115 audioio
->ioa_AllocKey
= key
;
122 audioio
->ioa_Request
.io_Unit
= (struct Unit
*) NULL
; /* Lenght is zero but a key is generated, unit is 0 and noerror. */
123 audioio
->ioa_Request
.io_Error
= IONOERROR
;
124 audioio
->ioa_AllocKey
= key
;
126 D(bug("NEWD: ADCMD_ALLOCATE asked combination 0\n"));
131 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
132 // Nothing... Try now to subtract other channels with lower pri.
134 D(bug("NEWD: I try to subtract\n"));
136 data
= audioio
->ioa_Data
;
137 len
= (audioio
->ioa_Length
& 15);
139 do /* First control search a combination which subtracts a combination with lower pri. */
141 actual
= *data
++; /* Actual combination. */
145 if ((actual
& (1 << 0)) && (eta
->et_unitmask
& (1 << 0)))
147 if (eta
->et_units
[0]->eu_pri
>= pri
)
151 if ((actual
& (1 << 1)) && (eta
->et_unitmask
& (1 << 1)))
153 if (eta
->et_units
[1]->eu_pri
>= pri
)
157 if ((actual
& (1 << 2)) && (eta
->et_unitmask
& (1 << 2)))
159 if (eta
->et_units
[2]->eu_pri
>= pri
)
162 if ((actual
& (1 << 3)) && (eta
->et_unitmask
& (1 << 3)))
164 if (eta
->et_units
[3]->eu_pri
>= pri
)
175 Devi semplicemente per i canali sottratti abortire le richieste di CMD_WRITE che giungevano dai task di
176 quelle unit� pagina 126, mettendo in error IOERR_ABORTED. Quelle in esecuzione invece vengono interrotte, quella
177 cached anche ma non viene messo niente in error.
180 setup_Units(actual
, key
, pri
, eta
);
181 audioio
->ioa_Request
.io_Unit
= (struct Unit
*) ((IPTR
) actual
);
182 audioio
->ioa_Request
.io_Error
= IONOERROR
;
183 audioio
->ioa_AllocKey
= key
;
189 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
190 // Ok, nothing to do, so or exit or put the IOAudio in waiting state.
192 if (audioio
->ioa_Request
.io_Flags
& ADIOF_NOWAIT
)
194 audioio
->ioa_Request
.io_Unit
= (struct Unit
*) NULL
;
195 audioio
->ioa_Request
.io_Error
= ADIOERR_ALLOCFAILED
;
196 D(bug("NEWD: I try to subtract\n"));
202 AddTail(&eta
->et_allocatelist
,
203 &audioio
->ioa_Request
.io_Message
.mn_Node
); /* This now in waiting state */
204 eta
->et_allocated
++; /* Increase the counter please. */
205 audioio
->ioa_Request
.io_Flags
&= ~IOF_QUICK
; /* Try this later. */
206 audioio
->ioa_Request
.io_Error
= ADIOERR_ALLOCFAILED
;
207 D(bug("NEWD: ADCMD_ALLOCATE put in waiting allocate list IOAudio '%x'\n",
212 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
215 audioio
->ioa_Request
.io_Unit
= (struct Unit
*) NULL
; // Lenght is zero but a key is generated, unit is 0 and noerror.
216 audioio
->ioa_Request
.io_Error
= IONOERROR
;
217 audioio
->ioa_AllocKey
= key
;
218 D(bug("NEWD: Arrived ADCMD_ALLOCATE with ioa_lenght == 0 IOAudio (%x)\n",
225 * If the IOAudio can't be processed put the request at the end of the et_allocatelist.
228 * - What to do when the lenght is > 15 ? Actually this condition is not present because the lenght is anded with 15.
229 * - Do the procedure of removing the cmd_writes when channels are stolens.
230 * - Do the part of reput the request in a list in which must stay waiting for reallocs.
231 * - Pay attention if abortio aborts an ADCMD_ALLOCATE it is removed and the counter of alloc waiting is wrong.
235 VOID
_ADCMD_ALLOCATE(struct IOAudio
*audioio
, ETASK
*eta
)
237 AllocateProc(audioio
, eta
);
238 Signal(audioio
->ioa_Request
.io_Message
.mn_ReplyPort
->mp_SigTask
, STOLEN_SIG
);
246 * Copies the data from the audio to the unit fields. This is a pre-cached system as the original audio.device used to do.
250 VOID
UnitCopyData(EUNIT
*unit
, struct IOAudio
*audioio
)
253 if (audioio
->ioa_Length
> 131072)
255 unit
->eu_len
= 131072;
259 if (audioio
->ioa_Length
< 2)
265 unit
->eu_len
= audioio
->ioa_Length
;
269 if ((period
= audioio
->ioa_Period
) < 124)
272 unit
->eu_data
= audioio
->ioa_Data
;
273 unit
->eu_cycles
= audioio
->ioa_Cycles
;
275 if (audioio
->ioa_Request
.io_Flags
& ADIOF_PERVOL
)
277 unit
->eu_volume
= audioio
->ioa_Volume
* 1024;
278 //unit->eu_freq = unit->eu_clock / ((ULONG) audioio->ioa_Period);
279 unit
->eu_freq
= unit
->eu_clock
/ period
;
282 unit
->eu_audioio
= audioio
;
283 //audioio->ioa_Request.io_Flags &= ~IOF_QUICK; // This will be outputted surely so treat it as async.
292 * Do the necessary procedures to change on the fly period and volume into an unit.
296 VOID
UnitAHIPerVol(EUNIT
*unit
, struct IOAudio
*audioio
)
298 unit
->eu_freq
= unit
->eu_clock
/ ((ULONG
) audioio
->ioa_Period
);
299 unit
->eu_volume
= audioio
->ioa_Volume
* 1024;
306 * Inits ahi and play the sample.
307 * It removes the data from the precached place as the original audio.device used to do.
311 VOID
UnitInitAhi(EUNIT
*unit
)
313 if (!unit
->eu_usingme
)
315 unit
->eu_ahireq
.ahir_Std
.io_Data
= unit
->eu_data
;
316 unit
->eu_ahireq
.ahir_Std
.io_Length
= unit
->eu_len
;
317 unit
->eu_ahireq
.ahir_Frequency
= unit
->eu_freq
;
318 unit
->eu_ahireq
.ahir_Volume
= unit
->eu_volume
;
319 unit
->eu_usingme
= unit
->eu_audioio
;
320 unit
->eu_audioio
= NULL
;
321 unit
->eu_savecycles
= unit
->eu_cycles
; // The save value.
322 unit
->eu_actcycles
= unit
->eu_cycles
; // The actual counter.
324 if (unit
->eu_savecycles
!= 1) // Save the values for infinite repeating...
326 unit
->eu_repdata
= unit
->eu_data
;
327 unit
->eu_replen
= unit
->eu_len
;
328 unit
->eu_repfreq
= unit
->eu_freq
;
329 unit
->eu_repvolume
= unit
->eu_volume
;
332 BeginIO((struct IORequest
*) &unit
->eu_ahireq
);
334 if (unit
->eu_usingme
->ioa_Request
.io_Flags
& ADIOF_WRITEMESSAGE
)
336 D(bug("NEWD: Reply WRITE_MESSAGE from IOAudio (%x)\n",
338 ReplyMsg(&unit
->eu_usingme
->ioa_WriteMsg
);
347 * This is used to reinit ahi when we are under infinite cycles.
350 VOID
UnitInitRepAhi(EUNIT
*unit
)
352 unit
->eu_ahireq
.ahir_Std
.io_Data
= unit
->eu_repdata
;
353 unit
->eu_ahireq
.ahir_Std
.io_Length
= unit
->eu_replen
;
354 unit
->eu_ahireq
.ahir_Frequency
= unit
->eu_repfreq
;
355 unit
->eu_ahireq
.ahir_Volume
= unit
->eu_repvolume
;
356 BeginIO((struct IORequest
*) &unit
->eu_ahireq
);
363 * Flushes an eaudio.device unit. So:
364 * 1) Aborts the running audio wave.
365 * 2) Get all the CMD_WRITE in list waiting repling them to their task with IOERR_ABORTED.
366 * 3) Returns all the waitcycles in waitcyclelist with IOERR_ABORTED.
368 * ?? The running IOAudio must be replied??
372 VOID
FlushUnit(EUNIT
*unit
)
374 struct IOAudio
*audioio
;
376 if (!(CheckIO((struct IORequest
*) &unit
->eu_ahireq
))) // I stop if exists the running audio output.
378 AbortIO((struct IORequest
*) &unit
->eu_ahireq
);
379 WaitIO((struct IORequest
*) &unit
->eu_ahireq
);
381 D(bug("NEWD: FlushUnit(): The audio in port (%d) was running now is stopped\n",
385 unit
->eu_usingme
= NULL
;
387 while ((audioio
= (struct IOAudio
*) GetMsg(unit
->eu_port
))) // Now removes all the CMD_WRITE present in the list.
389 audioio
->ioa_Request
.io_Error
= IOERR_ABORTED
;
390 ReplyMsg(&audioio
->ioa_Request
.io_Message
);
392 D(bug("NEWD: FlushUnit(): Removed from the list of port (%d) the CMD_WRITE request (%x).\n",
393 unit
->eu_id
, audioio
));
396 while ((audioio
= (struct IOAudio
*) RemHead(&unit
->eu_waitcyclelist
))) // Removes all the ADCMD_WAITCYCLES for this unit.
398 D(bug("NEWD: FlushUnit(): Found IOAuido (%x) in waitcyclelist, now i reply it with IOERR_ABORTED.\n",
401 audioio
->ioa_Request
.io_Error
= IOERR_ABORTED
;
402 ReplyMsg(&audioio
->ioa_Request
.io_Message
);
412 VOID
_CMD_RESET(struct IOAudio
*audioio
, ETASK
*eta
)
414 BYTE unit
, chan
, final
= 0;
416 UBYTE error
= IONOERROR
;
418 D(bug("NEWD: Arrived CMD_RESET from IOAudio (%x), unit(%d)\n", audioio
,
419 audioio
->ioa_Request
.io_Unit
));
421 if ((unit
= (((IPTR
) audioio
->ioa_Request
.io_Unit
) & 15)))
425 chan
= writechn
[unit
];
426 channel
= eta
->et_units
[chan
];
428 if (channel
->eu_allockey
== audioio
->ioa_AllocKey
)
431 D(bug("NEWD: CMD_FLUSH for unit (%d)\n", chan
));
435 error
= ADIOERR_NOALLOCATION
;
438 unit
&= ~(1 << chan
);
443 audioio
->ioa_Request
.io_Unit
= (struct Unit
*) ((IPTR
) final
);
444 audioio
->ioa_Request
.io_Error
= error
;
445 Signal(audioio
->ioa_Request
.io_Message
.mn_ReplyPort
->mp_SigTask
, 1
446 << audioio
->ioa_Request
.io_Message
.mn_ReplyPort
->mp_SigBit
);
453 * Does some procedures usefull to reset the unit, Called by CMD_RESET and other.
457 VOID
ResetUnit(EUNIT
*unit
)
459 unit
->eu_audioio
= NULL
; /* This is sufficent to erase the pre-cache requestes. */
460 FlushUnit(unit
); /* This stops the running audio and removes all the quequed CMD_WRITE and ADCMD_WAITCYCLES. */
468 * This block try again to ADCMD_ALLOCATE some IOAUdio request which are waiting for channels. Actually it is called from
469 * ADCMD_FREE or ADCMD_SETPREC.
471 * - Pay attention to the counter of the allocate in waiting if an abortio removes it the system collapses !!!!!!!!
475 VOID
ReAllocateUnits(ETASK
*eta
)
478 struct IOAudio
*wait
;
480 if ((allocated
= eta
->et_allocated
)) // If any in list waiting for being allocated.
482 while ((wait
= (struct IOAudio
*) RemHead(&eta
->et_allocatelist
)))
486 D(bug("NEWD: ADCMD_FREE: Trying to allocate this again. IOAudio (%x)\n", wait
));
487 AllocateProc(wait
, eta
);
489 if ((wait
->ioa_Request
.io_Flags
& IOF_QUICK
) == 0)
491 if ((wait
->ioa_Request
.io_Error
== ADIOERR_ALLOCFAILED
)
492 && (wait
->ioa_Request
.io_Flags
& ADIOF_NOWAIT
))
494 ReplyMsg(&wait
->ioa_Request
.io_Message
);
496 else if (wait
->ioa_Request
.io_Error
== IONOERROR
)
498 ReplyMsg(&wait
->ioa_Request
.io_Message
);
502 if (--allocated
== 0)
504 break; // Decrease the number in list and exit if empty.
513 * Frees some units then:
514 * 1) See if other ADCMD_ALLOCATE are in waiting state.
518 VOID
_ADCMD_FREE(struct IOAudio
*audioio
, ETASK
*eta
)
520 BYTE unit
, chan
, final
= 0;
522 UBYTE error
= IONOERROR
;
524 D(bug("NEWD: Arrived CMD_FREE from IOAudio (%x), unit(%d)\n", audioio
,
525 audioio
->ioa_Request
.io_Unit
));
527 if ((unit
= (((IPTR
) audioio
->ioa_Request
.io_Unit
) & 15)))
531 chan
= writechn
[unit
];
532 channel
= eta
->et_units
[chan
];
534 if (channel
->eu_allockey
== audioio
->ioa_AllocKey
)
538 ResetUnit(channel
); // Reset this one please.
539 eta
->et_unitmask
&= ~(1 << chan
); // This channel is now free.
540 channel
->eu_allockey
= 0; // Not needed!
541 channel
->eu_pri
= -127; // Not needed!
543 D(bug("NEWD: CMD_FREE freed unit (%d)\n", chan
));
545 //else error = ADIOERR_NOALLOCATION;
549 error
= ADIOERR_NOALLOCATION
;
552 unit
&= ~(1 << chan
);
557 D(bug("NEWD: Now i reply CMD_FREE from IOAudio (%x), unit(%d)\n", audioio
,
558 audioio
->ioa_Request
.io_Unit
));
560 audioio
->ioa_Request
.io_Unit
= (struct Unit
*) (IPTR
) final
;
561 audioio
->ioa_Request
.io_Error
= error
;
563 //Signal(audioio->ioa_Request.io_Message.mn_ReplyPort->mp_SigTask,STOLEN_SIG);
564 Signal(ematsys
->ts_calltask
, STOLEN_SIG
);
566 if (final
) // Only if something now is freed touch the allocating waiting for...
568 ReAllocateUnits(eta
);
569 // verificare ora il discorso dei locks.
578 * See again the part of bad allockkey the signal there is wrong.
581 VOID
_CMD_WRITE(struct IOAudio
*audioio
, ETASK
*eta
, EUNIT
*unit
)
583 D(bug("NEWD: Arrived CMD_WRITE from IOAudio (%x), emaunit (%d), cycles (%d), flags (%d)\n",
584 audioio
, unit
->eu_id
, audioio
->ioa_Cycles
, audioio
->ioa_Request
.io_Flags
));
585 D(bug("NEWD: Arrived CMD_WRITE from IOAudio (%x), period (%d), len (%d), pri (%d) key (%d)\n",
586 audioio
, audioio
->ioa_Period
, audioio
->ioa_Length
,
587 audioio
->ioa_Request
.io_Message
.mn_Node
.ln_Pri
, audioio
->ioa_AllocKey
));
588 D(bug("NEWD: Arrived CMD_WRITE from IOAudio (%x), data (%d) volume (%d)\n",
589 audioio
, audioio
->ioa_Data
, audioio
->ioa_Volume
));
591 //D(bug("datalist\n",0, 0,0,0,0));
592 //ablo = audioio->ioa_Data;
595 // D(bug("%d ",*ablo,0,0,0,0));
597 //}while((counter++) < 100);
598 //D(bug("\n",0, 0,0,0,0));
600 if (audioio
->ioa_AllocKey
== unit
->eu_allockey
)
602 audioio
->ioa_Request
.io_Flags
&= ~IOF_QUICK
;
603 AddTail(&unit
->eu_writewaitlist
,
604 &audioio
->ioa_Request
.io_Message
.mn_Node
); // Put the new one in the tail of the list.
605 audioio
= (struct IOAudio
*) RemHead(&unit
->eu_writewaitlist
); // Pick the head.
607 if ((unit
->eu_status
& UNIT_STOP
) == 0) // If the unit isn't stopped.
609 if ((unit
->eu_usingme
== NULL
) && (unit
->eu_audioio
== NULL
)) // Precache free, executing free.
611 UnitCopyData(unit
, audioio
);
614 if ((audioio
= (struct IOAudio
*) RemHead(
615 &unit
->eu_writewaitlist
)))
617 UnitCopyData(unit
, audioio
);
623 if ((unit
->eu_usingme
!= NULL
) && (unit
->eu_audioio
== NULL
))
625 UnitCopyData(unit
, audioio
);
629 if ((unit
->eu_usingme
== NULL
) && (unit
->eu_audioio
!= NULL
))
632 UnitCopyData(unit
, audioio
);
638 AddHead(&unit
->eu_writewaitlist
,
639 &audioio
->ioa_Request
.io_Message
.mn_Node
); // Reput if channel is stopped or cache and running are busy.
645 D(bug("NEWD: CMD_WRITE bad allockey or inaccessible channel, IOAudio (%x), key (%d)\n",
646 audioio
, audioio
->ioa_AllocKey
));
647 audioio
->ioa_Request
.io_Unit
= NULL
;
648 audioio
->ioa_Request
.io_Error
= ADIOERR_NOALLOCATION
;
650 Signal(audioio
->ioa_Request
.io_Message
.mn_ReplyPort
->mp_SigTask
, 1
651 << audioio
->ioa_Request
.io_Message
.mn_ReplyPort
->mp_SigBit
);
653 if ((audioio
->ioa_Request
.io_Flags
& IOF_QUICK
) == 0)
655 ReplyMsg(&audioio
->ioa_Request
.io_Message
);
664 * Processes all the commands which interacts with all the units.
668 VOID
process_UnitsCmd(struct IOAudio
* MyIORequest
, ETASK
*eta
)
670 switch (MyIORequest
->ioa_Request
.io_Command
)
673 _ADCMD_ALLOCATE(MyIORequest
, eta
);
677 _ADCMD_FREE(MyIORequest
, eta
);
681 _ADCMD_PERVOL(MyIORequest
, eta
);
685 _ADCMD_SETPREC(MyIORequest
, eta
);
689 _ADCMD_FINISH(MyIORequest
, eta
);
692 case ADCMD_WAITCYCLE
:
693 _ADCMD_WAITCYCLE(MyIORequest
, eta
);
697 _ADCMD_LOCK(MyIORequest
, eta
);
701 _CMD_FLUSH(MyIORequest
, eta
);
705 _CMD_RESET(MyIORequest
, eta
);
709 _CMD_STOP(MyIORequest
, eta
);
713 _CMD_START(MyIORequest
, eta
);
717 _CMD_UPDATE(MyIORequest
, eta
);
721 _CMD_CLEAR(MyIORequest
, eta
);
725 _CMD_READ(MyIORequest
, eta
);
728 case CMD_ABORTIO
: // This is a my command.
729 _CMD_ABORTIO(MyIORequest
, eta
);
732 case CMD_CLOSE
: // This is a my command.
733 _CMD_CLOSE(MyIORequest
, eta
);
742 * Frees the ETASK system, all ports, closes the device etc..
746 VOID
free_ETask(ETASK
*eta
)
748 CloseLibrary((struct Library
*) eta
->et_gfxbase
);
750 free_EUnit(eta
, eta
->et_units
[3]); // Free the units.
751 free_EUnit(eta
, eta
->et_units
[2]);
752 free_EUnit(eta
, eta
->et_units
[1]);
753 free_EUnit(eta
, eta
->et_units
[0]);
755 if (!CheckIO((struct IORequest
*) eta
->et_openahireq
))
757 AbortIO((struct IORequest
*) eta
->et_openahireq
);
760 CloseDevice((struct IORequest
*) eta
->et_openahireq
);
761 DeleteIORequest((struct IORequest
*) eta
->et_openahireq
);
762 DeleteMsgPort((struct MsgPort
*) eta
->et_portahi
);
763 DeleteMsgPort((struct MsgPort
*) eta
->et_portunits
);
764 DeleteMsgPort((struct MsgPort
*) eta
->et_portunit3
);
765 DeleteMsgPort((struct MsgPort
*) eta
->et_portunit2
);
766 DeleteMsgPort((struct MsgPort
*) eta
->et_portunit1
);
767 DeleteMsgPort((struct MsgPort
*) eta
->et_portunit0
);
768 enode_FreeNode((ENODE
*) eta
);
775 * Initilizes the new style of manage the problem, so it allocs the unique task structure with 4 msgports for audio channels, 1 ports
776 * for manage requests for every channels, 4 structs for the units.
780 ETASK
*init_ETask( VOID
)
784 if ((eta
= (ETASK
*) enode_AllocNode(sizeof(ETASK
),
785 (unsigned long int) FindTask(NULL
))))
788 eta
->et_unitmask
= 0;
790 if ((eta
->et_portunit0
= (struct MsgPort
*) CreateMsgPort()))
792 if ((eta
->et_portunit1
= (struct MsgPort
*) CreateMsgPort()))
794 if ((eta
->et_portunit2
= (struct MsgPort
*) CreateMsgPort()))
796 if ((eta
->et_portunit3
= (struct MsgPort
*) CreateMsgPort()))
798 if ((eta
->et_portunits
799 = (struct MsgPort
*) CreateMsgPort()))
802 = (struct MsgPort
*) CreateMsgPort()))
804 if ((eta
->et_openahireq
805 = (struct AHIRequest
*) CreateIORequest(
807 sizeof(struct AHIRequest
))))
809 eta
->et_openahireq
->ahir_Version
= 4;
814 (struct IORequest
*) eta
->et_openahireq
,
818 = (struct GfxBase
*) OpenLibrary(
819 "graphics.library", 0L)))
821 if (eta
->et_gfxbase
->DisplayFlags
824 eta
->et_clock
= 3546895;
828 eta
->et_clock
= 3579545;
831 if ((eta
->et_units
[0] = init_EUnit(
835 if ((eta
->et_units
[1]
841 if ((eta
->et_units
[2]
847 if ((eta
->et_units
[3]
862 &eta
->et_allocatelist
); // The allocating waiting for.
864 = 0; // No one in list.
884 (struct Library
*) eta
->et_gfxbase
);
888 (struct IORequest
*) eta
->et_openahireq
)))
891 (struct IORequest
*) eta
->et_openahireq
);
895 (struct IORequest
*) eta
->et_openahireq
);
899 (struct IORequest
*) eta
->et_openahireq
);
902 DeleteMsgPort((struct MsgPort
*) eta
->et_portahi
);
905 DeleteMsgPort((struct MsgPort
*) eta
->et_portunits
);
908 DeleteMsgPort((struct MsgPort
*) eta
->et_portunit3
);
911 DeleteMsgPort((struct MsgPort
*) eta
->et_portunit2
);
914 DeleteMsgPort((struct MsgPort
*) eta
->et_portunit1
);
917 DeleteMsgPort((struct MsgPort
*) eta
->et_portunit0
);
920 enode_FreeNode((ENODE
*) eta
);
935 VOID
free_EUnit(ETASK
*estruct
, EUNIT
*unit
)
938 if(IsListEmpty(&unit
->eu_writewaitlist
))
940 D(bug("NEWD: free_Unit() writewaitlist is empty (unit %d).\n", unit
->eu_id
));
944 D(bug("NEWD: free_Unit() writewaitlist is NOT empty (unit %d).\n", unit
->eu_id
));
947 if (IsListEmpty(&unit
->eu_waitcyclelist
))
949 D(bug("NEWD: free_Unit() waitcyclelist is empty (unit %d).\n", unit
->eu_id
));
953 D(bug("NEWD: free_Unit() waitcyclelist is NOT empty (unit %d).\n", unit
->eu_id
));
957 if (!(CheckIO((struct IORequest
*) &unit
->eu_ahireq
)))
959 AbortIO((struct IORequest
*) &unit
->eu_ahireq
);
962 DeleteIORequest((struct IORequest
*) &unit
->eu_ahireq
);
970 * Initializes the unit block. The unit is just an iorequest to interact with AHI or TIMER device.
971 * Returns the unit or NULL if fails.
974 * *unit = InitEUnit(*etask,channel,*msgport)
977 EUNIT
*init_EUnit(ETASK
*estruct
, UBYTE channel
, struct MsgPort
*myport
)
981 if ((unit
= (EUNIT
*) CreateIORequest(estruct
->et_portahi
, sizeof(EUNIT
))))
983 NewList(&unit
->eu_writewaitlist
); // All the ones under writing.
984 NewList(&unit
->eu_waitcyclelist
); // All the ones under waitcycle.
985 unit
->eu_clock
= estruct
->et_clock
;
986 unit
->eu_id
= writechn
[channel
];
987 unit
->eu_port
= myport
;
988 unit
->eu_usingme
= NULL
;
989 unit
->eu_audioio
= NULL
;
990 unit
->eu_status
= 0; // Status ready.
991 unit
->eu_ahireq
.ahir_Std
.io_Message
.mn_Node
.ln_Pri
= 0;
992 unit
->eu_ahireq
.ahir_Std
.io_Command
= CMD_WRITE
;
993 unit
->eu_ahireq
.ahir_Std
.io_Offset
= 0;
994 unit
->eu_ahireq
.ahir_Type
= AHIST_M8S
;
995 unit
->eu_ahireq
.ahir_Link
= NULL
;
996 unit
->eu_ahireq
.ahir_Std
.io_Message
.mn_ReplyPort
= estruct
->et_portahi
;
997 unit
->eu_ahireq
.ahir_Std
.io_Device
998 = estruct
->et_openahireq
->ahir_Std
.io_Device
;
999 unit
->eu_ahireq
.ahir_Std
.io_Unit
1000 = estruct
->et_openahireq
->ahir_Std
.io_Unit
;
1002 if (channel
& (1 << 1 | 1 << 2))
1004 unit
->eu_ahireq
.ahir_Position
= 0x10000; // right.
1008 unit
->eu_ahireq
.ahir_Position
= 0; // left.
1021 * The slave process main function.
1024 VOID
TaskBody( VOID
)
1026 ULONG waitsignal
, signalset
;
1027 struct IOAudio
*ioaudioreq
;
1032 if ((eta
= init_ETask()))
1035 eta
->et_slavetask
= FindTask(NULL
);
1036 ematsys
->ts_initio
->ioa_Request
.io_Error
= IONOERROR
;
1037 Signal(ematsys
->ts_opentask
, STOLEN_SIG
);
1039 D(bug("NEWD: SLAVE PROCESS OPERATING.....\n"));
1041 waitsignal
= (1 << eta
->et_portunit0
->mp_SigBit
) | (1
1042 << eta
->et_portunit1
->mp_SigBit
) | (1
1043 << eta
->et_portunit2
->mp_SigBit
) | (1
1044 << eta
->et_portunit3
->mp_SigBit
) | (1
1045 << eta
->et_portunits
->mp_SigBit
) | (1
1046 << eta
->et_portahi
->mp_SigBit
);
1050 signalset
= Wait(waitsignal
);
1052 if (signalset
& (1 << eta
->et_portunit0
->mp_SigBit
)) // PORT 0.
1055 = (struct IOAudio
*) GetMsg(eta
->et_portunit0
)))
1057 _CMD_WRITE(ioaudioreq
, eta
, eta
->et_units
[0]);
1058 Signal(ioaudioreq
->ioa_Request
.io_Message
.mn_ReplyPort
->mp_SigTask
,
1062 if (signalset
& (1 << eta
->et_portunit1
->mp_SigBit
)) // PORT 1.
1065 = (struct IOAudio
*) GetMsg(eta
->et_portunit1
)))
1067 _CMD_WRITE(ioaudioreq
, eta
, eta
->et_units
[1]);
1068 Signal(ioaudioreq
->ioa_Request
.io_Message
.mn_ReplyPort
->mp_SigTask
,
1072 if (signalset
& (1 << eta
->et_portunit2
->mp_SigBit
)) // PORT 2.
1075 = (struct IOAudio
*) GetMsg(eta
->et_portunit2
)))
1077 _CMD_WRITE(ioaudioreq
, eta
, eta
->et_units
[2]);
1078 Signal(ioaudioreq
->ioa_Request
.io_Message
.mn_ReplyPort
->mp_SigTask
,
1082 if (signalset
& (1 << eta
->et_portunit3
->mp_SigBit
)) // PORT 3.
1085 = (struct IOAudio
*) GetMsg(eta
->et_portunit3
)))
1087 _CMD_WRITE(ioaudioreq
, eta
, eta
->et_units
[3]);
1088 Signal(ioaudioreq
->ioa_Request
.io_Message
.mn_ReplyPort
->mp_SigTask
,
1092 //--------------------------------------------------------------------------------------------------------------------------
1093 if (signalset
& (1 << eta
->et_portahi
->mp_SigBit
)) // AHI REPLY PORT.
1095 while ((unit
= (EUNIT
*) GetMsg(eta
->et_portahi
)))// reply the I/Os.
1097 //D(bug("NEWD: this is the real ahi return unit(%d), ioreq (%d)\n",unit->eu_id, unit->eu_usingme));
1099 if ((ioaudioreq
= unit
->eu_usingme
)) // This one is ended.
1101 if (unit
->eu_savecycles
) // No infinite in this != 0.
1103 if (--unit
->eu_actcycles
== 0)
1106 (IPTR
) ioaudioreq
->ioa_Request
.io_Unit
;
1107 tmpunit
|= 1 << unit
->eu_id
;
1108 ioaudioreq
->ioa_Request
.io_Unit
1111 ioaudioreq
->ioa_Request
.io_Error
= IONOERROR
;
1113 ReplyMsg(&ioaudioreq
->ioa_Request
.io_Message
);
1117 "NEWD: AHI RETURNS Unit(%d), ioreq (%d)\n",
1118 unit
->eu_id
, ioaudioreq
,
1122 unit->eu_usingme = NULL; // This informs that the unit now is free.
1124 if(unit->eu_audioio)
1126 UnitInitAhi(unit); // Ok send soon now the pre-cached.
1129 while(ioaudioreq = (struct IOAudio*) RemHead(&unit->eu_writewaitlist)) // Examine for this unit only one request in waiting status.
1131 D(bug("NEWD: Founded ioreq (%d) in writewaitlist, now i process it.\n",ioaudioreq,0,0,0,0));
1133 _CMD_WRITE(ioaudioreq,eta,unit);
1135 if(unit->eu_audioio)
1137 break; // If the precached is empty you can exit.
1141 unit
->eu_usingme
= NULL
;
1143 if (unit
->eu_audioio
)
1148 = (struct IOAudio
*) RemHead(
1149 &unit
->eu_writewaitlist
)))
1151 UnitCopyData(unit
, ioaudioreq
);
1153 D(bug("NEWD: PUT ioreq (%x) IN PRECACHE\n", ioaudioreq
));
1159 = (struct IOAudio
*) RemHead(
1160 &unit
->eu_writewaitlist
)))
1162 UnitCopyData(unit
, ioaudioreq
);
1165 D(bug("NEWD: EXECUTED ioreq (%x)\n", ioaudioreq
));
1168 = (struct IOAudio
*) RemHead(
1169 &unit
->eu_writewaitlist
)))
1171 UnitCopyData(unit
, ioaudioreq
);
1173 D(bug("NEWD: PUT ioreq (%x) IN PRECACHE\n", ioaudioreq
));
1180 UnitInitRepAhi(unit
);
1183 else // This zero infinite loop.
1185 UnitInitRepAhi(unit
);
1188 ReplyWaitCycles(unit
, eta
); // Reply to whom was waiting for a cycle end.
1192 //--------------------------------------------------------------------------------------------------------------------------
1193 if (signalset
& (1 << eta
->et_portunits
->mp_SigBit
)) // ALL THE PORTS.
1196 = (struct IOAudio
*) GetMsg(eta
->et_portunits
)))
1198 process_UnitsCmd(ioaudioreq
, eta
);
1200 if (ioaudioreq
->ioa_Request
.io_Command
== CMD_CLOSE
)
1202 D(bug("NEWD: RECEIVED CLOSE\n"));
1208 //--------------------------------------------------------------------------------------------------------------------------
1213 ematsys
->ts_initio
->ioa_Request
.io_Error
= IOERR_OPENFAIL
; // Wrong! Inform my father...
1214 Signal(ematsys
->ts_initio
->ioa_Request
.io_Message
.mn_ReplyPort
->mp_SigTask
,
1215 1 << ematsys
->ts_initio
->ioa_Request
.io_Message
.mn_ReplyPort
->mp_SigBit
);
1219 VOID
UnitReWrite(EUNIT
*unit
)
1221 struct IOAudio
*ioaudioreq
;
1223 if ((unit
->eu_audioio
!= NULL
) && (unit
->eu_usingme
== NULL
))
1227 D(bug("NEWD: Cache presente ho initializzato unit %d\n", unit
->eu_id
));
1229 if ((ioaudioreq
= (struct IOAudio
*) RemHead(&unit
->eu_writewaitlist
)))
1231 UnitCopyData(unit
, ioaudioreq
);
1234 else if ((unit
->eu_audioio
== NULL
) && (unit
->eu_usingme
!= NULL
))
1236 D(bug("NEWD: Cache nulla ma ioreq in function %d\n", unit
->eu_id
));
1238 if ((ioaudioreq
= (struct IOAudio
*) RemHead(&unit
->eu_writewaitlist
)))
1240 UnitCopyData(unit
, ioaudioreq
);
1244 else if ((unit
->eu_audioio
== NULL
) && (unit
->eu_usingme
== NULL
))
1246 D(bug("NEWD: Tutto vuoto provo l'init in unit %d\n", unit
->eu_id
));
1248 if ((ioaudioreq
= (struct IOAudio
*) RemHead(&unit
->eu_writewaitlist
)))
1250 D(bug("NEWD: Tutto vuoto ma c' per l'init %d\n", unit
->eu_id
));
1252 UnitCopyData(unit
, ioaudioreq
);
1256 if ((ioaudioreq
= (struct IOAudio
*) RemHead(&unit
->eu_writewaitlist
)))
1258 D(bug("NEWD: Tutto vuoto e anche per il cache %d\n", unit
->eu_id
));
1259 UnitCopyData(unit
, ioaudioreq
);
1264 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1265 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1266 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1273 * - This must be ended!!!!!!!
1277 VOID
_ADCMD_LOCK(struct IOAudio
*audioio
, ETASK
*eta
)
1279 BYTE unit
, chan
, final
= 0;
1281 UBYTE error
= IONOERROR
;
1283 D(bug("NEWD: Arrived ADCMD_LOCK from IOAudio (%x), unit(%d)\n", audioio
,
1284 audioio
->ioa_Request
.io_Unit
));
1286 if ((unit
= (((IPTR
) audioio
->ioa_Request
.io_Unit
) & 15)))
1290 chan
= writechn
[unit
]; // Get the lowest channel.
1291 channel
= eta
->et_units
[chan
];
1293 if (channel
->eu_allockey
== audioio
->ioa_AllocKey
)
1295 final
|= 1 << chan
; // Ok for this unit the command is successful.
1297 // ????????????????????????????????????????????????
1302 error
= ADIOERR_NOALLOCATION
;
1305 unit
&= ~(1 << chan
);
1310 error
= ADIOERR_NOALLOCATION
;
1313 audioio
->ioa_Request
.io_Unit
= (struct Unit
*) (IPTR
) final
;
1314 audioio
->ioa_Request
.io_Error
= error
;
1315 Signal(ematsys
->ts_calltask
, STOLEN_SIG
);
1324 void audio_LOCK(struct IOAudio
*audioio
)
1328 ematsys
->ts_calltask
= FindTask(NULL
);
1329 oldsignals
= SetSignal(0, STOLEN_SIG
);
1331 PutMsg(global_eta
->et_portunits
, (struct Message
*) audioio
);
1333 SetSignal(oldsignals
, STOLEN_SIG
);
1335 if ((audioio
->ioa_Request
.io_Flags
& IOF_QUICK
) == 0)
1337 ReplyMsg(&audioio
->ioa_Request
.io_Message
);
1341 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1347 * - This must be ended!!!!!!!
1351 VOID
_ADCMD_FINISH(struct IOAudio
*audioio
, ETASK
*eta
)
1353 BYTE unit
, chan
, final
= 0;
1355 UBYTE error
= IONOERROR
;
1357 D(bug("NEWD: Arrived ADCMD_FINISH from IOAudio (%x), unit(%d)\n", audioio
,
1358 audioio
->ioa_Request
.io_Unit
));
1360 if ((unit
= (((IPTR
) audioio
->ioa_Request
.io_Unit
) & 15)))
1364 chan
= writechn
[unit
]; // Get the lowest channel.
1365 channel
= eta
->et_units
[chan
];
1367 if (channel
->eu_allockey
== audioio
->ioa_AllocKey
)
1369 final
|= 1 << chan
; // Ok for this unit the command is successful.
1371 // ????????????????????????????????????????????????
1375 error
= ADIOERR_NOALLOCATION
;
1376 unit
&= ~(1 << chan
);
1381 error
= ADIOERR_NOALLOCATION
;
1384 audioio
->ioa_Request
.io_Unit
= (struct Unit
*) (IPTR
) final
;
1385 audioio
->ioa_Request
.io_Error
= error
;
1386 Signal(audioio
->ioa_Request
.io_Message
.mn_ReplyPort
->mp_SigTask
, 1
1387 << audioio
->ioa_Request
.io_Message
.mn_ReplyPort
->mp_SigBit
);
1396 void audio_FINISH(struct IOAudio
*audioio
)
1398 PutMsg(global_eta
->et_portunits
, (struct Message
*) audioio
);
1399 Wait(1 << audioio
->ioa_Request
.io_Message
.mn_ReplyPort
->mp_SigBit
);
1401 if ((audioio
->ioa_Request
.io_Flags
& IOF_QUICK
) == 0)
1403 ReplyMsg(&audioio
->ioa_Request
.io_Message
);
1407 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1416 VOID
_ADCMD_PERVOL(struct IOAudio
*audioio
, ETASK
*eta
)
1418 BYTE unit
, chan
, final
= 0;
1420 UBYTE error
= IONOERROR
;
1422 D(bug("NEWD: Arrived ADCMD_PERVOL from IOAudio (%x), unit(%d)\n", audioio
,
1423 audioio
->ioa_Request
.io_Unit
));
1425 if ((unit
= (((IPTR
) audioio
->ioa_Request
.io_Unit
) & 15)))
1429 chan
= writechn
[unit
]; // Get the lowest channel.
1430 channel
= eta
->et_units
[chan
];
1431 if (channel
->eu_allockey
== audioio
->ioa_AllocKey
)
1433 final
|= 1 << chan
; // Ok for this unit the command is successful.
1434 UnitAHIPerVol(channel
, audioio
);
1438 error
= ADIOERR_NOALLOCATION
;
1441 unit
&= ~(1 << chan
);
1446 error
= ADIOERR_NOALLOCATION
;
1449 audioio
->ioa_Request
.io_Unit
= (struct Unit
*) (IPTR
) final
;
1450 audioio
->ioa_Request
.io_Error
= error
;
1451 Signal(audioio
->ioa_Request
.io_Message
.mn_ReplyPort
->mp_SigTask
, STOLEN_SIG
);
1461 void audio_PERVOL(struct IOAudio
*audioio
)
1463 struct Task
*oldtask
;
1466 oldtask
= audioio
->ioa_Request
.io_Message
.mn_ReplyPort
->mp_SigTask
;
1467 audioio
->ioa_Request
.io_Message
.mn_ReplyPort
->mp_SigTask
= FindTask(NULL
);
1468 oldsignals
= SetSignal(0, STOLEN_SIG
);
1470 PutMsg(global_eta
->et_portunits
, (struct Message
*) audioio
);
1473 audioio
->ioa_Request
.io_Message
.mn_ReplyPort
->mp_SigTask
= oldtask
;
1474 SetSignal(oldsignals
, STOLEN_SIG
);
1476 if ((audioio
->ioa_Request
.io_Flags
& IOF_QUICK
) == 0)
1478 ReplyMsg(&audioio
->ioa_Request
.io_Message
);
1482 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1488 * Scans the waitcyclelist and if there are some IOAudio waiting for the end of the wave it reply them to their tasks.
1492 VOID
ReplyWaitCycles(EUNIT
*unit
, ETASK
*eta
)
1494 struct IOAudio
*waitio
;
1496 while ((waitio
= (struct IOAudio
*) RemHead(&unit
->eu_waitcyclelist
)))
1498 D(bug("NEWD: ReplyWaitCycles(): Found IOAuido (%x) in waitcyclelist, now i reply it.\n",
1501 ReplyMsg(&waitio
->ioa_Request
.io_Message
);
1511 void audio_WAITCYCLE(struct IOAudio
*audioio
)
1515 D(bug("NEWD: Arrived ADCMD_WAITCYCLE from IOAudio (%x), unit(%d)\n",
1516 audioio
, audioio
->ioa_Request
.io_Unit
));
1518 unit
= (IPTR
) audioio
->ioa_Request
.io_Unit
;
1520 PutMsg(global_eta
->et_portunits
, (struct Message
*) audioio
); // For the ADCMD_WAITCYCLE only one unit accepted but i send it to the allunit msgport.
1521 Wait(1 << audioio
->ioa_Request
.io_Message
.mn_ReplyPort
->mp_SigBit
);
1523 if ((audioio
->ioa_Request
.io_Flags
& IOF_QUICK
) == 0)
1525 if (audioio
->ioa_Request
.io_Error
== ADIOERR_NOALLOCATION
)
1527 ReplyMsg(&audioio
->ioa_Request
.io_Message
);
1531 if (unit
!= (IPTR
) audioio
->ioa_Request
.io_Unit
) // If the value changed it isn't waiting for anyone so please reply.
1533 ReplyMsg(&audioio
->ioa_Request
.io_Message
);
1545 VOID
_ADCMD_WAITCYCLE(struct IOAudio
*audioio
, ETASK
*eta
)
1547 UBYTE unit
, chan
; // For the CMD_READ only one unit accepted.
1550 unit
= (IPTR
) audioio
->ioa_Request
.io_Unit
;
1551 chan
= writechn
[unit
& 15];
1553 if ((channel
= eta
->et_units
[chan
]))
1555 if (audioio
->ioa_AllocKey
== channel
->eu_allockey
)
1557 D(bug("NEWD: Arrived ADCMD_WAITCYCLE from IOAudio (%x),for unit (%d)\n",
1558 audioio
, channel
->eu_id
));
1560 if (channel
->eu_usingme
) // Yes there is a wave in execution.
1562 IPTR tmpunit
= (IPTR
) audioio
->ioa_Request
.io_Unit
;
1563 tmpunit
|= (1 << channel
->eu_id
);
1564 audioio
->ioa_Request
.io_Unit
= (APTR
) tmpunit
;
1566 audioio
->ioa_Request
.io_Error
= IONOERROR
;
1567 audioio
->ioa_Request
.io_Flags
&= ~IOF_QUICK
; // It becames async so clear IOF_QUICK.
1569 // Put the iorequest in waitcyclelist.
1570 Signal(audioio
->ioa_Request
.io_Message
.mn_ReplyPort
->mp_SigTask
,
1571 1 << audioio
->ioa_Request
.io_Message
.mn_ReplyPort
->mp_SigBit
);
1575 else // No, no wave in execution.
1577 IPTR tmpunit
= (IPTR
) audioio
->ioa_Request
.io_Unit
;
1578 tmpunit
&= ~(1 << channel
->eu_id
);
1579 audioio
->ioa_Request
.io_Unit
= (APTR
) tmpunit
;
1581 audioio
->ioa_Request
.io_Error
= IONOERROR
;
1582 Signal(audioio
->ioa_Request
.io_Message
.mn_ReplyPort
->mp_SigTask
,
1583 1 << audioio
->ioa_Request
.io_Message
.mn_ReplyPort
->mp_SigBit
);
1588 if (channel
->eu_usingme
)
1590 audioio
->ioa_Data
= (UBYTE
*) channel
->eu_usingme
;
1594 audioio
->ioa_Data
= NULL
;
1597 IPTR tmpunit
= (IPTR
) audioio
->ioa_Request
.io_Unit
;
1598 tmpunit
|= (1 << channel
->eu_id
);
1599 audioio
->ioa_Request
.io_Unit
= (APTR
) tmpunit
;
1601 audioio
->ioa_Request
.io_Error
= IONOERROR
;
1602 Signal(audioio
->ioa_Request
.io_Message
.mn_ReplyPort
->mp_SigTask
, 1
1603 << audioio
->ioa_Request
.io_Message
.mn_ReplyPort
->mp_SigBit
);
1609 IPTR tmpunit
= (IPTR
) audioio
->ioa_Request
.io_Unit
;
1610 tmpunit
&= ~(1 << channel
->eu_id
);
1611 audioio
->ioa_Request
.io_Unit
= (APTR
) tmpunit
;
1613 audioio
->ioa_Request
.io_Error
= ADIOERR_NOALLOCATION
;
1614 Signal(audioio
->ioa_Request
.io_Message
.mn_ReplyPort
->mp_SigTask
, 1
1615 << audioio
->ioa_Request
.io_Message
.mn_ReplyPort
->mp_SigBit
);
1618 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1620 VOID
StartWaiting(EUNIT
*unit
, ETASK
*eta
)
1622 struct IOAudio
*audioio
;
1624 if ((audioio
= (struct IOAudio
*) RemHead(&unit
->eu_writewaitlist
)))
1626 UnitCopyData(unit
, audioio
);
1629 if ((audioio
= (struct IOAudio
*) RemHead(&unit
->eu_writewaitlist
)))
1631 UnitCopyData(unit
, audioio
);
1640 * - Here is calles CMD_WRITE but it signals to the port. Pay attention or better remove it.
1643 VOID
_CMD_START(struct IOAudio
*audioio
, ETASK
*eta
)
1645 BYTE unit
, chan
, final
= 0;
1647 UBYTE error
= IONOERROR
;
1649 D(bug("NEWD: Arrived CMD_START from IOAudio (%x), unit(%d)\n", audioio
,
1650 audioio
->ioa_Request
.io_Unit
));
1652 if ((unit
= (((IPTR
) audioio
->ioa_Request
.io_Unit
) & 15)))
1656 chan
= writechn
[unit
]; // Get the lowest channel.
1657 channel
= eta
->et_units
[chan
];
1659 if (channel
->eu_allockey
== audioio
->ioa_AllocKey
)
1661 final
|= 1 << chan
; // Ok for this unit the command is successful.
1662 channel
->eu_status
&= ~UNIT_STOP
; // The unit now is ready.
1663 StartWaiting(channel
, eta
);
1667 error
= ADIOERR_NOALLOCATION
;
1670 unit
&= ~(1 << chan
);
1675 error
= ADIOERR_NOALLOCATION
;
1678 audioio
->ioa_Request
.io_Unit
= (struct Unit
*) ((IPTR
) final
);
1679 audioio
->ioa_Request
.io_Error
= error
;
1680 Signal(ematsys
->ts_calltask
, STOLEN_SIG
);
1689 void audio_START(struct IOAudio
*audioio
)
1693 ematsys
->ts_calltask
= FindTask(NULL
);
1694 oldsignals
= SetSignal(0, STOLEN_SIG
);
1696 PutMsg(global_eta
->et_portunits
, (struct Message
*) audioio
);
1698 SetSignal(oldsignals
, STOLEN_SIG
);
1700 if ((audioio
->ioa_Request
.io_Flags
& IOF_QUICK
) == 0)
1702 ReplyMsg(&audioio
->ioa_Request
.io_Message
);
1706 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1712 * - I have to stop the audio if the unit was outputting it. But it isn't removed now. I simply abort the AHI. Wait for a program
1713 * which uses differently CMD_STOP and CMD_START please.
1716 VOID
_CMD_STOP(struct IOAudio
*audioio
, ETASK
*eta
)
1718 BYTE unit
, chan
, final
= 0;
1720 UBYTE error
= IONOERROR
;
1722 D(bug("NEWD: Arrived CMD_STOP from IOAudio (%x), unit(%d)\n", audioio
,
1723 audioio
->ioa_Request
.io_Unit
));
1725 if ((unit
= (((IPTR
) audioio
->ioa_Request
.io_Unit
) & 15)))
1729 chan
= writechn
[unit
]; // Get the lowest channel.
1730 channel
= eta
->et_units
[chan
];
1732 if (channel
->eu_allockey
== audioio
->ioa_AllocKey
)
1734 final
|= 1 << chan
; // Ok for this unit the command is successful.
1735 channel
->eu_status
|= UNIT_STOP
; // The unit now is stopped.
1737 // stop the output if there is.
1739 if (channel
->eu_usingme
) // Is in execution ?
1741 if (!(CheckIO((struct IORequest
*) &channel
->eu_ahireq
)))
1743 AbortIO((struct IORequest
*) &channel
->eu_ahireq
);
1744 WaitIO((struct IORequest
*) &channel
->eu_ahireq
);
1747 channel
->eu_usingme
= NULL
; // For now i abort it but probably i have to pay attention more here.
1753 error
= ADIOERR_NOALLOCATION
;
1756 unit
&= ~(1 << chan
);
1761 error
= ADIOERR_NOALLOCATION
;
1764 audioio
->ioa_Request
.io_Unit
= (struct Unit
*) (IPTR
) final
;
1765 audioio
->ioa_Request
.io_Error
= error
;
1766 Signal(ematsys
->ts_calltask
, STOLEN_SIG
);
1775 void audio_STOP(struct IOAudio
*audioio
)
1779 ematsys
->ts_calltask
= FindTask(NULL
);
1780 oldsignals
= SetSignal(0, STOLEN_SIG
);
1782 PutMsg(global_eta
->et_portunits
, (struct Message
*) audioio
);
1783 //Wait(1 << audioio->ioa_Request.io_Message.mn_ReplyPort->mp_SigBit);
1785 SetSignal(oldsignals
, STOLEN_SIG
);
1787 if ((audioio
->ioa_Request
.io_Flags
& IOF_QUICK
) == 0)
1789 ReplyMsg(&audioio
->ioa_Request
.io_Message
);
1793 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1801 void audio_READ(struct IOAudio
*audioio
)
1803 D(bug("NEWD: Arrived CMD_READ from IOAudio (%x)\n", audioio
));
1805 PutMsg(global_eta
->et_portunits
, (struct Message
*) audioio
); // For the CMD_READ only one unit accepted but i send it to the allunit msgport.
1806 Wait(1 << audioio
->ioa_Request
.io_Message
.mn_ReplyPort
->mp_SigBit
);
1808 if ((audioio
->ioa_Request
.io_Flags
& IOF_QUICK
) == 0)
1810 ReplyMsg(&audioio
->ioa_Request
.io_Message
);
1820 VOID
_CMD_READ(struct IOAudio
*audioio
, ETASK
*eta
)
1822 UBYTE unit
, chan
; // For the CMD_READ only one unit accepted.
1825 unit
= (IPTR
) audioio
->ioa_Request
.io_Unit
;
1826 chan
= writechn
[unit
& 15];
1828 if ((channel
= eta
->et_units
[chan
]))
1830 if (audioio
->ioa_AllocKey
== channel
->eu_allockey
)
1832 //if(accessible con io unit)
1834 D(bug("NEWD: Arrived CMD_READ from IOAudio (%x),for unit (%d)\n",
1835 audioio
, channel
->eu_id
));
1837 if (channel
->eu_usingme
)
1839 audioio
->ioa_Data
= (UBYTE
*) channel
->eu_usingme
;
1843 audioio
->ioa_Data
= NULL
;
1846 IPTR tmpunit
= (IPTR
) audioio
->ioa_Request
.io_Unit
;
1847 tmpunit
|= (1 << channel
->eu_id
);
1848 audioio
->ioa_Request
.io_Unit
= (APTR
) tmpunit
;
1850 audioio
->ioa_Request
.io_Error
= IONOERROR
;
1851 Signal(audioio
->ioa_Request
.io_Message
.mn_ReplyPort
->mp_SigTask
,
1852 1 << audioio
->ioa_Request
.io_Message
.mn_ReplyPort
->mp_SigBit
);
1859 IPTR tmpunit
= (IPTR
) audioio
->ioa_Request
.io_Unit
;
1860 tmpunit
&= ~(1 << channel
->eu_id
);
1861 audioio
->ioa_Request
.io_Unit
= (APTR
) tmpunit
;
1863 audioio
->ioa_Request
.io_Error
= ADIOERR_NOALLOCATION
;
1864 Signal(audioio
->ioa_Request
.io_Message
.mn_ReplyPort
->mp_SigTask
, 1
1865 << audioio
->ioa_Request
.io_Message
.mn_ReplyPort
->mp_SigBit
);
1868 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1876 void audio_RESET(struct IOAudio
*audioio
)
1878 PutMsg(global_eta
->et_portunits
, (struct Message
*) audioio
);
1879 Wait(1 << audioio
->ioa_Request
.io_Message
.mn_ReplyPort
->mp_SigBit
);
1881 if ((audioio
->ioa_Request
.io_Flags
& IOF_QUICK
) == 0)
1883 ReplyMsg(&audioio
->ioa_Request
.io_Message
);
1887 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1895 void audio_FREE(struct IOAudio
*audioio
)
1899 D(bug("NEWDD: Sendinf CMD_FREE from IOAudio (%x), unit(%d) key %d\n",
1900 audioio
, audioio
->ioa_Request
.io_Unit
, audioio
->ioa_AllocKey
));
1902 ematsys
->ts_calltask
= FindTask(NULL
);
1903 oldsignals
= SetSignal(0, STOLEN_SIG
);
1905 PutMsg(global_eta
->et_portunits
, (struct Message
*) audioio
);
1908 SetSignal(oldsignals
, STOLEN_SIG
);
1910 D(bug("NEWDD: End of wait state for ADCMD_FREE IoAudio (%d), unit(%d)\n",
1911 audioio
, audioio
->ioa_Request
.io_Unit
));
1913 if ((audioio
->ioa_Request
.io_Flags
& IOF_QUICK
) == 0)
1915 ReplyMsg(&audioio
->ioa_Request
.io_Message
);
1919 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1927 VOID
_CMD_FLUSH(struct IOAudio
*audioio
, ETASK
*eta
)
1929 BYTE unit
, chan
, final
= 0;
1931 UBYTE error
= IONOERROR
;
1933 D(bug("NEWD: Arrived CMD_FLUSH from IOAudio (%x), unit(%d), replyport(%x)\n",
1934 audioio
, audioio
->ioa_Request
.io_Unit
, audioio
->ioa_Request
.io_Message
.mn_ReplyPort
));
1936 if ((unit
= (((IPTR
) audioio
->ioa_Request
.io_Unit
) & 15)))
1940 chan
= writechn
[unit
];
1941 channel
= eta
->et_units
[chan
];
1943 if (channel
->eu_allockey
== audioio
->ioa_AllocKey
)
1948 D(bug("NEWD: CMD_FLUSH for unit (%d)\n", chan
));
1952 error
= ADIOERR_NOALLOCATION
;
1955 unit
&= ~(1 << chan
);
1960 error
= ADIOERR_NOALLOCATION
;
1963 audioio
->ioa_Request
.io_Unit
= (struct Unit
*) (IPTR
) final
;
1964 audioio
->ioa_Request
.io_Error
= error
;
1965 Signal(ematsys
->ts_calltask
, STOLEN_SIG
);
1974 void audio_FLUSH(struct IOAudio
*audioio
)
1978 ematsys
->ts_calltask
= FindTask(NULL
);
1980 oldsignals
= SetSignal(0, STOLEN_SIG
); // Change signal set....
1981 PutMsg(global_eta
->et_portunits
, (struct Message
*) audioio
);
1983 SetSignal(oldsignals
, STOLEN_SIG
); // restore signal set.
1985 if ((audioio
->ioa_Request
.io_Flags
& IOF_QUICK
) == 0)
1987 ReplyMsg(&audioio
->ioa_Request
.io_Message
);
1991 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1999 void audio_ALLOCATE(struct IOAudio
*audioio
)
2001 struct Task
*oldtask
;
2004 D(bug("NEWD: ADCMD_ALLOCATE for IOAudio (%x) replyport (%x)\n", audioio
,
2005 audioio
->ioa_Request
.io_Message
.mn_ReplyPort
));
2007 oldtask
= audioio
->ioa_Request
.io_Message
.mn_ReplyPort
->mp_SigTask
;
2008 audioio
->ioa_Request
.io_Message
.mn_ReplyPort
->mp_SigTask
= FindTask(NULL
);
2009 oldsignals
= SetSignal(0, STOLEN_SIG
);
2011 PutMsg(global_eta
->et_portunits
, (struct Message
*) audioio
);
2014 audioio
->ioa_Request
.io_Message
.mn_ReplyPort
->mp_SigTask
= oldtask
;
2015 SetSignal(oldsignals
, STOLEN_SIG
);
2017 if ((audioio
->ioa_Request
.io_Flags
& IOF_QUICK
) == 0)
2019 if ((audioio
->ioa_Request
.io_Error
== ADIOERR_ALLOCFAILED
)
2020 && (audioio
->ioa_Request
.io_Flags
& ADIOF_NOWAIT
))
2022 ReplyMsg(&audioio
->ioa_Request
.io_Message
);
2024 else if (audioio
->ioa_Request
.io_Error
== IONOERROR
)
2026 ReplyMsg(&audioio
->ioa_Request
.io_Message
);
2031 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2039 void audio_WRITE(struct IOAudio
*audioio
)
2041 UBYTE unit
, chan
; // For the CMD_WRITE only one unit accepted.
2042 struct Task
*oldtask
;
2045 D(bug("NEWDD: Received ADCMD_WRITE from task %x\n", FindTask(NULL
)));
2047 unit
= (IPTR
) audioio
->ioa_Request
.io_Unit
;
2048 chan
= writechn
[unit
& 15];
2050 oldtask
= audioio
->ioa_Request
.io_Message
.mn_ReplyPort
->mp_SigTask
;
2051 audioio
->ioa_Request
.io_Message
.mn_ReplyPort
->mp_SigTask
= FindTask(NULL
);
2052 oldsignals
= SetSignal(0, STOLEN_SIG
);
2054 PutMsg(global_eta
->et_ports
[chan
], (struct Message
*) audioio
);
2057 audioio
->ioa_Request
.io_Message
.mn_ReplyPort
->mp_SigTask
= oldtask
;
2058 SetSignal(oldsignals
, STOLEN_SIG
);
2061 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2064 BOOL
AbortIOUnit(struct IOAudio
*audioio
, EUNIT
*unit
)
2066 if (unit
->eu_audioio
== audioio
) // Is in pre-cache?
2068 unit
->eu_audioio
= NULL
;
2069 //audioio->ioa_Request.io_Error = IONOERROR;
2071 D(bug("NEWD: ABORTIO IOAudio %x was in pre-cache, now replied\n",
2076 if (unit
->eu_usingme
== audioio
) // Is in execution ?
2078 if (!(CheckIO((struct IORequest
*) &unit
->eu_ahireq
)))
2080 D(bug("NEWD: It was really in execution\n"));
2082 AbortIO((struct IORequest
*) &unit
->eu_ahireq
);
2083 WaitIO((struct IORequest
*) &unit
->eu_ahireq
);
2086 unit
->eu_usingme
= NULL
;
2087 //audioio->ioa_Request.io_Error = IONOERROR;
2089 D(bug("NEWD: ABORTIO IOAudio %x was in execution, stopped and replied\n",
2101 * - Remember that AbortIO() could not suspend the wave soon but has to wait for the cycle end. Page 127 RKM.
2104 VOID
_CMD_ABORTIO(struct IOAudio
*audioio
, ETASK
*eta
)
2109 D(bug("NEWD: Received CMD_ABORTIO for IOAudio %x\n", audioio
));
2111 do // First of all verify if the ioaudio is the one present in each unit channel.
2113 if ((result
= AbortIOUnit(audioio
, eta
->et_units
[actunit
])))
2117 } while (++actunit
< 4);
2119 if (!result
) // If it isn't surely it stay in any list. Remove it and reply with IOERR_ABORTED
2121 Remove(&audioio
->ioa_Request
.io_Message
.mn_Node
); // Whereever you are remove it.
2122 audioio
->ioa_Request
.io_Error
= IOERR_ABORTED
;
2124 D(bug("NEWD: ABORTIO IOAudio %x not in pre-cache not in execution\n",
2128 Signal(audioio
->ioa_Request
.io_Message
.mn_ReplyPort
->mp_SigTask
, STOLEN_SIG
);
2135 UnitReWrite(eta->et_units[actunit]);
2136 } while(++actunit < 4);
2146 VOID
audio_ABORTIO(struct IOAudio
*audioio
, ETASK
*eta
)
2149 struct Task
*oldtask
;
2152 oldcmd
= audioio
->ioa_Request
.io_Command
;
2153 audioio
->ioa_Request
.io_Command
= CMD_ABORTIO
;
2155 oldtask
= audioio
->ioa_Request
.io_Message
.mn_ReplyPort
->mp_SigTask
;
2156 audioio
->ioa_Request
.io_Message
.mn_ReplyPort
->mp_SigTask
= FindTask(NULL
);
2157 oldsignals
= SetSignal(0, STOLEN_SIG
);
2158 PutMsg(eta
->et_portunits
, (struct Message
*) audioio
);
2162 audioio
->ioa_Request
.io_Message
.mn_ReplyPort
->mp_SigTask
= oldtask
;
2163 SetSignal(oldsignals
, STOLEN_SIG
);
2165 audioio
->ioa_Request
.io_Command
= oldcmd
;
2166 if ((audioio
->ioa_Request
.io_Flags
& IOF_QUICK
) == 0)
2167 ReplyMsg(&audioio
->ioa_Request
.io_Message
);
2176 VOID
_CMD_CLOSE(struct IOAudio
*audioio
, ETASK
*eta
)
2178 D(bug("NEWD: SLAVE PROCESS OPERATING END by CMD_CLOSE\n"));
2182 Signal(ematsys
->ts_calltask
, STOLEN_SIG
);
2191 VOID
audio_CLOSE(struct IOAudio
*audioio
, ETASK
*eta
)
2196 oldcmd
= audioio
->ioa_Request
.io_Command
;
2197 audioio
->ioa_Request
.io_Command
= CMD_CLOSE
;
2199 ematsys
->ts_calltask
= FindTask(NULL
);
2200 oldsignals
= SetSignal(0, STOLEN_SIG
);
2202 PutMsg(eta
->et_portunits
, (struct Message
*) audioio
);
2205 SetSignal(oldsignals
, STOLEN_SIG
);
2206 audioio
->ioa_Request
.io_Command
= oldcmd
;
2209 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2217 VOID
_CMD_CLEAR(struct IOAudio
*audioio
, ETASK
*eta
)
2219 BYTE unit
, chan
, final
= 0;
2221 UBYTE error
= IONOERROR
;
2223 D(bug("NEWD: Arrived CMD_CLEAR from IOAudio (%x), unit(%d)\n", audioio
,
2224 audioio
->ioa_Request
.io_Unit
));
2226 if ((unit
= (((IPTR
) audioio
->ioa_Request
.io_Unit
) & 15)))
2230 chan
= writechn
[unit
]; // Get the lowest channel.
2231 channel
= eta
->et_units
[chan
];
2233 if (channel
->eu_allockey
== audioio
->ioa_AllocKey
)
2235 final
|= 1 << chan
; // Ok for this unit the command is successful.
2239 error
= ADIOERR_NOALLOCATION
;
2242 unit
&= ~(1 << chan
);
2247 error
= ADIOERR_NOALLOCATION
;
2250 audioio
->ioa_Request
.io_Unit
= (struct Unit
*) (IPTR
) final
;
2251 audioio
->ioa_Request
.io_Error
= error
;
2252 Signal(audioio
->ioa_Request
.io_Message
.mn_ReplyPort
->mp_SigTask
, 1
2253 << audioio
->ioa_Request
.io_Message
.mn_ReplyPort
->mp_SigBit
);
2262 void audio_CLEAR(struct IOAudio
*audioio
)
2264 PutMsg(global_eta
->et_portunits
, (struct Message
*) audioio
);
2265 Wait(1 << audioio
->ioa_Request
.io_Message
.mn_ReplyPort
->mp_SigBit
);
2267 if ((audioio
->ioa_Request
.io_Flags
& IOF_QUICK
) == 0)
2269 ReplyMsg(&audioio
->ioa_Request
.io_Message
);
2273 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2281 VOID
_CMD_UPDATE(struct IOAudio
*audioio
, ETASK
*eta
)
2283 BYTE unit
, chan
, final
= 0;
2285 UBYTE error
= IONOERROR
;
2287 D(bug("NEWD: Arrived CMD_UPDATE from IOAudio (%x), unit(%d)\n", audioio
,
2288 audioio
->ioa_Request
.io_Unit
));
2290 if ((unit
= (((IPTR
) audioio
->ioa_Request
.io_Unit
) & 15)))
2294 chan
= writechn
[unit
]; // Get the lowest channel.
2295 channel
= eta
->et_units
[chan
];
2297 if (channel
->eu_allockey
== audioio
->ioa_AllocKey
)
2299 final
|= 1 << chan
; // Ok for this unit the command is successful.
2303 error
= ADIOERR_NOALLOCATION
;
2306 unit
&= ~(1 << chan
);
2311 error
= ADIOERR_NOALLOCATION
;
2314 audioio
->ioa_Request
.io_Unit
= (struct Unit
*) (IPTR
) final
;
2315 audioio
->ioa_Request
.io_Error
= error
;
2316 Signal(audioio
->ioa_Request
.io_Message
.mn_ReplyPort
->mp_SigTask
, 1
2317 << audioio
->ioa_Request
.io_Message
.mn_ReplyPort
->mp_SigBit
);
2326 void audio_UPDATE(struct IOAudio
*audioio
)
2328 PutMsg(global_eta
->et_portunits
, (struct Message
*) audioio
);
2329 Wait(1 << audioio
->ioa_Request
.io_Message
.mn_ReplyPort
->mp_SigBit
);
2331 if ((audioio
->ioa_Request
.io_Flags
& IOF_QUICK
) == 0)
2333 ReplyMsg(&audioio
->ioa_Request
.io_Message
);
2337 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2346 VOID
_ADCMD_SETPREC(struct IOAudio
*audioio
, ETASK
*eta
)
2348 BYTE unit
, chan
, final
= 0;
2350 UBYTE error
= IONOERROR
;
2352 D(bug("NEWD: Arrived ADCMD_SETPREC from IOAudio (%x), unit(%d)\n", audioio
,
2353 audioio
->ioa_Request
.io_Unit
));
2355 if ((unit
= (((IPTR
) audioio
->ioa_Request
.io_Unit
) & 15)))
2359 chan
= writechn
[unit
]; // Get the lowest channel.
2360 channel
= eta
->et_units
[chan
];
2362 if (channel
->eu_allockey
== audioio
->ioa_AllocKey
)
2364 final
|= 1 << chan
; // Ok for this unit the command is successful.
2366 = audioio
->ioa_Request
.io_Message
.mn_Node
.ln_Pri
; // Ok, for this unit change the priority.
2370 error
= ADIOERR_NOALLOCATION
;
2373 unit
&= ~(1 << chan
);
2378 error
= ADIOERR_NOALLOCATION
;
2381 audioio
->ioa_Request
.io_Unit
= (struct Unit
*) (IPTR
) final
;
2382 audioio
->ioa_Request
.io_Error
= error
;
2383 Signal(audioio
->ioa_Request
.io_Message
.mn_ReplyPort
->mp_SigTask
, 1
2384 << audioio
->ioa_Request
.io_Message
.mn_ReplyPort
->mp_SigBit
);
2386 // Now, because the priority of the channel is modified retry, if there are, to allocate some waiting requests for.
2390 ReAllocateUnits(eta
);
2400 void audio_SETPREC(struct IOAudio
*audioio
)
2402 PutMsg(global_eta
->et_portunits
, (struct Message
*) audioio
);
2403 Wait(1 << audioio
->ioa_Request
.io_Message
.mn_ReplyPort
->mp_SigBit
);
2405 if ((audioio
->ioa_Request
.io_Flags
& IOF_QUICK
) == 0)
2407 ReplyMsg(&audioio
->ioa_Request
.io_Message
);
2411 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////