Das Problem hat den Software-Entwicklern bei Amstrad sicher auch kraeftig zu knacken gegeben. Herausgekommen bei all diesen Bemühungen ist zunächst einmal der Überblick: LOW KERNEL JUMPBLOCK Die Firmware des Schneider CPC: LOW KERNEL JUMPBLOCKLOW KERNEL JUMPBLOCK, eine Sprungleiste, die im Bereich der Z80-Restarts liegt: von &0000 bis &003F.
Mit den Vektoren in dieser Sprungleiste können Grundlagen: UnterprogrammeUnterprogramme aufgerufen (Maschinencode über HIMEM: CALLCALL) oder angesprungen (JP) werden, wobei der ROM-Konfiguration: ROM-Status Anschluss eines Zusatz-ROM: ROM-StatusROM-Status oder auch die gesamte Die Speicherkonfiguration im Schneider CPC: ROM-KonfigurationROM-Konfiguration für die Zeit der Unterprogramm-Bearbeitung wählbar ist.
Das heißt, man ruft einen Vektor im Überblick: LOW KERNEL JUMPBLOCK Die Firmware des Schneider CPC: LOW KERNEL JUMPBLOCKLOW KERNEL JUMPBLOCK auf, übergibt ihm auf die jeweils vorgeschriebene Weise die Adresse der Routine, die man aufzurufen gedenkt und Informationen über den von der Routine benötigten ROM-Konfiguration: ROM-Status Anschluss eines Zusatz-ROM: ROM-StatusROM-Status bzw. Die Speicherkonfiguration im Schneider CPC: ROM-KonfigurationROM-Konfiguration. Die Behandlungs-Routine des Vektors stellt die Die Speicherkonfiguration im Schneider CPC: ROM-KonfigurationROM-Konfiguration ein, ruft das gewünschte Grundlagen: UnterprogrammeUnterprogramm auf und restauriert abschließend sogar wieder die alte Die Speicherkonfiguration im Schneider CPC: ROM-KonfigurationROM-Konfiguration.
Damit ist es möglich, bei eingeschaltetem RAM eine Routine in einem Erläuterung zu den Anschlüssen 40 bis 45: 42 - ROMEN (0)ROM aufzurufen, weil man vom kurzzeitigen Einblenden eines Erläuterung zu den Anschlüssen 40 bis 45: 42 - ROMEN (0)ROMs nichts mitbekommt.
Da der Aufruf der Vektoren des Überblick: LOW KERNEL JUMPBLOCK Die Firmware des Schneider CPC: LOW KERNEL JUMPBLOCKLOW KERNEL JUMPBLOCKs meist geschehen, wenn unten eben kein Erläuterung zu den Anschlüssen 40 bis 45: 42 - ROMEN (0)ROM eingeblendet ist, müssen die Vektoren nicht nur im Erläuterung zu den Anschlüssen 40 bis 45: 42 - ROMEN (0)ROM, sondern auch im RAM auf den gleichen Adressen eingetragen sein. Sie werden deshalb bei der Initialisierung des Rechners aus dem Erläuterung zu den Anschlüssen 40 bis 45: 42 - ROMEN (0)ROM in's RAM kopiert.
Dass man für diese Aufgaben den Bereich der Z80-Restarts gewählt hat, ist nicht ohne Hintergedanken geschehen. Die ROM-Konfiguration: RestartsRestarts sind ja Die CPU Z80: Unterprogramm-AufrufeUnterprogramm-Aufrufe, die im Unterschied zum normalen CALL-Befehl nur ein und nicht drei Datentypen: Bytes Datenbreite: BytesBytes beanspruchen.
Das hat man sich zunutze gemacht, und die 'Basic und Maschinencode: ParameterParameter'-Übergabe, also die Angabe von Routinen-Adresse und Die Speicherkonfiguration im Schneider CPC: ROM-KonfigurationROM-Konfiguration so festgelegt, dass man mit den ROM-Konfiguration: RestartsRestarts praktisch neue Befehle geschaffen hat. Bei einem Normalen Z80-CALL-oder -JP-Befehl folgen ja auf das Befehlsbyte (205 oder 195) als 'Argument' zwei Datentypen: Bytes Datenbreite: BytesBytes mit der Sprungadresse.
Die ROM-Konfiguration: RestartsRestarts sind ebenfalls ein Datentypen: Bytes Datenbreite: BytesByte lang, und erwarten u. Operationen: BD5B / 349A / 349A: FLO SUBA. als Argument die Sprungadresse. Was liegt also näher, als die Analogie komplett zu machen, und diese Adresse in gleicher Weise an das Befehlsbyte anzuhängen? In einem Assembler-Quelltext sähe das dann etwa so aus:
Speicheraufteilung durch ein Vordergrund-Programm: RST 3 LOW KERNEL JUMPBLOCK: 0000 - RST 0: LOW RESET ENTRY LOW KERNEL JUMPBLOCK: 0008 - RST 1: LOW LOW JUMP LOW KERNEL JUMPBLOCK: 0010 - RST 2: LOW SIDE CALL LOW KERNEL JUMPBLOCK: 0018 - RST 3: LOW FAR CALL LOW KERNEL JUMPBLOCK: 0020 - RST 4: LOW RAM LAM LOW KERNEL JUMPBLOCK: 0028 - RST 5: LOW FIRM JUMP LOW KERNEL JUMPBLOCK: 0030 - RST 6: LOW USER RESTART LOW KERNEL JUMPBLOCK: 0038 - RST 7: LOW INTERRUPT ENTRYRST #08
DEFW adresse
Damit hat man einen neuen Befehl erfunden, der Maschinencode über HIMEM: CALLCALL oder JP ersetzen kann. Zu lösen ist nur noch die Frage, wie man auch noch die ROM-Informationen übergibt. Beim ROM-Konfiguration: RestartsRestart 1 (RST_#08) ist das so geregelt:
Aufgerufen werden können mit diesem erweiterten Sprungbefehl (JP) nur Routinen im unteren Erläuterung zu den Anschlüssen 40 bis 45: 42 - ROMEN (0)ROM oder RAM. Das heißt, die Adresse liegt immer im Bereich &0000 bis &3FFF, die obersten beiden Adressbits A14 und A15 sind immer Real: NullNull.
Das macht man sich zunutze, um nun hier den gewünschten ROM-Konfiguration: ROM-Status Anschluss eines Zusatz-ROM: ROM-StatusROM-Status zu übergeben: Ein gesetztes Datenbreite: Bits Port B - Input: &F5xx: Bit 0: Port B - Input: &F5xx: Bit 4: Port B - Input: &F5xx: Bit 5: Port B - Input: &F5xx: Bit 6: Port B - Input: &F5xx: Bit 7: Port C - Output: &F6xx: Bit 4: Port C - Output: &F6xx: Bit 5:Bit 14 blendet das untere Erläuterung zu den Anschlüssen 40 bis 45: 42 - ROMEN (0)ROM aus und ein gesetztes Datenbreite: Bits Port B - Input: &F5xx: Bit 0: Port B - Input: &F5xx: Bit 4: Port B - Input: &F5xx: Bit 5: Port B - Input: &F5xx: Bit 6: Port B - Input: &F5xx: Bit 7: Port C - Output: &F6xx: Bit 4: Port C - Output: &F6xx: Bit 5:Bit 15 blendet das obere Erläuterung zu den Anschlüssen 40 bis 45: 42 - ROMEN (0)ROM aus (Nur für die Zeit des Grundlagen: UnterprogrammeUnterprogramms, versteht sich). Es ergeben sich folgende vier Kombinationen:
A14 A15 ROM-Konfiguration: ROM-Status Anschluss eines Zusatz-ROM: ROM-StatusROM-Status:
------------------------------------------------------------------------
0 0 oben Erläuterung zu den Anschlüssen 40 bis 45: 42 - ROMEN (0)ROM. unten Erläuterung zu den Anschlüssen 40 bis 45: 42 - ROMEN (0)ROM, Aufruf einer Routine im Betriebssystem-ROM
0 1 oben RAM. unten Erläuterung zu den Anschlüssen 40 bis 45: 42 - ROMEN (0)ROM, Aufruf einer Routine im Betriebssystem-ROM
1 0 oben Erläuterung zu den Anschlüssen 40 bis 45: 42 - ROMEN (0)ROM. unten RAM, Aufruf einer Routine im RAM
1 1 oben RAM. unten RAM, Aufruf einer Routine im RAM
------------------------------------------------------------------------
Ein Sprung zu einer Routine des Betriebssystems ab der Adresse &1234 mit eingeblendetem Bildschirm-RAM im obersten Adressviertel würde dann wie folgt erreicht:
Speicheraufteilung durch ein Vordergrund-Programm: RST 3 LOW KERNEL JUMPBLOCK: 0000 - RST 0: LOW RESET ENTRY LOW KERNEL JUMPBLOCK: 0008 - RST 1: LOW LOW JUMP LOW KERNEL JUMPBLOCK: 0010 - RST 2: LOW SIDE CALL LOW KERNEL JUMPBLOCK: 0018 - RST 3: LOW FAR CALL LOW KERNEL JUMPBLOCK: 0020 - RST 4: LOW RAM LAM LOW KERNEL JUMPBLOCK: 0028 - RST 5: LOW FIRM JUMP LOW KERNEL JUMPBLOCK: 0030 - RST 6: LOW USER RESTART LOW KERNEL JUMPBLOCK: 0038 - RST 7: LOW INTERRUPT ENTRYRST #08
DEFW #1234 + #8000
Zur Adresse wird noch &8000 addiert, wodurch Hardware-Basteleien: Das 8. Bitdas Bit A15 gesetzt ist, das das obere Erläuterung zu den Anschlüssen 40 bis 45: 42 - ROMEN (0)ROM aus- und das Bildschirm-RAM einblendet. Das Betriebssystem-ROM wird nicht aus- sondern eingeschaltet, weil Datenbreite: Bits Port B - Input: &F5xx: Bit 0: Port B - Input: &F5xx: Bit 4: Port B - Input: &F5xx: Bit 5: Port B - Input: &F5xx: Bit 6: Port B - Input: &F5xx: Bit 7: Port C - Output: &F6xx: Bit 4: Port C - Output: &F6xx: Bit 5:Bit A14 nicht gesetzt ist (Sonst hätte man auch noch &4000 addieren müssen).
Noch ein weiterer Punkt war zu beachten, um diese Vektoren einem Z80-Befehl so ähnlich wie nur irgend möglich zu machen: Es dürfen keine Die Tonausgabe: Das Kontrollregister (Reg. 7) Die Tonausgabe: Die möglichen Hüllkurvenformen (Reg. 13)Register verändert werden. Weder beim Sprung zur Routine noch beim Rücksprung.
Alle notwendigen Berechnungen werden deshalb mit Die CPU Z80: Der zweite Registersatz ROM-Konfiguration: der zweite Registersatzdem zweiten Registersatz der Die ICs im Überblick: Die CPU Z80 Das Innenleben der CPC-Rechner: Die CPU Z80 Die Anschlussbelegungen der wichtigsten ICs im CPC: Die CPU Z80CPU durchgeführt, den man normalerweise nicht benutzen darf. Daraus ergibt sich eine weitere Eigenart aller Restart-Befehle:
'Alle ROM-Konfiguration: RestartsRestarts lassen einen Alle noch folgenden Anschlüsse fallen unter die Rubrik STEUER- oder auch CONTROLBUS:: INT - InterruptInterrupt wieder zu !'
Das liegt daran, dass vor dem Register-Tausch der Alle noch folgenden Anschlüsse fallen unter die Rubrik STEUER- oder auch CONTROLBUS:: INT - InterruptInterrupt verboten werden muss, da der Alle noch folgenden Anschlüsse fallen unter die Rubrik STEUER- oder auch CONTROLBUS:: INT - InterruptInterrupt ebenfalls auf Die CPU Z80: Der zweite Registersatz ROM-Konfiguration: der zweite Registersatzden zweiten Registersatz zugreifen will. Nachdem alle Berechnungen erledigt sind, werden die normalen Die Tonausgabe: Das Kontrollregister (Reg. 7) Die Tonausgabe: Die möglichen Hüllkurvenformen (Reg. 13)Register wieder 'zurückgeklappt' und ein Alle noch folgenden Anschlüsse fallen unter die Rubrik STEUER- oder auch CONTROLBUS:: INT - InterruptInterrupt wieder zugelassen. Voila!
Nun könnte man also eine Sprungleiste im unteren Erläuterung zu den Anschlüssen 40 bis 45: 42 - ROMEN (0)ROM einrichten, auf die man mit erweiterten CALL-Befehlen zugreifen kann. Dass man im Schneider CPC aber speziell für Aufrufe von Routinen im untersten Adressviertel keine CALL-sondern nur zwei JP-Ersatz-Routinen mit den ROM-Konfiguration: RestartsRestarts 2 und 5 gebildet hat, zeigt, dass man bei Amstrad noch einen anderen Weg gegangen ist:
Die Sprungleisten des Betriebssystems: Die SprungleistenDie Sprungleiste für die Betriebssystem-Routinen werden bei der Initialisierung des Rechners in's zentrale RAM kopiert. Die Vektoren selbst werden mit den erweiterten JP-Befehlen gebildet.
Man ruft also nicht mit einem Restart-CALL einen normal mit JP gebildeten Vektor im Erläuterung zu den Anschlüssen 40 bis 45: 42 - ROMEN (0)ROM auf (der dann endgültig die Betriebssystem-Routine anspringt), sondern ruft mit einem normalen Maschinencode über HIMEM: CALLCALL den Vektor im RAM auf, der mit einem erweiterten JP-Befehl gebildet ist.
Das hat zwei Vorteile: Zum Einen kann man auch weiterhin bedingte Aufrufe von Grundlagen: UnterprogrammeUnterprogrammen benutzen. Wäre bereits der Aufruf des Vektors mit einem CALL-Restart gebildet Datenbreite: Wordsworden, so müsste man für jede Aufruf-Bedingung einen anderen ROM-Konfiguration: RestartsRestart verbrauchen:
eigenes Programm Sprungleiste im RAM Routine im Erläuterung zu den Anschlüssen 40 bis 45: 42 - ROMEN (0)ROM
---------------- ------------------- --------------
... ...
Maschinencode über HIMEM: CALLCALL NZ,VEKTOR -----> VEKTOR: Speicheraufteilung durch ein Vordergrund-Programm: RST 3 LOW KERNEL JUMPBLOCK: 0000 - RST 0: LOW RESET ENTRY LOW KERNEL JUMPBLOCK: 0008 - RST 1: LOW LOW JUMP LOW KERNEL JUMPBLOCK: 0010 - RST 2: LOW SIDE CALL LOW KERNEL JUMPBLOCK: 0018 - RST 3: LOW FAR CALL LOW KERNEL JUMPBLOCK: 0020 - RST 4: LOW RAM LAM LOW KERNEL JUMPBLOCK: 0028 - RST 5: LOW FIRM JUMP LOW KERNEL JUMPBLOCK: 0030 - RST 6: LOW USER RESTART LOW KERNEL JUMPBLOCK: 0038 - RST 7: LOW INTERRUPT ENTRYRST #08
... <--+ DEFW ROUTIN -----> ROUTIN: ...
... | ... ...
+-------------------------------------- RET
Der andere Vorteil ist, dass man alles im RAM ändern kann. Man kann in einen Vektor also einen Sprung zu einer anderen, eigenen Routine eintragen, die die selbe Aufgabe wahrnimmt. Nur eben besser, schneller, fehlerfrei oder leicht verändert. Dieses 'Umbiegen' wird 'Patchen' genannt, vom englischen: patch = Flicken.
|