home *** CD-ROM | disk | FTP | other *** search
- /* ___________________________________________________________________________
- ** |*************************************************************************|
- ** |*|¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯|*|¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯|*|
- ** |*| Set TAB to 4 for best readable file layout. |*| C++ MaxonDev 4.0 |*|
- ** |*|______________________________________________|*|____________________|*|
- ** |*************************************************************************|
- ** |*|¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯|*|¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯|*|
- ** |*| |*| $Id: rhosigma.c (28.04.01) |*|
- ** |*| ###### ###### |*| RhoSigma Source based on NDK 3.1 Includes 40.15 |*|
- ** |*| ## ## ## # |*| _________________________________________________ |*|
- ** |*| ## ## ## |*| |*|
- ** |*| ###### ## |*| Source file with RhoSigma's support functions |*|
- ** |*| ## ## |*| |*|
- ** |*| ## ## # |*| ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ |*|
- ** |*| ## ###### |*| Copyright © 1998-2001 RhoSigma, Roland Heyder |*|
- ** |*| |*| All Rights Reserved. |*|
- ** |*|_______________|*|___________________________________________________|*|
- ** |*************************************************************************|
- ** ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
- */
-
- /* Struktur-Includes */
- #include <exec/types.h>
-
- /* Library-Includes */
- #include <stdarg.h>
- #include <string.h>
- #include <clib/alib_protos.h>
- #include <pragma/exec_lib.h>
-
- /* Source-Header */
- #include <rhosigma/rhosigma.h>
-
- /*
- ** ---------------------------------------
- ** Funktionen aus RhoSigma-Include-Dateien
- ** ---------------------------------------
- */
-
- /* deklariert in »settings.h« */
- VOID DAJOIN(UWORD Count, ...)
- {
- STRPTR TxtPtr;
- WORD *xPosPtr;
- UWORD TxtLen, SpcLen, ArgCnt;
- va_list ArgPtr;
-
- va_start(ArgPtr, Count);
- for (ArgCnt=NULL; ArgCnt<Count; ArgCnt++)
- {
- /* Füllbytes von NULL auf SPACE ändern */
- TxtPtr = va_arg(ArgPtr, STRPTR);
- TxtLen = strlen(TxtPtr+3);
- SpcLen = (3-((TxtLen)&3));
- strncat(TxtPtr+3," ",SpcLen);
-
- /* gewünschte Ausrichtung berechnen */
- xPosPtr = (WORD*) TxtPtr;
- if (xPosPtr[0] == (WORD) DATPOS_C) xPosPtr[0] = (640-(TxtLen*8))/2
- else if (xPosPtr[0] == (WORD) DATPOS_L) xPosPtr[0] = 12;
- else if (xPosPtr[0] == (WORD) DATPOS_R) xPosPtr[0] = (640-(TxtLen*8))-12;
- }
- }
-
- /* deklariert in »extradefs.h« */
- VOID SMTJOIN(UWORD Count, ...)
- {
- STRPTR TxtPtr;
- WORD *xPosPtr;
- UWORD TxtLen, SpcLen, ArgCnt;
- va_list ArgPtr;
-
- va_start(ArgPtr, Count);
- for (ArgCnt=NULL; ArgCnt<Count; ArgCnt++)
- {
- /* Füllbytes von NULL auf SPACE ändern */
- TxtPtr = va_arg(ArgPtr, STRPTR);
- if (TxtPtr[3] == (UBYTE) FALSE)
- {
- TxtLen = strlen(TxtPtr+4);
- SpcLen = ((6-((TxtLen)&3))&3);
- strncat(TxtPtr+4," ",SpcLen);
- }
- else
- {
- TxtLen = strlen(TxtPtr+9);
- SpcLen = ((5-((TxtLen)&3))&3);
- strncat(TxtPtr+9," ",SpcLen);
- }
-
- /* gewünschte Ausrichtung berechnen */
- xPosPtr = (WORD*) TxtPtr;
- if (xPosPtr[0] == (WORD) SMTPOS_C) xPosPtr[0] = (640-(TxtLen*8))/2
- else if (xPosPtr[0] == (WORD) SMTPOS_L) xPosPtr[0] = 12;
- else if (xPosPtr[0] == (WORD) SMTPOS_R) xPosPtr[0] = (640-(TxtLen*8))-12;
- }
- }
-
- /*
- ** ----------------------------------------
- ** Support-Funktionen für Device-Handhabung
- ** ----------------------------------------
- */
-
- /*** rhosigma / GetIOReq() V2.118 ***
- *»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
- * Diese Funktion belegt und initialisiert einen neuen IORequest, welcher dann
- * zur Kommunikation mit Devices verwendet werden kann.
- * Da diese Routine universell einsetzbar sein soll, wird jedoch nur ein APTR
- * auf eine beliebige Struktur zurückgegeben, die man dann »casten« kann.
- *-----------------------------------------------------------------------------
- * Synopsis: IOReq = GetIOReq (Size)
- *
- * Eingaben: Size --> (UWORD) Größe des benötigten IORequests in Byte.
- *
- * Ergebnis: IOReq --> (APTR) Zeiger auf den neuen IORequest oder NULL,
- * wenn der Request nicht belegt werden konnte.
- *
- * Bemerkung: Die Ursache für das Fehlschlagen dieser Funktion ist entweder
- * Speichermangel, oder es war kein Signal-Bit für den Reply-Port
- * des IORequests mehr frei.
- *
- * Siehe auch: »CopyIOReq()«, »FreeIOReq()«
- *«««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««*/
-
- APTR GetIOReq(UWORD Size)
- {
- APTR IOReq = NULL;
-
- /* versuche Reply-Port zu belegen */
- struct MsgPort *Port = CreatePort(NULL,NULL);
- if (Port)
- {
- /* versuche IORequest zu belegen */
- IOReq = (APTR) CreateExtIO(Port,Size);
- if (!IOReq) DeletePort(Port);
- }
-
- /* initialisierter IORequest */
- return IOReq;
- }
-
- /*** rhosigma / CopyIOReq() V2.118 ***
- *»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
- * Diese Funktion legt eine Kopie von einem IORequest an, damit man z.B. für
- * Lese- und Schreibzugriffe einen seperaten Request zur Verfügung hat.
- * Da diese Routine universell einsetzbar sein soll, wird jedoch nur ein APTR
- * auf eine beliebige Struktur zurückgegeben, die man dann »casten« kann.
- *-----------------------------------------------------------------------------
- * Synopsis: CopyReq = CopyIOReq(OrigReq)
- *
- * Eingaben: OrigReq --> (APTR) Zeiger auf einen über »exec/OpenDevice()« be-
- * reits vollständig initialisierten IORequest.
- *
- * Ergebnis: CopyReq --> (APTR) Zeiger auf den neuen IORequest oder NULL,
- * wenn der Request nicht belegt werden konnte.
- *
- * Bemerkung: Die Ursache für das Fehlschlagen dieser Funktion ist entweder
- * Speichermangel, oder es war kein Signal-Bit für den Reply-Port
- * des IORequests mehr frei.
- * Der mit dieser Funktion erstellte IORequest muß, wenn er nicht
- * mehr benötigt wird, ebenfalls mit »FreeIOReq()« wieder freige-
- * geben werden.
- *
- * ACHTUNG: Sie dürfen niemals einen kopierten IORequest bei einen Aufruf
- * ¯¯¯¯¯¯¯¯ der Funktion »exec/CloseDevice()« verwenden. Benutzen Sie zu
- * diesem Zwecke immer den originalen IORequest, mit dem Sie auch
- * die Funktion »exec/OpenDevice()« aufgerufen haben.
- *
- * Siehe auch: »GetIOReq()«, »FreeIOReq()«
- *«««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««*/
-
- APTR CopyIOReq(APTR OrigReq)
- {
- /* APTR casten */
- struct IORequest *OldReq = (struct IORequest*) OrigReq;
-
- /* neuen IORequest mit entsprechender Size anfordern */
- APTR CopyReq = GetIOReq(OldReq -> io_Message.mn_Length);
- if (CopyReq)
- {
- /* neuen APTR jetzt casten */
- struct IORequest *NewReq = (struct IORequest*) CopyReq;
-
- /* alle wichtigen Einträge übertragen */
- NewReq -> io_Message.mn_Node.ln_Type = OldReq -> io_Message.mn_Node.ln_Type;
- NewReq -> io_Message.mn_Node.ln_Pri = OldReq -> io_Message.mn_Node.ln_Pri;
- NewReq -> io_Message.mn_Node.ln_Name = OldReq -> io_Message.mn_Node.ln_Name;
- NewReq -> io_Message.mn_Length = OldReq -> io_Message.mn_Length;
- NewReq -> io_Device = OldReq -> io_Device;
- NewReq -> io_Unit = OldReq -> io_Unit;
- }
-
- // initialisierter neuer IORequest */
- return CopyReq;
- }
-
- /*** rhosigma / FreeIOReq() V2.118 ***
- *»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
- * Diese Funktion gibt einen IORequest und alle damit verbundenen Resourcen
- * wieder an das System zurück.
- *-----------------------------------------------------------------------------
- * Synopsis: VOID FreeIOReq (IOReq)
- *
- * Eingaben: IOReq --> (APTR) Zeiger auf den freizugebenden IORequest.
- *
- * ACHTUNG: Diese Funktion darf nur für IORequests aufgerufen werden, die
- * ¯¯¯¯¯¯¯¯ entweder direkt mit der Funktion »GetIOReq()«, oder indirekt
- * über die Funktion »CopyIOReq()« erstellt worden sind.
- *
- * Siehe auch: »GetIOReq()«, »CopyIOReq()«
- *«««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««*/
-
- VOID FreeIOReq(APTR IOReq)
- {
- /* APTR casten */
- struct IORequest *Req = (struct IORequest*) IOReq;
-
- /* Wenn IORequest != NULL, dann erst Reply-Port und dann */
- /* IORequest selbst freigeben */
- if (Req)
- {
- struct MsgPort *Port = Req -> io_Message.mn_ReplyPort;
- if (Port) DeletePort(Port);
- DeleteExtIO(Req);
- }
- }
-
- /*** rhosigma / DoCMD() V2.118 ***
- *»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
- * Diese Funktion initialisiert den IORequest mit dem angegbenen Kommando
- * und sendet dieses dann im synchronen IO-Modus an das Device.
- *-----------------------------------------------------------------------------
- * Synopsis: Error = DoCMD (IOReq, Comm)
- *
- * Eingaben: IOReq --> (APTR) Zeiger auf den IORequest des anzusprechen-
- * den Devices.
- * Comm --> (UWORD) Auszuführendes Device-Kommando.
- *
- * Ergebnis: Error --> (BYTE) Ist NULL, wenn alles in Ordnung, sonst eine
- * Fehlernummer des angesprochenen Devices
- * (s.a. Device-Includes).
- *
- * Siehe auch: »SendCMD()«, »WaitCMD()«
- *«««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««*/
-
- BYTE DoCMD(APTR IOReq,UWORD Comm)
- {
- /* APTR casten */
- struct IORequest *Req = (struct IORequest*) IOReq;
-
- /* IORequest mit Device-Kommando laden und Request ans Device senden */
- /* und Ergebnis des Aufrufs zurückgeben */
- Req -> io_Command = Comm;
- return DoIO(Req);
- }
-
- /*** rhosigma / SendCMD() V2.118 ***
- *»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
- * Diese Funktion initialisiert den IORequest mit dem angegbenen Kommando
- * und sendet dieses dann im asynchronen IO-Modus an das Device.
- *-----------------------------------------------------------------------------
- * Synopsis: VOID SendCMD (IOReq, Comm)
- *
- * Eingaben: IOReq --> (APTR) Zeiger auf den IORequest des anzusprechen-
- * den Devices.
- * Comm --> (UWORD) Auszuführendes Device-Kommando.
- *
- * Bemerkung: Da diese Funktion nicht auf die Beendigung des IO-Vorgangs
- * wartet, kann sie natürlich auch keine Auskunft über Erfolg oder
- * Fehlschlag des selbigen geben. Sie sollten daher, wenn Sie mit
- * den anderen Dingen, welche Sie asynchron nebenherlaufen lassen
- * haben, fertig sind, die Funktion »WaitCMD()« aufrufen, welche
- * sowohl die eventuelle Fehlernummer liefert, sowie die erforder-
- * lichen Abschlußarbeiten erledigt.
- *
- * Siehe auch: »DoCMD()«, »WaitCMD()«
- *«««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««*/
-
- VOID SendCMD(APTR IOReq,UWORD Comm)
- {
- /* APTR casten */
- struct IORequest *Req = (struct IORequest*) IOReq;
-
- /* IORequest mit Device-Kommando laden und ans Device senden */
- Req -> io_Command = Comm;
- SendIO(Req);
- }
-
- /*** rhosigma / WaitCMD() V2.118 ***
- *»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»
- * Diese Funktion wartet auf die Beendigung eines zuvor mittels »SendCMD()« ge-
- * starteten asynchronen IO-Vorgangs.
- *-----------------------------------------------------------------------------
- * Synopsis: Error = WaitCMD (IOReq)
- *
- * Eingaben: IOReq --> (APTR) Zeiger auf einen bereits an ein Device ge-
- * sendeten IORequest.
- *
- * Ergebnis: Error --> (BYTE) Ist NULL, wenn alles in Ordnung, sonst eine
- * Fehlernummer des angesprochenen Devices
- * (s.a. Device-Includes).
- *
- * Bemerkung: Mit einem »SendCMD()/WaitCMD()«-Paar erreichen Sie praktisch
- * das geleiche, wie mit einem Aufruf von »DoCMD()«, nur mit dem
- * Unterschied, daß Ihr Task bei letzteren in Wartestatus ver-
- * setzt wird, und Sie bei ersterer Methode während der anfallen-
- * den Wartezeit (z.B. wenn eine Disk geladen wird) anderen Auf-
- * gaben nachgehen können (z.B. Berechnungen etc.). Sollte der
- * IO-Vorgang bereits beendet sein, wenn Sie diese Funktion auf-
- * rufen, dann kehrt sie unverzüglich mit entsprechenden Ergebnis
- * zurück.
- *
- * Siehe auch: »DoCMD()«, »SendCMD()«
- *«««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««*/
-
- BYTE WaitCMD(APTR IOReq)
- {
- /* APTR casten */
- struct IORequest *Req = (struct IORequest*) IOReq;
-
- /* Auf Beendigung des IO-Vorgangs warten und Fehler merken */
- BYTE Err = WaitIO(Req);
-
- /* Eventuell noch gesetztes Signal-Bit löschen */
- /* dazu zuerst Signal-Bit ermitteln */
- struct MsgPort *Port = Req -> io_Message.mn_ReplyPort;
- ULONG SigMask = 1<<(Port -> mp_SigBit);
-
- /* Dann Signal-Task ermitteln und Bit löschen */
- struct Task *Tcb = (struct Task*) Port -> mp_SigTask;
- Tcb -> tc_SigRecvd = ((Tcb -> tc_SigRecvd)|SigMask)^SigMask;
-
- /* Funktion beenden und Fehler zurückgeben */
- return Err;
- }
-
-