/* Funktionen-Sammlung fuer den Anschluss des PIO-Interface des KC87 an den Parallelport des PC im EPP- Modus. Zugriff auf IO-Ports: mit outb zur Port-Ausgabe eines Byte: outb( byte , Portadresse ); mit inb zur Port-Eingabe eines Byte: byte=inb( Portadresse ); Notwendig ist vorher die Anforderung zur Erlaubnis fuer eine Portnutzung: iopl( Level ) keine Erlaubnis - 0 normale Programme, verursacht Segmentation fault! mit Erlaubnis > 0 z.B. iopl(3) fuer weiteste Rechte Compilieren mit: gcc -o (progname) -O3 -Wall (sourcename.c) danach ggf: chmod a+x (progname) Verdrahtung des IO-Interface-Kabels: s. Notiz am File-Ende. */ #include #include #include /*Fuer libc5: unistd.h , fuer glibc: sys/io.h notwendig*/ #include #include /*Globale Variablen fuer das Hauptprogramm:*/ FILE * ifi; FILE * ofi; /*allg. Filename */ char finame[255]=""; /*stri - Empfangs-/Sendepuffer fuer Strings: */ char stri[255]=""; /*status - Stand des Status-Ports 379H, moegliche Werte: 0 RDYB=low, KC87 nicht aktiv, Grundzustand 1 RDYB=high, Eingabedaten sind gueltig bzw. Datebyte kann ausgegeben werden 2 3 RESET (wird spaeter eingefuehrt) 4 5 Kein Filename angegeben. 6 Fehler bei der File-Eingabe Der Returnwert aller Funktionen sollte ausgewertet werden. */ int status=0; unsigned char sbyte=0x00; unsigned char cbyte=0x00; unsigned char ibyte=0x00; unsigned char obyte=0x00; /*Allgemein Returncode:*/ int rc=0; /*Oft verwendete Variablen:*/ int lp=0,hp=0,anz=0,i=0; /* Vorhandenen Grundfunktionen:*/ /* 1.)Status intern feststellen: Feststellen, ob der KC87 aktiv senden oder empfangen will. Pruefen, ob BRDY=P10=high gestellt ist, dh. ob 379H.6=1 ist. Diese Statuspruefung muss immer vor jeder I/O-Operation durchgefuehrt werden! Ergebnis: Status in status Returnwert=status */ int ppstatus(void); /* 2.)Grundzustand einstellen, PC empfangsbereit machen, PC auf Input stellen mit: 37AH.5 - gibt Richtung des Datenflusses des Parallelports an mit 1=PC-Input 0=PC-Output BSTB=P14=high setzen, d.h. 37AH.1=/P14=0 setzen. kein PC-Interrupt ausgenutzt:mit 37AH.4=0 Returnwert=status */ int ppreset(void); /* 3.) Empfang eines Bytes: Grundsatz: in_byte() darf nur aufgerufen werden, wenn status=1 festgestellt wurde. Ergebnis in ibyte, Returnwert: status */ int in_byte(void); /* 4.) Senden eines Bytes Grundsatz: out_byte() darf nur aufgerufen werden, wenn status=1 festgestellt wurde. Auszugebendes Byte in obyte, Returnwert: status */ int out_byte(void); /* 5.) Empfangen eines Strings Grundsatz: in_string() sollte erst aufgerufen werden, wenn status=1 festgestellt wurde. Die Eingabe des Strings wird durch das Zeichen LF, Code 0AH beendet, LF wird nicht Bestandteil des Strings. Sollte das Zeichen CR, Code 0DH auftreten, so wird es ignoriert. Ergebnis: String in stri, Returnwert: 0 - Eingabe OK 1 - keine Eingabe moeglich / Fehler bei der Eingabe */ int in_string(void); /* 6.) Senden eines Strings Grundsatz: out_string() sollte erst aufgerufen werden, wenn status=1 festgestellt wurde. Die Stringausgabe wird durch das Zeichen LF abgeschlossen. Ist im String kein LF enthalten, so wird es angehaengt. Auszugebender String in stri, Returnwert: 0 - Ausgabe OK 1 - keine Ausgabe moeglich */ int out_string(void); /* 7. Hilfsfunktionen: */ int pruefen(int code); int warten(void); /**************************************************/ /*Pruefen, ob ein Byte geschrieben/gelesen werden kann: Argument =1 - Pruefen auf schreiben oder lesen Die Funktion wird erst verlassen, wenn der Status dem Argument entspricht. Returnwert=status */ int pruefen(int code) { while( 1 ) { ppstatus(); if( status != code ) { warten(); continue; } break; } return(status); } int warten(void) { int i,j=0; for(i=0;i<=1000;i++) {j++;} return(0); } int ppstatus(void) { iopl(3); sbyte=inb(0x379); status=(sbyte & 0x40); if( status > 0 ){ status=1; } iopl(0); return(status); } int ppreset(void) { iopl(3); cbyte=inb(0x37a); cbyte=cbyte & 0xfd; cbyte=cbyte | 0x20; outb(cbyte,0x37a); iopl(0); ppstatus(); return(status); } /*Grundsatz: in_byte() darf nur aufgerufen werden, wenn status=1 festgestellt wurde.*/ int in_byte(void) { iopl(3); /*BRDY ist high:*/ /*PC auf Eingabe stellen: ++++ggf. vorher immer machen++++*/ cbyte=inb(0x37a); cbyte=cbyte | 0x20 ; outb( cbyte, 0x37a ); /*Datenbyte lesen:*/ ibyte=inb(0x378); cbyte=inb(0x37a); /*BSTB=low und danach wieder high setzen:*/ cbyte=cbyte | 0x02 ; outb( cbyte, 0x37a ); warten(); cbyte=inb(0x37a); cbyte=cbyte & 0xfd ; outb( cbyte, 0x37a ); iopl(0); /*warten bis Handshake-Zyklus beendet ist.*/ while( ppstatus() == 1 ) { warten(); } return(status); } /*Grundsatz: out_byte() darf nur aufgerufen werden, wenn status=1 festgestellt wurde.*/ int out_byte(void) { iopl(3); /*BRDY ist high:*/ /*PC auf Ausgabe stellen:*/ cbyte=inb(0x37a); cbyte=cbyte & 0xdf ; outb( cbyte, 0x37a ); /*Datenbyte schreiben:*/ outb( obyte, 0x378 ); cbyte=inb(0x37a); /*BSTB =low danach high setzen:*/ cbyte=cbyte | 0x02 ; outb( cbyte, 0x37a ); warten(); cbyte=inb(0x37a); cbyte=cbyte & 0xfd ; outb( cbyte, 0x37a ); iopl(0); /*warten bis Handshake-Zyklus beendet ist.*/ while( ppstatus() == 1 ) { warten(); } return(status); } /*Grundsatz: in_string() sollte erst aufgerufen werden, wenn status=1 festgestellt wurde.*/ int in_string(void) { int i=0,oc=0; while( 1 ) { /*Pruefen, ob ein Byte geholt werden kann: */ pruefen(1); oc=in_byte(); /*CR ignorieren:*/ if( ibyte == 0x0d ) { continue; } /*LF schliesst den String ab: */ if( ibyte == 0x0a ) { stri[i]=0x00 ; break;; } stri[i]=ibyte; i++; } ppstatus(); return(status); } /*Grundsatz: out_string() sollte erst aufgerufen werden, wenn status=1 festgestellt wurde.*/ int out_string(void) { int i=0,oc=0; while( (stri[i] != 0x00) && (stri[i] != 0x0a) ) { /*Pruefen, ob ein Byte ausgegeben werden kann:*/ pruefen(1); obyte=stri[i]; oc=out_byte() ; i++; } /* LF ausgeben: Pruefen, ob ein Byte ausgegeben werden kann:*/ pruefen(1); obyte=0x0a; oc=out_byte() ; ppstatus(); return(status); } /* Verdrahtung des GPIO-Kabels am Parallelport: 378H.0 bis 378H.7 - Pin2 bis Pin9 - mit DA0 bis DA7 Datenbits 379H.6 - Pin10 - mit 1=BRDY=high 0=BRDY=low 37AH.1 - Pin14 negiert - mit 1=BSTB=low 0=BSTB=high */ /* zum Test: int main(void) { while( 1 ) { ppstatus(); printf("%d",status); warten(); } rc=status; return(rc); } */