Festlegung einer Softwareschnittstelle, die eine vollstndig
hardwareunabhngige Nutzung serieller Interfaces ermglicht
============================================================

Definition of a software interface, providing a fully hardware
independend use of serial interfaces
==============================================================
This file contains the english version too, begin to search at the 
middle of the text.


Text von: Harun Scheutzow, Dresdener Strae 83, D-10179 Berlin
Internet-Email: Harun_Scheutzow@B.maus.de
letzte nderung der Definition: 12.11.1993
letzte nderung der Erklrungen: 14.07.1995

Es sollen mglichst alle Funktionen definiert werden, die ein 
Terminalprogramm, ein bertragungsprotokoll oder z.B. ein Faxprogramm 
bentigt. Diese Funktionen sollen ein hardwareunabhngiges Interface fr 
Programme darstellen.

Dieser Vorschlag ist Eric Smith bekannt. Es ist (noch?) KEIN 
offizieller Atari-Standard. Eric findet den Vorschlag gut (nur die 
Callbacks hlt er bezglich Memory Protection fr nicht so toll) und 
meint: Es ist besser, einen inoffiziellen Standard zu haben, als gar 
keinen. Originalton im englischen Teil.

MiNT oder TOS oder ein nachzuladender Treiber sollen mglichst viele der 
hier beschriebenen Funktionen untersttzen, soweit es die Hardware zult. 
Es mu aber jede Soft damit rechnen, da eine Funktion nicht existiert 
(Rckmeldung EINVFN, -32). Verhindert dies die Arbeit der Soft, so mu der 
Nutzer darber informiert werden.

Dies hier ist ein Standardisierungsversuch fr das Interface, das 
Nutzerprogramme vorfinden. ber die Interna der Treiberimplementation soll 
nichts geschrieben werden. Bei allen Funktionen und Vorschlgen mu aber 
daran gedacht werden, da diese auch auf einem 68000 mit 8MHz bei 38400Bd 
ber den MFP (also ohne FIFO) realisierbar sind. Die steigende Leistung der 
CPUs ist kein Argument, da die gewnschte Datentransferrate auch stndig 
steigt.


Fopen, Fread, Fwrite, Fclose drften als normale GEMDOS-Funktionen jedem 
bekannt sein. Fcntl ist die im MiNT (und in HSMODEM) vorhandene 
GEMDOS-Funktion $104, mit LONG Fcntl( WORD filehandle, void * special, 
WORD subfunction). Fcntl liefert meist eine 0 als OK-Meldung, oder sonst 
einen Fehlercode. "filehandle" ist das GEMDOS-Filehandle, wie es auch fr 
Fread und Fwrite benutzt wird. "subfunction" ist ein 16-Bit-Wert, der die 
auszufhrende Funktion angibt. "special" ist ein Zeiger auf eine 
Speicherstelle, deren Datentyp (WORD, LONG, irgendeine Struktur) bei den 
einzelnen Unterfunktionen angegeben ist. Auf dieser Speicherstelle 
erwartet Fcntl seine Eingabeparameter. Eventuelle Rckgabeparameter werden 
ebenfalls auf dieser Speicherstelle hinterlassen.

Die Reservierung einer Schnittstelle will ich ber den ffnungsmodus von Fopen 
realisieren.



Hier ein Versuch der Dokumentation, was MiNT bereits bieten soll. 
Allerdings sind in MiNT nicht alle Funktionen vorhanden oder funktionieren 
nicht ganz, wie sie sollten. 


Manche Zeilen sind C, manche Kommentar. Bei den angegebenen 
Funktionsaufrufen handelt es sich wirklich um Musteraufrufe, und nicht etwa 
um migestaltete Prototypen.



Ermittlung, wieviel Byte nichtblockierend bertragen werden knnen
------------------------------------------------------------------
#define FIONREAD  (('F'<< 8) | 1)
#define FIONWRITE (('F'<< 8) | 2)
Fcntl( handle, &count, FIONREAD)
Fcntl( handle, &count, FIONWRITE)
In count wird als 32Bit-Wert die Anzahl der Byte hinterlassen, die beim 
nchsten Fread/Fwrite mindestens gelesen/geschrieben werden knnen. Da 
aber mglicherweise mehrere Programme auf einen Port schreiben knnten, 
sollte man nur den Returnwert von Fread/Fwrite fr voll nehmen.


Setzen und Rcksetzen von Break
-------------------------------
#define TIOCCBRK (('T'<< 8) | 20)
#define TIOCSBRK (('T'<< 8) | 21)
Fcntl( handle, dummy, TIOCSBRK); /* Break aktivieren */
Fcntl( handle, dummy, TIOCCBRK); /* Break lschen */
Fr "dummy" kann irgendein Zeiger eingesetzt werden, da es nicht 
ausgewertet wird.


Setzen/Abfragen der Eingabegeschwindigkeit und Steuerung der DTR-Leitung
------------------------------------------------------------------------
#define TIOCIBAUD (('T'<< 8) | 18)
Fcntl( handle, &speed, TIOCIBAUD);
Setze die Eingabegeschwindigkeit der Schnittstelle. In speed steht ein 
32Bit-Wert, der die gewnschte Geschwindigkeit unkodiert in Bit pro Sekunde 
angibt. speed = 19200 wrde auf 19200bps setzen. In speed wird die 
Geschwindigkeit vor dem Aufruf von TIOCIBAUD zurckgegeben. Ist sie 
unbekannt, wird -1 geliefert. Ist beim Aufruf speed = -1, so wird nur die 
Geschwindigkeit erfragt. Ist speed = 0, so wird das DTR-Signal auf inaktiv 
gebracht (gelscht), ohne die Geschwindigkeit zu beeinflussen. Bei 
geschwindigkeitssetzendem Aufruf wird DTR automatisch aktiviert. 
Rckgabewert ist ERANGE wenn die Geschwindigkeit nicht einstellbar ist. 
Dann wird als "Ausnahme" in speed die nchstniedrigere mgliche 
Geschwindigkeit geliefert. Gibt es keine nchstniedrige, so wird die 
kleinstmgliche zurckgegeben.


Setzen/Abfragen der Ausgabegeschwindigkeit und Steuerung der DTR-Leitung 
------------------------------------------------------------------------
#define TIOCOBAUD (('T'<< 8) | 19) Fcntl( handle, &speed, TIOCOBAUD);
Setze die Ausgabegeschwindigkeit der Schnittstelle. Die 
Funktionsbeschreibung ist identisch zu TIOCIBAUD. Untersttzt eine 
Schnittstelle getrennte Ein- und Ausgabegeschwindigkeit nicht, so 
beeinflut jeder Aufruf beide Geschwindigkeiten.


bertragungsprotokolleinstellungen erfragen
-------------------------------------------
#define TIOCGFLAGS (('T'<< 8) | 22)
Fcntl( handle, &flags, TIOCGFLAGS);
Liefert in flags einen 16Bit-Wert der eingestellten Parameter, die eine 
ODER-Verknpfung der folgenden Werte darstellen. Alle anderen Bit sind 
reserviert. Bei TIOCGFLAGS sollte man sie ignorieren. Sinnvollerweise 
erfragt man mit TIOCGFLAGS, modifiziert die bekannten Werte, und setzt dann 
per TIOCSFLAGS.

/* Anzahl der Stoppbits */
#define TF_STOPBITS 0x0003
/* 0x0000  nicht erlaubt
ERWEITERUNGSVORSCHLAG: So wird der Synchronmode aktiviert. Die restlichen 
Parameter erhalten im Synchronmode andere Bedeutungen. Diese sind spter 
noch festzulegen. */
#define TF_1STOP   0x0001 /* 1 Stoppbit */
#define TF_15STOP  0x0002 /* 1.5 Stoppbit */
#define	TF_2STOP   0x0003 /* 2 Stoppbit */

/* Anzahl der Bits pro Zeichen */
#define TF_CHARBITS 0x000C
#define TF_8BIT	0x0 /* 8 Bit */
#define TF_7BIT	0x4
#define TF_6BIT	0x8
#define TF_5BIT	0xC /* 5 Bit */

/* Handshakemodi und Paritt */
#define TF_FLAG  0xF000
#define T_TANDEM 0x1000 /* XON/XOFF (=^Q/^S) Flukontrolle aktiv */
#define T_RTSCTS 0x2000 /* RTS/CTS Flukontrolle aktiv */
#define T_EVENP  0x4000 /* even (gerade) Paritt aktiv */
#define T_ODDP   0x8000 /* odd (ungerade) Paritt aktiv */
/* even und odd schlieen sich gegenseitig aus */


bertragungsprotokolleinstellungen setzen
-----------------------------------------
#define TIOCSFLAGS (('T'<< 8) | 23)
Fcntl( handle, &flags, TIOCSFLAGS);
Setzt die Einstellungen, Beschreibung dieser bei TIOCGFLAGS. Rckgabewert 
ist ERANGE bei illegaler oder nicht untersttzer Kombination in flags.


Hier endet die Dokumentation der mir bekannten und verstndlichen 
Funktionen in MiNT. Es folgen die neuen Vorschlge.


Leeren der seriellen Puffer
---------------------------
#define TIOCFLUSH (('T'<< 8) | 8)
Fcntl( handle, special, TIOCFLUSH);
(ist doch im Mint "/* BUG: this should flush the input/output buffers */")
Auswhlbar ber den special-Parameter werden die seriellen Puffer 
unterschiedlich geleert:
special  Funktion
0
         Der Sendepuffer soll komplett gesendet werden. Die Funktion kehrt 
         erst zurck, wenn der Puffer leer ist (return E_OK, =0) oder ein 
         systeminterner Timeout abgelaufen ist (return EDRVNR, =-2). Der 
         Timeout wird vom System sinnvoll bestimmt.
1
         Der Empfangspuffer wird gelscht.
2
         Der Sendepuffer wird gelscht.
3
         Empfangspuffer und Sendepuffer werden gelscht.
-tout
         Ein negativer Parameter funktioniert wie 0, aber tout (man 
         beachte, tout selbst ist positiv) gibt den Timeout in 1/200 
         Sekunden vor.

Hier gibt es inzwischen eine Inkompatibilitt zwischen MiNT und den 
HSMODA-Treibern. In neueren MiNT-Versionen sind die Modi 0 bis 3 
realisiert und special ist ein Zeiger auf ein WORD (16 Bit), in dem der 
Modus steht. Bei den HSMODA-Treibern ist special jedoch kein Zeiger, 
sondern der Modus-Wert selbst!


Stoppen des Empfangs
--------------------
#define TIOCSTOP (('T'<< 8) | 9)
Ist nur in den Handshakemodi verfgbar und teilt dem Kommunikationspartner 
mit, da der Rechner nichts empfangen mchte. Die Funktion wartet eine 
sinnvolle Zeitspanne, um in der bertragung befindliche Zeichen 
einzusammeln. Dann geht sie davon aus, da der Partner schweigt und kehrt 
zurck. (Anwendungsbeispiel: Ein 8MHz-ST kann nicht gleichzeitig DMA und 
57600Bd-Empfang ber den MFP.)


Starten des Empfangs
--------------------
#define TIOCSTART (('T'<< 8) | 10)
Hebt die Wirkung von TIOCSTOP auf.


Erfragen/Setzen der Puffereinstellungen
---------------------------------------
#define TIOCBUFFER (('T'<<8) | 128)
special zeigt beim Aufruf auf eine Struktur:
LONG   Gre des Eingabepuffers in Byte
LONG   untere Wassermarke des Eingabepuffers in Byte
LONG   obere Wassermarke des Eingabepuffers in Byte
LONG   Gre des Ausgabepuffers in Byte
Soll ein Wert nur erfragt bzw. nicht gendert werden, so ist anstelle des 
Wertes eine -1 anzugeben. Wird anstelle eines Wertes -1 zurckgegeben, so 
wird diese Funktion nicht untersttzt. Werden Werte gesetzt, so sollte man 
auch den Rckgabewert prfen, da der Treiber bei ihm nicht passenden 
Vorgaben die nchstliegenden ihm passenden Werte einsetzt und benutzt. 
(Hinweis: Es ist allein Sache des Treibers, den Speicher irgendwo zu 
reservieren oder freizugeben. Das kann man auch unter TOS programmieren.)


Erfragen der I/O-Leitungen und Signalisierungsfhigkeiten
---------------------------------------------------------
#define TIOCCTLMAP (('T'<<8) | 129)
special ist Zeiger auf eine Struktur aus 6 LONGs, die durch den Treiber 
ausgefllt wird. In jedem LONG wird fr jede vorhandene 
Steuer/Melde-Leitung oder Fhigkeit das Bit auf 1 gesetzt.
1.LONG: Leitung ber TIOCCTL(GET/SET) abfrag/beeinflubar
2.LONG: Reaktion (Routinenaufruf) bei Eintreten des Zustandes mglich.
3.LONG: Reaktion (Routinenaufruf) bei Beendigung des Zustandes mglich.
4.LONG: reserviert fr zuknftige Erweiterungen, bis dahin 0
5.LONG: reserviert fr zuknftige Erweiterungen, bis dahin 0
6.LONG: reserviert fr zuknftige Erweiterungen, bis dahin 0
Die Zuordnung der Bits zu den "Leitungen" lautet:
#define TIOCM_LE   0x0001 /* line enable output, Ausgang */
#define TIOCM_DTR  0x0002 /* data terminal ready, Ausgang */
#define TIOCM_RTS  0x0004 /* ready to send, hat heute andere Bedeutung,
Ausgang */
#define TIOCM_CTS  0x0008 /* clear to send, hat heute andere Bedeutung,
Eingang */
#define TIOCM_CAR  0x0010 /* data carrier detect, Eingang */
#define TIOCM_CD   TIOCM_CAR /* alternativer Name */
#define TIOCM_RNG  0x0020 /* ring indicator, Eingang */
#define TIOCM_RI   TIOCM_RNG /* alternativer Name */
#define TIOCM_DSR  0x0040 /* data set ready, Eingang */
#define TIOCM_LEI  0x0080 /* line enable input, Eingang */
#define TIOCM_TXD  0x0100 /* Sendedatenleitung, Ausgang */
#define TIOCM_RXD  0x0200 /* Empfangsdatenleitung, Eingang */
#define TIOCM_BRK  0x0400 /* Break erkannt, Pseudo-Eingang */
#define TIOCM_TER  0x0800 /* Sendefehler, Pseudo-Eingang */
#define TIOCM_RER  0x1000 /* Empfangsfehler, Pseudo-Eingang */
#define TIOCM_TBE  0x2000 /* Hardware-Sendepuffer leer, Pseudo-Eingang */
#define TIOCM_RBF  0x4000 /* Hardware-Empfangspuffer voll, Pseudo-Eingang */

Nichtdefinierte Bits sollten ignoriert werden.

Das Nichtvorhandensein einer Leitung im TIOCCTLMAP bedeutet nur, da diese 
Leitung nicht per TIOCCTLxxx abfragbar/steuerbar ist. Es bedeutet nicht, 
da diese Leitung hardwaremig nicht existiert. Es ist mglich, da eine 
Leitung mit Callback-Routinen berwachbar ist, aber nicht mit TIOCCTLGET 
abgefragt werden kann.

Einige TIOCM_* haben Besonderheiten, die hier erklrt werden:

TIOCM_TER, TIOCM_RER
Der Routine wird in D0.b ein Byte bergeben, das den Fehler genauer angibt:
Byte Fehler
0    allgemeiner, nicht genauer spezifizierbarer Fehler
1    Hardware-Empfangspufferberlauf
2    Software-Empfangspufferberlauf
3    Parittsfehler
4    Rahmenfehler

Abfrage von TIOCM_BRK, TIOCM_RER und TIOCM_TER mit TIOCCTLGET: Ein 
auftretender "Fehler" setzt das Statusbit. Eine allgemeine (-1) oder 
spezielle Abfrage (auf BRK, RER, TER) liefert den Zustand des 
entsprechenden Statusbits und setzt es gleichzeitig zurck.

TIOCM_TBE
Der Routine wird in D0.w -1 bergeben, falls im Software-Sendepuffer kein 
Byte mehr ist. Andernfalls wird ein Byte aus dem Software-Sendepuffer 
gelesen und in D0.b bergeben, D0.bit15 ist dann =0. Die Routine gibt in 
D0.w -1 zurck, falls nichts gesendet werden soll. Sie gibt D0.bit15 =0 und 
in D0.b das Byte zurck, falls es gesendet werden soll. Diese Routine wird 
ebenfalls aufgerufen, wenn ein Byte neu in den Software-Sendepuffer 
geschrieben wurde, und der Sendepuffer schon lange leer ist. Gibt diese 
Routine ein selbst erzeugtes -1 zurck und stehen noch Daten im 
Software-Sendepuffer, so wird sie sptestens nach einer Sekunde erneut 
aufgerufen.

TIOCM_RBF
Der Routine wird in D0.b das empfangene Byte bergeben. Sie gibt in D0.w -1 
zurck, falls nichts in den Software-Empfangspuffer geschrieben werden 
soll. Andernfalls gibt sie D0.bit15 =0 und in D0.b das Byte zurck, das in 
den Software-Empfangspuffer geschrieben werden soll.


Abfragen der I/O-Leitungen und Signalisierungen
-----------------------------------------------
#define TIOCCTLGET (('T'<<8) | 130)
liefert auf der durch special angegebenen Speicherstelle ein LONG, in dem 
die aktuellen Zustnde der CTLleitungen abgelegt werden, Kodierung wie bei 
TIOCCTLMAP. Auf special wird auch ein Parameter hin bergeben: Ist er -1, 
so werden alle CTLleitungen erfragt, ist er <>-1, so darf nur ein Bit 
gesetzt sein, und es wird nur diese CTLleitung erfragt. Der Treiber darf 
trotzdem auch die Werte der anderen Leitungen zu liefern. Das geschieht aus 
Geschwindigkeitsgrnden. Unsinnig gesetzte Bits werden ignoriert.


Setzen der I/O-Leitungen und Signalisierungen
-----------------------------------------------
#define TIOCCTLSET (('T'<<8) | 131)
special zeigt auf eine Struktur:
LONG ctlmaske
LONG ctlvalues
Es werden die in ctlmaske gesetzten Bit (Kodierung wie bei TIOCCTLMAP) auf 
die in ctlvalues vorhandenen Werte gesetzt. In ctlmaske darf man natrlich 
nur Bits setzen, deren Funktion man kennt. Eingabeleitungen lassen sich 
nicht beeinflussen, solche Setzversuche werden wie unsinnige Bits 
ignoriert.


Konzept der Callback-Funktionen
-------------------------------
Ein Programm kann Funktionen anmelden, die beim Eintreten bestimmter 
Zustnde sehr schnell aufgerufen werden. Angemeldet wird die Funktion durch 
bergabe ihrer Adresse in procadr. Dabei ist Bit0 immer 0. Abgemeldet wird 
durch den gleichen Aufruf, aber mit gesetzem Bit0 (also =1) in procadr, 
also einer ungeraden Adresse! Bit31-1 mssen genau wie ctlline den gleichen 
Wert wie beim Installieren aufweisen. Wenn bei den einzelnen Funktionen 
nichts anderes steht, gelten folgende Grundstze:
- Nur Register D0 und A0 drfen verndert werden.
- Sie mu extrem kurz sein, mehr als 20 "normale" Assemblerbefehle sind
  unzulssig (ein MOVEM.L D1-D7/A1-A6,... oder DIV ist nicht als "normal"). 
  Anders ausgedrckt: die Laufzeit der Routine sollte auf einer CPU MC68000 
  200 Takte nicht berschreiten.
- Aufruf erfolgt im Supervisormode.
- Der aktuelle InterruptPriorityLevel ist unbestimmt.
- Ende mit RTS.

Es ist denkbar, da mehrere Programme gleichzeitig eine Leitung berwachen. 
Man mu die Routine abmelden, bevor sie durch eine nichtresidente 
Beendigung des Programms aus dem Speicher fliegt. Es ist egal, welcher 
Filehandle zur An-/Abmeldung benutzt wird, wenn er auf das entsprechende 
Device pat (z.B. Fopen, Fcntl(...,TIOCCTLSFAST) /*Anmeldung*/, Fclose, 
... Fopen, Fcntl(...,TIOCCTLSFAST) /*Abmeldung*/, Fclose).

Manche Funktionen werden nur bei bestimmten Handshakemodi existieren und 
knnen nur unter diesen Modi angemeldet, aber unter jedem Modus abgemeldet 
werden. Sie werden beim Umschalten des Handshakes automatisch aktiviert und 
deaktiviert, solange sie angemeldet sind.


Anmelden/Abmelden schneller Callback-Funktionen
-----------------------------------------------
#define TIOCCTLSFAST (('T'<<8) | 132)
Anmelden und Abmelden von Routinen, die bei Statusnderung der CTLleitungen
aufgerufen werden. special ist ein Zeiger auf Struktur:
LONG ctlline
LONG procadr
Die Routine wird mglichst (siehe dazu TIOCCTLMAP) bei jeder Flanke auf der 
in ctlline (dort darf nur ein Bit gesetzt sein, siehe TIOCCTLMAP) 
angegebenen Leitung aufgerufen. Der dabei angenommene neue Pegel der 
Leitung wird in D0.b bergeben: 0 inaktiv (bei DSR wre es TTL-High-Pegel) 
und $FF fr aktiv.
Returnwerte der Funktion:
E_OK    alles OK
1       Routine installiert, aber sie ist nicht die einzige. So langsam wird
        es zeitkritisch, das Programm sollte wenn mglich die Routine wieder
        deinstallieren. (Das ist nur eine Empfehlung)
EINVFN  diese berwachungsmglichkeit gibt es nicht
EACCDN  Routine kann nicht mehr installiert werden.


Anmelden/Abmelden langsamer Callback-Funktionen
-----------------------------------------------
#define TIOCCTLSSLOW (('T'<<8) | 133)
fast identisch zu CTLSIGFAST, mit einem Unterschied: Die Routine darf fast 
beliebig lang sein.


Erfragen der Anzahl noch nicht gesendeter Byte
----------------------------------------------
#define TIONOTSEND (('T'<<8) | 134)
Fcntl( handle, &count, TIONOTSEND)
In count wird als 32Bit-Wert die Anzahl der Byte hinterlassen, die noch 
nicht gesendet wurden. Es wird versucht, im Rahmen der Mglichkeiten 
(Hardware-FIFOs), mglichst genau zu bestimmen, wieviel nichtgesendete 
Zeichen im Rechner sind.


Einstellung des Verhaltens bei Fehlern
--------------------------------------
#define TIOCERROR (('T'<<8) | 135)
Fcntl( handle, &errmode, TIOCERROR);
errmode ist ein LONG. Ist errmode -1, wird in errmode nur die aktuelle 
Einstellung geliefert. Ist errmode >=0, so werden die Einstellungen gesetzt 
und die vorigen Werte geliefert. In Bit7..0 von errmode wird ein Zeichen 
bergeben. Bit8 =1 schaltet das Einfgen dieses Zeichens in den 
Empfangspuffer bei einem Empfangsfehler ein. Normalerweise ist Bit8 =0, bei 
einem Fehler wird kein Zeichen in den Puffer geschrieben. Bit9 =1 schaltet 
das Lschen des Empfangspuffers bei Empfang von Break ein, normalerweise 
ist Bit9 =0 und es erfolgt keine Pufferlschung bei Break. Rckgabewert ist 
E_OK, bei nicht untersttzten Einstellungen ERANGE.


--- Ende des Textes ---




Definition of a software interface, providing a fully hardware
independend use of serial interfaces
==============================================================

written by: Harun Scheutzow, Dresdener Strae 83, D-10179 Berlin
Internet-Email: Harun_Scheutzow@B.maus.de
last change of definition: 12.Nov.1993
last change of explaination: 24.Oct.1994

It should be defined (if possible) all functions, a terminal program, a 
transfer protocol such as ZMODEM or eg. a fax program will need. This 
functions realize a hardware independent interface for programs.

This proposal is known to Eric Smith. He wrote to me last:
"Note that I can't say that this will be an 'official' Atari standard 
right now; we haven't had time to review it completely and make it 
official. But it seems OK to me, and it's better to have an 
unofficial standard than no standard at all, I think."
(Only the callbacks he likes not so much, because of possible problems 
with memory protection).

MiNT or TOS or a loaded driver should support as much as possible of the 
functions described here, if the hardware allows it. But every software has 
to consider, that a function could not exist and only return the error 
EINVFN (-32). If the absence of a function prevents the proper work of the 
software, the user must be informed about this fact by this software.

This is a attemp to standardize the interface found by user programms. 
About the interna of driver implementation nothing should be written. All 
functions and suggestions should be implementable on an 68000 with 8MHz and 
38400Bd transfer by the MFP (68901, without hardware-FIFO). The rising 
performance of the CPUs is no argument, because the demanded data transfer 
rate rises permanently too.


Everybody should know Fopen, Fread, Fwrite, Fclose as normal 
GEMDOS-functions. Fcntl is the GEMDOS-function $104, with LONG Fcntl( WORD 
filehandle, LONG special, WORD subfunction), existing in MiNT (and in 
HSMODEM). Fcntl returns mostly a 0 as OK-message, or otherwise a error 
code. Any requested values are used to return in a memory cell the 
parameter special is pointing to, and not as return code of Fcntl.

Reserving of an interface I like to realize about the opening mode of Fopen.



The description of the following functions is a modified copy from same 
files included in a MiNT distribution.


Some lines are C, some comment. The function calls are really examples and 
not prototypes.


How many bytes may be transfered nonblocking?
---------------------------------------------
#define FIONREAD  (('F'<< 8) | 1)
#define FIONWRITE (('F'<< 8) | 2)
Fcntl( handle, &count, FIONREAD)
Fcntl( handle, &count, FIONWRITE)
count is a 32Bit-value in which the function returns the number of bytes, 
which can be at least read / written during the next Fread/Fwrite. Because 
more than one program could write to a interface, nobody should rely on 
this. Only Fread/Fwrite return, how much byte are really transfered.


Set and Reset Break
-------------------
#define TIOCCBRK (('T'<< 8) | 20)
#define TIOCSBRK (('T'<< 8) | 21)
Fcntl( handle, dummy, TIOCSBRK); /* aktivate Break */
Fcntl( handle, dummy, TIOCCBRK); /* clear Break */


Set/Inquire the input speed and DTR-line control
------------------------------------------------
#define TIOCIBAUD (('T'<< 8) | 18)
Fcntl( handle, &speed, TIOCIBAUD);
Set the input speed of the interface. speed is a 32Bit-value, which 
contains the requested speed uncoded in bits per second. speed = 19200 
would set the speed to 19200bps. The old (real) input speed is returned in 
speed. If the old speed is unknown, -1 is returned. If speed = -1 as input 
parameter of TIOCIBAUD, only the input speed is returned. If speed = 0, the 
DTR-line will be inaktivated (cleared, dropped), without influence on the 
real speed. Every TIOCIBAUD-call which sets the speed, aktivates 
automatically DTR. Returnvalue is ERANGE if the requested speed is not 
available. In this case (as exception) the next lowest legal speed is 
returned in speed. If a next lowest speed is unavailable too, the lowest 
legal speed is returned.


Set/Inquire the output speed and DTR-line control
-------------------------------------------------
#define TIOCOBAUD (('T'<< 8) | 19)
Fcntl( handle, &speed, TIOCOBAUD);
Set output speed of the interface. The function description is identical 
with TIOCIBAUD. If a device does not support different input and output 
speed, TIOCIBAUD and TIOCOBAUD affects both speeds.


Inquire protocol settings
-------------------------
#define TIOCGFLAGS (('T'<< 8) | 22)
Fcntl( handle, &flags, TIOCGFLAGS);
Get the terminal control flags bits. 16 bit flag word flags is set to 
reflect the current terminal state. It is a OR-connection of bits and bit 
combinations. Not defined bits should be ignored. A program should read 
the flags with TIOCGFLAGS, modify the interesting, and set the new value 
with TIOCSFLAGS.

/* Number of stopbits */
#define TF_STOPBITS 0x0003
/* 0x0000  illegal
extension proposal: This aktives the synchron mode. The remaining bits will 
have other meanings in synchron mode, which must be defined in future. */
#define TF_1STOP   0x0001 /* 1 Stopbit */
#define TF_15STOP  0x0002 /* 1.5 Stopbit */
#define	TF_2STOP   0x0003 /* 2 Stopbit */

/* Bits per character */
#define TF_CHARBITS 0x000C
#define TF_8BIT	0x0 /* 8 Bit */
#define TF_7BIT	0x4
#define TF_6BIT	0x8
#define TF_5BIT	0xC /* 5 Bit */

/* Handshake and parity */
#define TF_FLAG  0xF000
#define T_TANDEM 0x1000 /* XON/XOFF (=^Q/^S) flow control aktiv */
#define T_RTSCTS 0x2000 /* RTS/CTS flow control aktiv */
#define T_EVENP  0x4000 /* even parity aktiv */
#define T_ODDP   0x8000 /* odd parity aktiv */
/* even and odd are mutually exclusive */


Set protocol settings
---------------------
#define TIOCSFLAGS (('T'<< 8) | 23)
Fcntl( handle, &flags, TIOCSFLAGS);
Set the settings, description see TIOCGFLAGS. Returnvalue is ERANGE if a 
illegal or not support combination occurs in flags.


End of documentation of existing MiNT functions. New proposals follow:


Flush serial buffers
--------------------
#define TIOCFLUSH (('T'<< 8) | 8)
Fcntl( handle, special, TIOCFLUSH);
(in MiNT "/* BUG: this should flush the input/output buffers */")
Selected by the special-parameter the buffers are flushed in different 
ways:
special  function
0
         Send the transmit buffer. The function returns, if the transmit 
         buffer is empty (return E_OK, =0) or if a internal timeout occurs 
         (return EDRVNR, =-2). The system takes a reasonable timeout.
1
         Clear the receive buffer.
2
         Clear the transmit buffer.
3
         Clear receive and transmit buffer.
-tout
         A negative parameter works as 0, but tout (hint: tout is positive) 
         gives the timeout in 1/200 seconds.


Stop receive
------------
#define TIOCSTOP (('T'<< 8) | 9)
is only available in the handshake modi and signals the communication 
partner, that the computer wants to receive nothing. The function waits a 
reasonable time for collecting characters already in transmission. Then it 
returns, thinking, the partner stopped transmission. (Example for use: an 
8MHz-ST is unable to do simultaneously DMA and 57600Bd-receive by MFP.)


Start receive
-------------
#define TIOCSTART (('T'<< 8) | 10)
Eliminates effects of TIOCSTOP.


Inquire/Set buffer settings
---------------------------
#define TIOCBUFFER (('T'<<8) | 128)
special points to a structure:
LONG   input buffer size in byte
LONG   low water mark in byte
LONG   high water mark in byte
LONG   output buffer size in byte
If a value should inquired only, use a -1 instead of the value. Is a -1 
returned instead of a value, this function is not supported. If values are 
set, the returned values should be examined, because the driver may use not 
the given ones, but the next values the driver founds suitable. (Hint: The 
driver has to allocate an free the memory. That is implementable under 
plain TOS too.)


Inquire I/O-lines and signaling capabilities
--------------------------------------------
#define TIOCCTLMAP (('T'<<8) | 129)
special is a pointer to a structur of 6 LONGs which is filled out by the 
driver. In every LONG the corresponding bit is set to 1 for a existing 
control line or capability.
1.LONG: line inquire-/setable with TIOCCTL(GET/SET)
2.LONG: aktion (routine call) possible at start of condition
3.LONG: aktion (routine call) possible at end of condition
4.LONG: reserved for future extension, till then 0
5.LONG: reserved for future extension, till then 0
6.LONG: reserved for future extension, till then 0
corresponding bits and "lines":
#define TIOCM_LE   0x0001 /* line enable output, output */
#define TIOCM_DTR  0x0002 /* data terminal ready, output */
#define TIOCM_RTS  0x0004 /* ready to send, today other meaning, output */
#define TIOCM_CTS  0x0008 /* clear to send, today other meaning, input */
#define TIOCM_CAR  0x0010 /* data carrier detect, input */
#define TIOCM_CD   TIOCM_CAR /* alternative name */
#define TIOCM_RNG  0x0020 /* ring indicator, input */
#define TIOCM_RI   TIOCM_RNG /* alternative name */
#define TIOCM_DSR  0x0040 /* data set ready, input */
#define TIOCM_LEI  0x0080 /* line enable input, input */
#define TIOCM_TXD  0x0100 /* transmit data line, output */
#define TIOCM_RXD  0x0200 /* receive data line, input */
#define TIOCM_BRK  0x0400 /* Break detected, pseudo-input */
#define TIOCM_TER  0x0800 /* transmit error, pseudo-input */
#define TIOCM_RER  0x1000 /* receive error, pseudo-input */
#define TIOCM_TBE  0x2000 /* hardware-transmitter buffer empty, 
pseudo-input */
#define TIOCM_RBF  0x4000 /* hardware-receiver buffer full, pseudo-input */

Undefined bits should be ignored.

The absence of a line in TIOCCTLMAP means only, that this line is not 
accessible by TIOCCTLxxx. It does not mean, that this line does not exist 
in the hardware. It is possible, that a line can only be by monitored by 
callbacks, but not by TIOCCTLGET.

Some TIOCM_* have special features, described here:

TIOCM_TER, TIOCM_RER
The routine gets in D0.b a byte, describing the error in detail:
Byte Error
0    no more information available about this error
1    hardware-receiver buffer overflow
2    software-receiver buffer overflow
3    parity error
4    framing error

Requesting TIOCM_BRK, TIOCM_RER or TIOCM_TER via TIOCCTLGET: If the 
condition occurs, the corresponding status bit ist set. A common (-1) or 
dedicated (BRK, RER or TER) request returns the state of the corresponding 
bit and resets it.

TIOCM_TBE
The routine gets in D0.w -1, if the software-transmit buffer is empty. 
Otherways it gets a byte read out from the software-transmit buffer in 
D0.b, D0.bit15 is =0 in this case. The routine returns in D0.w -1, if 
nothing should be sent. It returns D0.bit15 =0 and in D0.b the byte, if the 
byte should be sent. The routine is called too, if a new byte is written 
into the software-transmit buffer and the buffer was empty before. If the 
routine returns a self generated -1 and there are bytes available in the 
software-transmit buffer, the routine is called again latest after one 
second.

TIOCM_RBF
The routine gets in D0.b the received byte. The routine returns in D0.w -1, 
if nothing should be written into the software-receive buffer. Otherwise it 
returns D0.bit15 =0 and in D0.b the Byte zurck, which should be written 
into the software-receive buffer.


Inquire I/O-lines and signals
-----------------------------
#define TIOCCTLGET (('T'<<8) | 130)
returns a LONG in the memory cell special points to, which contains the 
actual conditions of the CTLlines, coding see TIOCCTLMAP. On special is 
given a parameter to this function too: If -1, all CTLlines are inquired, 
if <>-1, only one bit has to be set, and only this CTLline is inquired. The 
driver may provide never the less the values of the other lines, because of 
speed reasons. Senseless set bits are ignored.


Set I/O-lines and signals
-------------------------
#define TIOCCTLSET (('T'<<8) | 131)
special points to a structur:
LONG ctlmaske
LONG ctlvalues
The bits which are set in ctlmaske (coding see TIOCCTLMAP), are set to the 
values in ctlvalues. A software should only set bit(s) in ctlmaske, if it 
knows its functions. Input lines are unchangable, such bits are ignored as 
senseless bits.


concept of callback-functions
-----------------------------
A programm can install functions, which are called nearly immediately if a 
condition occurs. A function becomes installed by giving its address in 
procadr. During this installation Bit0 is always 0. A function becomes 
uninstalled by the same call, but with set bit0 (=1) in procadr, with a odd 
address! Bit31-1 and ctlline must have the same value as during 
installation. If there are no special remarks for outstanding functions, 
the following basic rules apply:
- Only register D0 and A0 may be changed.
- It must be extremly short, more than 20 "normal" assembler instructions
  are not allowed (a MOVEM.L D1-D7/A1-A6,... or DIV is not "normal"). The 
  rum time of the routine should not exceed 200 clocks on a CPU MC68000.
- Call is made in supervisormode.
- The actual InterruptPriorityLevel is unknown.
- End with RTS.

It is possible, that several programs watch one line simultaneously. The 
routine must be uninstalled, before it leaves the memory because a non 
resident program termination. It is unimportant, which file handle is used 
for (un-/)registration, if it matches the device (e.g. Fopen, 
Fcntl(...,TIOCCTLSFAST) /*installation*/, Fclose, ... Fopen, 
Fcntl(...,TIOCCTLSFAST) /*uninstallation*/, Fclose).

Some functions exist only under special handshake modi and can only 
installed if this mode is activ, but uninstalled under every mode. Such 
functions are automatically activated and deaktivated, as long as they are 
installed.


Install/Uninstall fast callback-functions
-----------------------------------------
#define TIOCCTLSFAST (('T'<<8) | 132)
Installation and uninstallation of routines, which are called if changes on 
the CTLlines occur. special is a pointer to a structur:
LONG ctlline
LONG procadr
The routine is called on every transition (if possible, see TIOCCTLMAP) on 
the line marked in ctlline (only one bit should be set, see TIOCCTLMAP). 
The new level of the line is given in D0.b: 0 inaktiv (on the DSR line 
inaktiv means TTL-high-level, for example) and $FF aktiv.
Returnvalues of TIOCCTLSFAST:
E_OK    everything OK
1       routine installed, but it is not the only one. It becomes time
        critic, if possible, the programm should uninstall the routine. 
        This is only a recommendation.
EINVFN  this watch capability does not exist
EACCDN  routine can not be installed.


Install/Uninstall slow callback-functions
-----------------------------------------
#define TIOCCTLSSLOW (('T'<<8) | 133)
nearly identical to TIOCCTLSFAST, with one difference: The routine may be 
(nearly) as long as it likes to be.


Inquire number of unsent bytes
------------------------------
#define TIONOTSEND (('T'<<8) | 134)
Fcntl( handle, &count, TIONOTSEND)
The function returns in count as a 32bit-value the number of bytes, which 
are not sent at this moment. The function tries, limited by the hardware 
(hardware-FIFOs), exactly to find out how much unsent characters in the 
computer are.


Set error behavior
------------------
#define TIOCERROR (('T'<<8) | 135)
Fcntl( handle, &errmode, TIOCERROR);
Errmode is a 32bit value. If errmode is -1 as input parameter, in errmode 
is only the actual setting returned. If errmode >=0, the error behavior 
will be set and the old setting is returned in errmode. In Bit7..0 of 
errmode is a character. Bit8 =1 switchs on the insert of this character 
into the receive buffer if a receive error occurs. Normally is Bit8 =0, and 
no character is inserted during a error. Bit9 =1 switchs on the clearance 
of receive buffer if break is received, normally is Bit9 =0 and the buffer 
is not influenced by break. Returnvalue is E_OK, or ERANGE for not 
supported settings.


--- end of text ---
