dESµTerm

 

 

 

 

 

 


Diesen Treiber für die serielle Schnittstelle haben wir vor vielen Jahren (1990) gebastelt, als es noch das DOS Betriebssystem auf allen PC-Rechnern gab. Er tat in einigen unserer Programme treue Dienste.
Der Treiber soll hier beigefügt werden, denn für PC's und Laptops unter DOS, Windows 98, Windows NT ist er noch zu gebrauchen, um serielle Verbindungen zum SC12IPC@CHIP aufzubauen. Er kann beim Empfang ein XON/XOFF-Protokoll benutzen.

Dem Treiber ist eine main() Funktion angehängt, die als sehr einfaches Terminalprogramm für den SC12 benutzt werden kann. Die Voreinstellungen für die Übertragungsparameter sind ..

             COM 1:       19200 Baud, 8 Datenbits, keine Parität, 1 Stopbit
                                  kein XON/XOFF





// Serial.CPP
// ----------    Version 13.10.2002
//               Borland IDE C++ 3.1 oder 5.02
//               Sprache C und Inlineassembler
//               Model:  SMALL
//               Char:   unsigned
//               bearbeitet: BBS WiLu, D.Schwarzer

// IRQ-Treiber für die serielle Schnittstelle bei
// IBM-kompatiblen PC-Rechnern mit XON/XOFF Empfangs Flow
// Control

// -der Treiber sendet Zeichen über die Benutzerfunktion
//  serout(). diese Funktion wartet, bis das letzte Zeichen
//  gesendet wurde und gibt dann das aktuelle Zeichen aus.
// -der Treiber benutzt einen Empfangs-IRQ und legt alle
//  empfangenen Zeichen in einem Buffer ab. Der Buffer kann
//  durch die Funktionen ..

//   is_serin()  - liegt ein Zeichen im Buffer vor?
//   getserin()  - Zeichen holen

//   .. gelesen werden.

// -Ist das XON/XOFF Übertragungsprotokoll eingeschaltet,
//  sendet der Empfänger vor einem Bufferüberlauf XOFF
//  zum Sender um diesen zur Einstellung der Sendung zu
//  bewegen. Geschieht dies nicht füllt sich der Buffer
//  wieder von vorne (RingBuffer)und es gehen möglicherweise
//  Zeichen verloren. Die Wirkung von XOFF
//  wird durch Senden von XON wieder aufgeboben.

// -Die Übertragungsparameter können in globalen Variablen
//  gesetzt werden und durch die Funktion initSerial()
//  gesetzt werden. Werden keine Werte in die Parameter-
//  variablen eingetragen, benutzt der Treiber beim Aufruf
//  von initSerial die Vorgabewerte ..

//  19200 Baud, 8Daten, kein Parity, 1Stopbit, XON/XOFF aus

// -Mit der Funktion restSerial() kann der gesetzte
//  IRQ-Handler beim Verlassen dieses Programms wieder
//  entfernt werden. Diese Funktion sollte auch vor einem
//  zweiten Aufruf von initSerial() benutzt werden.

// -Es können beliebige Baudraten zwischen 2 bis 115.200
//  Baud angegeben werden. Der Treiber berechnet die ihm
//  mögliche Baudrate.
// -Die globale Strukturvariable ss enthält die vom Treiber
//  tatsächlich eingestellten Werte. Diese Struktur kann
//  für Anzeigen verwendet werden.

//  (c) 1993  Schwarzer,  BBS Winsen, 21423 Winsen/L
// ----------------------------------------------------- //

// COMx:      serielle Schnittstelle COM 1-2 (3,4)
// BAUDRATE:  Bits/Sekunde zwischen 2 und 115.200
// PARITY:    1 -ungerade, 2 -keine, 3 -ungerade
// DATENBITS: Zahl der Datenbits. Möglich 5, 6, 7 oder 8
// STOPBITS:  Zahl der Stopbits.  möglich 1 oder 2
// FLOW:      1 = XON/XOFF beim Empfang ein

// Voreinstellung

#define COMx          1      // COM 1
#define BAUDRATE   19200     // 19200 Bits/Sekunde
#define PARITY        2      // keine Paritätsprüfung
#define STOPBITS      1      // 1 Stopbit
#define DATENBITS     8      // 8 Datenbits
#define FLOW          0      // XON/XOFF Protokoll aus

// Die nachfolgenden Variablen enthalten die zur Laufzeit
// gültigen Werte der seriellen Schnittstelle. Sie können
// von einem externen Programm gesetzt werden, dann muss
// initSerial() aufgerufen werden.

int  COM       = COMx;        //  Schnittstellennummer
long baudrate  = BAUDRATE;    //  Baudrate
int  databit   = DATENBITS;   //  Anzahl der Datenbits
int  stopbit   = STOPBITS;    //  Anzahl der Stopbits
int  parityb   = PARITY;      //  Art der Paritätsprüfung
int  flow      = FLOW;        //  XON/XOFF beim Empfang

// ----------------------------------------------------- //

// Diese Rückgabestruktur enthält die zur Laufzeit
// bestehenden Einstellungen der Schnittstelle. Externe
// Programme können diese Angaben zur Anzeige benutzen 

struct Param_SS {
 unsigned COM;              // COM-nr Benutzter IBM Eingang
 long     baud;             // am 8250 eingestellte Baudrate
 int      datab;            // Anzahl Datenbits
 int      stopb;            // Anzahl Stopbits
 int      parity;           // KennNr. der Parität
 char     paritystrg[10];   // Bezeichnung der Parität
 unsigned INTnr;            // Benutzter INT -Vektor
 unsigned INTadr;           // Adresse auf die INTnr zeigt
 unsigned IRQnr;            // Benutzter IRQ
 char     methodestrg[10];  // Methode Polling/Interrupting
 char     abfragestrg[25];  // direkt oder über BIOS INT14h
} ss;

void initSerial   (void);   // ser Schnittst. aktivieren
void restSerial   (void);   // ser Schnittst. deaktivieren

void clrsbuf      (void);   // Empfangsbuffer löschen
void serout       (int c);  // warten dann Zeichen senden

int  is_serin     (void);   // Flagge: Zeichen im Buffer ?
int  getserin     (void);   // Funktion: Zeichen holen

// ------------------------------------------------------ //
#include <bios.h>
#include <dos.h>
#include <conio.h>
#include <string.h>

#define XON  0x11          // XON (CtrlQ) Sender soll senden
#define XOFF 0x13          // XOFF(CtrlS)        soll ruhen

// Typenbezeichnung der Schnittstellenbausteine:
// SAB 8250 oder SAB16C450 = NS16450 = UMC82450 oder NS16550
// Taktfrequenz der Bausteine  1,8432 MHz
// max. Baudrate bei direkter Programmierung 115200 Baud

// Anzahl der mit diesem Programm ansteuerbaren seriellen
// Schnittstellen.
const int commax = 4;

// Basisadressen der Schnittstellenbausteine für die
// seriellen DOS-Schnittstellen COM 1..4 in IBM kompatiblen
// Rechnern.
const unsigned com[5]  = { 0, 0x3F8, 0x2F8, 0x3E8, 0x2E8 };

// Registernamen (relative Adressen) des Schnittstellen-
// bausteins der seriellen Schnittstelle.
// (absolute Adresse = com[x] + Registername)
enum { IOR, IER, IIR, LCR, MCR, LSR, MSR };

// Interruptvektoren der Hardware-IRQ 4,3,10,11 die den
// Schnittstellen COM 1-4 zugeordnet sind. Die IRQ 10 u.
// 11 sind nur bei AT-Rechnern vorhanden Die meisten
// SS-Karten unterstützen deswegen nur die IRQ 4 und 3.Die
// Schnittstellen COM 3-4 werden von DOS erst ab
// Version 4.01 unterstützt.

//  COM  =  x              1      2      3      4
//  ---------------------------------------------
//  int IRQnr[5] = { 0,    4,     3,    10,    11  };
//  int INTnr[5] = { 0, 0x0C,  0x0B,  0x72,  0x73  };
    int IRQnr[5] = { 0,    4,     3,     4,     3  };
    int INTnr[5] = { 0, 0x0C,  0x0B,  0x0C,  0x0B  };

// absolute Adressen des gewählten 8250 Schnittstellen-
// bausteins initSerial() setzt diese Adressen

    int near R_IOR =  0x3F8+IOR;
    int near R_IER =  0x3F8+IER;
    int near R_IIR =  0x3F8+IIR;
    int near R_LCR =  0x3F8+LCR;
    int near R_MCR =  0x3F8+MCR;
    int near R_LSR =  0x3F8+LSR;
    int near R_MSR =  0x3F8+MSR;

// EmpfangsBuffer Hilfsvariable
// ----------------------------
int  near SerBufFul = 0;       // Flagge: 1 -EmpfangsBuffer
                               // voll
char near sibuf[0x1000];       // RingBuffer für die
                               // eingehenden Zeichen der
                               // ser. Schnittstelle
unsigned near widx = 0;        // Zeiger auf Schreibstelle
                               // im Buffer
unsigned near ridx = 0;        // Zeiger auf Lesestelle im
                               // Buffer
const int BUFFMASK = 0x0FFF;   // Umlauf_Maske für die
                               // Indexwerte

// Lese/Schreib  Hilfsfunktionen
// -----------------------------
int  near is_V24in  (void);    // Zeichen empfangen ?
int  near getV24in  (void);    // Zeichen holen
int  near is_V24out (void);    // bereit zum Senden ?
void near getV24out (int c);   // Zeichen c senden

// Initialisations Hilfsfunktionen
// -------------------------------
void near initirq (int comnr, int irqnr);
void near restirq (int comnr, int irqnr);
int  near getss   (int comnr, long* baud, int* parity,
                   int* datab, int* stopb);
int  near initss  (int comnr, long baud, char parity,
                   int databit, int stopbit);
void near getParam_SS (void);

// Definition des IRQ-Handlers
// ---------------------------
#ifdef __cplusplus          
#define __CPPARGS ...       
#else
#define __CPPARGS           
#endif
void interrupt (*oldVector)(__CPPARGS); // alter IRQ Vektor
void interrupt IBMCOMx (__CPPARGS);     // IRQ Handler
void  near     _ChrToBuf (void);        // IRQ Zeichen zum
                                        // EmpfangsBuffer


/**********************************************************/
// Funktion löscht den Empfangsbuffer und setzt die Buffer-
// Voll-Flagge auf Buffer leer. XON (Ctrl-Q) wird gesendet,
// um dem Sender zu signalisieren, dass der Empfänger bereit
// ist.
void clrsbuf (void)
{
  widx=ridx;
  if(SerBufFul){
   SerBufFul=0;
   if(flow)serout(XON);
  }
}

// FlaggenFkt: gibt 1 zurück, wenn noch Zeichen im
// EmpfangsBuffer sind, sonst wird 0 zurückgegeben.
int is_serin (void)
{
 if(widx !=ridx) return(1);   // es sind noch Zeichen im
                              // Buffer
 if(SerBufFul){               // keine Zeichen, aber Buffer
                              // voll
  if(flow)serout(XON);        // geflaggt. Buffer leer
  SerBufFul=0;                // flaggen und  Sender zum
                              // Senden auffordern
  }                           
 return (0);
}

// gibt ein Zeichen aus dem EmpfangsBuffer zurück. Die
// Rückgabe von 0 kann bedeuten, daß kein Zeichen im Buffer
// war, aber auch, daß sich im Buffer das Zeichen NULL
// befand. Deswegen sollte vor Aufruf dieser Funktion mit
// is_serin() geprüft werden, ob ein Zeichen im Buffer
// vorhanden ist.
int getserin (void)
{
  if (widx != ridx) {       // wenn Buffer Zeichen enthält..
   return (sibuf[ridx++ & BUFFMASK]);  // .. Zeichen holen
  }                                    // und zurückgeben
  if (widx==ridx && SerBufFul){        // wenn Buffer leer
                                       // u.Bufferüberlauf
    if(flow)serout(XON);               // geflaggt: Flagge
                                       // auf Buffer leer
    SerBufFul=0;                       // Sender mit XON
                                       // freigeben
  }
  return(0);                 // Rückgabe wenn Buffer leer
}

// Wartet, bis die serielle Schnittstelle zur Ausgabe eines
// Zeichens bereit ist und gibt das Zeichen aus.
void serout (int c) { while (!is_V24out()); getV24out(c);}


// *******************************************************//
//
// Hilfsfunktionen:  Schreiben /Lesen der seriellen
// Schnittstelle

// Test ob die serielle Schnittstelle zum Senden bereit ist
// Ein Zeichen kann mit getV24out gesendet werden.
// RÜCKGABE:  0 nicht bereit   1 Schnittstelle zum Senden
// bereit
int near is_V24out (void)
{
  asm { mov DX,R_LSR             // Status TxD direkt lesen
        in  AL,DX
        and AL,00100000B
        mov AH,0 }
  return (_AX);
}

// Ein Zeichen über die serielle Schnittstelle senden. Ob
// die Schnittstelle zum Senden bereits ist kann durch
// is_V24out getestet werden.
void near getV24out (int c)
{
  asm { mov  AX, c                // TxD direkt schreiben
        mov  DX, R_IOR
        out  DX, AL }
}

// Interrupthandler für die serielle Schnittstellen in IBM
// PC-kompatiblen Rechnern. Die empfangenen Zeichen werden
// in einem Buffer abgelegt, der mit getserin() gelesen
// werden kann.

// Eingabestatus der seriellen Schnittstelle abfragen. Das
// Zeichen kann mit getV24in() gelesen werden.
// RÜCKGABEN:  0 kein Zeichen      1 Zeichen steht bereit.
int near is_V24in (void)
{
  asm { mov  DX, R_LSR           // Status RxD direkt lesen
        in   AL, DX
        and  AL, 00000001B
        mov  AH, 0 }
  return (_AX);
}

// Ein Zeichen von der seriellen Schnittstelle lesen. Ob
// ein Zeichen vorliegt, kann mit is_V24in() geprüft werden
int near getV24in (void)
{
  asm { mov  DX, R_IOR           // RxD direkt lesen
        in   AL, DX
        mov  AH, 0 }
  return (_AX);
}
// Hole ein Zeichen der seriellen Schnittstelle und lege es
// im Buffer ab. Wenn der Buffer für die serielle
// Schnittstelle fast voll ist, wird ein Ctrl-S zum Sender
// geschickt und die Flagge 'SerBufFul' auf 1 gesetzt.
// Diese Funktion wird vom Interrupthandler aufgerufen.
void near _ChrToBuf (void)
{
 char ch;
 if(is_V24in ()){
   ch = getV24in();                // Zeichen holen und zum
                                   // Buffer
   if(((((widx&BUFFMASK)-(ridx&BUFFMASK))&BUFFMASK) > 0xF00)
           && !SerBufFul){
    if(flow)serout(XOFF); // wenn Buffer voll wird, Sender
    SerBufFul = 1;        // stoppen und Buffer-Voll flaggen
   }
   sibuf[widx++ & BUFFMASK] = ch; // Zeichen im Buffer
 }                                // ablegen
}

// Interrupthandler für IRQ an der seriellen Schnittstelle
void interrupt IBMCOMx (__CPPARGS)
{
  asm { push BP
        pushf
        push AX
        push BX
        push CX        // Register auf dem Stack sichern
        push DX
        push DI
        push SI
        push ES
        push DS
        sti            // weitere IRQ am 80x86 freigeben

        mov  DX, R_IIR
        in   AL, DX
        test AL, 004h  // IIR, Bit 2 -Receive Data available
        jz   EOI }     // irgend ein anderer IRQ
        _ChrToBuf();   // Zeichen holen und zum Buffer
  EOI:
  asm {
        mov  AL,020H   // COM1: 064H, COM2: 063H ?
        out  020H,AL   // IRQ am Interruptcontroller löschen

        pop DS
        pop ES
        pop SI         // gesicherte Register vom Stack
        pop DI         // holen
        pop DX
        pop CX
        pop BX
        pop AX
        popf
        pop BP }
}

// Funktionen für Init und Rücksetzen der ser.Schnittstelle

int near initss (int comnr, long baud, char parity,
                 int databit, int stopbit)
// initialisiert die seriellen Schnittstellen COM 1-4 bei
// IBM- Rechnern
// comnr:   Nummer d.zu initialisierenden Schnittstelle 1-4
// baud:    Übertragungsrate beliebig zwischen 2 und 115.200
// parity:  1 -ungerade, 2 -keine, 3 -ungerade
// databit: Zahl der Datenbits. möglich 5, 6, 7 oder 8
// stopbit: Zahl der Stopbits.  möglich 1 oder 2
{
 int dat, stop, par, portval;
 unsigned char blo, bhi;

 if (comnr <= 0 || comnr > commax) return (0);
 dat = databit-5;
 if (dat < 0 || dat > 5) dat = 3;   // Datenbits 5, 6, 7, 8
 stop = (0x04 & (stopbit*2));       // Stopbits  1, 2
 switch (parity) {
  case 3:  par = 0x18;  break;      // even (gerade)
  case 1:  par = 0x08;  break;      // odd  (ungerade)
  default: par = 0x00;  break; }    // keine

 // Teilerrate für angegebene Baudrate berechnen
 blo = (unsigned char)(115200L / baud);
 bhi = (unsigned char)(   450L / baud);

 // Wert von LCR lesen -->
 portval = inportb (com[comnr] +LCR);
 // Baudraten_Übertragung init
 outportb (com[comnr]+LCR, portval| 0x80);
 // Teilerrate Baud low /high
 outportb (com[comnr]+0,   blo);
 outportb (com[comnr]+1,   bhi);
 // Kontrollbyte übertragen
 outportb (com[comnr]+LCR, dat|stop|par);
 inportb  (com[comnr]);
 return(1);
}
// ermittelt die Einstellungen der Schnittstellen COM 1-4
// und gibt diese an die referenzierten Variablen zurück.
// Konnten gültige Werte gelesen werden gibt die Funktion
// 1 zurück sonst 0
// parity kann die Werte 1 = ungerade, 2 = keine, 3 gerade
// Parität annehmen.
// Das Programm benötigt als externe Angaben die Tabelle
// der Basisadessen der Schnittstellenbausteine 'com[]' und
// die relativen Adressen der Bausteinregister LCR, IOR ...
int near getss (int comnr, long *baud, int *parity,
                int *datab, int *stopb)
{
 int portval, frame;
 portval = inportb (com[comnr]+LCR);   // Baudrate ermitteln
 outportb (com[comnr]+LCR, portval | 0x80);
 *baud = inportb (com[comnr]+IOR) +
         inportb(com[comnr]+IER)*256;
 if ((*baud>2304) || (*baud<0)) return (0);
 *baud = 115200L / *baud;
 outportb (com[comnr]+LCR, portval);
 frame = inportb(com[comnr]+LCR);      // Kontrollbyte holen
 *parity = frame & 0x18;
 *parity = *parity >> 3;
 if (!(*parity)) *parity =2;           // keine Par.prüfung
                                       // wenn Par = 0 od.2
 *datab = 5 + (frame & 0x03);          // Datenbits
 *stopb = 1 + ((frame & 0x04) >> 2);   // Stopbits
  return(1);
}
// ermittelt die tatsächlichen Einstellungen der
// Schnittstelle und legt diese in der globlaen Struktur
// ss ab.
void near getParam_SS (void)
{
 ss.COM = COM;
 getss (COM, &ss.baud, &ss.parity, &ss.datab, &ss.stopb);
 switch (ss.parity) {
  case 1: strncpy(ss.paritystrg, "ungerade",10); break;
  case 2: strncpy(ss.paritystrg, "keine   ",10); break;
  case 3: strncpy(ss.paritystrg, "gerade  ",10); break; }
  ss.INTnr = INTnr[COM];
  ss.INTadr= com[COM];
  ss.IRQnr = IRQnr[COM];
}

// für die serielle Schnittstelle COMx wird einer der
// IRQs 3 oder 4 (siehe Tabelle IRQnr) freigegeben. Es wird
// der Interrupthandler IBMCOMx installiert. Seine Adresse
// wird in den Sofwareinterrupt eingetragen, der dem
// IRQx zugeordnet ist. (siehe Tabelle INTnr)
void near initirq (int comnr, int irqnr)
{
 oldVector = getvect (INTnr[comnr]); // alten Vektor sichern
 setvect (INTnr[COM], IBMCOMx);      // neuen setzen

  asm {  cli }                       // IRQ's an CPU sperren
  switch (irqnr) {
   case 3: {asm {in  AL,   021h      // IRQ-Controller ..
                 and AL,   0F7h      // IRQ 3 freigeben
                 out 021h, AL }
                            break;}
   case 4: {asm {in  AL,   021h      // IRQ-Controller
                 and   AL, 0EFh      // IRQ 4 freigeben
                 out   021h, AL }
                            break;}
 };
 outportb (com[comnr]+MCR, 0x0B); // set DTR, RTS, OUT2(IRQ)
 outportb (com[comnr]+IER, 0x01); // IRQ on RxD ready frei
 asm { sti }                      // IRQs an CPU zulassen
}
// schaltet die IRQ-Quellen am Schnittstellencontroller und
// am IRQ-Controller ab. Entfernt den Interrupthandler
// dieses Progamms und setzt den alten Handler ein. Die
// Baudrate, Stopbits und die Parität bleiben erhalten.

void near restirq (int comnr, int irqnr)
{
 asm { cli }                        // IRQ an CPU abschalten
 outportb (com[comnr]+MCR, 0x03);   // res OUT2(IRQ)
 outportb (com[comnr]+IER, 0x00);   // IRQ on RxD ready
                                    // sperren
 switch (irqnr) {
  case 3: {asm {in  AL,   021h      // IRQ-Controller ..
                or  AL,   008h      // IRQ 3 sperren
                out 021h, AL }
                          break;}
  case 4: {asm {in  AL,   021h      // IRQ-Controller
                or  AL,   010h      // IRQ 4 sperren
                out 021h, AL }
                          break;}
 };
 setvect (INTnr[COM], oldVector);   // alten IRQ-Handler
                                    // setzen
 asm { sti }                        // IRQ an CPU zulassen
}

// ********************************************************
// *serielle Schnittstelle initialisieren und zurücksetzen
// ********************************************************

// Setzt die serielle Schnittstelle auf die Werte zurück,
// die vor dem Start dieses Programms existierten.
void restSerial (void)  { restirq(COM, IRQnr[COM]); }

// initialisiert die gewünschte serielle Schnittstelle COMx
// mit den Vorgabewerten.
void initSerial (void)
{
  R_IOR =  com[COM]+IOR;       // absolute Adressen der
  R_IER =  com[COM]+IER;       // Register des ausgewählten
  R_IIR =  com[COM]+IIR;
  R_LCR =  com[COM]+LCR;       // Schnittstellenbausteins
  R_MCR =  com[COM]+MCR;       //8250 für COMx
  R_LSR =  com[COM]+LSR;
  R_MSR =  com[COM]+MSR;

  strncpy (ss.methodestrg, "Interrupt",10);
  strncpy (ss.abfragestrg, "direkte Abfrage des 8250",25);
  initss  (COM, baudrate, parityb, databit, stopbit);
  initirq (COM, IRQnr[COM]);

  while (is_V24in ()){           // Empfangsbuffer leeren
   getV24in ();
  }
  widx = ridx = 0;               // Bufferzeiger auf 0
  SerBufFul = 0;                 // Empfangsuffer leer
  getParam_SS ();                // Einstellungen in einer
}                                // Struktur festhalten 



// ********************************************************
// *  dESµTerm  DOS Terminal Demoprogramm für SC12IPC@CHIP
// ********************************************************

// main()
// DemoTerminal: wartet auf Zeichen vom Sender und übergibt
// dorthin Tastatureingaben. ESC bricht das Programm ab.
// Hier könnte noch ein ON/XOFF Handshake für Sendevorgänge
// eingebaut werden, was bei Tastendruckübergaben allerding
// relativ unnötig ist. Im Programm werden die Zeichen
// XON/XOFF ausgefiltert

#include <stdio.h>
#include <bios.h>
#define  ALTx 0x2D00      // ASCII-Code von [ALT-X]
#define  XON  0x11        // XON (CtrlQ) Sender soll senden
#define  XOFF 0x13        // XOFF(CtrlS)        soll ruhen

void main (void)
{
 unsigned c;
 clrscr();                          // löscht Bildschirm
 printf(" dESyTerm\n"
        "          DOS-Terminalprogramm"
        " .. Ende mit ALT-X\n\n");

 initSerial();                      // Treiber aktivieren
 clrsbuf();                         // Buffer löschen

 while (1){
  if(is_serin()){                   // Zeichen vorhanden
    c = getserin();                 // Zeichen holen
    if(c!=XON && c!=XOFF)
     printf("%c",c);                // Zeichen ausgeben
  } 
  if(bioskey(1)){                   // Taste  vorhanden 
   c= bioskey(0);                   // Taste  holen
   if(c==ALTx) break;               //    ALT-X Programmende
   serout(c);                       // Taste  senden
  }
 }

 restSerial();                      // Treiber deaktivieren
}

 

 

 





Bemerkungen
Dieses Programm besitzt einige Zeilen Inlineassembler, die vom Borland-Compiler 5.02 ohne Probleme übersetzt werden. Älteren Compiler können den TASM-Assembler voraussetzen.

Der Treiber kann ein XON/XOFF Empfangsprotokoll benutzen, damit sein Empfangsbuffer nicht überläuft. Unterstützt die Gegenstelle dieses Protokoll nicht, erhält sie die, für sie unsinnigen Zeichen, 0x11 und 0x13 gesendet. Beim Empfänger können wegen eines Bufferüberlaufs Zeichen verloren gehen.


Beim Empfang sollte dieses Programm ebenfalls auf XON/XOFF Zeichen der Gegenstelle achten, was in diesem Programm nicht geschieht. Hier werden die Zeichen ausgefiltert.



 .. dESµTerm


www.GoBlack.de