Zeichensatz von Word-Plus ändern

Mit dem Druckertreiber von Wordplus lassen sich zwar beliebige Zeichen definieren, sie werden auch gedruckt aber nicht auf dem Bildschirm angezeigt. Benutzt man z.b. die sonst kaum brauchbaren hebräischen Zeichen als Druckersteuerzeichen für die Umschaltung auf doppelt breite oder komprimierte Schrift (innerhalb einer Zeile), so erscheinen auf dem Bildschirm die dazu benutzten hebräischen Zeichen.

Snapshot aus Wordplus

Nun kann man sich sicher daran gewöhnen, für die Einstellung auf doppelt breite Schrift z.B. ein aleph einzugeben, aber die vielgerühmte Benutzerfreundlichkeit des ST ist dahin. Überhaupt sind die hebräischen Zeichen im Atari-Zeichensatz nicht mehr als ein dummer Gag, da diese Schrift von rechts nach links geschrieben wird. Ich kenne kein Textverarbeitungsprogramm, das diese Art zu schreiben unterstützt. Es bietet sich also an, diese Zeichen durch brauchbare Zeichen zu ersetzen.

Ein Beispiel :

Im Druckertreiber (PRINTER.HEX) wird eingefügt

C0.1B,57,01 * doppelt breite Schrift ein
C1,1 B,57,00    * doppelt breite Schrift aus
C2, 1B, 57, 00, 1B, 50, F* komprimierte

Schrift ein

C3,12,1B,6E *   komprimierte Schrift aus

Für die Zeichen CO bis C3 werden nun (nach der Benutzung von INSTALL.PRG) die entsprechenden Steuerzeichen zum Drucker geschickt. Auf dem Bildschirm erscheinen weiter die hebräischen Zeichen für CO ... C3. Sie sind im Atari ST fest eingebaut (im ROM) und (dort) nicht änderbar.

Die Lösung

Der Zeichensatz des ST wird vom ROM in den Arbeitsspeicher (RAM) kopiert und dort geändert. Nun muß dem Betriebssystem nur noch mitgeteilt werden, daß es die auf dem Bildschirm auszugebenden Zeichen nicht aus dem ROM sondern aus dem RAM holen soll.

Der Plan ist einfach, die Ausführung nicht. Die Kommunikation mit dem Betriebssystem erfolgt über die sog. Systemvariablen, die im Arbeitsspeicher ab Adresse $400 stehen. Von Atari festgelegt, dokumentiert und vielfach veröffentlicht sind nur die Variablen von $0400 - $0515. Die Adresse des Zeichensatzes ist leider nicht dabei. Der Benutzerspeicher beginnt aber erst bei $A100. Die Adresse des Zeichensatzes (genauer gesagt: der Fontdaten, das sind die Bitmuster der Bildschirmzeichen) wird in dem undokumentierten (und nicht von Atari in seiner Bedeutung festgelegten) Bereich zwischen $0515 und $A100 gespeichert.

WORDPLUS benutzt für die Bildschirmdarstellung des eingegebenen Textes die Textausgabe mit Attributen (fett, hell usw.), und zwar den 8x16 Font für die normale Darstellung und den 8x8-Font für die Darstellung im Grafik-Modus.

Die Daten des 8xl6-Zeichensatzes liegen im ROM ab $FD39B8, die 8x8-Fontdaten beginnen bei $FD2F5C. Für die Textausgabe mit Attributen wird ein Zeiger auf den Zeichensatz an den Adressen $607E (8x16) und $41A8 (8x8) gespeichert (ROM-Version vom 6.2.86).

Diese Adressen lassen sich mit einem Monitor-Programm und etwas Herumprobieren relativ schnell finden, doch das nächste Problem folgt auf dem Fuße. Mit der gleichen Leichtigkeit, wie ich die Zeiger ändere, kann das auch jedes andere Programm tun (z.B. Wordplus), und auch das Betriebssystem hat ein gewisses Eigenleben (von 196.608 Bytes Länge). Genau zu verfolgen, was denn da wo passiert, ist praktisch unmöglich.

Der neue 8 x 16- Zeichensatz

Hier führt nur Beharrlichkeit zum Ziel. Aber statt sich nun wochenlang durch Disassembler-Listings zu wühlen, liegt es doch viel näher, die Maschine für sich arbeiten zu lassen. Wenn die Befehle für das Ändern der Fontadressen in den VBL-Interrupt eingebunden werden, wird die nötige Beharrlichkeit auf die Maschine übertragen. Der Vertical-BLank-Interrupt wird vom Videocontroller 50, 60 oder 71 mal pro Sekunde (je nach Bildschirmauflösung) ausgelöst. Das laufende Programm wird dann unterbrochen, um z.B. einen Disketten- oder Monitorwechsel zu erkennen. Der Computer verfügt dadurch über ein - wenn auch sehr primitives Bewußtsein, das ihn seine (elektronische) Umgebung erkennen läßt.

Jedesmal, wenn sich der Computer der Außenwelt zuwendet, prüft er zunächst eine Liste der zu erledigenden Arbeiten. Diese Liste enthält normalerweise nur einen Eintrag, der vom Betriebssystem dort hineingeschrieben wird. Sie kann vom Benutzer erweitert werden.

Der erste freie Eintrag hat die Adresse $4D2. Dort kann die Adresse einer eigenen Interrupt-Routine untergebracht werden. Um die Adresse des Zeichengenerators zu indem, wird bei WORDPLUS nur ein sehr kurzes Programm gebraucht:

move.l #font8,$41A8 
move.l #font 16,$607E rts

Die Startadresse dieses Programms wird in -4D2 geschrieben, und von diesem Moment an werden die Adressen der geänderten Zeichensätze dem Computer bei jedem VBL-Interrupt mitgeteilt (bis zu ■1 mal pro Sekunde).

Bei diesem Verfahren muß das Hauptprogramm (WORDPLUS) nicht geändert werden. auch das Betriebssystem bleibt, wie es ist. Das Programm zur Änderung der Zeichensätze kann im AUTO-Ordner abgelegt werden und installiert dann beim Einschalten oder Reset des Rechners automatisch die neuen Zeichensätze. Es ist dadurch natürlich auch resetfest. Der Benutzerspeicher wird durch das Programm geringfügig verkleinert (um 8 KByte), und die Arbeitsgeschwindigkeit sinkt (kaum meßbar) um etwa 0,1 Prozent.

Das Programm

Mein Programm ist Kompromiß aus Einfachheit und Kürze und soll im Grunde nur zeigen, wie man sich einen eigenen Zeichensatz verschaffen kann. Es ersetzt lediglich die hebräischen Zeichen CO bis C3 durch selbstgeschnitzte Steuerzeichen für das Ein- und Ausschalten der doppelt breiten und der komprimierten Schrift (innerhalb einer Zeile). Der automatische Randausgleich ist natürlich hin, aber in Überschriften oder Briefköpfen sind die Steuerzeichen ganz nützlich (siehe Beispiel).

Zahlenfelder

In der zweiten Doppelstunde soll ein Programm entwickelt werden, das eine Folge Ion Zufallszahlen sortiert. 12 Zahlen von Wenn im Zeichensatz weitere Zeichen geändert werden sollen, dann müssen im Programm die beiden gleichlautenden Zeichen

move.l #3,dl * 4 Zeichen ändern

entsprechend angepaßt werden. Außerdem müssen die Bitmuster der neuen Zeichen im Datenteil des Programms eingetragen werden. Es kann dann nötig werden, die der Kesp Process-Funktion übergebene Zahl für den zu schützenden Speicherbereich zu vergrößern. In der vorliegenden Fassung belegt das Programm weniger als 7 KByte, hat also noch “Luft” für weitere Zeichen. Ein 8xl6-Zeichen braucht 16 Bytes und ein 8x8-Zeichen 8 Bytes. Um alle 29 hebräischen Zeichen in beiden Zeichensätzen durch eigene zu ersetzen, wird weniger als 1 KByte benötigt. Wenn man sich die Mühe macht, die kompletten (geänderten) Fontdaten an das Programm anzuhängen, kann man auf das Kopieren und Ändern der Daten verzichten. Das eigentliche Programm wird dann sehr kurz und zeigt seinen wahren Kern :

move.l #ein,-(sp) * Adresse der ein-Routine

move.w #38,-(sp)    *   Funktionsnummer (supexec)
trap #14    *   XBIOS   aufrufen (Interrupt erweitern)
addq.l #6,sp    * Stackpointer korrigieren
clr.w -(sp)
move.l #8192,-(sp)  * 8192 Bytes ab Basepage schützen
move.w #$31,-(sp)   *   Keep Process
trap #1 * Programm beenden
ein:
move.l #neufont,$4d2 * neufont in VBL einbinden
rts
neufont:
move.l #font16,$607e * für 8x16 Font 
move.l #font8,$41 a8 * für 8x8 Font rts
font16
dc.b......
font8
dc.b......

Die Reihenfolge der Bitmuster muß dann aber so sein, wie sie auch im ROM angeordnet sind, d.h. oberste Linie des ersten Zeichens, oberste Linie des zweiten Zeichens usw. Zwei komplette Zeichensätze (6144 Bytes) auf diese Weise als Datenzeilen einzugeben, wird sich aber wohl niemand antun. Einfacher ist es, ein kleines BASIC-Programm zu benutzen, das die geänderten Zeichensätze aus dem Speicher ausliest und in eine ASCII-Datei schreibt, die dann einfach an den Quelltext angehängt werden kann.

Dazu muß zunächst (mit dem folgenden Programm) ein neuer Zeichensatz erzeugt und getestet werden. Die Datenzeilen des Programms enthalten die Bitmuster von je einem neuen Zeichen in der Reihenfolge : oberste Linie, zweite Linie von oben, usw. Rainer Kracht

* Zeichengenerator ändern, R.Kracht, 30.11.87

pea kopiel6 *   Adresse des Kopierprogramms
move.w #38,-(sp)    *   im Supervisormodus
trap    #14 *   Zeichensatz (8x16) kopieren
addq.l  #6,sp   *   Stackpointer korrigieren

pea kopie8  *   Adresse des Kopierprogramms
move.w #38,-(sp)    *   im Supervisormodus
trap    #14 *   Zeichensatz (8x8) kopieren
addq.l  #6,sp   *   Stackpointer korrigieren

move.l #3,dl    *   4 Zeichen ändern
h1:
move.l #font16,a0   *   Adresse des neuen   (8x16)  Zeichensatzes
add.l #192,aO   *   Nummer des ersten   Zeichens
add.l dl,a0 *   plus Zeichenzähler
move.l #neul6,al    *   Adresse der neuen Zeichendaten
move.l dl,d2    *   Zeichenzähler holen
lsl.l #4,d2 *   mal 16
add.l d2,al *   plus Anfangsadresse der neuen Daten
move.l #15,dO   *   16 Bytes kopieren
h2:
move.b (al)+, (aO)  *   Daten in neuen Zeichensatz übertragen
add.l   #256,aO *   Adresse des nächstes Bytes
dbra d0,h2  *   nächstes Byte
dbra dl,hl  *   nächstes Zeichen ändern

move.l #3,dl    *   4 Zeichen ändern
h3:
move.l  #font8,a0   *   Adresse des neuen   (8x8) Zeichensatzes
add.l   #192,a0 *   Nummer des ersten   Zeichens
add.l   dl,a0   *   plus Zeichenzähler
move.l  #neu8,al    *   Adresse der neuen   Zeichendaten
move.l dl,d2    *   Zeichenzähler holen
lsl.l #3,d2 * mal 8
add.l d2,al * plus Anfangsadresse der neuen Daten
move.l #7,d0    * 8 Bytes kopieren
h4:
move.b (al)+,(aO)   * Daten in neuen Zeichensatz übertragen
add.l #256,aO   * Adresse des nächstes Bytes
dbra    d0,h4   *   nächstes Byte
dbra    dl,h3   *   nächstes Zeichen ändern

move.l  #ein,-(sp)  *   Adresse der ein-Routine
move.w  #38,-(sp)   *   im Supervisormodus
trap    #14 *   Interrupt erweitern
addq.l #6,sp    * Stackpointer korrigieren

clr.w -(sp)

move.l #8192,-(sp)  * 8192 Bytes ab Basepage schützen

move.w  #$31,-(sp)  *   Keep Process

trap    #1  *   Programm beenden

kopiel6:

move.l  #$fd39b8,a0 *   Anfangsadresse  der (8x16)  Fontdaten

move.l  #font16,al  *   Anfangsadresse  der neuen   Fontdaten

move.l #4095,dO * 4096 Bytes kopieren

kop:

move.b  (a0)+,(al)+ *   Daten übertragen

dbra    d0,kop  *   nächstes Byte

rts

kopie8:

move.l  #$fd2f5c,a0 *   Anfangsadresse  der (8x8)   Fontdaten

move.l  #font8,al   *   Anfangsadresse  der neuen   Fontdaten

move.l #2047,dO * 2048 Bytes kopieren

kop2:

move.b (a0)+,(al)+  * Daten übertragen

dbra d0,kop2    *   nächstes    Byte

rts

ein:

move.l tneufont,$4d2    *   heufont in VBL einbinden

rts

neufont:

move.l #font16, $607e   * für 8x16 Font

move.l #font8,$41a8 * für 8x8 Font

rts

neul6:

dc.b 0,120,108,102,102,102,108,120,0,126,126,126,126,126,126,C 
dc.b 0,120,108,102,102,102,108,120,0,126,66,66,66,66,126,0 
dc.b 0,102,108,120,112,120,108,102,0,126,126,126,126,126,126,C 
dc.b 0,102,108,120,112,120,108,102,0,126,66,66,66,66,126,0

Conti 6: ds.b 4096

neu8:

dc.b 224,144,144,144,159,239,15,15 dc.b 224,144,144,144,159,233,9,15 dc.b 144,160,192,192,175,159,15,15 dc.b 144,160,192,192,175,153,9,15

font8: ds.b 2048


Rainer Kracht



Links

Copyright-Bestimmungen: siehe Über diese Seite
Classic Computer Magazines
[ Join Now | Ring Hub | Random | << Prev | Next >> ]