Artikel pedia
| Home | Kontakt | Artikel einreichen | Oberseite 50 artikel | Oberseite 50 autors
 
 


Artikel kategorien
Letztes fugte hinzu
    Ms-access

   Instrumentation + schnittstellen

   Pc tuning - volle kraft voraus für ihr system

   Informatorische grundlagen

   Javascript

   Interne sortieralgorithmen - der kern der sache

   Plotter und sonstige drucker

   Frage 20 (rössl priska)

   Internet - programmierung

   Monitore

   Semesterarbeit und spezialgebiet für informatik

   Erörterungs zum thema

   Inhaltsverzeichnis

   Einführung in die entwicklung ganzheitlicher informationssysteme:

   Titel dokument
alle kategorien

  Druckeransteuerung unter turbo-pascal für dos

        Druckeransteuerung unter Turbo-Pascal für DOS                     Sven Thoms und Bernd Osterloth Gymnasium Osterburg Kurs Schmidt 12; Jahr 1998  Annotation: Diese Facharbeit beschäftigt sich mit der Problematik der Druckeransteuerung im Allgemeinen und deren technischer Realisierung mit Hilfe eines in der Programmiersprache PASCAL geschriebenen Programmes. Es soll eine beliebige Datei (ASCII-codiert) gedruckt werden. Das Programm ist von der graphischen Oberfläche her bewußt einfach gehalten, um den Nutzer nicht vom Wesentlichen abzulenken.       Gliederung: Benutzer-Dokumentation Zweck und Anwendungsbereich Anweisungen   Entwickler-Dokumentation 2.1 Lösungsideen und Algoritmen   3 Zusammenfassung                                                                               Zweck und Anwendungsbereich   Dieses Druckprogramm ist nur für den Schul- und Hausgebrauch geeignet, obwohl es leicht zu bedienen und einfach aufgebaut ist, verfügt es aber nicht über einstellbare Druckoptionen. Dieses Programm wurde im Informatikunterricht und teils in Heimarbeit, unter der Projektaufgabe "Entwickeln und testen sie ein Pascal-Programm, mit dessen Hilfe ASCII-Textdateien auf einem Drucker durch direkte Druckeransteuerung ausgedruckt werden können," entwickelt und geschrieben.

In diesem Pascal-Programm wurden die geforderten Richtlinien erfüllt, sowie einige der möglichen Erweiterungen eingebunden.   Spezifikationen :   - Das Datenübertragungsprotokoll zum Drucker ist ADQ-Handshake. - Es wird auf DIN A4-Einzelblätter mit insgesamt 58 Zeilen/Druckseite gedruckt. - Nach dem Druck jeder Seite, jedoch nicht nach der letzten, ist auf dem Bildschirm eine Meldung auszugeben, mit der der Benutzer aufgefordert wird, ein neues Blatt in den Drucker einzulegen sowie der Hinweis, daß erst dann weitergedruckt wird, wenn die ESC-Taste - und nur diese - gedrückt wurde.   Erweiterungen :   die Textzeilen sind fortlaufend numeriert auf Seite 1 wird der Dateiname ausgedruckt des weiteren wird das aktuelle Systemdatum auf Seite 1 ausgedruckt ebenfalls nützlich bei der Archivierung ist die fortlaufende Seitennumerierung mit Angabe der Gesamtanzahl der Seiten und der Drucker wird nach dem Druck einer Datei auf seine Standardeinstellungen zurückgesetzt   Anweisungen   Bei der Benutzung dieses Druck-Programms braucht der Anwender nur sehr wenig zu beachten, da es nur wenige, dafür aber eindeutige Anweisungen gibt. Aus diesem Grund ist ein leichtes, problemloses Arbeiten möglich.

Voraussetzung für den Ausdruck ist, daß der Drucker eingeschaltet und das bei Programmstart Papier im Drucker ist. Ansonsten meldet sich das Programm mit einer Fehlermeldung und der Aufforderung den Drucker einzuschalten bzw. Papier einzulegen. Das Programm wird nach diesen Fehlermeldungen beendet und kann nach Behebung der Fehler erneut gestartet werden. Die Arbeitsanweisungen beschränken sich auf das Eingeben des Dateinamens, der zum Ausdruck gewünschten Datei, sowie dem Blatteinlegen. Der Dateiname darf nicht mehr als 8 Zeichen und die Dateiendung nicht mehr als 3 Zeichen lang sein.

Das sind jedoch Beschränkungen der FAT (File Allocation Table = Dateizuordnungstabelle) von DOS. Erst mit VFAT unter Windows 95 bzw. mit NTFS, dem File System von Windows NT könnten theoretisch auch mehr Dateizeichen verwendet werden. Microsoft bietet zum Zweck der Erweiterung der Funktionalität von DOS-Programmen unter Windows ab Version 95 ein Support Pack für Programmierer an, um dann auch mit mehr als 8 Zeichen zu arbeiten. Die Eingabe des Dateinamens wird dann mit <Enter> bestätigt.   2 Entwickler-Dokumentation   2.

1 Lösungsideen und Teilalgorithmen   Die gestellte Aufgabe aus dem Bereich der Technischen Informatik befaßt sich mit dem Thema der direkten Druckeransteuerung über die Centronics-Schnittstelle. Diese Schnittstelle ist eine spezielle parallele Schnittstelle, bei der die Daten bit-parallel auf 8 parallelen Datenleitungen übertragen werden. Für die Übertragungung der Zeichen vom Computer zum Drucker wurde in diesem Druck-Programm ein einfaches, aber erprobtes Übertragungsprotokoll, das ADQ-Handshake oder ADQ-Protokoll verwendet. Obwohl der Aufbau der CENTRONICS-Schnittstelle die Realisierung unterschiedlicher Übertragungsprotokolle zuläßt, so ist das ADQ-Handshake doch eines der zuverlässigsten und wurde auch verwendet, damit die Arbeit mit dem Programm problemlos erfolgen kann. Zunächst habe ich mich mit dem Aufbau der Druckerschnittstelle und den Zuständen ausgewählter Register-Signale beschäftigt, worauf erste kleine Pascal-Programme folgten, die durch Bitmanipulation in Bytes Zugriff auf die Register der Schnittstelle erhielten. Diese Programme nutzen selbstentwickelte Bit-Filter, die Bit-Masken einsetzen.


Dabei verwendet man die in PASCAL zulässige Verknüpfung von Bytes mit Hilfe der logischen Operatoren AND, OR sowie XOR. Um die Codierung dieser Programme in PASCAL zu erleichtern, sollte man Lösungsalgorithmen aufstellen, in denen eindeutig der Programmablauf mit eigenen Worten beschrieben ist. Um eine komplette und umfangreiche Datei fehlerfrei auszudrucken, waren die Prozeduren Zeilenvorschub und Seitenvorschub notwendig. Alle globalen Variablen des Programms sind im Programmkopf vereinbart worden, weil mehrere Prozeduren mit ihnen arbeiten. Dagegen sind viele Variablen lokal deklariert, da die Prozeduren und Funktionen ähnliche Programmabläufe haben, und man deshalb Variablennamen mehrmals verwenden kann, ohne das Komplikationen auftreten. Ich habe mir zur Aufgabe gestellt, die wichtigsten Prozeduren zu erläutern, da ein PASCAL-Programm meistens aus mehreren Prozeduren besteht, die miteinander verknüpft zusammenarbeiten.

Den Anfang macht hierbei die Prozedur strobeimpuls. Quelltext: procedure strobeimpuls; var steuer_byte,ergebnis_byte,maske:byte; begin maske:=1; steuer_byte:=port[890]; ergebnis_byte:=(steuer_byte XOR maske); port[890]:=ergebnis_byte; delay(10); port[890]:=steuer_byte; end; Diese Prozedur ist charakteristisch für das Druck-Programm, da sie eine der wichtigsten im ganzen Programm ist und da sie nach dem Prinzip der Bitmanipulation arbeiten.Die Aufgabe der Prozedur liegt in der Aussendung eines Signals, das dem Drucker mitteilt, daß ein Datenwort zu "Weiterverarbeitung" bereits im Datenregister vorhanden ist. Die Realisierung erfolgt, indem der PC dem Drucker mitteilt, daß er das Steuerbyte A0 mindestens 10 Millisekunden lang auf Eins setzt, somit einen Bitwechsel vollführt, der ein Signal darstellt.       In der ersten Zeile wird formal der Prozedurname festgelegt, ihm folgt in der zweiten Zeile die Deklaration der zu benutzenden Variabeln steuer_byte, ergebnis_byte und der Bitmaske des Typus byte. Die Anweisungen beginnen mit dem Setzen der Bitmaske auf 1.

Dann wird aus dem Steuerregister mit der Adresse 890 dez das steuer_byte ausgelesen. Da die Maske 1 ist, wird nun mit Hilfe der Operation XOR das ergebnis_byte auf jeden Fall auf 1 gesetzt. Das ergebnis_byte wird nun in das Steuerregister mit der Adresse 890 dez zurückgeschrieben. Eine Pause von 10 ms ermöglicht dem PC die Auswertung und Reaktion auf das ergebnis_byte. Der Strobeimpuls wird generiert, womit die Aufgabe ein Signal abzugeben erfüllt wurde. Anschließend wird das Byte steuer_byte in das Steuerregister mit der Adresse 890 dez zurückgeschrieben.

Die Prozedur strobeimpuls wird in meinem Programm in 50% aller Prozeduren verwendet, man benötigt diese Prozedur zum Druck jeden Zeichens, sowie zur Konfigurierung des Druckers, sie ist für mich ein kausales Hilfsmittel. Bevor die Daten ausgedruckt werden können, müssen sie jedoch erst einmal aus der Datei ausgelesen werden. Dies geschieht mit Hilfe der Prozedur datei_sequentiell_lesen. Quelltext: procedure datei_sequentiell_lesen; var znummer, zzaehler, seite:integer; s,seiten:string;   begin seitenanzahl; seite:=1; str(seite,seiten); wort_drucken('Seite'+' '+Seiten+' '+'von'+' '+gesamt); zeilenvorschub; reset(quelldatei); znummer:=0; while not eof(quelldatei) do   begin znummer:=znummer+1; str(znummer,s); readln(quelldatei,zeile); zeile:=s+' '+zeile; wort_drucken(zeile); if ((znummer MOD 58=0) AND (not eof(quelldatei))) then begin seitenvorschub; seite:=seite+1; str(seite,seiten); writeln('Bitte neues Blatt einlegen, wenn Drucker fertig ist!'); delay(10000); writeln('Weiter mit Escape-Taste!'); repeat until readkey=escape; wort_drucken('Seite'+' '+Seiten+' '+'von'+' '+gesamt); zeilenvorschub; clrscr; end; end; if eof(quelldatei) then begin clrscr; writeln('Drucken beendet'); seitenvorschub; end; end;   Wieder wird zunächst der Prozedurname festgelegt. In dieser Prozedur kommen schon einige Erweiterungen zum Einsatz. Zum Beispiel wird jede einzelne Zeile der auszulesenden Datei numeriert.

Dies geschieht über den Zähler znummer, der bei jedem Durchlauf der While not Eof Schleife um 1 hochgesetzt wird, also bei jeder neu eingelesenen Zeile. Der Zähler wird über den Befehl str dann noch ins String-Format übersetzt, um dann zusammen mit der Zeile ausgedruckt zu werden. Wenn der Zähler znummer 58 oder ein Vielfaches davon beträgt, wird ein Seitenvorschub gestartet; eine im Programm definierte Prozedur. Die aktuelle Seitenanzahl Seite, die zuvor auf 1 gesetzt wurde, wird nun um 1 erhöht, um dann auf der nächsten Seite zusammen mit der in der Prozedur seitenanzahl ermittelten Gesamtseitenzahl gesamt ausgedruckt zu werden. Um dem Anwender jedoch Zeit zum Neueinlegen eines Blattes Papier zu geben, wird der Seiteneinzug solange verzögert, bis der Anwender die Escape-Taste betätigt hat. Dann wird der Druck der restlichen Zeilen der Datei fortgesetzt, immer mit einem Seitenvorschub und einem darauf folgenden Seiteneinzug führt.

Der Seiteneinzug ist aber nur eine Folge des Strobeimpulses, der in der Prozedur wort_drucken durchgeführt wird, um die nach dort übergebene Variable zeile auszudrucken. Hier noch einmal zum näheren Verständnis der Quelltext der Prozedur wort_drucken: procedure wort_drucken(zeile: string) ; var zk_laenge,i:integer; zeichen:char; begin zk_laenge:=length(zeile); For i:=1 to zk_laenge do begin zeichen:=zeile[i]; port[888]:=ord(zeichen); strobeimpuls; delay(10); end; zeilenvorschub; end;   Wie sehr schön zu erkennen ist, findet sich hier unsere eingelesene Zeile aus der Prozedur datei_sequentiell_lesen wieder. Diese wird jetzt auf ihre Länge hin untersucht. Vom ersten Zeichen an bis zum letzten der Zeichenkette wird nun das jeweilige Zeichen ins Datenregister verschoben, um von dort per Strobeimpuls an den Drucker zu wandern. Dieser führt dann noch einen Zeilenvorschub aus, um schließlich die nächste Zeile zu drucken. Es sei an dieser Stelle angemerkt, daß der Computer die Zeilen viel schneller aus der Datei ausliest, als diese gedruckt werden können.

Das stellt jedoch keinen Nachteil dar, da der Puffer im Drucker groß genug ist, die ankommenden Daten zwischenzuspeichern.   Das war eigentlich schon der gesamte Vorgang des Druckens samt Auslesen der Informationen aus der ASCII-Datei. Der Auslesevorgang findet sich, diesmal aber ohne Druckvorgang, auch noch einmal in der Prozedur seitenanzahl. Sie dient lediglich dazu, im voraus die Gesamtanzahl der Zeilen der Datei festzustellen, um diese dann später immer mit der aktuellen Seitenzahl auszudrucken, wenn eine neue Seite beginnt. Hier der Quelltext der Prozedur Seitenanzahl: procedure seitenanzahl; var zeilennummer, seitenzahl:integer;   begin reset(quelldatei); zeilennummer:=0; while not eof(quelldatei) do begin zeilennummer:=zeilennummer+1; readln(quelldatei); end; seitenzahl:=zeilennummer div 58; if zeilennummer mod 58 <> 0 then seitenzahl:=seitenzahl+1; str(seitenzahl, gesamt); close(quelldatei); end;   Dividiert man die Anzahl der Zeilen, gespeichert in der Variablen zeilennummer durch die Anzahl der Zeilen pro Seite, so ergibt sich daraus die Gesamtseitenzahl. Bei einer nicht ganzen Zahl ist die Seitenzahl entsprechend immer einen Zähler höher.

Die Prozeduren online_test (Abfrage, ob der Drucker eingeschaltet bzw. neudeutsch “online”Ist), busy (Abfrage der Verfügbarkeit des Druckers) fragen mittels bestimmter Bitmasken das Statusregister des Druckers mit der Adresse 889 dez ab und sind im Hauptprogramm dem eigentlichen Druckvorgang vorgestellt, ebenso wie die Prozedur prüfen.   In der Prozedur pruefen wird beim Öffnen der zu druckenden Datei auf das IO-Ergebnis gewartet und entsprechend seinem Wert der Vorgang weitergeführt oder mit einem Hinweis auf die nicht vorhandene Datei beeendet.   Besonders erwähnenswert ist die Prozedur datum_drucken. In ihr wird das Systemdatum mit Hilfe des Befehls getDate ausgelesen. Mittels eines Datenfeldes werden den Werten 0 bis 6, je nach Wochentag, der Variable dow, die Wochentage zugeordnet und dann zusammen mit dem Datum gedruckt.

Hier der Quelltext: procedure datum_drucken; var Jahr, Monat, tag:string; const Tage: array [0..6] of String[10] =('Sonntag','Montag','Dienstag', 'Mittwoch','Donnerstag','Freitag','Samstag'); var y, m, d, dow : Word; begin GetDate(y,m,d,dow); str(y,Jahr); str(m,Monat); str(d,Tag); wort_drucken(Tage[dow]+','+' '+'der'+' '+ Tag+'.'+Monat+'.'+Jahr);zeilenvorschub;end;     Zusammenfassung   Obwohl heute sicherlich niemand mehr einen Druckertreiber für DOS schreiben würde, der derart genere
echo"
"; }?>
Dabei verwendet man die in PASCAL zulässige Verknüpfung von Bytes mit Hilfe der logischen Operatoren AND, OR sowie XOR. Um die Codierung dieser Programme in PASCAL zu erleichtern, sollte man Lösungsalgorithmen aufstellen, in denen eindeutig der Programmablauf mit eigenen Worten beschrieben ist. Um eine komplette und umfangreiche Datei fehlerfrei auszudrucken, waren die Prozeduren Zeilenvorschub und Seitenvorschub notwendig. Alle globalen Variablen des Programms sind im Programmkopf vereinbart worden, weil mehrere Prozeduren mit ihnen arbeiten. Dagegen sind viele Variablen lokal deklariert, da die Prozeduren und Funktionen ähnliche Programmabläufe haben, und man deshalb Variablennamen mehrmals verwenden kann, ohne das Komplikationen auftreten. Ich habe mir zur Aufgabe gestellt, die wichtigsten Prozeduren zu erläutern, da ein PASCAL-Programm meistens aus mehreren Prozeduren besteht, die miteinander verknüpft zusammenarbeiten.

Den Anfang macht hierbei die Prozedur strobeimpuls. Quelltext: procedure strobeimpuls; var steuer_byte,ergebnis_byte,maske:byte; begin maske:=1; steuer_byte:=port[890]; ergebnis_byte:=(steuer_byte XOR maske); port[890]:=ergebnis_byte; delay(10); port[890]:=steuer_byte; end; Diese Prozedur ist charakteristisch für das Druck-Programm, da sie eine der wichtigsten im ganzen Programm ist und da sie nach dem Prinzip der Bitmanipulation arbeiten.Die Aufgabe der Prozedur liegt in der Aussendung eines Signals, das dem Drucker mitteilt, daß ein Datenwort zu "Weiterverarbeitung" bereits im Datenregister vorhanden ist. Die Realisierung erfolgt, indem der PC dem Drucker mitteilt, daß er das Steuerbyte A0 mindestens 10 Millisekunden lang auf Eins setzt, somit einen Bitwechsel vollführt, der ein Signal darstellt.       In der ersten Zeile wird formal der Prozedurname festgelegt, ihm folgt in der zweiten Zeile die Deklaration der zu benutzenden Variabeln steuer_byte, ergebnis_byte und der Bitmaske des Typus byte. Die Anweisungen beginnen mit dem Setzen der Bitmaske auf 1.

Dann wird aus dem Steuerregister mit der Adresse 890 dez das steuer_byte ausgelesen. Da die Maske 1 ist, wird nun mit Hilfe der Operation XOR das ergebnis_byte auf jeden Fall auf 1 gesetzt. Das ergebnis_byte wird nun in das Steuerregister mit der Adresse 890 dez zurückgeschrieben. Eine Pause von 10 ms ermöglicht dem PC die Auswertung und Reaktion auf das ergebnis_byte. Der Strobeimpuls wird generiert, womit die Aufgabe ein Signal abzugeben erfüllt wurde. Anschließend wird das Byte steuer_byte in das Steuerregister mit der Adresse 890 dez zurückgeschrieben.

Die Prozedur strobeimpuls wird in meinem Programm in 50% aller Prozeduren verwendet, man benötigt diese Prozedur zum Druck jeden Zeichens, sowie zur Konfigurierung des Druckers, sie ist für mich ein kausales Hilfsmittel. Bevor die Daten ausgedruckt werden können, müssen sie jedoch erst einmal aus der Datei ausgelesen werden. Dies geschieht mit Hilfe der Prozedur datei_sequentiell_lesen. Quelltext: procedure datei_sequentiell_lesen; var znummer, zzaehler, seite:integer; s,seiten:string;   begin seitenanzahl; seite:=1; str(seite,seiten); wort_drucken('Seite'+' '+Seiten+' '+'von'+' '+gesamt); zeilenvorschub; reset(quelldatei); znummer:=0; while not eof(quelldatei) do   begin znummer:=znummer+1; str(znummer,s); readln(quelldatei,zeile); zeile:=s+' '+zeile; wort_drucken(zeile); if ((znummer MOD 58=0) AND (not eof(quelldatei))) then begin seitenvorschub; seite:=seite+1; str(seite,seiten); writeln('Bitte neues Blatt einlegen, wenn Drucker fertig ist!'); delay(10000); writeln('Weiter mit Escape-Taste!'); repeat until readkey=escape; wort_drucken('Seite'+' '+Seiten+' '+'von'+' '+gesamt); zeilenvorschub; clrscr; end; end; if eof(quelldatei) then begin clrscr; writeln('Drucken beendet'); seitenvorschub; end; end;   Wieder wird zunächst der Prozedurname festgelegt. In dieser Prozedur kommen schon einige Erweiterungen zum Einsatz. Zum Beispiel wird jede einzelne Zeile der auszulesenden Datei numeriert.

Dies geschieht über den Zähler znummer, der bei jedem Durchlauf der While not Eof Schleife um 1 hochgesetzt wird, also bei jeder neu eingelesenen Zeile. Der Zähler wird über den Befehl str dann noch ins String-Format übersetzt, um dann zusammen mit der Zeile ausgedruckt zu werden. Wenn der Zähler znummer 58 oder ein Vielfaches davon beträgt, wird ein Seitenvorschub gestartet; eine im Programm definierte Prozedur. Die aktuelle Seitenanzahl Seite, die zuvor auf 1 gesetzt wurde, wird nun um 1 erhöht, um dann auf der nächsten Seite zusammen mit der in der Prozedur seitenanzahl ermittelten Gesamtseitenzahl gesamt ausgedruckt zu werden. Um dem Anwender jedoch Zeit zum Neueinlegen eines Blattes Papier zu geben, wird der Seiteneinzug solange verzögert, bis der Anwender die Escape-Taste betätigt hat. Dann wird der Druck der restlichen Zeilen der Datei fortgesetzt, immer mit einem Seitenvorschub und einem darauf folgenden Seiteneinzug führt.

Der Seiteneinzug ist aber nur eine Folge des Strobeimpulses, der in der Prozedur wort_drucken durchgeführt wird, um die nach dort übergebene Variable zeile auszudrucken. Hier noch einmal zum näheren Verständnis der Quelltext der Prozedur wort_drucken: procedure wort_drucken(zeile: string) ; var zk_laenge,i:integer; zeichen:char; begin zk_laenge:=length(zeile); For i:=1 to zk_laenge do begin zeichen:=zeile[i]; port[888]:=ord(zeichen); strobeimpuls; delay(10); end; zeilenvorschub; end;   Wie sehr schön zu erkennen ist, findet sich hier unsere eingelesene Zeile aus der Prozedur datei_sequentiell_lesen wieder. Diese wird jetzt auf ihre Länge hin untersucht. Vom ersten Zeichen an bis zum letzten der Zeichenkette wird nun das jeweilige Zeichen ins Datenregister verschoben, um von dort per Strobeimpuls an den Drucker zu wandern. Dieser führt dann noch einen Zeilenvorschub aus, um schließlich die nächste Zeile zu drucken. Es sei an dieser Stelle angemerkt, daß der Computer die Zeilen viel schneller aus der Datei ausliest, als diese gedruckt werden können.

Das stellt jedoch keinen Nachteil dar, da der Puffer im Drucker groß genug ist, die ankommenden Daten zwischenzuspeichern.   Das war eigentlich schon der gesamte Vorgang des Druckens samt Auslesen der Informationen aus der ASCII-Datei. Der Auslesevorgang findet sich, diesmal aber ohne Druckvorgang, auch noch einmal in der Prozedur seitenanzahl. Sie dient lediglich dazu, im voraus die Gesamtanzahl der Zeilen der Datei festzustellen, um diese dann später immer mit der aktuellen Seitenzahl auszudrucken, wenn eine neue Seite beginnt. Hier der Quelltext der Prozedur Seitenanzahl: procedure seitenanzahl; var zeilennummer, seitenzahl:integer;   begin reset(quelldatei); zeilennummer:=0; while not eof(quelldatei) do begin zeilennummer:=zeilennummer+1; readln(quelldatei); end; seitenzahl:=zeilennummer div 58; if zeilennummer mod 58 <> 0 then seitenzahl:=seitenzahl+1; str(seitenzahl, gesamt); close(quelldatei); end;   Dividiert man die Anzahl der Zeilen, gespeichert in der Variablen zeilennummer durch die Anzahl der Zeilen pro Seite, so ergibt sich daraus die Gesamtseitenzahl. Bei einer nicht ganzen Zahl ist die Seitenzahl entsprechend immer einen Zähler höher.

Die Prozeduren online_test (Abfrage, ob der Drucker eingeschaltet bzw. neudeutsch “online”Ist), busy (Abfrage der Verfügbarkeit des Druckers) fragen mittels bestimmter Bitmasken das Statusregister des Druckers mit der Adresse 889 dez ab und sind im Hauptprogramm dem eigentlichen Druckvorgang vorgestellt, ebenso wie die Prozedur prüfen.   In der Prozedur pruefen wird beim Öffnen der zu druckenden Datei auf das IO-Ergebnis gewartet und entsprechend seinem Wert der Vorgang weitergeführt oder mit einem Hinweis auf die nicht vorhandene Datei beeendet.   Besonders erwähnenswert ist die Prozedur datum_drucken. In ihr wird das Systemdatum mit Hilfe des Befehls getDate ausgelesen. Mittels eines Datenfeldes werden den Werten 0 bis 6, je nach Wochentag, der Variable dow, die Wochentage zugeordnet und dann zusammen mit dem Datum gedruckt.

Hier der Quelltext: procedure datum_drucken; var Jahr, Monat, tag:string; const Tage: array [0..6] of String[10] =('Sonntag','Montag','Dienstag', 'Mittwoch','Donnerstag','Freitag','Samstag'); var y, m, d, dow : Word; begin GetDate(y,m,d,dow); str(y,Jahr); str(m,Monat); str(d,Tag); wort_drucken(Tage[dow]+','+' '+'der'+' '+ Tag+'.'+Monat+'.'+Jahr);zeilenvorschub;end;     Zusammenfassung   Obwohl heute sicherlich niemand mehr einen Druckertreiber für DOS schreiben würde, der derart generelle Funktionen bietet, war die Arbeit an diesem Projekt doch sehr interessant. Ob nun DOS oder Windows, die Prinzipien der Bitmaskenprogrammierung kommen in allen möglichen Gerätetreibern und bei allen Betriebssystemen zum Einsatz.

  vollständiger Sourcecode program druck; uses dos, crt; var quelldatei:text; quelldateiname:string[12]; zeile:string[125]; busy_wert:integer; druck_string:string[125]; zeichen:char; datei_vorhanden:boolean; taste:char; gesamt:string; const escape=chr(27);     {--------Abfrage, ob der Drucker druckbereit ist------}     procedure busy; var status_byte,maske,ergebnis_byte:byte; begin clrscr; maske:=128; status_byte:=port[889]; ergebnis_byte:=(status_byte and maske); if ergebnis_byte=maske then busy_wert:=1 else busy_wert:=0; end;   procedure strobeimpuls; var steuer_byte,ergebnis_byte,maske:byte; begin maske:=1; steuer_byte:=port[890]; ergebnis_byte:=(steuer_byte XOR maske); port[890]:=ergebnis_byte; delay(10); port[890]:=steuer_byte; end;                               procedure zeilenvorschub; begin port[888]:=10; strobeimpuls; end;   procedure wort_drucken(zeile: string) ; var zk_laenge,i:integer; zeichen:char; begin zk_laenge:=length(zeile); For i:=1 to zk_laenge do begin zeichen:=zeile[i]; port[888]:=ord(zeichen); strobeimpuls; delay(10); end; zeilenvorschub; end;   {------Abfrage, ob Drucker an ist-----}   procedure online_test; var status_byte, neu_byte, maske:byte; bit_wert,i:integer; begin i:=1; repeat clrscr; maske:=16; status_byte:=port[889]; neu_byte:=(status_byte AND maske); if neu_byte=maske then bit_wert:=1 else bit_wert:=0; if bit_wert=0 then writeln('Bitte schalten Sie den Drucker ein!'); delay (1000); i:=i+1; until (neu_byte=maske) or (i=15); if neu_byte<>maske then begin writeln('Abbruch des Druckprogrammes'); delay(5000); halt; end; end;   procedure druckerpuffer_leeren; begin port[888]:=13; strobeimpuls; end;   procedure seitenvorschub; begin port[888]:=12; strobeimpuls; end;             procedure seitenanzahl; var zeilennummer, seitenzahl:integer;   begin reset(quelldatei); zeilennummer:=0; while not eof(quelldatei) do begin zeilennummer:=zeilennummer+1; readln(quelldatei); end; seitenzahl:=zeilennummer div 58; if zeilennummer mod 58 <> 0 then seitenzahl:=seitenzahl+1; str(seitenzahl, gesamt); close(quelldatei); end;     procedure datei_sequentiell_lesen; var znummer, zzaehler, seite:integer; s,seiten:string;   begin seitenanzahl; seite:=1; str(seite,seiten); wort_drucken('Seite'+' '+Seiten+' '+'von'+' '+gesamt); zeilenvorschub; reset(quelldatei); znummer:=0; while not eof(quelldatei) do   begin znummer:=znummer+1; str(znummer,s); readln(quelldatei,zeile); zeile:=s+' '+zeile; wort_drucken(zeile); if ((znummer MOD 58=0) AND (not eof(quelldatei))) then begin seitenvorschub; seite:=seite+1; str(seite,seiten); writeln('Bitte neues Blatt einlegen, wenn Drucker fertig ist!'); delay(10000); writeln('Weiter mit Escape-Taste!'); repeat until readkey=escape; wort_drucken('Seite'+' '+Seiten+' '+'von'+' '+gesamt); zeilenvorschub; clrscr; end; end; if eof(quelldatei) then begin clrscr; writeln('Drucken beendet'); seitenvorschub; end; end;     procedure pruefen (VAR quelldatei:text; var datei_vorhanden:boolean); begin (*$I-*) reset (quelldatei); (*$I+*) if IOresult <> 0 then begin datei_vorhanden:=false; end else begin datei_vorhanden:=true; close(quelldatei); end; end;   procedure kopfzeile_drucken; begin wort_drucken(quelldateiname); zeilenvorschub; end;   procedure datum_drucken; var Jahr, Monat, tag:string; const Tage: array [0..6] of String[10] = ('Sonntag','Montag','Dienstag', 'Mittwoch','Donnerstag','Freitag', 'Samstag'); var y, m, d, dow : Word;   begin GetDate(y,m,d,dow); str(y,Jahr); str(m,Monat); str(d,Tag); wort_drucken(Tage[dow]+','+' '+'der'+' '+ Tag+'.'+Monat+'.'+Jahr); zeilenvorschub; end;     begin clrscr; online_test; write('Welche Datei soll gedruckt werden? :');readln(quelldateiname); assign(quelldatei,quelldateiname); pruefen(quelldatei,datei_vorhanden); if datei_vorhanden=false then begin writeln('Die zu druckende Datei ist nicht da'); readln; halt; end;   busy; if busy_wert=1 then begin kopfzeile_drucken; datum_drucken; datei_sequentiell_lesen; close(quelldatei); delay(10); druckerpuffer_leeren; seitenvorschub; end; end.  

Suchen artikel im kategorien
Schlüsselwort
  
Kategorien
  
  
   Zusammenfassung Der Vorleser

   sachtextanalyse

   interpretation zwist

   Fabel interpretation

   literarische charakteristik

   interpretation bender heimkehr

   felix lateinbuch

   interpretation der taucher von schiller

   textbeschreibung

   charakterisierung eduard selicke
Anmerkungen:

* Name:

* Email:

URL:


* Diskussion: (NO HTML)




| impressum | datenschutz

© Copyright Artikelpedia.com