CODINGLISTINGS ★ Drucken mit dem 8. Bit ★

Drucken mit dem 8. Bit (CPC Amstrad International)Coding Listings
★ Ce texte vous est présenté dans sa version originale ★ 
 ★ This text is presented to you in its original version ★ 
 ★ Este texto se presenta en su versión original ★ 
 ★ Dieser Text wird in seiner Originalfassung präsentiert ★ 

Dieser Beitrag wendet sich an die stolzen Besitzer des CPC 464 und der RAM-Erweiterung der Firma Vortex, die nicht auf eine 8-Bit Druckausgabe verzichten wollen, um z.B. Grafiken von Turbo-Pascal unter dem 62k-CP/M zu erstellen. Als Voraussetzung hierfür ist der Eingriff in den Rechner laut Heft 5'86 CPC-Intemational , der das 8. Bit unter Verwendung des Ports C Bit 5 des 8255 (Datenausgabe an Rekorder) bereitstellt, zu sehen. Zur Ansteuerung dieser neu geschaffenen Schnittstelle sind schon viele Programme veröffentlicht worden, die sich aber alle an die »Nur-Basic-Programmierer« richten. Was macht aber der »62k-CP/M-ler“? Der muß, ob er will oder nicht, in die Tiefen des BDOS und der Bankumschaltung hinabtauchen, um zu erforschen, wo er seine Routine zur erweiterten Druckerausgabe zu lassen hat. Dieser Beitrag soll Ihnen das Tieftauchen ersparen (vielleicht gibt es ja auch Nichtschwimmer unter den 62k-CP/M-lem), und einen Einblick in die Bankumschaltung geben. Alle Leser, zu denen sich noch nicht die RAM-Aufteilung unter dem 62k-CP/M herumgesprochen hat, sollten sich folgendes Schema näher betrachten, (s. Skizze 1—3) welches den Speicher Ihres Rechners zeigt:

Dem aufmerksamen Leser wird auffallen, daß sich der RAM, wie er sich den Programmen unter 62k-CP/M darstellt, in verschiedenen Speicherbänken befindet. BIOS 1, das ist die CP/M Zero-Page, liegt in der Grundbank, dem eingebauten Speicher, genauso wie der untere Teil des TPA. Der obere Teil des TPA und ein weiterer Teil des BIOS liegt in der RAM-Erweiterung auf Bank 1. Durch die Elektronik der Bankumschaltung ist gewährleistet, daß ein CP/M-Programm diese beiden Speicherbereiche als durchgängigen RAM sieht. Der obere Bereich der Grundbank, mit BIOS 2 gekennzeichnet, beinhaltet im wesentlichen die allseits beliebten und nützlichen Sprungleisten und Routinen der Firmware, und ist ansonsten leer. Hier ist viel Platz für eigene Routinen, auch für die erweiterte Druckerausgabe (von 8600 bis A7FF) die den Firmware-Einsprung MC-PRINT-CHAR patched. Dieser Einsprung liegt bei BD2B der Grundbank. Wie bekommt man nun ein Programm in diesen Bereich? - Ganz einfach: man lädt es in den unteren TPA, schaltet den oberen Block des Speichers auf die Grundbank und verschiebt das Programm an die vorgesehene freie Stelle. Dann schaltet man den oberen Block zurück auf Bank 1 und springt WBOOT an. Fertig ist die auf 8 Bit erweiterte Druckerausga-be-Routine. Was man dazu kennen muß, sind freilich die Befehle zur Bankumschaltung. Derer gibt es jedoch zweierlei: Zum einen besitzt die Speichererweiterung ein Bank-Select-Register, was wir hier nicht brauchen, da für das 62k-CP/M immer nur die Bank 1 der Erweiterung aktiv ist, zum anderen werden Bit 5 und Bit 6 des Ports 7Fxx, der auch das Gate-Array anspricht, zum Blockselect und Mapping-Enable benutzt. Dabei bedeuten:

BIT 5:1= Schalte Grundbank ab und blende Erweiterung ein 0 = Schalte Erweiterung ab und blende Grundbank ein BIT 6:1= Wähle oberen Block der Erweiterung an 0 = Wähle unteren Block der Erweiterung an

Was wir hier brauchen ist nur das 5. Bit des Ports 7Fxx, da der obere Block der Speichererweiterung immer angewählt bleiben kann, es sei denn, man möchte im Drucker-Spooler irgend etwas manipulieren (natürlich nur von einem Programm aus, was oberhalb 8000 im RAM liegt, da es sich sonst selbst den Teppich unter den Füßen wegzieht).

Da jetzt die grundlegenden Dinge bekannt sind, kann man sich getrost dem Listing zuwenden. Das Programm heißt CENTRONI.COM, wurde mit dem Wordstar geschrieben und danach durch den Makroassembler M80 und den Linker L80 genudelt. Sie können es auch einfach mit dem DDTZ eingeben, da es nicht so umfangreich ist. Wenn Sie das tun, brauchen Sie natürlich nicht auf die Label »Anfang« und »Done« bzw. »Ende« zu achten. Sie tippen einfach die Mnemonics ein und überall, wo im Op-Code ein Label steht, schauen Sie in der Spalte links nach und geben die entsprechenden Hex-Werte ein.

Wie Sie sicher schon erraten haben, sind eigentlich 2 Programme nötig. Einmal die Drucker-Routine selber und als zweites ein Ladeprogramm, welches die Drucker-Routine in die Grundbank schiebt und den Restart bei BD2B durch einen Sprung auf die Routine ersetzt.

Das Ladeprogramm beginnt bei »Start«. Als erstes wird durch DI der Interrupt gesperrt, was man bei Bankumschaltungen tunlichst immer machen sollte, da sich sonst der Rechner diskret verabschiedet. Danach wird die Bankumschaltung durch das Laden von BC mit 7FEE (7F = Portadresse, EE = »gängiger« Wert, der eigentlich alles so läßt wie es ist) vorbereitet und das Bit 5 in C zurückgesetzt (Sie erinnern sich: BIT 5=0 schaltet die Erweiterung ab und blendet die Grundbank ein). OUT (C),C vollbringt die Bankumschaltung. Die nächsten Befehle laden an die Stelle BD2B der Firmware-Sprungleiste den Sprung zur neuen Drucker-Routine, hier nach A400. Sie können sich auch einen anderen Speicherbereich aussuchen, der frei ist, müssen dann aber auch die Call-Adressen in der Drucker-Routine entsprechend ändern. Falls Sie mit dem Assembler arbeiten, ändern Sie nur den Wert in der Konstanten »Ziel« und hinter der Assembler-Direktive .Phase. Im Anschluß daran werden in die Register HL die Quelle, in DE das Ziel und in BC die Anzahl der zu verschiebenden Bytes geladen und mit LDIR das Verschieben des Programms realisiert. Zum glücklichen Ende gehört noch die Einblendung der Bank 1 der Erweiterung, das Zulassen des Interrupts und ein Jump nach 0000.

Die Drucker-Routine tippen Sie direkt im Anschluß an das Ladeprogramm ein. Sie rettet zuerst BC und setzt das neue 7. Bit zu 0 (mit D7LOW). Dann wird untersucht, ob das auszugebende Zeichen das 7. Bit gesetzt hat (also >127 ist). Wenn nein wird es einfach ausgegeben (MCPRCA), ansonsten wird in XPRI1 das 7. Bit gesetzt, das Zeichen ausgegeben und das 7. Bit wieder rück- gesetzt. Zum Schluß wird BC restauriert und die Routine mit RET verlassen. Die beiden Routinen D7LOW und D7HIGH laden erst die Portadresse F6 (Port C des 8255) nach B und lesen den Port aus. Dann wird das Bit 5 entweder rückgesetzt (LOW) oder gesetzt (HIGH) und wieder ausgegeben. Für alle M80 Besitzer sei gesagt, daß der Befehl ».PHASE Adresse« den Assembler anweist, den Code für den Speicher ab Adresse zu erzeugen (hier A400), aber direkt hinter das Ladeprogramm abzulegen. Der Befehl ».DEPHASE« macht diese Direktive rückgängig. Außerdem braucht der M80 die Label »Anfang« und »Start« für die Berechnung der Anzahl Byte, die umgeladen werden sollen. Nach dem Linken steht Ihnen die Datei CENTRONI.COM zur Verfügung.

Diejenigen unter Ihnen, die das Programm mit dem DDT oder DDTZ eingegeben haben, gehen mit CTRL C ins Betriebssystem und speichern mit »Save 1 Centroni.com« das Programm ab.

Zu bemerken ist, daß das Programm nicht mit dem Druckerspooler der RAM-Erweiterung zusammenarbeitet. Schalten Sie also den Spooler ab (mit der Datei »SPOOL.COM«).

Da wir gerade dabei sind in den Speicherbänken rumzuwühlen, können wir auch noch ein anderes Problem behandeln. Haben Sie schon mal versucht von Turbo-Pascal unter 62k-CP/M einige Firmware-Routinen anzuspringen (mittels INLINE-Statements)? -Ja werden Sie sagen, das geht doch tadellos. Tut es auch, solange Ihr Programm den freien Speicher nicht bis zum Anschlag (FBASE) ausnutzt. Falls doch (vielleicht mittels riesiger Arrays) können Sie nach Aufruf von Firmware-Routinen den Rechner nur noch ausschalten oder wenigstens ein System-Reset durchführen, da der Prozessor ins Bodenlose abgetaucht ist. Der Grund dafür ist, daß Ihre Arrays eine Sprungleiste in der Bank 1, die parallel zur Firmware-Sprungleiste der Grundbank liegt, also mitten im TPA, überschrieben und damit zerstört haben. Sehen Sie sich die Sprungleiste im TPA in unzerstörtem Zustand an, sehen Sie nur lauter CALL F554. Alle Firmware-Calls gehen also auf eine Routine in BIOS. Wenn Sie also im Inline-Statement mit CALL BBF6 z.B. die Routine GRA-LINE-ABSOLUT aufrufen, so wird über BBF6: CALL F554 nach F554 gesprungen, wobei die nachfolgende Adresse, hier also BBF9 auf dem Stack liegt. Innerhalb der Routine F554 wird der Wert aber vom Stack geholt und nach 004F in die Zero-Page geladen, außerdem wird das L-Register mit 57 geladen. Danach folgt über die zentrale Bankumschalt-Routine F4FD gekoppelt mit ihrem Teil in der Zero-Page bei 004A der Einsprung in die Grundbank bei 8000. In der dortigen Routine wird das H-Register mit A8 geladen und der Interrupt-Vektor umgebogen, was hier aber nebensächlich ist. Mittels PUSH HL und RET erfolgt ein Sprung nach A857, was wiederum eine Sprungleiste ist. Von dort erfolgt der Einsprung in eine Routine bei 8118 die den Wert aus 4F holt. Dieser Wert stellt das ursprüngliche Sprungziel plus 3 in die Firmware dar. Dieser wird jetzt nun 3 mal dekrementiert und als Adresse angesprungen. Damit ist der Firmware-Aufruf bewerkstelligt. Falls Sie mit Ihren Arrays aber die Sprungleiste mit den CALL's F554 überschrieben haben, funktioniert das ganze nicht. Die Lösung des Problems liegt in dem direkten Ansprung von F554 und zwar nicht über ein CALL sondern ein JUMP, wobei vorher die zu CALLende Adresse+3 auf den Stack gePUSHd wird. Das sieht im Inline-Statement folgendermaßen aus:

PROCEDURE Call;
(* in BC steht die zu rufende *) BEGIN (* Adresse *)
INLINE ($03/$03/$03/
(* INC BC/INC BC/INC BC/ *)
$C5/ (* PUSH BC *)
$C3/$54/$F5); (* JP F554 *)
END; (* Call *)

Uber die Procedure Call laufen alle Firmware-Aufrufe. Die aufrufenden Proceduren übergeben im BC-Register das Sprungziel, also die Firmware-Adresse. Bei dem oben genannten Beispiel GRA-LINE-ABSOLUT = BBF6 sieht das so aus:

PROCEDURE GraLineAbsolute (x,y: Integer);
BEGIN
INLINE ($2A/x/ (* LD HL,(x) *)
$EB/ (* EX DE,HL *)
$2A/yl (* LD HL,(y) *)
$01/$F6/$BB/ (* LD BC.BBF6 *)
$C3/Call); (* JP Call *)
END; (* GraLineAbsolute *)

Mit der Procedure Call sind sie jetzt in der Lage, alle Firmware-Routinen zu nutzen.

Wer auf den Geschmack gekommen ist, unter CP/M noch einige trickreiche Routinen, die die Firmware stark beanspruchen, zu basteln, soll sich doch mal an einer Hardcopy-Routine versuchen, die aus einem CP/M-Programm ohne weiteres aufge-ruten werden kann (z.B. mit CTRL kleine ENTER-Taste). Man könnte diese Routine vielleicht in die Ticker-Chain (1/50 sec) einklinken .... usw. Viel Spaß beim Programmieren.

Anleitung zum Test des Drucker-Programmes.

  • Voraussetzung ist ein CPC464 mit 8-Bit Centronics-Schnittstelle
  • 62k-CP/M laden
  • Druckerspooler abschalten, falls überhaupt initialisiert mittel SPOOL.COM
  • Drucker einschalten, am besten auf Engschrift
  • Datei TEST.COM aufrufen
    • Diese Datei gibt den Zeichensatz von 20hex bis 7Fhex und von A0hex bis FEhex aus. Dabei erscheinen bei A0hex bis FEhex die gleichen Zeichen wie von 20hex bis 7Fhex.
  • Jetzt CENTRONI.COM aufrufen
  • Datei TEST.COM erneut aufrufen
    • Diese Datei gibt den Zeichensatz von 20hex bis 7Fhex und von A0hex bis FEhex aus. Dabei erscheinen bei A0hex bis FEhex jetzt die Grafikzeichen.

(L. Papenkort) , CPCAI

★ PUBLISHER: CPC Amstrad International
★ YEAR: 1987
★ CONFIG: CP/M
★ LANGUAGE:
★ LiCENCE: LISTING
★ COLLECTION: CPC AMSTRAD INTERNATIONAL-SONDERHEFT
★ AUTHOR: L. Papenkort
 

★ AMSTRAD CPC ★ DOWNLOAD ★

Aucun fichier de disponible:
» Vous avez des fichiers que nous ne possédons pas concernent cette page ?
★ AMSTRAD CPC ★ A voir aussi sur CPCrulez , les sujets suivants pourront vous intéresser...

Lien(s):
» Applications » Druckermenü (CPC Magazin)
» Applications » Drucken im Hintergrund
» Applications » Schildchen - Drucker (CPC Amstrad International)
» Applications » Drucker - Rsx (CPC Amstrad International)
» Applications » Adressenkartei Mit Etikettenausdruck (Schneider CPC-Welt)
» Applications » Drucken unter LOGO (CPC Amstrad International)
Je participe au site:
» Vous avez des infos personnel, des fichiers que nous ne possédons pas concernent ce programme ?
» Vous avez remarqué une erreur dans ce texte ?
» Aidez-nous à améliorer cette page : en nous contactant via le forum ou par email.

CPCrulez[Content Management System] v8.7-desktop
Page créée en 453 millisecondes et consultée 82 fois

L'Amstrad CPC est une machine 8 bits à base d'un Z80 à 4MHz. Le premier de la gamme fut le CPC 464 en 1984, équipé d'un lecteur de cassettes intégré il se plaçait en concurrent  du Commodore C64 beaucoup plus compliqué à utiliser et plus cher. Ce fut un réel succès et sorti cette même années le CPC 664 équipé d'un lecteur de disquettes trois pouces intégré. Sa vie fut de courte durée puisqu'en 1985 il fut remplacé par le CPC 6128 qui était plus compact, plus soigné et surtout qui avait 128Ko de RAM au lieu de 64Ko.