Der Wordplus-Druckertreiber

Wer hat nicht schon einmal ein Programm geschrieben, das Daten nicht nur verwalten, sondern auch ausdrucken soll? Also macht man sich Gedanken, wie der Drucker das druckt, was er soll. Man sucht die Druckersteuerbefehle aus dem Handbuch, schreibt die entsprechenden Routinen und freut sich. Nach einiger Zeit, wenn man sich einen anderen Drucker zulegt oder das Programm einem Freund, der zwar auch einen ATARI, aber einen anderen Drucker hat. weitergibt, freut man sich schon weniger. Man sucht die Druckersteuerbefehle des anderen Druckers aus dem Handbuch, schreibt die entsprechenden Routinen neu und freut sich wieder. Wiederum etwas später, wenn man sich wieder einen anderen Drucker zulegt oder das Programm einem anderen Freund, der auch einen ATARI, aber einen ganz anderen Drucker hat. weitergibt, freut man sich wahrscheinlich nicht mehr und fragt sich: WARUM????

Damit die Freude nicht durch solche Erlebnisse zu oft und zu sehr getrübt wird (man hat ja schon genug Probleme mit dem Computer, der nicht so will, wie er soll), muß man sich einen Druckerstandard schaffen. Am besten einen, dem man sagt: Das ist ein Epson-, Nec P6-, ATARI-Drucker. Und, o Wunder, eine kleine Anweisung, und Buchstaben, Wörter, Zeilen usw. werden unterstrichen, fett oder kursiv gedruckt. Auch werden plötzlich Buchstaben wie abgdefh korrekt (soweit sie im Druckerzeichensatz vorhanden sind) wiedergegeben. Ein möglicher Standard könnte der Druckertreiber von Wordplus sein. Jeder ATARI-Besitzer wird früher oder später die Bekanntschaft mit diesem Programm machen. Und da es über einen Druckertreiber für jeden Drucker (notfalls schreibt man ihn sich selbst) verfügt, sollte dieser doch auch für eigene Programme zu benutzen sein. Mit den von mir entwickelten Prozeduren, die in den Quellcode eines selbstgeschriebenen Programmes kopiert werden, braucht man sich keine Gedanken mehr über den angeschlossenen Drucker zu machen. Der große Nachteil eines Standards muß hier aber angesprochen werden: Da ja der Standard für alle Drucker gelten soll, kann er nicht spezielle Druckerkommandos (wie 23,5 Zeichen/ Zoll oder rot/violette Schrift) unterstützen. Ob die mit dem Wordplus erreichbaren Befehle auch den Ansprüchen des Anwenders genügen, muß jeder selbst entscheiden.

Nach dieser Einführung kommen wir ans Eingemachte: Die Prozeduren lesen die fertig übersetzte Treibertabelle (z.B.: PRINTER.CFG), die auch von Wordplus benutzt wird. ein. Dazu muß das vom Anwender geschriebene PRINTER.HEX-File erst mit dem INSTALL.PRG, das in dem Wordplus-Programmpaket enthalten ist, übersetzt werden. Das hat den Nachteil, daß man im Besitz des Wordplus-Programms sein muß.

Der Aufbau von PRINTER.CFG

Die ersten acht Bytes der Datei enthalten die Buchstabenfolge "GST-CGF:". Das ist so etwas wie eine Copyright-Meldung.

[0]: Zeichenbreite (nur für Typenraddrucker)
[1]: Zeilenvorschub
[2]: Vorwärtsdruck (nur für Typenraddrucker)
[3]: Rückwärtsdruck (nur für Typenraddrucker)
[4]: Vertikaltabulator
[5]: Horizontaltabulator
[6]: Normal Fettschrift ein
[7]: Normal Fettschrift aus
[8]: NLQ Fettschrift ein
[9]: NLQ Fettschrift aus
[10]: Normal Kursivschrift ein
[11]: Normal Kursivschrift aus
[12]: NLQ Kursivschrift ein
[13]: NLQ Kursivschrift aus
[14]: Normal Helldruck ein
[15]: Normal Helldruck aus
[16]: NLQ Helldruck ein
[17]: NLQ Helldruck aus
[18]: Normal Superscript ein
[19]: Normal Superscript aus
[20]: NLQ Superscript ein
[21]: NLQ Superscript aus
[22]: Normal Subscript ein
[23]: Normal Subscript aus
[24]: NLQ Subscript ein
[25]: NLQ Subscript aus
[26]: Normal unterstreichen ein
[27]: Normal unterstreichen aus
[28]: NLQ unterstreichen ein
[29]: NLQ unterstreichen aus
[30]: Seitenvorschub
[31]: horizontale Initialisierung (zu Beginn des Druckens)
[32]: vertikale Initialisierung (zu Beginn des Druckens)
[33]: Drucker-Reset (am Ende eines Druckvorganges)
[34]: Backspace
[35]: Carriage Return
[36]: Blattlänge
[37]: Zeilenvorschub bei Grafik setzen
[38]: Umschalten in den Grafikmodus
[39]: unbenutzt
[40]: Normal Pica
[41]: NLQ Pica
[42]: Normal Elite
[43]: NLQ Elite
[44]: Normal Schmalschrift
[45]: NLQ Schmalschrift
[46]: Normal Breitschrift
[47]: NLQ Breitschrit
[48]: Farbe Schwarz
[49]: Farbe Magenta (rot)
[SO]: Farbe Cyan (Blau)
[51]: Farbe Gelb

Tabelle 1

Mit ihrer Hilfe kann man überprüfen, ob das einzulesende File wirklich ein Druckertreiber ist (siehe Prozedur cfg_ok). Danach folgt der Druckername, der durch ein NULL-Byte ('\0') beendet wird. Es sind die Zeichen, die vom Anwender direkt in das *.HEX-File geschrieben wurden. Hier besteht die Gefahr, daß das Array druname, in dem der Druckername gespeichert wird, zu klein ist (Literaturangaben reichen von 28 bis 64), also z.B.: BYTE druname[64]:

Die nächsten sechs Bytes enthalten Konfigurationsvariablen und werden im 6 Byte langen Feld cfgvaria abgespeichert. Sie haben folgende Bedeutung:

cfgvaria[0]:
Druckertyp = 1. wenn Typenraddrucker mit Feinpositionierung
Druckertyp = 0. wenn Matrixdrucker oder Typenraddrucker ohne Feinpositionierung

cfgvaria[1]:
Zeichenbreite (nur für Typenraddrucker, sonst immer = 0)

cfgvaria[2]:
Abstand zwischen zwei Zeilen in Punkten (nur für Typenraddrucker, sonst immer = 0)

cfgvaria[3]:
Druckkopfposition nach einem Zeilenvorschub (nur für Typenraddrucker, sonst immer = 0)

cfgvaria[4]:
horizontaler Versatz für Fettdruck (nur für Typenraddrucker, sonst immer = 0)

cfgvaria[5]:
Steht hier eine 1. macht Wordplus nach jeder Seite eines auszudruckenden Textes eine Pause (bei Endlospapier = 0).

Danach folgen die Liste der verfügbaren Steuerbefehle und der verfügbaren oder eventuellen Ersatzbuchstaben. Beide Listen werden mit einem NULL-Byte ('\0') abgeschlossen und sind prinzipiell gleich aufgebaut.

Die Liste der Steuerbefehle beinhaltet 52 mögliche Kommandos, von denen die meisten belegt sind. Diese Kommandos bestehen aus Bytes, die an den Drucker gesendet werden, um den gewünschten Effekt zu erzielen. Als Beispiel seien die Bytes des Epson-Druckertreibers zum Unterstreichen hexadezimal angegeben, wie sie im *.HEX-File stehen könnten:

[26]: 1B, 2D, 1            * Normal unterstreichen an
[28]: 1B, 78, 0, 1B, 2D, 1 * NLQ unterstreichen aus

Alle Befehlsfolgen zu erklären, würde den Rahmen dieses Artikels sprengen. Tabelle 1 soll nur dieses sagen: Wenn z.B. ein Wort unterstrichen werden soll, muß die Prozedur cfg_befehl mit den Parametern (hier beide dezimal) cfg_befehl(26,128): bzw. cfg_befehl(28.128); aufgerufen werden.

Die einzelnen Befehle setzen sich wie folgt zusammen: Das erste Byte eines jeden Befehls beinhaltet die Länge der Befehlsfolge minus zwei (da es sich selbst und die Befehlsnummer mitzählt). Dann kommt die Befehlsnummer und danach die Befehlsfolge (alles als Bytes).

Die Liste der Ersatzbuchstaben enthält Buchstaben bzw. Steuerbefehle, die an den Drucker geschickt werden, um ein bestimmtes Zeichen zu drucken bzw. zu simulieren. Wiederum beinhaltet das erste Byte die Länge der Befehlsfolge minus zwei (da es sich selbst und die Nummer des zu druckenden Buchstabens mitzählt). Es kommen folgende Werte in Frage (vergleiche cfg_load).

len=0:Die Liste ist zuende.
len=2:Das Zeichen ist weder vorhanden, noch kann es simuliert werden. -> Es wird ein Leerzeichen gespeichert.
len=3:Es gibt genau einen Ersatzbuchstaben: Er wird in das Feld cfgascii kopiert.
len>3:Es gibt mehrere Ersatzbuchstaben: Für sie wird ein String reserviert, in dem die folgenden Ersatzbuchstaben eingelesen werden. Dann kommen die Buchstabennummer (0-255) und die Ersatzbuchstaben.

Zum Programm

Das Demonstrationsprogramm soll die Einsatzweise der Prozeduren in selbstgeschriebenen Programmen verdeutlichen und besteht aus mehreren Abschnitten: Zuerst kommen einige gebräuchliche include-Files und Makros, die in jedem Programm Vorkommen und daher nicht weiter erklärt werden. Je nach eingelesenen include-Files muß noch das Makro NULL als #define NULL ((void *)0L) definiert werden.

Dann kommen die für die Prozeduren wichtigen Variablen:

UBYTE   *cfgbefehl[52];
UBYTE   cfgbeflen[52]:
UBYTE   *cfgascii[256]:
UBYTE   cfgaslen[256]:
UBYTE   cfgvaria[6]:
BYTE    druname[64];
BOOLEAN normalschrift;

*cfgbefehl[52] ist ein Feld von 52 Strings (unsigned char *), in denen die Befehlsfolgen abgespeichert werden. Im Feld cfgbeflen[52] werden die Längen der Strings als unsigned char abgespeichert.

*cfgascii[256] und cfgaslen[256] sind analog aufgebaut. Die Variablen cfgvaria[6] und druname[64] wurden schon oben erklärt.

Da Wordplus beim Aufrufen der Treiberbefehle grundsätzlich zwischen Normal- (Draft-) und (Near-) Letter-Quality-(NLQ)-Schrift unterscheidet, sollte auch im eigenen Programm so vorgegangen werden (diese Information wird in der Variablen normalschrift gespeichert). Hierauf folgen (alphabetisch geordnet) die Prototypen der Prozduren und die Prozeduren selbst.

VOID    cfg_befehl(UBYTE,UBYTE); 
BOOLEAN cfg_ok(WORD);
VOID    cfg_init(VOID):
BOOLEAN cfg_load(BYTE []):
VOID    cfg_print(UBYTE *);

Zu Beginn eines jeden Programmes (bzw. vor Aufruf aller anderen Prozeduren) muß die Prozedur cfg_init gestartet werden (vergleiche main). Sie initialisiert die Felder *cfg_befehl[52] mit dem NULL-Pointer, cfgbeflen[52] mit der Befehlslänge 0, *cfgascii[256] mit den jeweiligen ASCII-Werten und cfgaslen[256] mit der Länge 1. Für den Nicht-C-Programmierer sei gesagt, daß die Funktion calloc(a,b); einen Pointer auf ein Feld reserviert (und dann auch zurückliefert), welches a Elemente der Elementlänge b hat. Vergleichen Sie bitte:

cfgbefehl[befehlnr]=calloc(len-2,1);

und

cfgascii[asciinr]=calloc(len-2,1): 

aus cfg_load.

Dann wird die Prozedur cfg_load aufgerufen. der man den Namen des zu ladenden Treibers übergibt. Diese öffnet das File, überprüft mit Hilfe der Prozedur cfg_ok, ob es auch ein Wordplus-Treiber ist, und lädt der Reihe nach den Druckernamen, die Konfigurationsvariablen, die Steuerbefehle und die ASCII-Ersatzbuchstaben (vgl. Programm-Listing).

Jetzt können nach Belieben die Prozeduren cfg_befehl und cfg_print verwendet werden, jedoch sollte der Drucker vor dem Drucks organg durch cfg_befehl(31,128); und cfg_befehl(32,128); initialisiert und hinterher durch cfg_befehl(33,128); reinitialisiert werden (siehe Prozedur main).

Die Prozedur cfg_befehl schickt die Befehls-Bytes an den Drucker. Bei manchen Befehlen wird ein Offset verwendet (z.B. Befehl Nr. 37: Der Drucker benötigt nicht nur die Steuerzeichen zur Einstellung des Zeilenvorschubs, sondern auch den Zeilenabstand selbst als Wert). Bei allen anderen Befehlen (wie Unterstreichen. Fettschrift usw.) kann die Zahl 128 als zweiter Parameter übergeben werden (vergleiche cfg_print).

Mit der Prozedur cfg_print können Strings an den Drucker ausgedruckt werden. Dabei interpretiert die Prozedur Steuerzeichen wie Zeilenvorschub (%N). Unterstreichen an bzw. aus (%U bzw. %u) und andere mit Hilfe des Buchstabens '%'.

Am Ende des Listings steht die main-Prozedur, die den Programmrahmen für die Prozeduren enthält. Sie ist wiederum in sechs Teile geteilt:

  1. Der Anwender wird gebeten, den Namen des zu benutzenden Treibers einzugeben.
  2. In diesem Teil wird der Treiber installiert: überprüfen, ob Drucker online. Treiber initialisieren. Treiber laden. Drucker initialisieren.
  3. Dem Anwender wird der Druckername (laut Treiber) und einige Informationen mitgeteilt. Außerdem werden die Felder asctab1 - asctab4 mit ASCII-Zeichen initialisiert.
  4. Hier wird demonstriert, wie die String-Ausgabe mit dem Treiber funktioniert. Interessant ist dabei der Einbau von Steuerzeichen.
  5. wie der letzte Punkt, aber mit dem Unterschied, daß erst in Normal- und jetzt in NLQ-Schrift gedruckt wird. Nach dem Ausdruck wird der Drucker reinitialisiert.
  6. Hier sind noch einige Fehlermeldungen aufgeführt. Ich hoffe, Sie haben nach Lesen des Artikels den Wordplus-Druckertreiber und die Funktionsweise der Prozeduren verstanden und können diese in Ihren eigenen Programmen erfolgreich einsetzen. Da nichts perfekt ist und alles irgendwie verbessert werden kann, hier noch einige Anregungen:

Wenn man die Prozeduraufrufe Fread nach Fehlern abfragt (Fread()<0), kann man verhindern, daß sich das Programm wegen eines fehlerhaften Configurations-Files aufhängt.


/********************************************************************/
/*                                                                  */
/* Demo-Programm zum Gebrauch das 1st Wordplus-Druckertreibers      */
/*                                                                  */
/*      by Paul Adam            (C) MAXON Computer GmbH             */
/*         Hoppendamm 14                                            */
/*         4400 Münster                                             */
/*                                                                  */
/********************************************************************/

/* gebräuchliche includes *******************************************/

#include <TOS.H> 
#include <STDIO.H> 
#include <STDLIB.H> 
#include <STRING.H>

/* gebräuchliche Makros *********************************************/

#define VOID         void           /* für Funktionen, die      */
                                    /* keinen Wert übernehmen   */
                                    /* bzw. zurück geben        */
#define BOOLEAN      char           /* hier 8-bit integer       */
#define BYTE         char           /* 8-bit integer            */
#define UBYTE        unsigned char  /* unsigned 8-bit integer   */
#define WORD         int            /* 16-bit integer           */
#define TRUE         1
#define FALSE        0
#define CLR_SCREEN() Cconout(0x011B);Cconout('E')
#define MARTE()      Crawcin()      /* erwartet Eingabe         */
/* eventuell muß NULL noch als long integer Null definiert werden */

/* Wichtige globale Variablen für den Druckertreiber ****************/

UBYTE  *cfgbafahl[52];  /* Feld für die Steuerbefehle               */
UBYTE   cfgbaflan[52];  /* Feld für die Länge der Befehle           */
UBYTE  *cfgascii[256];  /* Feld für die ASCII-Ersatzbuchstaben      */
UBYTE   cfgaslan[256];  /* Feld für die Anzahl der Ersatzbuchstaben */
UBYTE   cfgvaria[6];    /* Feld für die Konfigurationsvariablen     */
BYTE    druname[64];    /* Feld für den Druckernamen                */
BOOLEAN normalschrift;  /* TRUE-Normal, FALSE=Near Letter Quality   */

/* Wichtige Routinen für den Druckertreiber *************************/

VOID    cfg_befehl(UBYTE,UBYTE); /* Führt einen Druckerbefehl aus   */
BOOLEAN cfg_ok(WORD);            /* TRUE, wenn geöffnete Datei ein  */
                                 /* 1st-Word-Plus-Treiber ist       */
VOID    cfg_init(VOID);          /* Initialisiert die Treiberarrays */
BOOLEAN cfg_load(BYTE []);       /* TRUE, wenn der Druckertreiber   */
                                 /* geladen worden ist              */
VOID    cfg_print(UBYTE *);      /* Druckt einen (NULL-begrenzten)  */
                                 /* String aus                      */

VOID cfg_befehl(ascnr,offset)
UBYTE ascnr,offset;
{
    BYTE j;
    for (j=0;j<cfgbeflen[ascnr];j++)
        Cprnout((*(cfgbefehl[ascnr]+j)==128?offset:*(cfgbefehl[ascnr]+j))); 
/* Es wird überprüft, ob der dem Drucker zu übergebene Befehl einen */ 
/* Offset (==128?) enthält. Wenn ja, wird der als "offset" ge-      */
/* speicherte Parameter an den Drucker geschickt.                   */
}

BOOLEAN cfg_ok(file)
WORD file;
{
    BOOLEAN treiberok=FALSE;
    BYTE txtbuf[8];
    Fread(file,8,txtbuf);
    if (!strncmp(txtbuf,"GST-CFG:",8)) treiberok=TRUE; 
    return(treiberok);
/* Von der geöffneten Datei "file" werden 8 Buchstaben gelesen und  */ 
/* mit der Zeichenfolge "GST-CFG:" verglichen.                      */
}

VOID cfg_init()
{
    UBYTE i;
    for (i=0;i<52;i++)          /* Das Befehlsarray wird        */
    {                           /* initialisiert:               */
        cfgbeflen[i]=0;         /* Befehllänge=0                */
        cfgbefehl[i]=NULL;      /* => kein Befehl gespeichert   */
    }
    for (i=0;i<255U;i++)        /* Das ASCII-Ersatz-Array wird  */
    {                           /* initialisiert:               */
        cfgaslen[i]=1;          /* Min Buchstabe ist vorhanden  */
        cfgascii[i]=calloc(1,1);/* Der gespeicherte Buchstabe   */
        *cfgascii[i]=i;         /* entspricht seiner Nummer     */
                                /* z.B. : '0'=48, 'A'=65        */
    }
    cfgaslen(2550]=1;           /* Das letzte Feld muß extra    */
    cfgascii[255U]=calloc(1,1); /* initialisiert werden, da es  */
    *cfgascii[255U]=i;          /* sonst einen "Überlauffehler" */
                                /* in der for-Schleife gibt.    */ 
                                /* (wegen "UBYTE i;": i=0-255)  */
}

BOOLEAN cfg_load(nana)
BYTE name[];
{
    BOOLEAN eingelesen=FALSE;
    UBYTE len,i=0,asciinr,ascii,befehlnr;
    WORD file; 
    file=Fopen(name,0); 
    if (file>=0)
    {
        eingelesen=cfg_ok(file);    /* Überprüfen, ob geöffnetes File   */
        if (eingelesen)             /* ein 1st-Word-Plus-Treiber ist    */
        {
            do                      /* Der Druckername wird eingelesen. */
            {
                Fread(file,1,druname+i);
            } while (druname[i++]!='\0');
            Fread(file,6,cfgvaria); /* Die Konfigurationsvariablen      */
                                    /* werden eingelesen.               */
            Fread(file,1,&len);     /* Die Steuerbefehle werden gelesen:*/
            while (len!=0)          /* "wenn Liste noch nicht zuende"   */
            {
                Fread(file,1,&befehlnr);   /* Die Befehlsnummer wird gelesen.   */
                cfgbeflen[befehlnr]=len-2; /* da len sich und befehlnr mitzählt */ 
                cfgbefehl[befehlnr]=calloc(len-2,1);   /* Der Befehl selbst     */
                Fread(file,len-2,cfgbefehl[befehlnr]); /* wird gelesen          */
                Fread(file,1,&len);
            }
            Fread(file, 1, &len);           /* Die Buchstaben werden gelesen:   */
            while (len!=0)                  /* "wenn Liste noch nicht zu ende"  */
            {
                Fread(file,1,&asciinr);     /* Nummer des Ersatzbuchstaben      */
                if (len==2) *cfgascii[asciinr]=' ';     /* Buchstabe kann nicht */
                else                                    /* gedruckt werden      */
                {
                    cfgaslen[asciinr]=len-2; /* da lan sich und befehlnr mitzahlt*/ 
                    if (len==3) Fread(file,1,cfgascii[asciinr]);
                                            /* Es gibt genau einen Buchstaben   */ 
                    else if (len>3)         /* Es gibt mehrere Ersatzbuchstaban */
                    {
                        free(cfgascii[asciinr]);        /* Für mehrere Buchsta- */
                        cfgascii[asciinr]=calloc(len-2,1); /* ben wird ein String */
                        Fread(file,lan-2,cfgascii[asciinr]); /* reserviert und ein- */
                    }                                   /* gelesen.             */
                }
                Fread(file,1,&len);
            }
        }
        Fclose(file);
    }
    return(eingelesen);
}

VOID cfg_print(string)
UBYTE *string;
{
    UBYTE i=0,j,code=0; 
    while (string[i])
    {
        if (string[i]=='%')                 /* Der String wird nach Steuer-     */
        {                                   /* zeichen (z.B.: %N) überprüft     */
            switch (string[i+1])            /* Die Liste der verfügbaren        */
            {                               /* Steuerzeichen:                   */
                case '%': for (j=0;j<cfgaslen['%'];j++)/* Das Zeichen wird      */
                          Cprnout(*(cfgascii['%']+j)); i++; break; /* gedruckt  */ 
                case 'N': code=1;                           break; /* <RETURN>  */
                case 'F': if (normalschrift) code=6,  else code=8;  break;
                case 'f': if (normalschrift) code=7;  else code=9;  break;
                case 'K': if (normalschrift) code=10; else code=12; break;
                case 'k': if (normalschrift) code=11; else code«13; break;
                case 'L': if (normalschrift) code=14; else code=16; break;
                case 'l': if (normalschrift) code=15; else code=17; break;
                case 'H': if (normalschrift) code=18; else code=20; break;
                case 'h': if (normalschrift) code=19; else code=21; break;
                case 'T': if (normalschrift) code=22; else code=24; break;
                case 't': if (normalschrift) code=23; else code=25; break;
                case 'U': if (normalschrift) code=26; else code=28; break;
                case 'u': if (normalschrift) code=27; else code=29; break;
                case 'P': if (normalschrift) code=40; else code=41; break;
                case 'E': if (normalschrift) code=42; else code=43; break;
                case 'S': if (normalschrift) code=44; else code=45; break;
                case 'B': if (normalschrift) code=46; else code=47; break;
            }
            if (code)                           /* wenn der string[i]='%' und    */
            {                                   /* string[i+1] ein Steuerzeichen */
                cfg_befehl(code,128);           /* war, wird der entsprechende   */
                i++;                            /* Befehl an den Drucker gesendet*/
            }
        }
        else for (j=0;j<cfgaslen[string[i]];j++)/* Die Ersatzbuchstaben          */ 
              Cprnout(*(cfgascii[string[i]]+j));/* des in "string[i]" ge-        */
                                                /* speicherten Buchstaben        */ 
                                                /* werden gedruckt               */
        i++;                                    /* das nächste Zeichen von string*/
    }
}

/* Demo-Programm ***************************************************/

VOID main (VOID);

VOID main()
{
    BYTE treibername[64];
    UBYTE i,asctab1[100],asctab2[100],asctab3[100],asctab4[100);
/* Programmteil I *************************************************/ 
    CLR_SCREEN();
    printf("\nDemo-Programm zum Gebrauch das 1st-Word-Plus-Druckertrei") ; 
    printf("bers\n\nGeben sie den Namen (mit vollständigem Pfad) des C"); 
    printf("onfigurationsets ein (*.CFG):\n"); 
    scanf("%s",treibername);
/* Programmteil II ***********************************************/ 
    if (Cprnos()==-1)                           /* Drucker online?              */
    {
        cfg_init();
        if (cfg_load(treibername))
        {
            cfg_befehl(31,128);                 /* Horizontale und Vertikale    */
            cfg_befehl(32,128);                 /* Druckerinitialisierung       */
/* Programmteil III *********************************************/ 
            printf("\nDer galadene Treiber ist für den %s.\n\nFolgen",druname); 
            printf("der Text sollte zweimal korrekt ausgedruckt werden:\n\nT"); 
            printf("ext kann unterstrichen, fett, und/oder kursiv geschriebe") ; 
            printf("n werden. Je nach\nTreiber können hochgestellte oder tie"); 
            printf("fgesetze Buchstaben verwendet werden.\n\nFolg. ASCII-Z"); 
            printf("eichen können gedruckt werden.\n(Ersatzweise werden Leer"); 
            printf("zeichen gedruckt. Soll ein Prozentzeichen gedruckt\nwerd"); 
            printf("en, müssen zwei Zeichen übergeben werden: %%%% für %%)\n"); 
            for (i=0;i<80;i++)    Bconout(5,i); printf("\n"); 
            for (i=80;i<160;i++)  Bconout(5,i); printf("\n"); 
            for (i=160;i<240;i++) Bconout(5,i); printf("\n"); 
            for (i=240;i<255;i++) Bconout(5,i); Bconout(5,i);
            printf(\n\nSollte dieser Text nicht korrekt ausgedruckt werden,"); 
            printf(" überprüfen Sie bitte\nzuerst den Druckertreiber."); 
            for (i=0;i<38;i++)    asctab1[i]=i;     asctab1[80]='\0';
            for (i=38;i<81;i++)   asctab1[i]=i-1;   asctab1[81]='\0';
            for (i=80;i<160;i++)  asctab2[i-80]=i;  asctab2[80]='\0'; 
            for (i=160;i<240;i++) aactab3[i-160]=i; asctab3[80]='\0'; 
            for (i=240;i<255;i++) asctab4[i-240]=i; asctab4[80]='\0'; 
            asctab1[0]= asctab1[10]=asctab1[12]=asctab1[13]=' ';
/* NULL-Begrenzer, Line-Feet, Form-Feet, Carriage-Return                        */
/* Programmteil IV **********************************************/ 
            normalschrift=TRUE,              /* Erstes Mal in Pica-Normalschrift*/
            cfg_print("*PText kann %Uunterstrichen, %Ffett und/odar %Kkursiv"); 
            cfg_print("%u%f%k geschrieben werden. Je nach%NTreiber können %H"); 
            cfg_print("hochgestellta%h oder %Ttiefgesetzte%t Buchstaben verw"); 
            cfg_print("endet werden. %N%NFolgende ASCII-Zeichen können gedruc"); 
            cfg_print("kt werden:%N(Ersatzweise werden Leerzeichen gedruckt."); 
            cfg_print(" Soll ein Prozentzeichen gedruckt%Nwerden, müssen zwe"); 
            cfg_print("i Zeichen übergeben werden: %%%% für %%)%N"); 
            cfg_print(asctab1); cfg_befehl(1,128); 
            cfg_print(asctab2); cfg_befehl(1,128); 
            cfg_print(asctab3); cfg_befehl(1,128); 
            cfg_print(asctab4); cfg_befehl(1,128);
/* Programmteil V ***********************************************/ 
            normalschrift=FALSE;            /* Zweites Mal in Elite-NLQ-Schrift*/
            cfg_print("%E%NText kann %Uunterstrichen,%Ffett und/oder %Kkurs"); 
            cfg_print("iv%u%f%k geschrieben werden. Je nach%NTreiber können "); 
            cfg_print("%Hhochgestellte%h oder %Ttiefgesetzte%t Buchstaben ve"); 
            cfg_print("rwendet werden.%N%NFolgende ASCII-Zeichen können gedr"),
            cfg_print("uckt werden:%N(Ersatzweise werden Leerzeichen gedruck");
            cfg_print("t. Soll ein Prozentzeichen gedruckt%Nwerden, müssen z");
            cfg_print("wei Zeichen übergaben werden: %%%% für %%)%N");
            cfg_print(asctab1); cfg_befehl(1,128);
            cfg_print(asctab2); cfg_befehl(1,128);
            cfg_print(asctab3); cfg_befehl(1,126);
            cfg_print(asctab4); cfg_befehl(1,128);
            cfg_befehl(33,128);             /* Druckerreset                   */
        }
/* Programmteil VI **********************************************/ 
        else
        {
            printf("\n\n\nDie angegebene Datei konnte nicht eingelesen werden\n");
            printf("bzw. ist kein Treiber von 1st-word-plus!");
        }
    }
    else printf("\n\n\nDer Drucker ist nicht online.");
    WARTE();
    exit(0);            /* Turbo-C-spezifisch */
}


Paul Adam
Aus: ST-Computer 04 / 1990, Seite 116

Links

Copyright-Bestimmungen: siehe Über diese Seite