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
Anmerkungen: |
| impressum | datenschutz
© Copyright Artikelpedia.com