Maschinencode auf dem CPCObwohl der Schneider CPC mit einem außerordentlich leistungsfähigen Basic-Interpreter ausgestattet ist, ergibt sich doch früher oder später der Wunsch nach 'Maschinencode'. Dabei muss man grundsätzlich zwei Fälle unterscheiden: Einmal kann man Assembler-Routinen als Grundlagen: UnterprogrammeUnterprogramme einsetzen, die die Der Sound Manager: FähigkeitenFähigkeiten des Basic-Interpreters besonders bei zeitkritischen oder zeitintensiven Prozeduren erweitern. Zum anderen können aber auch Maschinencode-Programme als ein eigenständiges 'Vordergrund-Programm' gestartet werden. Hintergrund-Programme = System-Erweiterungen Vordergrund-Programme = Hauptprogramme Und wie das in der Informatik so ist, kann man beide Fälle erneut fein systematisch untergliedern: Wo soll denn der Maschinencode herkommen? Handelt es sich um Maschinencode auf dem CPC: ROM-SoftwareROM-Software oder wird die Software von einem Einleitung: MassenspeicherMassenspeicher eingeladen? Maschinencode auf dem CPC: ROM-SoftwareROM-Software
Kassetten/Disketten-Software
Vordergrundprogramme vom MassenspeicherZum Starten eines Hauptprogrammes von Diskette oder Kassette sollte immer der Vektor &MACHINE PACK: BD13: MC BOOT PROGRAMBD13 MAIN FIRMWARE JUMPBLOCK: MACHINE PACK Die Laderoutine muss dann, wie es die Bezeichnung schon andeutet, das Assemblerprogramm in den Speicher des Rechners einladen, und kehrt danach mit 'RET' zu MAIN FIRMWARE JUMPBLOCK: MACHINE PACK Danach wird der Computer vollständig initialisiert und das Programm gestartet. Normalerweise wird man ein eigenständiges Maschinencode-Programm aber vom Basic-Interpreter aus einladen, weil dieser ja 'by default' nach dem Einschalten des Computers gestartet wird. Einleitung: BASIC Die Aufruf-Bedingungen für das Maschinencode-Programm selbst sind dabei die selben, wie für jedes andere Vordergrund-Programm auch: BC = &B0FF = letztes Datentypen: Bytes Das RAM-Vordergrund-Programm muss sich dann zunächst seinen statischen Variablenbereich reservieren, danach evtl. Speicheraufteilung durch ein Vordergrund-Programm: Hintergrund-ROMsHintergrund-ROMs initialisieren (auch Die Abteilungen des Betriebssystems: AmsdosAmsdos muss, wenn es benötigt wird, erst noch initialisiert werden!) und kann erst dann so richtig loslegen. ROM-SoftwareAlle Erläuterung zu den Anschlüssen 40 bis 45: 42 - ROMEN (0)ROMs mit zusätzlicher Software oder Vordergrund-Programmen müssen, wollen sie in den Genuss der existierenden Kernel-Routinen kommen, im obersten Adressviertel der Die ICs im Überblick: Die CPU Z80 Dabei enthält der Schneider CPC einen Soft/Hardware-Mechanismus, mit dem den einzelnen 16k-ROM-Bloecken eine 'ROM-Selekt-Adresse' im Bereich von &00 bis &FB (252) zugeordnet wird. (Die ROM-Konfiguration: ROM-Selektion power on ROMDie für das Basic-ROM reservierte Adresse ist &00. Man kann aber auch ein anderes Vordergrund-ROM auf dieser ROM-Selekt-Adresse installieren. Das Basic-ROM bleibt auf jeder noch nicht benutzten Adresse erreichbar, weil es über keine eigene Selekt-Decodierung verfügt und immer von anderen Erläuterung zu den Anschlüssen 40 bis 45: 42 - ROMEN (0)ROMs, die sich angesprochen fühlen, ausgeblendet werden muss. Der MAIN FIRMWARE JUMPBLOCK: KERNEL Dadurch kann man seinen Computer beispielsweise zu einem PASCAL-Rechner oder auch reinrassigen CP/M-Rechner machen. Im Amsdos-Disketten-Kontroller ist ein Platz für eine Drahtbrücke vorgesehen, die, wenn man sie einsetzt, die Selekt-Adresse für das Amsdos-ROM von &07 auf &00 ändert! Dadurch wird Die Abteilungen des Betriebssystems: AmsdosAmsdos anstelle des Basic-Interpreters gestartet. Die Initialisierungs-Routine von Die Abteilungen des Betriebssystems: AmsdosAmsdos, das eigentlich ein 'Speicheraufteilung durch ein Vordergrund-Programm: Hintergrund-ROMsHintergrund-ROM' ist, testet, ob Die Abteilungen des Betriebssystems: AmsdosAmsdos auf der Adresse &00 eingeblendet wurde und startet in diesem Fall Einleitung: CP/MCP/M! ROM-TypenJeder ROM-Block hat einen sogenannten Amsdos: HeaderHEADER. Die ersten Datentypen: Bytes #C000 DEFB Ty
#C001 DEFB Mark number
#C002 DEFB Version number
#C003 DEFB Modification level
#C004 DEFS Resident System Extensions: external command tableExternal command table
....
Die drei Datentypen: Bytes Das erste Datentypen: Bytes #C000 DEFB #00 ; Vordergrund-ROM
oder #C000 DEFB #00+#80 ; Eingebautes Vordergrund-ROM
oder #C000 DEFB #02 ; Erweiterungs-ROM
oder #C000 DEFB #01 ; Speicheraufteilung durch ein Vordergrund-Programm: Hintergrund-ROMsHintergrund-ROM
&80Im Typ-Byte des Basic-ROMs ist Datenbreite: Bits Wenn der MAIN FIRMWARE JUMPBLOCK: KERNEL &00Erläuterung zu den Anschlüssen 40 bis 45: 42 - ROMEN (0)ROMs, die Vordergrund-Programme enthalten, werden mit einem Datentypen: Bytes &02Sehr umfangreiche Vordergrund-Programme können bis zu vier 16k-Blocks umfassen. Diese müssen dann aufeinanderfolgende Selekt-Adressen haben. Nur das erste Erläuterung zu den Anschlüssen 40 bis 45: 42 - ROMEN (0)ROM darf in seinem Amsdos: HeaderHeader als Vordergrund-ROM gekennzeichnet sein. Die bis zu drei 'nachfolgenden' Erläuterung zu den Anschlüssen 40 bis 45: 42 - ROMEN (0)ROMs müssen als Erweiterungs-ROM deklariert werden. Vor allem mit dem Restart_2 ist es dabei möglich, von jedem Erläuterung zu den Anschlüssen 40 bis 45: 42 - ROMEN (0)ROM eines Hauptprogrammes aus Grundlagen: UnterprogrammeUnterprogramme in 'benachbarten' Erweiterungs-ROMs aufzurufen. &01Alle Erläuterung zu den Anschlüssen 40 bis 45: 42 - ROMEN (0)ROMs, die keine eigenständige Software enthalten, sondern nur zusätzliche Routinen, die von einem Vordergrund-Programm benutzt werden können, müssen als Speicheraufteilung durch ein Vordergrund-Programm: Hintergrund-ROMsHintergrund-ROM markiert werden. Alle Speicheraufteilung durch ein Vordergrund-Programm: Hintergrund-ROMsHintergrund-ROMs sollten auf Select-Adressen von &01 bis &07 (CPC 464) bzw. &00 bis &0F (CPC 664, 6128) installiert werden, weil der Vektor KERNEL: BCCB: KL ROM WALKKL ROM WALK nur diese ROM-Adressen abklappert und auch nur für diese Erläuterung zu den Anschlüssen 40 bis 45: 42 - ROMEN (0)ROMs Zeiger auf deren reservierten RAM-Bereich speichern kann. Das Amsdos-ROM hat die Select-Adresse &07. Hintergrund-Routinen von MassenspeichernHintergrund-Software, die erst nachtraeglich von Kassette oder Diskette eingeladen wird, muss vom Vordergrund-Programm ihren Platz zugewiesen bekommen. CPC-typisch ist dabei die Methode, dass das Vordergrund-Programm von seinem Memory Pool von oben her etwas abtritt. Beim eingebauten Basic-Interpreter müsste man also Die Aufteilung des RAM durch den Basic-Interpreter: Chaos über HIMEMHIMEM herabsetzen und danach die Datei mit dem Assemblerprogramm dorthin einladen. Problematisch ist für das eingeladene Maschinencode-Programm vor allem, dass nicht vorhersehbar ist, an welche Adresse es denn nun genau zu liegen kommt. Die Anschlussbelegungen der wichtigsten ICs im CPC: Das RAM 4164Das RAM wird ja dynamisch von oben und von unten her den verschiedenen Erweiterungen zugeteilt, wobei die Grenzen des noch verfügbaren Memory Pools langsam aufeinander zu wachsen. Da Maschinencode-Programme, bis auf ganz wenige Ausnahmen, nicht ortsunabhängig geschrieben werden können, müssen sie der Datentypen: Realrealen Lage angepasst, also 'relocalisiert' werden. Am Ende dieses Kapitels wird deshalb ein einfacher 'Relocater' für Z80-Assemblerprogramme beschrieben. Dieses Zusatz-Programm muss aufgerufen werden, bevor die erste Routine in der Erweiterung benutzt werden kann. Dabei passt es alle Adressierungsarten der Z80: Absolutabsoluten Adressen an die aktuelle Lage des Programmes an. Im Anschluss an die Relozierung können noch weitere Initialisierungen vorgenommen werden, zum Beispiel die Einbindung als Maschinencode über HIMEM: RSXRSX: Resident System ExtensionsDer MAIN FIRMWARE JUMPBLOCK: KERNEL |Einleitung: BASIC
In dieses System sind alle Vordergrund-ROMs und alle initialisierten Speicheraufteilung durch ein Vordergrund-Programm: Hintergrund-ROMsHintergrund-ROMs eingebunden und ebenfalls alle nachgeladenen Maschinencode-Programme, die sich über den Vektor &KERNEL: BCD1: KL LOG EXTBCD1 KL LOG EXT dem Betriebssystem vorgestellt haben. Dafür wird für jedes Programmpaket eine 'Resident System Extensions: external command tableexternal command table', also eine Tabelle der externen Kommandos benötigt. Die einzelnen Tabellen werden über eine verkettete Trees: ListenListe 'zusammengehalten'. Zusätzlich zu jeder Kommandotabelle werden vier Datentypen: Bytes Bei Vorder- und Speicheraufteilung durch ein Vordergrund-Programm: Hintergrund-ROMsHintergrund-ROMs ist die Resident System Extensions: external command tableexternal command table Bestandteil des ROM-Headers. Wird ein Speicheraufteilung durch ein Vordergrund-Programm: Hintergrund-ROMsHintergrund-ROM initialisiert, so darf es sich vom Memory Pool etwas Speicherplatz reservieren (Siehe Kapitel über die Speicheraufteilung durch ein Vordergrund-Programm: Speicher-Aufteilung totalSpeicher-Aufteilung der CPCs). Dabei zieht der MAIN FIRMWARE JUMPBLOCK: KERNEL Mit dem Vektor &KERNEL: BCD4: KL FIND COMANDBCD4 KL FIND COMAND kann zu einem Kommando-Namen dessen Adresse und ROM-Select-Byte erfragt werden. Dabei werden die Kommando-Tabellen von hinten her durchsucht. Die RSX-Erweiterungen, die zuletzt eingeführt wurden, werden als erste überprüft. Sollten also zwei Routinen mit dem gleichen Namen existieren, so wird die aeltere von der später angefügten Routine 'verdeckt'. Beim Suchen eines Kommandos werden zuerst alle Maschinencode über HIMEM: RSXRSXes im RAM abgeklappert, dann alle Speicheraufteilung durch ein Vordergrund-Programm: Hintergrund-ROMsHintergrund-ROMs und, wenn der Befehl immer noch nicht gefunden wurde, auch noch alle Vordergrund-ROMs ab der ROM-Select-Adresse &08 (Garbage Collection: ... beim CPC 464beim CPC 464) bzw. &10 (bei den CPCs 664 und 6128), bis der MAIN FIRMWARE JUMPBLOCK: KERNEL Der Vektor MAIN FIRMWARE JUMPBLOCK: KERNEL Sonst muss man die entsprechende Routine noch via Restart_3 (LOW KERNEL JUMPBLOCK: 0018 - RST 3: LOW FAR CALLLOW FAR CALL) oder über &001LOW KERNEL JUMPBLOCK: 000B: LOW KL LOW PCHL external command tableNach diesen Einzelheiten bleibt nur noch das 'Layout' der Resident System Extensions: external command tableexternal command tables zu klären: ; Aufbau der Namenstabellen für RSX-Kommandos: ; --------------------------------------------- RSXTAB: DEFW BCD1: KL LOG EXT: 2. Namenstabelle (NAMTAB)NAMTAB ; Zeiger auf Namenstabelle JP ROUT1 ; \ JP ROUT2 ; \ Sprungleiste zu den Routinen. JP ROUT3 ; > Können natürlich auch mit ... ; / ROM-Konfiguration: RestartsRestarts gebildet werden. JP ROUTn ; / ; BCD1: KL LOG EXT: 2. Namenstabelle (NAMTAB)NAMTAB: DEFB "R","O","U","T","1"+#80 DEFB "R","O","U","T","2"+#80 DEFB "R","O","U","T","3"+#80 ... DEFB "R","O","U","T","n"+#80 DEFB 0 Dabei müssen die Sprung-Vektoren in der Reihenfolge der Namen in der Namenstabelle aufeinanderfolgen. In der Namenstabellen werden die Namen der einzelnen RSX-Befehle in ihrer ASCII-Codierung abgelegt. Im letzten Buchstaben eines Namens muss jeweils Hardware-Basteleien: Das 8. Bitdas 7. Bit gesetzt sein. Abgeschlossen wird die Tabelle durch ein Nullbyte. Bei Speicheraufteilung durch ein Vordergrund-Programm: Hintergrund-ROMsHintergrund-ROMs wird der erste Eintrag benutzt, um das Erläuterung zu den Anschlüssen 40 bis 45: 42 - ROMEN (0)ROM zu initialisieren. Hier sollte der Name möglichst so gestaltet werden, dass man ihn nicht von Einleitung: BASIC Auch kann man von einem Vordergrund-Programm aus gut Erklärung der Anschlussbelegung: Testtesten, ob ein spezielles Speicheraufteilung durch ein Vordergrund-Programm: Hintergrund-ROMsHintergrund-ROM bereits initialisiert ist, indem man mit MAIN FIRMWARE JUMPBLOCK: KERNEL Vordergrund-ROMs sollten normalerweise nur einen Eintrag haben: Den, mit dem sie gestartet werden. Nur wenn ein Erläuterung zu den Anschlüssen 40 bis 45: 42 - ROMEN (0)ROM mehrere, voneinander unabhängige Vordergrund-Programme enthält, können in der Kommando-Tabelle auch mehrere Einträge auftauchen. Als praktische Beispiele folgen nun Assemblerprogramme für eine RAM-RSX und ein ROM-Header: ; RAM-RSX-Erweiterung z.LOW KERNEL JUMPBLOCK: 000B: LOW KL LOW PCHL ; ROM-Header z. LOW KERNEL JUMPBLOCK: 000B: LOW KL LOW PCHL Der Aufruf einer RSX-Erweiterung gestaltet sich in Assembler nicht ganz so einfach, wie in Einleitung: BASIC ; Aufruf einer Maschinencode über HIMEM: RSXRSX in Maschinensprache ; ------------------------------------ ... LD HL,NAME ; Zeiger auf den Namen nach HL laden Maschinencode über HIMEM: CALLCALL #BCD4 ; MAIN FIRMWARE JUMPBLOCK: KERNEL |