Zurück zur Firmware
Die Neugierde ließ mich damals an AMSTRAD schreiben mit der Bitte um Aufklärung über die Organisation des Bildschirmspeichers. Ich erhielt umgehend einige neue technische Reports über JOYCE Interna, die erst später in Sonderheften der "PC Schneider International" publiziert wurden. In der im Dezember 1986 erschienenen Sonderausgabe der "JOYCE-Revue" wurde der folgende Artikel veröffentlicht.
Die Joyce-Revue wurde leider sehr bald eingestellt.
Ich habe im Laufe der Zeit Infos über die Hardware zusammengestellt.
Später fand sich unter http://www.systemed.net/pcw/hardware.html eine Zusammenstellung der Hardware, die ich übersetzt habe.
Eine sehr gute Zusammenstellung über den Aufbau des Joyce findet sich hier.
John Elliot, der sehr engagiert ist, veröffentlichte im Jahr 2002 das Dokument: PCW Hardware.


Übersicht JOYCE Firmware
Stand: November 1986

INHALT

1. CP/M BDOS und BIOS

2. CP/M-GSX

3. JOYCE Speicher

4. Zeichentabelle

4.1 Zugriff auf Zeichentabelle und Video RAM

4.2 RSX Einbindung

4.3 Änderung der Zeichentabellen

5. Das Video RAM - Grafik auf dem JOYCE

5.1 Das Roller RAM

5.2 Grundsätzliches zur Grafik


Zu beachten ist, daß alle Beschreibungen und die meisten Programme als Basis zum Arbeiten auf Assemblerebene erstellt sind.
Da die Beschreibungen und die im Anhang angegebenen Programme recht lang sind, wäre es vielleicht ganz gut, wenn alle Interessenten mir eine Leerfloppy inklusive frankiertem Briefumschlag schicken würden. Ich kopiere dann den Inhalt des vorliegenden Textes sowie fertig assemblierte Programme, soweit im Anhang angegeben.

1.CP/M BDOS und BIOS

Allgemein zugänglich sind Informationen über CP/M in einschlägigen Publikationen. Hierin findet man alles über die Funktionen des Basic Disc Operating Systems (BDOS) und des Basic Input Output Systems (BIOS).

Im allgemeinen wird ein Assemblerprogrammierer die BDOS Schnittstelle verwenden, in seltenen speziellen Fällen die BIOS Schnittstelle. Um Programme, die an einem beliebigen CP/M Rechner geschrieben wurden, auch an anderen Rechnern laufen zu lassen (Stichwort Portabilität), sollten folgende Punkte nicht gemacht werden: 1) Umgehung der Standardschnittstellen BDOS und BIOS durch gezielte Zugriffe auf die Hardware des jeweiligen Rechners. Hiermit können ganz sicher Programme mit einem großen I/O Aufwand optimiert werden, aber sie sind nicht portabel. (Ein gutes Beispiel für diese schlechte Anwendung ist ein Programm in MC 11/86: Schnellkopieren. Hier wird nämlich direkt auf die Hardware des MC-CP/M-Computers zugegriffen) 2) Benutzung von nicht standardisierten Bildschirm- und Druckersteuerzeichen. Das was den Bildschirm des JOYCE löscht, läßt den Bildschirm eines anderen Rechners vielleicht heftig flackern.

Natürlich gibt es Abweichungen von dieser Regel, gerade eine Anzahl Dienstprogramme (Utilities) des JOYCE tun dies (z.B. SETKEYS, LANGUAGE, SETSIO etc.).

Die Entwickler von CP/M Plus, Digital Research (DR), haben in der BIOS Tabelle eine Funktion für den sog. System Implementator, beim JOYCE also AMSTRAD, vollkommen frei wählbar gelassen (In den DR Handbüchern taucht dafür das Label USERF - USER Function - auf), man erhält hier die Möglichkeit, auf zusätzlich Firmware zuzugreifen. Durch diese "Hintertür" lassen sich viele Funktion aufrufen, die durch das BDOS und BIOS nicht verfügbar sind. Hit Hilfe einer dieser Firmwarefunktionen kann man z.B.: - eigene Zeichensätze wählen, also auch beliebige neue Zeichen generieren. Die AMSTRAD Utility LANGUAGE macht Gebrauch davon - den Bildschirm direkt ansprechen, also Grafik durchführen.

2.CP/M GSX1

Zum letzten Punkt eine Bemerkung. Es sind zwei vergleichbare Programme auf dem Markt, die Grafik auf dem JOYCE zulassen: MICA und DR DRAW. Spielt man mit beiden Programmen, so stellt man schnell fest, daß MICA wesentlich schneller in der Grafik ist als DR DRAW. Wie kommt das? Bekanntlich wird unter CP/M Plus eine Hilfe geliefert, die sich GSX (Graphic System Extension) nennt. Aktiviert wird sie mit dem Kommando GENGRAF. Das GSX ist nun nichts weiter als eine BDOS Erweiterung über RSX (Resident System Extension). RSX bietet die Möglichkeit, neue BDOS Funktionen zu installieren (wie bei GSX) oder bestehende zu manipulieren (wie z.B, bei PUT). So wie es auf "normaler" CP/M Betriebssystemebene das BIOS und BDOS mit klaren Softwareschnittstellen gibt, hat man hier das GDOS (Grafik Disk Operating System) und GIOS (Grafik Input Output System) zu Verfügung. Das GDOS ist also auch eine klar definierte Schnittstelle. Alle Parameter, die dem GDOS übergeben werden, müßen allerdings mühsam berechnet werden, natürlich unsichtbar für den Programmierer. Dies macht GSX so langsam und damit auch DR DRAW, das über eben diese Schnittstelle arbeitet. MICA hingegen greift direkt auf die Firmware zu ohne die verlangsamende GSX Aufbereitung. Dadurch erhält man eine erstaunliche Geschwindigkeit. (Aber bitte immer Punkt 1 von oben beachten: MICA ist nicht portabel, DR DRAW läuft auch auf anderen CP/M PLUS Maschinen).

3.JOYCE Speicher

Was ist eigentlich mit dem Speicher des JOYCE? Kalkuliert man einmal etwas genauer, so stellen sich folgende Fragen:
1)Der JOYCE Mikroprozessor Z80 kann 64kByte adressieren. Nach den Booten von CP/M stehen 61kByte TPA (Transient Program Area) zur Verfügung.
F:Passen BDOS und BIOS in die verbleibenden 3kByte?
A:Nein
 
2)Der JOYCE wird geliefert mit 256(512)kByte. Zieht man die möglichen 64kByte der Z80 Adressierung ab, so verbleiben 192(448)kByte. Die RAM Disk hat eine Kapazität von 112(368)kByte, Differenz: 80kByte.
F:Wo sind die vermißten 80kByte?
A:Versteckt in anderen Memory Bänken
Die etwas kurzen Antworten bedürfen natürlich einer Erklärung. Das CP/M Plus unterscheidet sich neben BDOS und BIOS Erweiterungen besonders dadurch, daß dieses CP/M mehr Speicher verwalten kann als es der Z80 Mikroprozessor zuläßt. Dies geschieht über sog. Speicherbänke, die je nach Bedarf zu- bzw. abgeschaltet werden können. Jede Speicherbank besteht wieder aus Speicherblöcken, wobei allen Bänken ein Block (Common memory COMMON) gemeinsam ist. Beim JOYCE ist jeder Block 16kByte lang, der gemeinsame Block ist im obersten Speicherbereich zu finden, nämlich von C000 bis FFFF. Dies ist ja auch der Bereich, in dem die BDOS und BIOS Einsprünge liegen. Im Common werden natürlich auch die RSX Module eingebunden, da dies ja BDOS Erweiterungen sind.

Im JOYCE lassen sich drei Bänke einschalten:
Bank 0: BDOS, BIOS, Video RAM - also das Betriebssystem
Bank 1: TPA - also der Benutzerbereich
Bank 2: CCP - der Command Console Processor
Neben diesen Bänken gibt es eine weitere Bank, die allerdings nicht über BDOS Aufrufe angewählt werden kann:

Bank 3: Video RAM, Zeichentabellen

Bisher sah die Speicherkalkulation so aus: 64kByte adressierbar vom Z80, 112(368)kByte RAM Disk und 80kByte unauffindbar.
Mit der Kenntnis um die Bänke ergibt sich nun:

            Bank 0      Bank 3       Bank 1       Bank 2
        -----------------------------------------------------
FFFF    I                                                   I
        I                 Common memory                     I
COOO    I                                                   I
        -----------------------------------------------------
BFFF    I    BIOS     I   Matrix,   I          I	
        I    BDOS     I   Roller    I          I	
8000    I             I   RAM       I          I	
        -----------------------------..........--------------
7FFF    I                           I          I            I
        I       Video RAM           I    TPA   I    CCP     I
4000    I                           I          I            I
        -----------------------------..........--------------
3FFF    I                           I          I	
        I BIOS extended jump block  I          I	
0000    I                           I          I
        ----------------------------------------	

Das macht 9 Blöcke*16kByte=144 kByte!!

Gerade die Bank 3, die nicht über BDOS aufgerufen werden kann, ist die für Grafik Freaks entscheidende Bank, da hier auf das Video RAM zugegriffen werden kann.

4.Zeichentabelle

Neben dem Zugriff auf das Video RAM kann in Bank 3 auch auf die JOYCE Zeichentabelle zugegriffen werden. Diese Tabelle wird z.B. geändert über die Utility LANGUAGE. Hier werden die sog. nationalen Zeichensätze angepaßt (Beispiel: das deutsche Zeichen Ä erscheint im amerikanischen Zeichensatz als [).

Verwiesen sei in diesem Zusammenhang auf das für den JOYCE verfügbare 3-D Chess Programm, welches die Möglichkeit bietet, den kompletten Zeichensatz kursiv am Bildschirm darzustellen!

Wie liegt nun ein Zeichen vor in der Zeichentabelle?
Betrachtet man sich einmal den Bildschirm des JOYCE genauer, so stellt man fest, daß ein Zeichen aus mehreren Punkten, die in mehreren Zeilen untereinander liegen, besteht. In der Tat ist dies beim JOYCE eine Matrix aus 8 Punkten mal 8 Zeilen. Bekanntlich besteht ein Byte aus 8 Bit, so daß eine solche Matrix für je ein Zeichen tatsächlich aus 8 Bytes besteht. Am Beispiel des Zeichens 'A' soll dies verdeutlicht werden:

ZeileBits der MatrixHexadezimalwert
10001100018
2001111003C
30110011066
40110011066
5011111107E
60110011066
70110011066
80000000000
Die letzte Seile wird nur für Zeichen mit Unterlängen (g, j usw.) benutzt.
Das Video RAM speichert nun für jedes Zeichen eine solche Matrix. Beim JOYCE hat man ja 90 Zeichen pro Zeile bei 32 Zeilen, also 2880 Zeichen pro Bild. Oder 2880 Matrizen á 8 Bytes, also 23040 Bytes = 22,5 kBytes. Wie im Handbuch beschrieben, ergibt sich daraus eine Auflösung von 90x8 zu 32x8 Punkten, also 720x256.
Definieren kann man nun die Zeichentabelle als feste Anordnung von 256 Matrizen (dies ist die Anzahl Zeichen, die der JOYCE kann) und das Video RAM als variable Anordnung von Matrizen, gebildet aus den festen Matrizen der Zeichentabelle.

4.1 Zugriff auf Zeichentabelle und Video RAM

Hier tauchen nun zwei Fragen auf:
1)Wie kommt man an die Zeichentabelle, so daß beliebige eigene Zeichen gebildet werden können?
2)Wie kommt man an das Video RAM, so daß man sich eigene Grafik, bestehend aus Bildern aufgeteilt in Matrizenportionen, generieren kann?
Dies funktioniert mit der oben erwähnten Hintertür - USERF. Hier wird nun eine Funktion ausgewählt, die Funktion SCR RUN ROUTINE (SCR ist offensichtlich die Abkürzung von SCReen, also Bildschirm). Parameter können für diese Routine in allen Registern mitgegeben werden, wobei das Registerpaar BC die Adresse einer Routine beinhalten muß, die während der Aktivität der SCR RUN ROUTINE ausgeführt wird. Dies ist in der Regel eine Laderoutine, die Daten aus dem Speicher in das Video RAM/Zeichentabelle lädt oder umgekehrt.

Wichtig: Diese Routine im Registerpaar BC muß im Common memory liegen - klar, schließlich erfolgt ja eine Bankumschaltung, so daß eine Routine, die nicht im Common läge, ausgeblendet würde!

Wie kann man denn nun diese Routine aufrufen?
Der Aufruf geschieht im Assembler wie folgt:
(1)    CALL    USERF
(2)    DW      00E9H
(1)Die Adresse für USERF ergibt sich aus einem normalen BIOS Aufruf mit der Funktion 30. Dies kann als Unterprogramm z.B. wie folgt geschehen:
USER:   LHLD   1          ; Laden der Basisadresse aus Speicher 0001H
        PUSH   B
        LXI    B,(30-1)*3 ; Offset für Funktionsnummer 30
        DAD    B          ; Reale Sprungadresse berechnen
        POP    B
        PCHL              ; Und ab geht's
(2)Der Wert '00E9H' ist in Wirklichkeit nichts anderes als eine Sprungadresse im sog. 'BIOS extended jumpblock', der in Bank 3 zu finden ist (Siehe Bild oben). Das ist der 'normalen' BIOS Sprungadresse genau nachempfunden.

4.2 RSX2 Einbindung

Bevor es nun losgeht, noch ein Hinweis zur Einbindung einer RSX, die in den folgenden Programmen benötigt wird.
Zunächst die Frage, was passiert eigentlich, wenn ich nach dem System Prompt (A>) XYZ eintippe, vorausgesetzt es existiert ein File XYZ.COM? Wenn der CCP das File tatsächlich gefunden hat, wird ein Loader (Ladeprogramm) aktiviert, welcher das .COM File in die TPA lädt beginnend mit Adresse 0100H. Danach erfolgt dann der Programmstart bei 0100H. Der Loader schaut sich aber erstmal das .COM File an und erkennt, ob es sich dabei um ein RSX Modul alleine oder ein kombiniertes RSX+COM File handelt. Im Falle einer RSX wird diese zuerst geladen, aber nicht ab 0100H sondern in den höchsten verfügbaren Speicher. Dieser liegt genau vor dem BDOS Einsprung. Natürlich wird der BDOS Einsprung zurechtgebogen, so daß jeder BDOS Aufruf zunächst im neuen RSX landet. Es gibt zwei Typen von RSX, den temporären und den residenten. Die erste Type wird zumeist zusammen mit einem .COM File verwendet und bei Beendigung des .COM Files aus dem Speicher entfernt. Die zweite Type wird meist alleine benutzt und fest im Speicher installiert, bis sie von irgendeinem Hilfsprograrnm wieder entfernt wird. Die CP/M Utility PUT ist ein solches Beispiel: Das Kommando PUT CONSOLE OUTPUT TO FILE ABC [SYS] lädt eine RSX, die jeden BDOS Aufruf, der Daten zur Konsole ausgibt, auch benutzt, um Daten in die Datei ABC zu schreiben. Die RSX bleibt solange im Speicher, bis das Kommando PUT CONSOLE OUTPUT TO CONSOLE eingegeben wird. Die Datei ABC wird proper geschlossen und die RSX aus dem Speicher genommen, so daß nun alle Ausgabe wieder allein auf die Konsole gehen.

Das Erstellen einer RSX zusammen mit einem .COM File soll folgende Eingabe verdeutlichen. Annahme: Das Benutzerprogramm ABC.ASM soll mit der RSX DEF.ASM (beides also noch Quellen) verbunden werden:
EingabeAktionDatenfluß
RMAC ABC.. AssemblierenABC.ASM -> ABC.REL
LINK ABC.. Linken (Binden)ABC.REL -> ABC.COM
 
RMAC DEF.. AssemblierenDEF.ASM -> DEF.REL
LINK DEF [OP].. LinkenDEF.REL -> DEF.PRL
 
RENAME DEF.RSX=DEF.PRL.. UmbenennenDEF.PRL -> DEF.RSX
 
GENCOM ABC DEF.. EinbindenDEF -> (DEF,ABC).COM

4.3 Änderung, der Zeichentabellen

Beigefügt ist ein Programmpaket zur Manipulation von Zeichentabellen, das aus zwei Assemblerquellen und einem BASIC Programm besteht:
-CHARSET.ASM. Dies ist eine RSX, die eine entsprechende Zeichenmatrix einliest, entweder aus der JOYCE Tabelle oder einer Benutzertabelle.
-SETMAT.ASM. Dies ist ein Assemblerprogramm, das zusammen mit der RSX CHARSET die komplette Zeichentabelle des JOYCE in ein File einliest und, falls gewünscht, eine neue Tabelle aus einem anderen File einliest.
-MATEDIT.BAS. Dies ist ein BASIC Programm, das eine Bearbeitung einer vorher eingelesenen Zeichentabelle erlaubt.
Die beiden Assemblerprogramme CHARSET und SETMAT werden, wie oben beschrieben, als Kombination RSX und .COM File gebunden. Die erzeugte Tabelle liegt abschließend nicht im binären Origalformat vor, sondern ist ASCII codiert, so daß BASIC damit arbeiten kann.

Nun zur Beschreibung:

CHARSET.ASM

Das wichtigste an diesem Programm ist der korrekte RSX Header! Dieser muß wirklich exakt stimmen, da er die wichtigen Informationen für den Loader enthält. Für diese RSX habe ich die neuen BDOS Funktionen 38 und 39 gewählt: Funktion 38 lädt eine Matrix aus der JOYCE Zeichentabelle und Funktion 39 speichert eine Matrix in die JOYCE Zeichentabelle. Beide Funktionen benötigen folgende Parameter:

Register HL enthält die Adresse, die auf einen Parameterblock zeigt. Dieser Block besteht aus 9 Bytes. Das erste Byte ist der Hexwert des Zeichens, auf dessen Matrix zugegriffen werden soll. Die folgenden 8 Bytes stellen die eigentliche Matrix dar. Bei Funktion 38 werden diese Bytes gefüllt von der bestehenden Matrix, während bei Funktion 39 die Bytes als neue Matrix definiert werden.

Die eigentliche Funktion der RSX ist wie folgt:
Zunächst wird getestet, ob ein Aufruf der BDOS Funktionen 38 oder 39 erfolgt. Falls nicht, erfolgt ein Sprung auf eine Adresse, die vom Loader eingetragen wird und üblicherweise der alte BDOS Einsprung ist. Wird eine der beiden Funktionen aufgerufen, so wird simpel ein Ladevorgang durchgeführt.

SETMAT.ASM

Dies Programm wird aufgerufen mit
      SETMAT file1
oder  SETMAT file1 file2
Die bestehende Zeichentabelle wird in das "file1" geschrieben, während eine Neudefinition aus dem (optionalen) "file2" geladen wird, d.h. wird nur "file1" angegeben, so wird auch nur die bestehende Tabelle gelesen. Wird bei den Filenamen keine Extension angegeben, so erhält "file1" automatisch die Extension ".ALT" und "file2" die extension ".NEU".
Der Aufruf

SETMAT MATRIX NEU.X

erzeugt also ein File "MATRIX.ALT" und liest die Neudefinition aus dem File "NEU.X".
Bei Dateifehlern bricht das Programm sofort ab, ebenfalls wenn beim Einlesen der Neudefinition ein fehlerhaftes Zeichen gefunden wird.
Bevor die eigentliche Neudefinition durchgeführt wird, werden die Daten aus "file2" komplett zwischengespeichert. Hiermit wird verhindert, daß bei einem Lesefehler nur ein Torso neu definiert wird.
Das Programm endet mit einer Meldung, aus der zu erkennen ist, ob ein fehlerhaftes oder normales Ende vorliegt.

MATEDIT.BAS

Das BASIC Programm erlaubt eine Bearbeitung der von SETMAT erzeugten Daten. Die eingelesenen Matrixelemente werden in einem 8x8 Raster bitweise dargestellt, wobei ein nicht gesetztes Bit einer Leerstelle (dunkel) entspricht und ein gesetztes Bit als invertierte Leerstelle (hell) dargestellt wird. Außerdem wird der Hexwert, dessen Matrix gerade bearbeitet wird, ebenfalls angezeigt.
Auch existiert ein Editiercursor, der nach dem Aufbau einer Matrix in der linken oberen Ecke auftaucht. Bei nicht gesetztem Bit ist dies das Zeichen '_', bei gesetztem Bit das invertierte Zeichen 'X'.
Bevor überhaupt editiert werden kann, wird noch nach dem Filenarnen gefragt. Dieser kann mit oder ohne Extension angegeben werden, im letzten Fall wird automatisch die Extension ".ALT" gesetzt. Grundsätzlich erhält das neue File den gleichen Namen aber immer mit der Extension ".NEU". Ein bereits vorhandenes File wird überschrieben!
Nach einer Wartepause, in der zunächst das alte File in das neue kopiert wird, kann das Editieren beginnen. Erlaubt sind die Tasten [Pfeiltasten], mit denen der Editiercursor bewegt wird. Soll ein Bit in der Matrix geändert werden, so betätigt man die Taste ENTER (oder RETURN). Ist das Editieren einer Matrix beendet, so wird das mit der Taste CAN angezeigt. Hiermit wird automatisch die folgende Matrix abgerufen oder das Programm beendet, wenn alle Matrizen (256!!) bearbeitet sind. Ein Abbruch der Arbeit kann mit der Taste EXIT erfolgen. Das Programm fragt, ob die bisherige Arbeit abgespeichert werden soll oder nicht.
Es ist einzusehen, daß die Prozedur bei 256 Zeichen recht zeitaufwendig ist. Deshalb besteht die Möglichkeit, eine Matrix gezielt zu editieren. Dies geschieht mit der Taste [+]. Das Programm fragt nach dem Hexwert, dessen Matrix bearbeitet werden soll. In diesem Modus sind die Tasten EXIT und [+] unwirksam. Nach Beendigung - Taste CAN - wird die zuletzt bearbeitete Matrix wieder dargestellt.

5. Das Video RAM - Grafik auf dem JOYCE

Nach den ausführlichen Beschreibungen der Zeichenmatrixmanipulationen erfolgt in dem vielleicht wichtigsten Abschnitt eine eher dürftige Beschreibung über die Behandlung von Grafik am JOYCE. Dies liegt daran, daß Grafik weitaus allgemeiner gehandhabt wird als die Matrixbearbeitung, so daß kein allgemeiner Algorithmus angeboten werden kann. Denn bei der Matrix ist das Format klar und beschränkt auf 256 Elemente. Die Möglichkeiten der Grafik sind uferlos und unterliegen nur den Phantasien des jeweiligen Programmierers.
Deshalb soll dieser Abschnitt auch nur eine Richtschnur sein und lediglich Grundsätze erörtern. Als Basis gilt auch hier Abschnitt 4, da der Speicherzugriff auf das Video RAM ähnlich dem Zugriff auf eine Matrix ist und ebenfalls vom Common memory aus operieren muß.
Voraus sei nochmals darauf hingewiesen, daß ein gesamtes Bild am JOYCE einen Speicher von 90x32x8Bytes = 22,5kBytes benötigt! Bedenkt man, daß das Common memory maximal 16kBytes lang ist, so wird klar, daß das Bild in Einzelsegmente zerlegt werden muß.
Zu bedenken ist noch, daß das Erstellen eines Bildes auf Assemblerebene recht schwierig ist, so daß eine Hochsprache zur Unterstützung benötigt wird. Einige für den JOYCE angebotene Hochsprachen unterstützen aber Grafik schon (über GSX), wodurch dieser Abschnitt eigentlich eher informativen Charakter hat.

5.1 Das Roller RAM

Obwohl bekannt ist, wo das Video RAM zu finden ist, bedeutet es leider nicht, daß Speicherplätzen im Video RAM eindeutig Positionen auf dem Bildschirm zugeordnet sind. Dies liegt zum Teil daran, daß der Bildschirm bekanntlich scrollt. D.h. ist der Schirm voll beschrieben, so verschwindet die erste Zeile vom Bildschirm, die nächsten Zeilen werden um eine Zeile nach oben bewegt bis dann die letzte Zeile frei ist und beschrieben werden kann. Eine Methode, das Scrollen zu vollziehen, liegt darin, auch die Daten des Video RAM entsprechend zu verschieben, so daß die erste Zeile immer eine feste Position im RAM hat. Im JOYCE wird das RAM nicht verschoben, stattdessen wird jeweils die Adresse der ersten Zeile - und natürlich damit auch aller folgenden Zeilen - geändert. Dies sieht stark nach Unordnung aus. Zum Glück gibt es aber doch eine Ordnung in Form einer Tabelle, in der nun die Startadressen der jeweiligen Zeilen zum bestehenden Augenblick zu finden sind. Diese Tabelle wird Roller RAM genannt und besteht aus 512 Adressen, da ja beim JOYCE 32x8=256 Zeilen vorhanden sind. Jede Adresse weist auf eine Zeile von 90 Zeichen bzw. 90x8=720 Bildpunkten (Pixels), allerdings in kodierter Form, d.h. die Werte in der Tabelle sind keine direkten Adressen. Die Inhalte der Tabelle müßen noch aufbereitet werden, dies kann so geschehen, wie es im Programm ROLLER.ASM angegeben ist. Auf Grund der später noch erörterten Aufteilung ist es zweckmäßig, jeweils acht Zeilen zu einer Einheit zu verbinden, also 90x8=720Bytes. Dies entspricht genau einer von 32 verfügbaren Zeichenzeilen des JOYCE.

Anordnung der Adressen im Roller RAM

        ---------------
  0,  1 I Pixel Row 0 I    Pixel Row = Bildpunkt Zeile
        ---------------
  2,  3 I Pixel Row 1 I
        ---------------
            .....
        ---------------
510,511 I Pixel Row 255
        ---------------
Zuordnung der Daten Bytes zu den Pixel Rows

=======================================================================
            ---------------------------------------- ... -------------
Row   0 ->  I Byte     0 I Byte     8 I Byte    16 I ... I Byte   712 I
            ---------------------------------------- ... -------------
Row   1 ->  I Byte     1 I Byte     9 I Byte    17 I ... I Byte   713 I
            ---------------------------------------- ... -------------
                     ...                         ...
            ---------------------------------------- ... -------------
Row   7 ->  I Byte     7 I Byte    15 I Byte    23 I ... I Byte   719 I
            ---------------------------------------- ... -------------
=======================================================================
            ---------------------------------------- ... -------------
Row   8 ->  I Byte   720 I Byte   728 I Byte   736 I ... I Byte  1432 I
            ---------------------------------------- ... -------------
                     ...                         ...
            ---------------------------------------- ... -------------
Row 255 ->  I Byte 22327 I Byte 22335 I Byte 22343 I ... I Byte 23039 I
            ---------------------------------------- ... -------------
Das doppelt umrandete Feld entspricht genau einer Zeichenzeile

An dieser Darstellung sind zwei Dinge festzustellen:

-Die Anordnung von jeweils acht Bytes untereinander entspricht genau der Anordnung einer Zeichenmatrix, wobei 90 Matrixelemente nebeneinander gerade einer Zeile auf dem Bildschirm entsprechen.
-Das, was für eine Zeichendarstellung gut ist, ist nicht so gut für eine Bilddarstellung, bei der die Bytes üblicherweise in einer Reihe nebeneinander abgelegt sind (siehe Abb.)

Übliche Bilddarstellung (Abtasten Zeile für Zeile)

            ---------------------------------------- ... -------------
Row   0 ->  I Byte     0 I Byte     1 I Byte     2 I ... I Byte    89 I
            ---------------------------------------- ... -------------
Die gewohnte Methode, Bilder darzustellen, ist offensichtlich die Abtastung. Sie entspricht unserer erlernten zweidimensionalen Darstellungsweise. Bilder oder besser Bildsegmente sollten in dieser Form dargestellt werden. Ein Umkopieren in das oben angegebene Format kann dann über ein Hilfsprogramm erfolgen, wie z.B. das Programm COPY.ASM es macht.

5.2 Grundsätzliches zur Grafik

Allgemein liegt eine Darstellung in mathematischer Form vor, bestehend aus einer oder mehreren Gleichungen. Natürlich kann dies in einem Programm auch ein festes Datenfeld sein, welches dann portionsweise in das Video RAM übertragen wird. An der allgemeinen Darstellung einer mathematischen Abbildung soll das Vorgehen prinzipiell erläuert werden.


      y |                                             .
        |                                            .
Start   |------------------------------------------.--------|
        |  /     /     /     /     /     /     /  .  /     /|
        |./     /     /     /     /     /     /  .  /     / |
Ende    |-.-------------------------------------.-----------|
        |  .                                   .
        |      .                             .
        |        .                         .
        |           .                   .
        |               .          .
        |                   ..
        |
        |
        |
        |--------------------------------------------------------------
                                                                  x
Das vorliegende Bild, berechenbar über eine Gleichnung, soll am Bildschirm dargestellt werden. Der schraffierte Bereich stellt eine Zeile aus 90 Matrizen dar, also 720 Bytes. Es müßen nun die zu den x Werten gehörenden y Werte berechnet werden, im Bild durch Punkte dargestellt. Hierzu kann das Programm BITACC.ASM Hilfestellung leisten, das in Abhängigkeit zweier Parameter, die dem x bzw. y Wert entsprechen, das Bit setzt, welches der Koordinate (x,y) zugewiesen ist.

Wie wohl schon an diesem einfachen Beispiel zu erkennen ist, benötigt man zur Berechnung ein Fließkommapaket, d.h. Unterprogramme, die die Berechnung mit Dezimalzahlen unterstützen. Ohne dieses Paket kann natürlich auch eine Berechnung in BASIC durchgeführt werden, wobei z.B. ein File erzeugt wird, in dem die Bildpunkte gespeichert sind. Dieser Prozess ist aber sehr rechenintensiv und kostet eine Menge Zeit. Der Datensatz mit den Bildpunkten kann dann von einem schnellen Assembler-Programm in das Video RAM geschrieben werden.

 

Da ich selbst bisher wenig mit Grafik gearbeitet habe, was sicherlich am etwas drögen Stil dieses Abschnittes zu erkennen ist, bin ich natürlich an weitern Erkenntnissen sehr interessiert.

Zum Abschluß noch kurz die Beschreibung der drei Hilfsprogramme für die Grafikbearbeitung.

ROLLER.ASM

Dies ist das wichtigste Programm, da es die tatsächliche Adresse für eine Zeile im Video RAM ermittelt, die ja kodiert im Roller RAM zu finden ist. Dieses Programm muß im Common memory liegen, da auf das Video RAM in Bank 3 zugegriffen wird. Der Aufruf des Programmes gleicht dem Aufruf, wie der für den Matrixzugriff war:

        MVI     A,LINE          ; Laden der gesuchten Zeile
        LXI     B,VIDSR         ; Laden der Adresse im Common
        CALL    USERF           ; Bank 3 einstellen
        DW      00E9H           ; Extended BIOS Aufruf

Wie man sieht, muß vor dem Aufruf die gesuchte Zeile (0..31) im Akkumulator stehen. Ebenfalls vorher müßen die 720Bytes für das Bildsegment in das Common memory geladen sein, dies ist als Label 'buffer' im Listing zu finden. Selbstverständlich muß das Bildsegment das besprochene Matrixformat aufweisen.

COPY.ASM

Dies Programm kopiert das besprochene Zeilenformat in das Matrixformat. Hierzu müßen die Register DE und HL auf zwei 720Byte Puffer weisen, wovon der Puffer, auf den Register HL weist, das Zeilenformat besitzt. Nach Ende der Routine findet man in dem Puffer, auf den Register DE zeigte, das Matrixformat.

BITACC.ASM

Dies Programm erwartet in Register HL die Adresse eines 720Byte Puffers in den die Bildinformationen geschrieben werden. Außerdem muß die x,y Koordinate übergeben werden, undzwar steht im Register DE der x Wert (0..719), der einem Bit entspricht, und im Register B steht der y Wert. Das Programm berechnet die Adresse im Puffer, dessen selektiertes Bit gesetzt werden soll, und setzt dann entsprechend das Bit in der Adresse.

E N D E

Programmpaket I: Änderung des JOYCE Zeichensatzes

Programm 1CHARSET.ASMAssemblerprogramm im Common Memory (RSX) für die Änderung des Zeichensatzes
Programm 2SETMAT.ASMAssemblerprogramm zum Einlesen oder Neudefinieren von Zeichensätzen
Programm 3MATEDIT.BASBASIC Programm3 zum Bearbeiten von Zeichensätzen. Hiermit können eigene Zeichensätze individuell gestaltet werden.

 

Programmpaket II: Grafikmöglichkeiten auf dem JOYCE

Programm 4ROLLER.ASMAssemblerprogramm zur Berechnung absoluter Bildschirmadressen aus gegebenen Zeilen.
Programm 5COPY.ASMAssemblerprogramm zum Umkopieren von xy Bildsegmenten in das JOYCE Format
Programm 6BITACC.ASMAssemblerprogramm zum Setzen eines Bits in einem Bildausschnitt bei gegebenen xy Koordinaten.

Die folgenden Fußnoten sind Nachträge:
1.Eine Beschreibung der GSX-Funktionen findet sich z.B. in einer Artikelserie in der CT: "GSX ohne Geheimnisse"
2.Die Funktion einer RSX wurde u.a. in einem Artikel der CT erläutert: "Systemerweiterungen unter CP/M-Plus"
3.Später habe ich MATEDIT.PAS in PASCAL geschrieben