VC 20
Anwendung

Deutscher Zeichensatz für den VC 20

Wenn man die ersten (Programmier-) Schritte mit seinem neu erworbenen VC 20 gegangen ist und schon das eine oder andere Programm »geboren« hat, vielleicht ein Adressenprogramm oder eine Lagerliste, spätestens dann wird man die Entdeckung machen, daß der VC 20 trotz deutscher Produktionsstätte nur Englisch spricht, für deutsche Umlaute und »ß« also kein Interesse zu haben scheint.

Dies bedauert man noch umso mehr, wenn man eine anschließbare elektronische Schreibmaschine mit deutschem Typensatz besitzt.

Zwar ist auf der Tastatur des VC 20 kein Platz für einen deutschen Zeichensatz vorgesehen, es ist jedoch möglich, bestimmte Tasten dafür auszuwählen, deren CHR$-Code demjenigen des gewünschten deutschen Umlautes auf der Schreibmaschine entspricht.

Auf diese Weise kann man zwar deutsche Texte drucken, aber auf dem Bildschirm sieht ein solcher Text recht merkwürdig aus: Hier steht zum Beispiel das Zeichen für das britische Pfund statt »ö«.

Auch hier ist mit einigem Know-how Abhilfe zu schaffen oder mit meinem Programm »DEUZEI«.

Der Zeichengenerator

Woher weiß der VC 20 eigentlich, wie die einzelnen Zeichen auszusehen haben, die man auf dem Bildschirm sieht? Hierzu bedient er sich eines Speicherbereichs Hex. 8000 bis 8FFF beziehungsweise 32768 und 36863 dezimal.

In diesem ROM-Bereich sind in genau festgelegter Reihenfolge (vergleiche Bildschirm-Code-Tabelle des Handbuches) die Bitmuster aller verfügbaren Zeichen in jeweils acht hintereinander stehenden Speicherstellen festgelegt.

Wie das funktioniert, veranschaulicht Bild 1: Jedes Zeichen ist auf dem Bildschirm in einer 8 x 8-Matrixwiedergegeben, ein Bildpunkt entspricht einer »1« im Dualcode, sonst steht die »0« (freie Felder). Da ja pro Speicherplatz 8 Bit gespeichert werden, benötigt man 8 Byte pro Zeichen.

Bild 1. Die 8 x 8-Matrix des Buchstabens »a«

Der Computer weiß durch sein Betriebssystem, welche acht Speicherstellen er bei einem Tastendruck abfragen muß, es erscheint soweit recht leicht möglich, ihm ein geändertes Bitmuster in diese Speicherstellen zu »schmuggeln«, zum Beispiel durch POKEs. Dies scheitert allerdings daran, daß der Zeichengenerator im ROM-Bereich liegt und somit nur Lesen, aber nicht Verändern der gespeicherten Daten zuläßt.

Hier hat dankenswerterweise Commodore ein Hintertürchen offengelassen, um doch noch am Datensatz manipulieren zu können. Man kann dem Betriebssystem mitteilen, daß der Zeichensatz an einer anderen Stelle sitzt als normal; dies ist in Speicherstelle 36869 codiert.

Benutzt man nun einen RAM-Bereich für den alternativen Zeichensatz, so kann man nach Lust und Laune Veränderungen der Bitmuster vornehmen.

Da man ja doch wohl gern die Bitmuster der meisten Zeichen übernehmen möchte, wäre es ganz sinnvoll, vor der Kreation einiger neuer Zeichen erst einmal die Bitmuster des Zeichengenerator-Bereichs in den ausgewählten RAM-Bereich zu kopieren (immerhin 4 KByte). Diese Aufgabe übernimmt ein kleines Maschinenprogramm (Listing 2), das im Programm »DEUZEI« integriert ist. Ein Kopieren durch Basic-POKEs ist hingegen recht zeitraubend.

Um Speicherplatz im RAM zu sparen, kopiert »DEUZEI« allerdings nur den Zeichenset 2, der Groß- und Kleinbuchstaben, Ziffern und einige Grafikzeichen enthält (normal und invers), aber nur 2 KByte RAM beansprucht.

»DEUZEI« benutzt den RAM-Speicher wie folgt: Zeichengenerator: Page 16 bis 23; Bildschirmspeicher: Page 24 und 25; Basicprogramme ab Page 26 (Bild 2). Eine Page entspricht einem 256-Byte-Block. Der Bildschirmspeicher befindet sich beim VC 20 ab 8 KByte Erweiterung normalerweise in Page 16 und 17 (4096 bis 4607), muß bei »DEUZEI« allerdings »umziehen«; dies erfährt das Betriebssystem durch entsprechende Codierung der Speicherstellen 648 (siehe Zeile 130) und 36869 (zugleich Pointer für den Zeichengenerator).

Das eigentliche Programm »DEUZEI« beginnt bei der Speicherstelle 6656 (Page 26). Da man es nach dem Generieren des neuen Zeichensatzes ja nicht mehr benötigt, wird es beim Einladen eines neuen Programms ab Page 26 gelöscht. Es fehlen dem neuen Programm also nur genau 2 KByte RAM-Speicherplatz, den der neue Zeichensatz beansprucht.

»DEUZEI« intern

Zeile 110-120: Ab Speicherstelle 700 wird das Maschinenprogramm (35 Byte) abgelegt (unbenutzter RAM- Bereich).
Zeile 130: Pointer für neuen Zeichengenerator-Bereich und Bildschirm-Bereich.
Zeile 140: Zeichen-Set 2 wird durch Starten des Maschinenprogramms ab Page 16 abgelegt.
Zeile 210-270: Bitmuster für deutsche Umlaute wird in neuen Zeichensatz gePOKEd.
Zeile 300-360: Bitmuster für Umlaute (invers)
Zeile 410: Umschaltsperre zum anderen Zeichen-Set (nur ein Zeichen-Set existiert im neuen Zeichengenerator-Bereich).
Zeile 420-450: Bildschirm-Display (neue Zeichen erscheinen)
Zeile 510-530: Data für Maschinenprogramm
Zeile 540-600: Data für Umlaute Ä,Ö,Ü,ä,ö,ü,ß
Zeile 700-760: Data für inverse Umlaute Ä,Ö,Ü,ä,ö,ü,ß

CHR$-Codes:

17 = Cursor nach unten
18 = Inverse Zeichen an
28 = rot
31 = blau
147 = clr home
156 = purpur
Bild 2. VC 20-Speicher ab 8 KByte Erweiterung

Eingabe von »DEUZEI«

Wenn man nun das Programm »DEUZEI« in den Computer eingibt und übereifrig mit RUN startet, wird man eine böse Überraschung erleben: Das Programm stürzt sofort ab und ist zudem auch noch gelöscht!

Des Rätsels Lösung: Normalerweise werden Basicprogramme ja ab Page 18 (Speicherstelle 4608 = 18*256) abgelegt. In diesen Bereich transformiert allerdings das Maschinenprogramm den neuen Zeichensatz und »zerstört« frühzeitig das Basicprogramm. Man muß folglich Sorge tragen, daß das Programm ab Page 26 im Speicher steht. Hierzu sollte man folgendermaßen vorgehen:

  1. »DEUZEI« eingeben und auf Band oder Floppy abspeichern (kein RUN!)
  2. Programm mit NEW löschen und folgende Basiczeile eingeben:
    1 POKE 44,26:POKE 6656,0:PRINT CHR$(3):RUN
  3. RETURN-Taste drücken, aber nicht RUN!
  4. POKE 44,26:POKE 6656,0 eintippen, dann RETURN-Taste drücken
  5. Eingabe von NEW; RETURN-Taste
  6. Einladen des abgespeicherten »DEUZEI«
  7. POKE 44,18 eintippen und unter neuem Namen abspeichern.

Die kleine Mühe hat sich sicherlich gelohnt, denn das neu abgespeicherte Programm ist nun absolut »wartungsfrei«. Es kann ganz normal eingeladen werden, setzt automatisch die Basicuntergrenze auf Page 26, generiert den neuen Zeichensatz in 2 bis 3 Sekunden und erlaubt das Einladen beliebiger Basicprogramme ohne Zusatz-POKEs.

Erklärung für obige Prozedur: Die erste Basiczeile muß am Anfang von Page 18 liegen, der Interpreter erwartet das so. Startet man das »umgebaute« Programm, so wird in dieser Zeile der neue Basicbeginn mitgeteilt, und zwar mit POKE 44,26.

Dieses Miniprogramm wird mit PRINT CHR$(3) abgebrochen und mit RUN in der gleichen Zeile das eigentliche »DEUZEI« ab Page 26 gestartet. Dies sitzt bereits richtig, da man es (siehe unter 4) gleich in Page 26 geladen hat. Danach wurde der Basicanfang wieder durch POKE 44,18 herabgesetzt und somit das funktionsfähige Programm abgespeichert.

Dieses Vorgehen bedeutet zwar, daß beim Abspeichern fast 2 KByte unbrauchbares Material mit abgespeichert wird, aber der Vorteil der besonderen Bedienungsfreundlichkeit überwiegt doch eindeutig.

Arbeiten mit »DEUZEI«

Nach dem Einladen des — wie oben beschrieben bearbeiteten — Programms »DEUZEI« erscheinen die neuen Sonderzeichen auf dem Bildschirm normal/invers, und beliebige Programme können geladen werden.

Die neuen Zeichen und ihr CHR$- beziehungsweise POKE-Code:


ä ö ü Ä Ö Ü ß
CHR$: 91 92 93 123 124 125 94
POKE: 27 28 29 91 92 93 30
statt: [
£ ]
SHIFT [ SHIFT £ SHIFT ]

Dieser Zeichensatz bleibt erhalten, solange der VC 20 eingeschaltet ist, wird allerdings durch Betätigen der RUN STOP/RESTORE-Tasten abgeschaltet; es wird wieder der Pointer auf den normalen Zeichensatz gesetzt. Durch Eingabe von: POKE 36869,236:POKE 648,24:CLR kann man aber wieder den neuen Zeichensatz verfügbar machen. Leider sind sich offensichtlich nicht alle Produzenten von Drucker-Interfaces bezüglich der CHR$-Codes für die deutschen Umlaute einig. So kann es vorkommen, daß bei bestimmten Druckern das »ß« nicht gedruckt wird, wenn es auch noch so deutlich am Bildschirm prangt. Das ist allerdings kein Beinbruch, man muß nur herausfinden, welchen CHR$-Code dieses Zeichen vom Hersteller erhalten hat. Eine Anpassung von »DEUZEI« ist dann mit Hilfe der Tabellen des VC 20-Handbuchs einfach:

  1. In CHR$-Tabelle Zeichen suchen, das der Code-Nummer entspricht.
  2. In POKE-Tabelle den POKE-Wert für dieses Zeichen ablesen.
  3. POKE-Wert*8+4096 ergibt erste Speicherstelle für neues Zeichen; diesen Wert im Listing ersetzen.

Beispiel: Buchstabe »ß« ist als CHR$(94) vorgesehen.

Normales Zeichen (Pfeil nach oben) entspricht POKE 30. 30*8+4096 = 4336. In Zeile 270 des Listings ist dieser Wert zu finden. Ist nun der CHR$-Code beispielsweise für »ß« = 126 (entspricht dem Zeichen 7r), so ergibt sich aus der POKE-Tabelle: 94*8+4096 = 4848 als neuer Wert im Listing.

Um die entsprechenden Speicherplatzdaten für die inversen Zeichen zu finden, muß man nur zu den berechneten Werten noch 1024 addieren (vergleiche DATA-Zeilen 700 bis 760 in Listing 1).

»DEUZEI«-Ausbau

Wem die deutschen Sonderzeichen nicht ausreichen für seine verschiedenen Vorhaben, der kann natürlich recht einfach in das Programm noch zusätzliche »Phantasiezeichen« einbauen. Das Auffinden der gewünschten Speicherstelle und die Berechnung der 8 Byte-Werte für das Bitmuster der 8x8-Zeichenmatrix sollten ja keine Schwierigkeiten mehr bereiten.

Als Beispiel sei der Ersatz des »Klammeraffen« (CHR$:64; POKE:0) durch eine »Brezel« aufgezeigt, die ab Speicherstelle 0*8+4096 = 4096 codiert wird (Bild 3). Diese beiden Programmzeilen wären hier einzufügen:
361 forbr=0to7:readda%:poke4096+br,da%:next
770 data0,60,66,165,153,153,102,0

In analoger Weise kann man sich auch leicht beliebige andere Zeichen definieren.

Bild 3. Die 8 x 8-Matrix des Grafiksymbols »Brezel«
(Peter Wülknitz/ev)
10 rem ********************************
20 rem *                              *
30 rem *   deutscher  zeichensatz     *
40 rem *   fuer vc-20 band/floppy     *
50 rem *                              *
60 rem *p. w]lknitz karl-christ-str. 18
70 rem *   6900 heidelberg  -1984-    *
80 rem *                              *
90 rem ********************************
100 rem * zeichensatz - transfer *
110 formp=1to35
120 readda%:poke699+mp,da%:next
130 poke36869,236:poke648,24:clr
140 sys700
150 fort=1to35:readda%:next
190 :
200 rem * neue zeichen *
210 forag=0to7:readda%:poke4824+ag,da%:next
220 forog=0to7:readda%:poke4832+og,da%:next
230 forug=0to7:readda%:poke4840+ug,da%:next
240 forak=0to7:readda%:poke4312+ak,da%:next
250 forok=0to7:readda%:poke4320+ok,da%:next
260 foruk=0to7:readda%:poke4328+uk,da%:next
270 forss=0to7:readda%:poke4336+ss,da%:next
300 foragi=0to7:readda%:poke5848+agi,da%:next
310 forogi=0to7:readda%:poke5856+ogi,da%:next
320 forugi=0to7:readda%:poke5864+ugi,da%:next
330 foraki=0to7:readda%:poke5336+aki,da%:next
340 foroki=0to7:readda%:poke5344+oki,da%:next
350 foruki=0to7:readda%:poke5352+uki,da%:next
360 forssi=0to7:readda%:poke5360+ssi,da%:next
390 :
400 rem * finale *
410 poke657,128
420 x=1:print"{clr}{down}{down}{down}{sret}{rvon}{rght}{rght}{rght}Sonderzeichen:":print:print
430 print"{blk} [  \  ]  {SHIFT-+}  {CBM--}  {SHIFT--}   ^":print
440 print"{red} {rvon}[  \  ]  {SHIFT-+}  {CBM--}  {SHIFT--}   ^":print
450 print"{down}{down}{down}{blu}{rvon}Es darf geladen werden"
490 :
500 rem * datenbank *
510 data169,0,133,251,169,136,133,252,169,0,133,253,169,16,133,254
520 data162,8,160,0
530 data177,251,145,253,136,208,249,230,252,230,254,202,208,242,96
540 data90,36,66,126,66,66,66,0
550 data90,36,66,66,66,36,24,0
560 data90,66,66,66,66,66,60,0
570 data36,0,56,4,60,68,58,0
580 data36,0,60,66,66,66,60,0
590 data36,0,66,66,66,70,58,0
600 data60,66,66,124,66,66,124,64
700 data165,219,189,129,189,189,189,255
710 data165,219,189,189,189,219,231,255
720 data165,189,189,189,189,189,195,255
730 data219,255,199,251,195,187,197,255
740 data219,255,195,189,189,189,195,255
750 data219,255,189,189,189,185,197,255
770 data195,189,189,131,189,189,131,191
Listing 1. Basiclader für »DEUZEI«. Die Zeichen »\« und »^« in den Zeilen 430 und 440 bedeuten »£« und »↑«.
02BC  A9 00      LDA #$00    Low-byte Zeichenbereich laden
02BE  85 FB      STA $FB     speichern in dez. 251
02C0  A9 88      LDA #$88    High-byte Zeichenbereich laden
02C2  85 FC      STA $FC     speichern in dez. 252
02C4  A9 00      LDA #$00    Low-byte neuer Z.-Bereich laden
02C6  85 FD      STA $FD     speichern in dez. 253
02C8  A9 10      LDA #$10    High-byte neuer Z.-Bereich laden
02CA  85 FE      STA $FE     speichern in dez. 254
02CC  A2 08      LDX #$08    X-Register: Zahl der Blöcke
02CE  A0 00      LDY #$00    Y-Register Null setzen (Zähler)
02D0  B1 FB NEXT LDA($FB),Y  Laden von Koppeladr. (i.indiz.)
02D2  91 FD      STA($FD),Y  Speichern in Koppeladresse
02D4  88         DEY         Zähler -1
02D5  D0 F9      BNE NEXT    Y nicht 0, dann Sprung zu NEXT
02D7  E6 FC      INC $FC     High-byte Z.-Bereich +1
02D9  E6 FE      INC $FE     High-byte neuer Z.-Bereich +1
02DB  CA         DEX         Block-Zähler -1
02DC  D0 F2      BNE NEXT    X nicht 0, dann Sprung zu NEXT
02DE  60         RTS         zurück zu Basic
Listing 2. Assembler-Listing zu »DEUZEI«. Das Assemblerprogramm ist im Basiclader nach Listing 1 bereits enthalten und braucht nicht zusätzlich eingegeben zu werden.
PDF Diesen Artikel als PDF herunterladen
Mastodon Diesen Artikel auf Mastodon teilen
← Vorheriger ArtikelNächster Artikel →