Dein Genie 3s, die 5 unbekannten Wesen Nun soll auch ein Z180-Prozessor Chef im System sein können Helmut Bernhardt, Arnulf Sopp Vorbemerkung: Im Folgenden ist viel von "wir"' die Rede. Dies aus Gründen der Sprachökonomie. Jeder von uns machte aber in Wirklichkeit das, was er am besten konnte: Helmut die Hardare. Arnulf die Software. Das Pflichtenheft für beides entstand unter Mitwirkung etlicher Gebinde Hopfenbrause. Die Hardware Vor längerer Zeit hatten wir unter ähnlichem Titel mal eine Erweiterung für den Genie IIIs beschrieben (1), mit der sämtliche Speicher (User-RAM, Vi- deo-RAM, HRG-RAM und Zeichengenerator-RAM) auf die vierfache Größe erweitert werden konnten. Außerdem fiel dabei noch ein SRAM ab, das parallel zum Boot-EPROM arbeitete. Dafür haben wir an den Sockel der Z80-CPU ein Adapter-Board gesteckt, das den Z80 aufnahm und einen schreib- und lesbaren Port bereitstellte, mit dessen Bits die Umschaltung dar Speicherbanks gesteuert wurde. Über dieses primitive Banking kann z.B. ein Genie 2s-Anwender, der auf eine HD64180-CPU umgerüstet hat (2), nur milde lächeln, wenn er seinen Computer mit 9,2 MHz (gegenüher 7,2 MHz des G3s) fährt. Es galt, dieses Manko beim G3s auszubügeln. Dafür haben wir ein neues Adapter-Board gebaut, auf dem nun kein Z80 (auch kein HD64180), sonden ein Z180 steckt. Der Z180 hat (wie auch der neuere HD64180-PLCC) 20 Adreßleitungen und kann damit über seine MMU und die beiden DMA-Känle 1 Megabyte RAM direkt adressieren. Um diese CPU so, wie sie gedacht ist, direkt zu nutzen, hätte das riesige Betriebssystem G-DOS 2.3 (oder Calva-DOS 2.4, die auf 1 Megabyte angepaßte Version) vollkommen auf HD64180-MMU-Banking umgeschrieben werden müssen. In über 63 kB SYS- und anderen systemeigenen Files hatten alle OUT-befehle an die System-Steuerports F9h und FAh gesucht und auf entsprechende Z180-MMU-Befehle geändert werden müssen. Außer viel Arbeit hätte das auch die Kompatibilität mit anderen Computern dieser und ähnhicher Bauart gekostet. Da entschieden wir uns dafür, dem Calva-DOS sein Banking über die Systemteuerports zunächst mal zu erhalten. Die Ports F9h, FAh und FBh (früher F3h) auf dem Adapter-Board haben ihre volle Funktionsfähigkeit behalten. Nun ist aber der Einsatz eines HD64180 bzw. Z180 witzlos, wenn dessen MMU und DMAC nicht benutzt werden können. Wir haben beide Möglichkeiten eingerichtet: Nach dem Einschalt-Reset sind alle Systemport-Bits auf 0 gesetzt und ein voll G3s-kopatibler Computer incl. Erweiterung auf vierfache Speichergröße liegt vor. Durch Setzen des früher anders belegten Bits D6 in Port FBh kann aber umgeschaltet werden in einen lupenreinen Z180-Computer: alle Banking- und Common-Definitions-Bits der Systemports hahen dann keine Fünktion mehr. Das RAM wird ausschließlich durch die Adreßleitungen der CPU adressiert. Nur das Einblenden von memory mapped I/O-Baugruppen in die dafür vorgesehenen physikalischen Adreßbereiche erfolgt, wie im G3s-Modus, durch die entsprechenden Systemport-Bits. Gleichwohl sind deren logische Adressen variabel. Der G3s dekodiert bei ihrer Selektion nur die Adreßbits 0-1. Wie der Z180 derzeit sein physikalisches Megabyte in bis zu drei logische Adreßbereiche unterteilt, indem er mit A12-A19 jongliert, da redet ihm der G3s nicht drein. Um die Ausmaße eines Adapter-Boards mit diesen Umschaltmöglichkeiten (s. Foto) in Grenzen zu halten, mußten wir zwei PALs einsetzen. PAL 1 erzeugt lediglich die Port-Freigabesignale /OUTFB und /INFB (und noch einige weitere Freigabesignale - s. PAL-Listing), mit denen das Latch 74LS273 und der Lesetreiber 74LS244 angesteuert werden, die den zusätzlichen Port BFh realisieren. Die eigentliche Steuerung der RAM-Adressierung leistet PAL 2. Durch die Ausgänge /CAS0-/CAS3 wird eine der vier Reihen von 41256er RAM-Chips selektiert. A16 und A17 wählen darin einen 64 kB-Block an. Für die Adressierung im Z180-Modus gelangen die Adressen A16-A19 an das PAL. Im G3s-Modus erfolgt das Banking durch die Bits D6 und D7 von Port F9h sowie D0 und D1 von Port FBh. D7 von Port FBh entscheidet, ob bei logischer Adressierung im eingestellten Common-Bereich (0000h-3FFFh oder E000h-FFFFh) nur innerhalb eines 256 kB-Bereichs oder innerhalb des gesamten 1 MB-Speichers der unterste 64 kB-Block adressiert werden soll. Der Zugriff auf den eingestellten Common-Bereich wird durch das high aktive Signal COMLH (U84, 74LS00 Pin 11 auf dem CPU-Board) angezeigt. Dieses Signl wird ebenfalls an das PAL geführt (wie auch D1 von Port FBh. das die Auswirkung von COMLH steuert), Durch D6 von Port FBh erfolgt schlielich die Steuerung ob der G3s-Modus oder der Z180-Modus für die Adressierung des RAMs zuständig ist. Das PAL-Assemblerlisting veranschaulicht alle diese Steuerfunktionen. Damit die Signale/CAS0-/CAS3 anstelle, der bisherigen Signale /CAS0- /CAS3 an die RAMs gelangen, ist U43, 74LS125 zu entfernen. Die Signale /CAS0 - /CAS3 des Adapter-Boards werden den RAMs über die Pins 3, 6, 11 und 8 der Fassung von U43 zugeführt. Die an diesen Pins liegenden Pull up-Wider- stände R57-R60 sollten ausgelötet werden. Die Versorgung mit +5V und GND kann von den Pins 14 und 7 derselben Fassung erfolgen. Und schließlich liefert ihr Pin 9 auch noch das Signal /CAS für den Adapter. Alle Signale, die dem Adapter-Board vom CPU-Board zugeführt werden müssen, werden über den Stecker CN2 geführt; ebenso die Signale die das Adapter-Board dem CPU-Board liefert. Nur die ursrünglichen Z80-Pin-Signale laufen über den Sockel des Z80. Der Einsatz eines Z180 bringt aber auch neue Probleme mit sich. Beim Z8O wird der Sysemtakt extern erzeugt und der CPU über Pin 6 eingespeist. Beim HD64180 und beim Z180 wird der Systemtakt, von der CPU geliefert. Dieser Takt wird intern aus einem von außen zugeführten, doppelt so hohen Takt hergeleitet. Der G3s hat die Möglichkeit (leider auch die Notwendigkeit), zwischen einer hohen Frequenz und den normalen 1,77 MHz des TRS-80 umzuschalten. Diese Umschaltung muß bereits mit dem doppelten Muttertakt erfolgen. Es muß also zwischen 18.332 und 3,55 MHz umgeschaltet werden. Dadurch kann die CPU nicht mehr mit einem normalen Quarz, an den Pins XT und EXT beschaltet werden. Es müssen externe Oszillatorshaltungen benutzt werden. Der jeweils selektierte Takt wird über einen Treiber (74LS125) an den Pin EXT der CPU geschaltet. Die Auswahl des jeweiligen Taktes wird durch die Signale LO (U41, 74LS74, Pin 9) und HI (U41, 74LS74 Pin 8) auf dem CPU-Board gesteuert. Die bisherige Taktquelle im System wird durch Entfernen von U44, 74LS161 abgeschaltet. Damit der nun von der CPU gelieferte Systemtakt auch auf dem CPU-Board verfügbar wird, müssen die Pins 5 und 6 von U39, 74LS125 aus der Fassung gebogen werden und die Pins 5 und 6 der Fassung miteinander verbunden werden. Die Widerstände R51, R52 und R79 sollten entfernt werden. Die für das ursprüngliche 256 kB-Banking des G3s verantwortlichen Bits 6 und 7 des Ports F9h (hier als Signale F96 und F97 bezeichnet) sind von den Pins 14 und 13 von U88, 73LS139 zu beziehen. Die vom Port FBh auf dem Adapter-Board zur Vervierfachung von Video- RAM, Zeichensatz-RAM und HRG-RAM gelieferten Bits 2-5 (FB2-FB5) werden in dieser Reihenfolge an folgende IC-Pins der Hauptplatine geführt: U13', 73LS157, Pin 6 U13', 74LS177, Pin 3 BIG5 und BIG6, 6264, Pins 23 (diese Pins aus der Fassung biegen) BTG5 und BIG6, 6264, Pins 2 (diese Pins sind bereits außerhalb der Fasung) U13' ist ein mit den Pins 1, 8, 15 und 16 huckepack auf U13, 74LS157 gelötetes IC 74LS157. Die weitere Beschaltung dieses ICs gibt folgende Abbilung wieder: Abb. 1: U15' ist ebenfalls ein auf U15, 74LS157 mit den Pins 1, 8, 15 und 16 huckepack gelötetes weiteres IC 74S157. Die Pins 15 und 16 von BIG1, 6845 sind aus der Fassung zu biegen und mit U13' zu verdrahten. Schließlich sind noch die Adressen A16 und A17 von CN2 den RAMs gemultiplext zuzuführen. Das Multiplxen bsorgt ein auf U34, 74S157 wiederum mit den Pins 1, 8, 15 und 16 huckepack gelöteter 74S157 (U34'), der an den Pins 13 und 14 mit A16 und A17 zu versorgen ist. Der Multiplex-Ausgang Pin 12 wird über 33 Ω mit den Pins 1 aller RAMs (32x 41236) verbunden. Zur Vereinfachung des bis hierhin Gesagten sei das alles noch einmal in einer Tabelle wiedergegeben: Verbindunen von CN2 zum CPU-Board Stecker CN2 CPU-Board Pin Signal IC Typ Pin ------------------------------------------------------------- 1 +5V U43 LS125 14 * # huckepack gelötete 2 GMD U43 LS125 7 * ICs 74LS(S)157 3 /HI U41 LS74 8 (s. Text und Abil- 4 /LO U41 LS74 9 dungen 5 FB3 U13' LS157 3 # 6 FB2 U13' LS157 6 # 7 FB5 BIG5/BIG6 6264 7 8 FB4 BIG5/BIG6 6264 23 (aus der Fassung biegen) 9 F96 U88 LS139 14 10 F97 U88 LS139 13 * U43 entfernen und 11 /CASO U43 LS125 3 * Sockel auslöten, 12 COMLH U88 LS139 15 Signale von CN2 an 13 /CAS2 U43 LS125 11 * die Lötpunkte der 14 /CAS3 U43 LS125 8 * entsprechenden Pins 15 /CAS U43 LS159 9 ' des Sockels von U43 16 /CAS1 U43 LS125 6 ' anlöten 17 A16 U33' S157 13 # 18 A17 U34' S157 13 # Außerdem sind auf dem CPU-Board noch folgende (z. T. beim Einbau des 4xG3s-Z80-Adapters schon durchgeführten) Änderungen nötig: Die aus den Fassugnen gbogenen Pins 27 von BIG5 und BIG6 und U16' (alle, 74S157) sind mit Pin 5 von U57, 74S04 zu verbinden. Die Pins 27 von BIG5 und BIG6 (6264), die beide außerhalb der Fassung hängen, werden mit Pin 1 von U54, 74LS32 verbunden. Pin 27 von BIG4, 6264 wird mit Pin 3 von U54, 74LS32 verlötet. Abb. 2:Pinout des Z180 und seines Sockels Abb. 3: Auszüge aus der Schaltung Die Listings der beiden PALs PAL16L8 10.03.90 H. Bernhardt Portdecodierung im GIIIs mit Z180 für zusätzl. Systemports A0 A1 A2 A3 A4 A5 A6 A7 WR GND RD OUTFB OUTFC OUTF3 IODC INF3 INFC IORQ INFB VCC /INFB = /IORQ * /RD * A7 * A6 *A5 * A4 * A3 * /A2 + A1 *A0 /OUTFB = /IORQ * /WR * A7 * A6 *A5 * A4 * A3 * /A2 + A1 *A0 /INFC = /IORQ * /RD * A7 * A6 *A5 * A4 * A3 * A2 + /A1 *A0 /OUTFC = /IORQ * /WR * A7 * A6 *A5 * A4 * A3 * A2 + /A1 *A0 /INF3 = /IORQ * /RD * A7 * A6 *A5 * A4 * /A3 * /A2 + A1 *A0 /OUTF3 = /IORQ * /WR * A7 * A6 *A5 * A4 * /A3 * /A2 + A1 *A0 /IODC = /IORQ * * A7 * A6 *A5 * A4 * A3 * /A2 PAL16L8 10.03.90 H. Bernhardt RAM-Steuerung im GIIIs mit Z180 ZA16 ZA17 FB0 FB1 COMLH F96 F97 FB6 FB7 GND CAS A17 CAS1 CAS2 CAS3 CAS0 ZA18 ZA19 A16 VCC /ZA16 = /FB6 * /F96 + /FB6 * COMLH + FB& * ZA16 /ZA17 = /FB6 * /F97 + /FB6 * COMLH + FB6 * /ZA17 /CAS0 = /FB6 * /CAS * /FB1 * /FB0 + /FB6 * /CAS * COMLH * /FB7 + FB6 * /CAS * ZA19 * /ZA18 /CAS1 = /FB6 * /CAS * /FB1 * FB0 * /COMLH + /FB6 * /CAS * /FB1 * FB0 * FB7 + FB6 * /CAS * /ZA19 * ZA18 /CAS2 = /FB6 * /CAS * FB1 * /FB0 * /COMLH + /FB6 * /CAS * FB1 * /FB0 * FB7 + FB6 * /CAS * ZA19 * /ZA18 /CAS3 = /FB6 * /CAS * FB1 * FB0 * /COMLH + /FB6 * /CAS * FB1 * FB0 * FB7 + FB& * /CAS * ZA19 * ZA18 Abb. 4: Layout (lötseitig gesehen) Abb. 5: Bestückungsplan Abb. 6: aufgebautes, angeschlossenes Board Die Sorftware Der Z180 verleitet mit seiner interessnten MMU (Memory Management Unit) und seinem DMAC (Direct Memary Access Controller) geradezu zu Spielereien. Der Leser sei versichert daß wir ihnen auch ausgiebig frnten. So ist es z. B. kein Problem, den Bildschirm oder irgendeinen anderen physikalichen Speicherabschnitt logisch gleich dreimal an verschiedenen Adressen im 64 kB-Fenster der CPU vorliegen zu haben. Hier soll aber ganz bierernst nur vorgestellt werden, was an Änderngen im DOS und Unterstützungen für das DOS prgrammiert wurde, um die Vorteile der neuen CPU nutzen zu können. Zum Verständnis dessen, was sich nun eigentlich zum Besseren ändert, möchten wir außer den im Hardware-Teil schon genannten Veröffentlichungen noch auf ein Sonderheft des Club-80 (3) und einen Info-Artikel (4) hinweisen, die zum Thema HD64180 erschienen sind. Diese CPU ist softwaremäßig identisch mit dem Z180. Eine erneute Beschreibung der im wesentlichen gleichen Eigenschaften erübrigt sich an dieser Stelle. Es sind vier Programme, die für den Z180 geändert bzw. neu erstellt wurden: Patches in zwei verschiedenen Teilen von SYS0/SYS konfigurieren den Z180, um seine Arbeitsgeschwindigkeit und seine MMU auf optimale Werte einzustellen und um seinen DMAC dem System verfügbar zu machen. SYS26/SYS ist zuständig, um die SYS-Files des DOS in Bank 0 des Speichers zu puffern. Es wird nun nur noch angesprungen, wenn nicht der Rechtspeil gedrückt wurde (was bedeuten würde, daß das DOS nicht gepuffert werden soll). In SYS26 steht nun der DMA-Treiber aus dem neuen SYS0 bereits zur Verfügung, was alle Blockladevorgänge beschleunigt. Die Pufferung der DOS-Moduln benötigt jetzt nicht mehr das aufwendige Banking, das bisher erforderlich war, denn der DMAC kann von überall her den vollen Adneßbereich des Z180 überstreichen. Eine Änderung in der SYS-Laderoutine, für den DOS-Kern ebenfalls in SYS66 untergebracht, lädt nun die SYS-Programme bei einem DOS-Request mit RST 28h per DMA entsprechend schneller und weniger speicheraufwendig. Daß im Zuge dessen viel Platz in SYS26 frei wurde, der edleren Zwecken zur Verfügung gestellt werden kann, sei nebenbei erwähnt. Zudem ist der besondere Sektorpuffer 3A00h-3AFFh für die SYS-Moduln jetzt nicht mehr notwendig - freier Speicher für andere Anwendungen. Dann entstand ein Anwenderfile (bei uns TRAP/CMD geheißen), das hauptsächlich Gerald Schröders Illegal-Trap-Programm in Bank 0 und Bank 1 an die, logische Adresse 0000h patcht. Hier springt der Z180 nämlich hin, wenn er einen Befehl antrifft, den er nicht kennt (für nähere Erleuterungen möchten wir auf Geralds Artikel im Info Nr. 17 verweisen). Außerdem wird hier die Delay-Routine an 0060h verlangsamt, denn der Z180 arbeitet zu schnell, um mit dem alten Verzögerungsprogramm noch die korrekten Wartezeiten zu erzielen. Und schließlich zimmerten wir ein Utility-Programm namens SYSTEST/CMD für den DOS-Tüftler (Listing 5). Wenn ein SYS-File, umgeschrieben wurde und nach Murphy's Gesetz noch Fehler enthalten muß, kann es zunächst in der Bank 0 gepuffert und (notfalls bei offenem Floppy-Türchen) von dort aus getestet werden. Damit erübrigt sich gleichzeitig die Notendikeit, vor dem Test erneut zu booten, um die Datei in die Bank 0 zu kriegen, von wo sie beim gebankten DOS aufgerufen wird. Alle Änderngen in SYS0 und SYS26 sowie die neuen Files TRAP/CMD und SYSTEST/CMD sind in den Listings wiedergegeben. Weitere Teile, die sich in den beiden SYS-Programmen nicht geändert haben, sind mit LIST OFF ausgespart worden, um den Rahmen dieses Sonderhefts nicht zu sprengen. Dasselbe gilt für TRAP/CMD, soweit es Geralds bereits bekanntes Trap-Programm betrifft. Damit hat der Leser natürlich die Schwierigkeit, daß unklar bleibt, wo die Patches in den Files liegen sollen, und was sich in der Folge sonst noch ändert. Sorry - da können wir nur anbieten, eine Systemdiskette bei Arnulf anzufordern. Die Listings sollen lediglich den Umgang mit den neuen Möglichkeiten des Z180 demonstrieren und die sich ergebenden Voreile besingen. Es werden auch kleinere Teile der Listings unverständlich bleiben, weil sie sich auf nicht gelistete Programmabschnitte beziehen. Es handelt sich nämlich nicht um besondere Schöpfungen für dieses Sonderinfo, sondern um die Sources für das geänderte DOS. Wenn etwa Labels auftauchen, die sonst nirgends wiederzufinden sind, einfach darüber hinweglesen! Die genannten Programme sind auch noch längst nicht der Weisheit letzter Schluß. So ist es beispielsweise wünschenswert, einige Konfigurationen des Z180 (WAIT-Zyklen, Refreshes, MMU, vielleicht noch mehr) bereits im Boot-EPROM erledigen zu lassen. So weit sind wir jedoch selbst noch nicht. Gegf. wird man in einem kommenden Clubinfo Weieres dazu vorfinden. Soweit Befehle enthalten sind, die zwar der Z180, nicht aber der Z80 kennt, sind sie mit ihren Hex-Entsprechungen als DB-(DEFB-)Statememts eingefügt. ZEUS kennt sie nämlich bedauerlicherweise auch nicht. In einem Kommentar erscheint dann jeweils der Befehl in Z180-Assembler. Die Programme sind essentiell für das Betriebssystem. Ohne Betriebssystem kein Computer. Daher wird unbedingt empfohlen, alles zunächst mit einer Kopie der Systemdiskette auszuprobieren (für SYS29 kann aber auch SYSTEST gefahren werden!). Erst, wenn sich die Kopie als funktionstüchtig erwiesen hat, hat die alte Systemdisk asgedient! Nun zu den Programmen im einzelnen: SYS0/SYS ist die Seele des G3s. Es ist in seinem ersten Teil eine Fortsetung von DOS/SYS. Hier ist die erste Modifikation für den Z180 untergebracht: Die Anzahl der WAIT-Zyklen für Speicher- und Portzugriffe wird eingestellt, und zwar auf den schnellstmöglichen Wert. Solle er sich im Einzelfall als Überforderung des Systems herausstellen, kann der Wert 00h für den Akku mit DDE auf einen anderen Betrag gepatcht werden (XOR A hätte den Akku ebenfalls gelöscht, jedoch ohne die MöglichXeit einer einfachen Änderung). Danach wird die MMU des Z180 auf den Normalzustand des G3s eingerichtet. So kann, etwa für einen DMA (s. u.), die Z180 Speicherkonfiguration in aller Regel geschaltet werden, ohne daß sich etwas am Banking-Zustand ändert. Die zusätzlichen Befehle (s. Listing 1) werden einfach in die (zuvor per Disassembly gewonnene) Source eingefügt, das Programm neu assembliert. Es besteht aus zwei Sektoren, die in die ersten beiden Sektoren von SYS0/SYS gepatcht werden (das kann z. B. SUPERZAP). Das Listing 2 zeigt ebenfalls einen Patch in SYS0. Anfangs wird getestet, ob der Rechtspfeil während des Bootens gedrückt wurde. Ist das nicht der Fall, möchte der User das DOS in Bank 0 des Computers puffern, um es später ohne die Laufwerke verfügbar zu haben. Dieser Test war bisher in SYS26 untergebracht. Es erschien uns überflüsig, SYS26 anzuspringen, wenn es bei gedrücktem Rechtspfeil ohnehin gleich wieder verlassen wird. Dann enthält das Listing einen Treiber für den DMAC des Z180. Er erwartet beim Einsprung in HL die Anfangsadresse des zu transferierenden Blocks, in DE die Zieladresse, in BC den Bytezähler. Bis hierher entspricht der Treiber dem Z80-Befehl LDIR. Neu ist der Inhalt des Akkus, der in seinen beiden Nibbles die Adressen A16-19 des Quell- und des Zielbereichs enthält. So kann ein DMA auf das volle Megabyte des Z180-Adressraums zugreifen. Die internen DMAC-Register SAROB (Kanal 0, Quelle, Bits 16-19) und DAROB (Kanal 0, Ziel, Bits 16-19) werden nur in ihren unteren 4 Bits beachtet. So war es zur Laufzeit- und Platzersparnis möglich, auf das Löschen der oberen 4 Bits zu verzichten: Der Befehl RRD (Zeile 94) rotiert die hier relevanten Bits 3-7 ins untere Nibble von DAROB, der folgende Befehl LD (scrphys),A packt einfach den kompletten Akku mit seinem unwichig gewordenen oberen Nibble nach SAROB. In Zeile, 102 wird die G3s-MMU deaktiviert, indem in Port FBh das Bit 6 gesetzt wird (s. Hardware-Teil). Nur so kann der DMA-Treiber über das ganze Megabte verfügen. Ansonsten könnte nur das 64 kB-Fenster, das gerade vom G3s bearbeitet wurde, vom DMAC überstrichen werden. Also ist beim Einsprung in die DMA-Routine unbedingt darauf zu achten, daß die MMU-Konfiguration des Z180 mit der des G3s zumindest in wichtigen Speicherabschnitten übereinstimmt: Der Treiber muß sich nach dem Umschalten selber wiederfinden können, der Stack muß ebenfalls an derselben logischen Adresse vorliegen. Erst nach dem Rückschaltbefehl (Zeile 111) ist Entwarnung gegeben. Bei der Rückkehr aus dem Programm enthalten alle Register ihren alten Wert, der gerettet wurde. Im Gegensatz dazu gibt der Befehl LDIR die Quell- und Zielregister um den Betrag des Bytezählers erhöht zurück. BC selbst ist dann 0000h. Dieser Service hätte mit in den Treiber eingebaut werden können, der verfügbare Platz reichte jedoch nicht. Zudem haben beide Möglichkeiten ihre Vor- und Nachteile. An dieser Portion von SYS0 ist nur der filerelative Sektor 10h interessant. Das ist der diskreltive Sektor 15h. Die Source gem. Listing 2 wird assembliert. Von der so entstandenen CMD-Datei muß nun (mit SUPERZAP oder wie auch immer) der erste Sektor nach SYS0 kopiert werden, und zwar in den eben bezeichneten Sektor. Wichtig ist, daß dieser Sektor des CMD-Programms genau am relativen Byte FFh aufhört, also ganz unten rechts. Danach, im nächsten Sektor, folgt der Rest, der mit einem neuen Record-Header beginnt. Bis dorthin können NOPs bzw. DW 0000h- oder DB 00h-Statements eingefügt werden. Um das Puzzle u erleichtern, folgt hier ein Sektor-Dump der den relativen Sektor 10h von SYS0 wiedergibt: file: SYS0/SYS drv: 0 frs: 0010h drs: O015h 00: 01(C 0032 3E40 D3F9 FBC1 D1E1 C9E5 D5C5 2 >@ 10: 3E01 F3D3 F9C3 0AF0 3A07 43F6 3032 8232 > : C 02 2 20: E60F FE04 2o11 3AF8 42CB 5F28 0A3A 4038 : B ( :@8 30: E640 3EFC CC02 4421 7F32 1180 4401 0B00 @> D! 2 D 40: EDB0 1180 4421 0042 CD24 4428 0BFE 1820 D! B $D( 50: 2B3E 0132 0743 180E EBCD 284C 201E 1162 +> 2 C (L b 60: 32D5 1198 31E9 2100 3011 AD4E 0100 023E 2 1 ! 0 N > 70: 10CD BD35 E1F1 32F9 42C3 6744 F5CD C901 5 2 8 gD 80: 3E46 EF4F 564c 782F 5359 533A 300D 0170 >F OVLx/SYS:0 p 90: BB35 22F0 35ED 53F3 35ED 43F6 35E5 21F5 5" 5 s 5 C 5 # A0: 3577 ED67 32F2 3521 F735 C501 2708 F5D8 5w g2 5! 5 B0: FBF5 F640 F3D3 FBED 9B01 3102 ED9B F1D3 @ 1 C0: FBF1 C1E1 C940 0200 0000 0000 0000 0000 @ D0: 0000 0000 0000 0000 0000 0000 0000 0000 E0: 0000 0000 0000 0000 0000 0000 0000 0000 F0: 0000 0000 0000 0000 0000 0000 0000 0000 Es ist ausreichend, das im Hex- und im ASCII-Teil unterstrichene Zählbyte des Record-Headers (rel. Sektorbyte 8Fh) genau so zu zappen un den Rest auszunullen. Dann dürfte nichts mehr schiefgehen. Voraussetzung ist, daß das Zählbyte auch an dieser Stelle steht. Ansonsten muß es eben auf andere Weise angepaßt werden, damit das letze Datenbyte des Sektors an der sektorrelativn Stelle FFh zu liegen kommt. Listing 3 behandelt ein paar Änderungen in SYS26. Dort wird, wie schon erwähnt, das Puffern des DOS im Speicher veranlaßt. Gleichzeitig wird der DOS-Kern gepatcht: Soll ein SYS-File mit RST 28h geladen werden, wird nicht mehr die Floppy angeworfen. Statt dessen wird das Programm aus der Bank 0 geholt. Dafür dient ein besonderes Minimal-DIR: Pro SYS-Modul enthält es zwei Bytes. Das erste ist das MSB der Pufferadresse in Bank 0. Da das LSB immer 00h ist, da also jedes SYS-File am Anfang eines 256Byte-Blocks beginnt, genügt das MSB. Das zweite Byte gibt die Länge des Files in Sektoren an. Gepuffert werden nur die Programme SYS1-19. GDOS/SYS, IHHALT/SYS und SYS0/SYS haben hier keine Bedeutung und bleiben deshalb auf der Floppy. Ihr Platz im Mini-DIR ist mit Nonsene (GDOS) bzw. mit Nullen (INHALT und SYS0) gefüllt. Eine spezielle Laderotine für SYS-Programme liest dieses DIR und transferiert dann die Sektoren ursprünglich nach 3A00h, einen besonderen Sektorpuffer. Von dort wird das File sektorweise in den Overlay-Speicher des DOS geladen und schließlich angesprungen. Hier die Änderungen die die Vorteile des Z180 ausnutzen: Der DMAC benötigt kein Banking, um Daten zu trasnsportieren. Die Unterprogramme, die das DOS in den Speicher laden und es später beim Betrieb von dort wieder abholen, konnten deshalb wesentlich verkürzt (und damit beschleunigt) werden. Das UP putsys puffert die SYS-Files. Dazu wird zunächst der Teil von INHALT/SYS ab 5200h in den Speicher geladen, der SYS-Programme enthält. Der Platzbedarf von 0800h Bytes zerstört dabei nach Reset den Inhalt des Anwenderspeichers. Daher wird (ab Label boot) zunächst dieser Bereich in die Bank 1 gerettet um später restauriert zu werden. Dann wird das besondere SYS-DIR im Block 3900h eingerichtet. Die ersten Bytes des Blocks müssen ausgenullt werden, damit bei einem DOS-Request nicht versucht wird, INHALT oder SYS0 aus der Bank 0 zu holen; die Nullen sind Signalbytes für das Verbot. Anschließend wird ab 4100h in Bank 0 das restliche DOS abgelegt. Mit der Restauration des Anwenderspeichers und dem Transfer des SYS-DIR an seine endgültige Adresse 4000h in Bank 0 endet dieser Teil von SYS26. Der Patch im DOS-Kern, der SYS-Dateien aus der Bank 0 holt, ist anschließend gelistet. Der verfügbare Speicherlatz im residenten Teil von SYS0 (ab 3BE1h) reicht dazu nicht aus. Ein notwendige Unterprogramm macht deshalb an der Stelle 3738h weiter (was auch bisher schon so war). Dieses UP kann nun per DMA auf aufwendiges Banking verzichten, das zuvor nötig war. Immerhin 13 Bytes wurden frei die Arbeitsgeschwindigkeit stieg enorm. Das nächste Programm, das mit Listing 4 hier vorgestelt werden soll, ist in dieser Form ein reines Anwender-File. Wegen seiner Wichtigkeit erscheint es sinnvoll, es später einer SYS-Datei einzuverleiben, vielleicht gleich SYS26. Es nimmt ein paar Patches im BASIC-Interpreter vor, die dem Z180 gerecht werden. Seine Arbeitsgeschwindigkeit ist deutlich höher als die des Z80, weil viele Befehle weniger Taktzyklen beanspruchen. Dadurch beschleunigt sich die Delay-Routine an 0060h bedenklich. Wartezeiten, die dort z.B. für den Floppy-Controller abgetrödelt werden, sind nun zu kurz. Eine geringfügige Änderung schafft Abhilfe, so daß die Verzögerungen fast genau mit der alten Zeiten identisch werden: In der alten Version wird mit einem JR NZ-Befehl in die Schleife zurückverzeigt, wenn der Zähler BC noch nicht abgelaufen ist. Die neue Variante durchläuft zuerst den Befehl RET Z, und zwar jedesmal. Hat der Zähler noch etwas Stoff, geht es mit bedinungslosem JR zurück in die Schleife. Der zusätzliche Return-Befehl, der bei jedem Schleifendurchlauf gelesen werden muß, kostet die erwünschten Taktzyklen zur Verlangsamung. Dies alles trifft freilich nur bei der langsameren Takt Fequenz von 1,77 MHz zu, die über Port FAh, Bit 6 gewählt werden kann. Alle kritischen Verzögerungsschleilen des DOS werden jedoch, soweit uns bekannt, erst nach dieser Taktumschaltung durchlaufen. Wo nicht, ist die verkürzte Laufzeit durch den High-Speed-Takt des Z180-Boards immerhin noch erträglich zu schnell. Direkt an die Delay-Schleife schließt sich der NMI-Service an. Der TRS-80 benutzt ihn als Reset-Ersatz. Beim G3s ist der NMI unbenutzt (hard- warermäßig übrigens auch nicht zugänlich - die freien Tasten links oben und unten in der Haupttastatur können mit dem NMI-Pin der CPU verdrahtet werden). Unsere Serice-Rouine läßt einfach nur die Interrupts wieder zu. Damit können z. B. die Dreitastenbefehle aktiviert werden, wenn man etwa jederzeit mit dem Debugger den Speicher und die Reister im Auge haben möchte. Hauptbestandteil dieses Programms ist jedoch Gerald Schröders Error-Trap-Routine. Dorthin verzweigt der Z180, wenn ein ihm unbekannter Opcode angetroffen wird. Auch hier möchten wir wieder auf schon erschienene Erklärungen verweisen, um Wiederholungen zu vermeiden (Info Nr. 17). Beim Einsprung am Label start wird der Beginn der Trap-Routine, nämlich ein Sprung nach 1650h. nach 0000h ff. gezapt. Vor dem eigentlichen JP findet sich ein NOP. Hier kann der User bei einem Trap-Interrupt auch etwas anderes als diesen Sprung veranlassen. Mit F7h (RST 30h) an dieser Stelle wird z. B. in den Debuger gesprungen. Besonders in der Experimentierphase, wenn der Z180 noch neu ist, wird man das gelegentlich wollen. Bei 1650h sind die BASIC-Befehle im Klartext abgelegt. Das Trap-Programm überschreibt sie. Wer gerne in BASIC arbeitet, kann so natürlich nicht verfahren. Eine andere Adresse muß her. In einem kommenden Info wird die Lösung des Problems zu lesen sein. In Bank 1 soll ebenfalls Geralds Trap-Programm verfügbar sein. Dort ist ab 0000h Platz dafür, ein JP erübrigt sich. Diese neue Ladeadresse erfordert die Relokation aller festen Adressen im Trap-Pogramm. Das beginnt mit Zeile 188 im Listing. Der Vorgang ist etwas verzwickt. Wir möchten aber darauf verzichten, ihn über die Kommentare im Listing hinaus zu erleutern. Dies kann kein Lehrbuch über Z80-Assembler sein). Alle kritischen Adressen wurden mit einem Label versehen, addr1-addr15. addr1 ist im Listing sichtbar, die übrigen nicht. Diese Labels finden sich in der Tabelle addrtab wieder. Nur ein Detail soll beleuchtet werden. Weil der Leser u. U. nicht gleich RAMDISK (s. u.) über JP 4405h abfahren möchte: Beim Sprung nach 4405h wird über den Requestcode 63h nach SYS1 verzweigt. Mit, diesem code im Akku (ACHTUNG: mit etlichen anderen nicht!) wird als erstes der Stack neu eingerichtet, weil dabei eine Rückkehr zum Aufrufer nicht stattfinden soll. Für den CALL dma und die PUSHes und POPs im DMA-Treiber genügt ein vorübergehender Stack an beliebiger Stelle. Er wird hier (zeile 199,) kurz und schnell unter die Trap-Routine gelegt. Bei einem anderen Aussprung aus TRAP/CMD, ganz besonders mit RET, muß zuvor der Original-Stack unbedingt gerettet und nachher restauriert werden. Das geht mit dem Strickmuster nach dem auch die Zeilen 192 und 189/190 (in dieser Reihenfolge!) funkionieren. Das hätten wir unter Dreingabe von ein paar Bytes und Mikrosekunden natürlich auch hier so machen können, aber dieser schlitzohrigere Weg war halt gar zu verlockend. Nachdem nun die Trap-Routine auch nach Bank 1 tranferiert ist, wird zuletzt die RAM-Disk des G3s aktiviert. Dieser Programmbestandteil wäre verzichbar. Da wir aber immer mit der RAM-Disk arbeiten, kann das getrost gleich mit erledigt weren. Wenn nein: Unbedingt die Aussprungs-Bedingungen beachten (Stack, s. o.). Übrigens ist der ursprüngliche Name des Proramms MEMDISK/CMD. Hier handelt es sich um eine geänderte Version. SYSTEST transferiert ein CMD-Programm, das als SYS-File des DOS dienen soll, in die Bank 0, von wo die SYS-Dateien mit RST 28h aufgerufen werden. Prinzipiell geht das mit jeder Datei, in der Regel wird es sich jedoch um neue Versionen eines echten DOS-Moduls handeln. Es beginnt gem. Listing 5 mit der Prüfung, ob das DOS überhaupt schon in Bank 0 gepuffert ist. Das ist die Voraussetzung, weil sonst die neue Datei nicht mit RST 28h erreichbar wäre. Sollte das noch nicht geschehen sein, wird SYS26 (s. d.) mit FCh im Akku zuerst aufgerufen, um das DOS zu banken. Zum Test dient ein Lückenfüller-NOP, das bei der geänderten SYS-Laderoutine an der Stelle 4C0Bh stehen muß. Das eigentliche Arbeitsprogrogramm klärt nun zunächst, was für ein CMD-File in we1ches SYS-Programm kopiert werden soll. Diese Angaben können jedoch schon beim Aufruf gemacht werden, denn die Befehlssyntax ist SYSTEST<,FILSPEC<,SYSNR>>. Wenn der zweite oder beide Befehlsparameter weggelassen werden, wird nach ihnen gefragt. Dabei wird FILESPEC in der üblichen Weise. z. B. auch mit Laufwerksnummer, eingegeben. SYSNR ist nur eine Dezimzahl für SYSx/SYS. In der Bank 0 befinden sich nur die Files SYS1-29. Das Programm prüft daher auch, ob mit SYSNR eine zulässige Datei benannt wurde. Außerdem darf die Testdatei höchstens so lang sein wie die Zieldatei in Bank 0. Sonst würde das dahinter liegende SYS-File übesschrieben werden. In diesem Falle, wie überhaupt bei jedem denkbaren Fehler, bricht das Pragramm mit einer DOS-Fehlermeldung ab. Dies geschieht mit einem Sprung nach DOSERR (4409h), wo der Stack neu eingerichtet wird. Daher durfte getrost ignoriert werden, ob gerade ein PUSH oder CALL den Stack verbogen hat. Auch hier sollen allzu weitschweifige Erklärungen des Programms vermieden werden. Die Kommentare mögen genügen. Für die ausgiebigen Aufrufe etlicher DOS-Routinen möchten wir auf Grossers "DOS-Buch" (5) verweisen, ohne das wir es übrigens wohl auch nicht geschafft hätten. Es sei nur darauf hingewiesen, daß wieder der DMA benutzt werden konnte, und daß ein komfortabler Befehl des Z180. MLT ww (3), das Umrechnen einer Dezimal- in eine Binärzahl erleichterte (zeile 31/32). In der kommenden Zeit, liegt eine interessante Aufgabe in der weiteren Umgestaltung des Systems auf den Z180 hin. Wir würden uns freuen, wenn auch die Nachbauer des Z180-Boards gelegentlich mit Software im Club-Info vertreten wären. Vorschlag: Auch und gerade die RAM-Disk kann von der neuen CPU profitieren. Literatur: (1) Bernhardt, Sopp, Sonder-Info "Dein GIIIs, die 4 unbekannten Wesen", Michelbach,/Bilz 1986 (2) Bernhardt, "512k-RAM-Addressierung mit flexibler MMU", Club-Info 18, Michelbach/Bilz 1987 (3) Bernhardt, Schröder Sonder-Info "HD64180". Gschlachtenbretzingen 1989 (4) Schröder, "Z80, HD6418 und Illegals", Club-Info 17, Michelbach/Bilz 1987 (5) Grosser, "Das DOS-Buch", Aachen 1985 00001 ;Listing 1: Patch in SYS0/SYS, rel. Sektor 00h: 00002 ;SYS0/SYS konfiguriert den Z180 für G-DOS 00003 ;FRS 006 (hier nicht interessierende Teile sind mit LIST OFF 00004 ;DRS 05h ausgespart - erkennbar an den springenden Zeilennummern) 00035 4010 3E00 00036 m4d10 LD A,00h ;A <- 00: Memory: 0 WAITs, I/O: 1 WAIT 4012 ED 00037 DB 0edh,39h,32h ;OUT0(32h),A 4015 3E83 00038 LD A,83h ;RFSH alle 80 Zyklen 2 Zyklen lang 4017 ED 00039 DB 0edh,39h,36h ;OUT0(36h),A 4D1A 21624E 00040 LD HL,mmutab ;Tabelle der MMU-Werte 4010 013803 00041 LD BC,endtab-mmutab'256+38h ;3 Werte ab Port 38 4020 ED 00042 DB 0edh,93h ;001110 (Werte ausgeben) 00208 00209 ;Tabelle zum Einrichten der MMU des 2180 4E62 10 00210 mmutab DB 10h ;Common 1 ab 1.1000 4E63 10 00211 DB 10h ;Bank-Area ab 1.4000 4E64 E4 00212 DB 0e4h ;hierfür die logischen Adressen 00213 endtab 00000 Fehler 00001 ;Listing 2: Patch in SYS0/SYS im relativen Sektor 10h: 00002 ;SYS0/SYS stellt einen DMA-Treiber zur Verfügung 00003 ;FRS 10h (unteressierende Teile sind mit LIST OFF 00004 ;DRS 15h ausgespart - erkennbar an springenden Zeilennummern) 00005 00037 ;Test auf Rechtspfeil: DOS banken oder nicht? (früher in SYS26/SYS) 3229 3A4038 00038 LD A,(m3840) ;Tastatur Steuerzeichen 322C E640 00039 AND 40h ;Rechtspfeil gedrückt? (nein: DOS banken) 322E 3EFC 00040 LD A,0fch ;Requestcode für SYS26/SYS 3230 CCO244 00041 CALL Zm4402 ;mit OST 28h SYS26 aufrufen (DOS banken) 3233 217F32 00042 m322c LD HL,m3275 ;Filename 'OVL4/SYS' 00081 00082 ;Unterprogr. für DMA: HL = LSW Quelle, DE = LSW Ziel, BC = Bytezähler, 00083 ;A Bit 0-3 = MSB der Quelle, A Bit 4-7 . MSB des Ziels 00084 ;(858 . most significant byte, A16-19, obere 4 Bits der Adresse, 00085 ; LSW . less word, A0-15, untere 16 ' ) 00086 3588 00087 ORG 35bbh 3588 22E035 00088 dma LD (srclog),HL ;Quellbereich log. LSW x.HL 35BE ED53F335 00089 LD (dstlog),DE ;Zielbereich log. LSW x.DE 35C2 E043F635 00090 LD (bytcnt),BC ;Bytezähler 0.BC 35C6 E5 00091 PUSH HL 35C7 210535 00092 LD HL,dstphys ;Zielbereich Phys. MSB Ah.DE 35CA 77 00093 LD (HL),A ;MSB setzen (016-19: Bit 4-7) 35C8 ED67 00094 RRD ;Nibbles rotieren (A16-19: Bit 0-3) 35CD 32F235 00095 LD (srcphys),A ;Quellbereich phys. MSB Al.HL 3500 21F735 00096 LD HL,tabend ;Beginn der DMA-Wertetabelle 3503 C5 00097 PUSH 8C 3504 012708 00098 LD BC,0827h ;8 Werte ab Port 27 abwärts 3507 F5 00099 PUSH AF 3508 DBFB 00100 IN A,(0fbh) ;Systembyte 2 35DA F5 00101 PUSH AF ;retten 3508 F640 00102 OR 40h ;MMU des Z180 freigeben 3500 F3 00103 DI 350E D3FB 00104 OUT (Ofbh),A 00105 ; OTDMR ;DMAC aufsetzen 35E0 ED 00106 DB 0edh,9bh ;(Hex-Entsprechung des Befehls) 35E2 013102 00107 LD BC,0231h ;2 Werte ab Port 31 abwärts 00108 ; OTDMR ;Rest aufsetzen u. DMA abschießen 35E5 ED 00109 DB 0edh,9bh 35E7 F1 00110 POP AF ;altes Systembyte 2 35E8 D3FB 00111 OUT (0fbh),A 35EA F1 00112 POP AF 35E8 C1 00113 POP 8C 35EC E1 00114 POP HL 35ED C9 00115 RET 00116 00117 ;Wertetabelle für den DMA-Controller (fallende Reihenfolge für OTDMR) 35EE 40 00118 DB 40h ;30, DSTAT: Kanal 0, Zustand 'scharf' 35EF 02 00119 DB 02h ;31, DMODE: Speicher zu Speicher, Burst-Modus 35F0 0000 00120 srclog DW 0000h ;20/1, SAROL/H: Duelladresse LSW x.#### 35F2 00 00121 srcphys DB 00h ;22, SAR0B: MS8 #.xxxx 35F3 0000 00122 dstlog DW 0000h ;23/4, DAR0L/H: Zieladresse LSW x.#1114 35F5 00 00123 dstphys DB 00h ;25, DAROB: MSB #.xxxx 35F6 0000 00124 bytcnt DW 0000h ;26/7, BCR0L/H: Bytezähler für die Programmlänge 35F7 00125 tabend EQU $-1 ;Ende der Tab., womit der Zeiger HL geladen wird 00000 Fehler 00001 ;Listing 3: Patch in SYS26/SYS: 00002 ;SYS26/SYS neue Routine zum Puffern und Laden von SYS-Files 00003 ;in Bank 0 des User-RAMs 00004 ;(hier nicht interessierende Teile sind mit LIST OFF 00005 ;ausgespart - erkennbar an den springenden Zeilennummern) 00006 35BB 00012 dma EQU 35bbh ;Adresse des DMA-Treibers 00331 00332 ;UP zum Übertragen von SYS-Files in die Bank 0 00333 ; E: HL = Adresse RAM-DIR-Eintrag 00334 ; D = Länge des Files in Sektoren 00335 ; E = Adreß-MSB des Files in der Bank 0 00336 4F1C E5 00337 putsys PUSH HL ;39xx, DIR-Eintrag des akt. SYS-Files 4F1D D5 00338 PUSH DE' ;E . MSB des SYS-Files, D . Länge in Skt. 4F1E C5 00339 PUSH BC 4F1F F5 00340 PUSH AF 4F20 73 00341 LD (HL),E ;MSB der Zieladresse ins SYS-DIR 4F21 23 00342 INC HL ;nächste Stelle 4F22 72 00343 LD (HL),D ;Zählbyte eintragen 4F23 210042 00344 LD HL,m4200 ;Sektorpuffer 4F26 010001 00345 LD BC,0100h ;Länge 1 Skt. 4F29 53 00346 LD D,E ;DE <- Zieladresse (MSB) des Sektors 4F2A 59 00347 LD E,C ;(LSB immer =00) 4F28 3E01 00348 LD A,01h ;von Bank 1 nach Bank 0 4F2D CDB835 00349 CALL dma ;Block übertragen 4F30 F1 00350 POP AF 4F31 C1 00351 POP BC 4F32 D1 00352 POP DE 4F33 E1 00353 POP HL 4F34 FB 00354 EI 4F35 C9 00355 RET 00356 00357 ;Einsprung bei Boot: RAM-Inhalt retten, SYS-Files in der Bank 0 puffern 4F36 210052 00358 boot LD HL,m5200 ;Beginn des zu überschreibenden Bereichs 4F39 110008 00359 LD DE,0800h ;Zwischenpuffer dafür in Bank 1 4F3C 42 00360 LD B,D ;BC <- 0800, zu überschreibender Bereich 4F30 48 00361 LD C,E 4F3E ES 00362 PUSH HL 4F3F D5 00363 PUSH DE 4F40 3E11 00364 LD A,11h ;von Bank 1 nach Bank 1 4F42 CDB835 00365 CALL dma ;RAM-Inhalt retten 4F45 ED739141 00366 LD (m4f10),SP ;alten Stach retten 4F49 CDCB4E 00367 CALL m4f55 ;DIR-Sektoren mit SYS-Entries laden 4F4C 210039 00368 LD HL,m3900 ;vorläufiger SYS-DIR-Puffer 4F4F 110139 00369 LD DE,m3900+1 ;zum Ausnullen vorbereiten 4052 78 00370 LD A,E ;A <- 01, Zähler für 1 Durchgang 4053 32074F 00371 LD (filelen),A ;dort ablegen 4056 0E06 00372 LD C,06h ;Zähler 6 Bytes (f3 = 00 seit m4f55) 4058 75 00373 LD (HL),L ;1. Byte des SYS-DIR-Puffers ausnullen 4059 EDB0 00374 LDIR ;Rest ausnullen (hier schneller als DMA) 409 1E41 00375 LD E,41h ;ab Page 4100 die SYS-Files puffern 4040 El 00407 POP HL ;Adresse des gepufferten RAM-Inhalts 4041 D1 00408 POP DE ;seine frühere Ladeadresse 4042 44 00409 LD B,H ;BC <- 0800h, Blocklänge (C=00 seit LDIR) 4043 3E11 00410 LD 4,11h ;von Bank 1 nach Bank 1 4045 CDBB35 00411 CALL dma ;RAM-Inhalt ab 5200h restaurieren 4048 210039 00412 LD HL,m3900 ;Puffer für SYS-DIR 4FAB 110040 00413 LD DE,m4000 ;endgültige Adresse dafür in Bank 0 4FAE 0601 00414 LD 8,01h ;Länge 256 Bytes (C = 00) 4080 AF 00415 XOR A ;A - 00: Bank 0 -> Bank 0, 'kein Fehler' 4081 C3BB35 00416 JP dma ;Block übertragen und zurück ins DOS 00417 00418 ;Patch im DOS-Kern: Einsprung bei DOS-Request mit RST 28h 0303 00419 offs4 EAU $-4be1h ;Abstand zur Ladeadresse 4084 3E40 00420 m4be1 LD A,34000/256 ;DIR des gebankten DOS (Adreß-MSB) 4066 323037 00421 LD (addrmsb-offs3),A ;in Laderoutine patchen 4F69 CD3837 00422 CALL m3738-offs3 ;in den Sektorpuffer übertragen 408C 2642 00423 LD H,m4200/256 ;Sektorpuffer (MS8) 4FBE 341743 00424 LD 4,(4317h) ;SYS-Kenner 40C1 07 00425 RLCA ;2 (wegen 2 Bytes pro Eintrag) 40C2 6F 00426 LD L,A ;als LSB des Zeigers laden 4FC3 7E 00427 LD A,(HL) ;Adreß-MSB des SYS-Files in Bank 0 4FC4 323037 00428 LD (addrmsb-offs3),A ;in die Laderoutine patchen 4FC7 23 00429 INC HL ;auf Längenbyte stellen 4008 7E 00430 LD A,(HL) ;laden 40C9 87 00431 OR A ;= 00? (dann INHALT/SYS oder SYSO/SYS) 4FCA 2815 00432 JR Z,m4c0e ;Fehler, falls ja (nicht vorhanden) 4FCC 213837 00433 LD HL,m3738-offs3 ;modifizierte Sektor-Laderoutine 4000 22604C 00434 LD (4c6dh),HL ;in SYSO patchen 4002 CD2B4C 00435 CALL 4c2bh ;SYS-File laden 4005 221E4C 00436 LD (4c1eh),HL ;Startadresse des SYS-Files dort patchen 4008 213644 00437 LD HL,4436h ;alte Sektor-Laderoutine 4008 22604C 00438 LD (4c6dh),HL ;restaurieren 4FDE 00 00439 NOP ;Füller bis zur alten Fortsetzung 40E1 00440 m4c0e EQU §+2 00441 00442 ;neue Laderoutine für SYS-Files 18A7 00443 offs3 EQU $-3738h 4FDF E5 00444 m3738 PUSH HL 40E0 D5 00445 PUSH DE 40E1 C5 00446 PUSH BC 4FE2 210000 00447 LD HL,0000h ;Duellblock in Bank 0 40E4 00448 addrmsb EQU $-1 ;MSB wird jeweils gepatcht 40E5 7C 00449 LD A,H ;Adreß-MSB 40E6 3C 00450 INC A ;100h Bytes weiter 4FE7 323037 00451 LD (addrmsb-offs3),A ;MSB für nächsten Block patchen 4FEA 3E10 00452 LD 4,10h ;aus Bank 0 nach Bank 1 4FEC 110042 00453 LD DE,m4200 ;Sektorpuffer 4FEF 010001 00454 LD BC,0100h ;Sektorlänge 4002 CDBB35 00455 CALL dma ;Block übertragen 4005 Cl 00456 POP BC 4006 D1 00457 POP DE 4007 EI 00458 POP HL 4008 AF 00459 XOR A ;Flag 'kein Fehler' 4009 C9 00460 RET 00000 Fehler 00001 ;Listing 4: Einige Änderungen für den Z180 im BASIC-Interpreter 00002 ;TRAP/CMD Hauptsächlich Delay und Illegal-TRAP-Routine 00003 ; (Gerals Schröders TRAP-Routine idt mit LIST-OFF aus- 00004 ; gespart, nachzulesen Club-Info Nr. 17, nur ihr 00005 ; GIIIs-spezifischer Anfang ist gelistet 00006 0000 00007 target1 EQU 0000h ;Zieladresse der Trap-Routine in Bank 1 1650 00008 target0 EQU 1650h ;dto. in Bank 0, vorläufig im BASIC Bereich 35BB 00009 dma EQU 35BB ;Aresse des DMA-Treibers 00010 5200 00011 ORG 5200h 00012 00013 ;Trap-Einsprung für Adresse 9 5200 00 00014 lowmem NOP ;Platz für eventl. F7 (RST 30, Debugger) 5201 C35016 00015 JR target0 ;Einsprung bei Trap-Interrupt 00016 00017 ;Einsprung der Warteschleife und NMI-Routineab Adresse 0060 5204 0B 00018 delay DEC BC ;(alter Teil der Delay-Routine 5205 78 00019 LD A,B ;bleibt unverändert) 5206 B1 00020 OR C 5207 C8 00025 Ret Ẑ ;neu: wird immer bearbeitet (Verrzögerung) 5208 18FA 00022 JR delay ;jetzt Laufzeit etwa wie Z80 00023 520A FB 00024 nmi EI ;NMI: Interrupt zulassen 520B C9 00025 RET 00026 00027 ;Fehlerbehandlung bzw. Illegal-Simulation nach einem Trap-Interrupt 00028 ;vorläufige Version: kein anderer RST 00h außer TRAP berücksichtigt! 388C 00029 offs EQU $-target0 ;Abstand zur Arbeitsadresse 520C F3 00030 trap DI ;Interrupt aus 520D F5 00031 PUSH AF ;Akku und Flags retten 520E DBFA 00032 IN A,(0fah) ;System-Byte 1 5210 32FA16 00033 LD (fsbuff-offs),A ;puffern 5211 00034 addr1 EQU $-2 5213 E6DF 00035 AND 0dfh ;evtl. Schreibschutz aufheben 5215 03FA 00036 OUT (0fah),A ;System-Byte neu ausgeben 00171 52C7 DBFA 00172 start IN A,(0fah) ;System-Byte 1 52C9 E6DF 00173 AND 0dfh ;evtl. Schreibschutz aufheben 52CB F3 00174 DI 52CC D3FA 00175 OUT (0fah),A ;neu ausgeben 52CE 240052 00176 LD HL,(lowmem) ;Code für Adresse 0000h 52D1 00177 LD (0000h),HL ;am Zielort ablegen 52D4 1A0202 00178 LD HL,(lowmem+2) ;Fortsetzung, insgesamt 4 Byte 52D7 220200 00179 LD (0003h),HL 52DA 52DD 00180 LD HL,delay ;neue Verzögerungs-Routine 52DD 116000 00181 LD DE,0060h ;Zieladresse 52E0 010B00 00182 LD BC,trap-delay ;Länge 52E3 EDB0 00183 LDIR ;(wenige Bytes) LDIR schneller als DMA 52E5 115016 00184 LD DE,target0 ;Zieladresse (HL bereits auf Quelle trap) 52E8 018800 00185 LD BC,atart-trap ;Länge 52EB 3E01 00186 LD A,01h ;von Bank1 nach Bank0 52ED CDBB35 00187 CAll dma ;Block übertragen (schneller als LDIR) 52F0 060F 00188 LD B,ebdtab-addrtab/2 ;Anzahl zu relozierender Abressen 52F2 311E53 00189 adrlop LD SP,addrtab ;Stack auf Adressentabelle 52F3 00190 spbuff EQU $-2 52F5 E1 00191 POP HL ;eine Adresse abholen 52F6 ED73F352 00192 LD (spbuf),SP ;Tabelle als Stack retten 52FA F9 00193 LD SP,HL ;dortige Adresse = Stack 52FB E1 00194 POP HL ;dortiges Word abholen 52FC ED52 00195 SBC HL,DE ;auf neue Basisadresse umrechnen 52FE E5 00196 PUSF HL ;neues Woed ablegen 52FF 10F1 00197 DJNZ addrlop ;bis alle Adressen bearbeitet 5301 210C52 00198 LD HL,trap ;Adresse der Trap-Routine 5304 F9 00199 LD SP,HL ;unterhalb neuer Stack 5305 110000 00200 LD DE,target1 ;Zieladresse in Bank 1 5308 018800 00201 LD BC,start-trap ;Länge der TRAP-Routine 5308 3E11 00202 LD 4,11h ;von Bank 1 nach Bank 1 5300 CDCB35 00203 CALL dma ;TRAP-Routine nach Bank 1 verladen 5310 211653 00204 LD HL,ramdisk ;Aufruf der RAM-Disk (kann entfallen) 5313 C30544 00205 JR 4405h ;als DOS-Befehl ausführen und ENDE 00206 5316 52 00207 ramdisk DM 'RAMDISK',Odh ;Nage des RAM-Disk-Programms, CR 00208 00209 ;Tabelle der zu relozierenden Adressen in der TRAF-Routine 531E 1152 00210 addrtab DW addr1,addr2,addr3,addr4,addr5,addr6,addr7,addr8 532E 7352 00211 DW addr9,addr10,addr11,addr12,addr13,addr14,addr15 00212 endtab 00000 Fehler 00001 ;Listing 5: Ein geändertes SYS-File soll vor dem endgültigen Gebrauch 00002 ;SYSTEST/CMD in Bank 0 gepuffert und von dort aus getestet werden. 00003 6000 00004 ORG 6000h 00005 3588 00006 dma EAU 35bbh ;DMA-Treiber 00007 6000 34084C 00008 start LD 4,(4c0bh) ;bei depuffertem DOS steht dort 00 6003 87 00009 OR A ;ist das DOS in Bank 0 schon gepuffert? 6004 2807 00010 JR Z,go_baby ;alles klar, falls ja 6006 05 00011 PUSH HL ;Befehlszeiger retten 6007 3EFC 00012 LD A,Ofch ;Requestcode für SYS26: DOS erst bunkern 6009 CD0244 00013 CALL 4402h ;dort steht RST 28h für den DOS-Request 600C El 00014 POP HL ;Befehlszeiger 600D CDD54C 00015 go_baby CALL 4cd5h ;HL auf nächsten Befehlsparameter stellen 6010 2006 00016 JR NZ,makefcb ;falls etwas folgt 6012 11AF60 00017 LD DE,filespc ;Text 'Name ..." 6015 CD9560 00018 CALL getinpt ;ausgeben, Dateinamen einlesen 6018 11E060 00019 makefcb LD DE,fcb ;FCB-Adresse 6018 CD1C44 00020 CALL 441ch ;Dateinamen in den FCB übertragen 601E 02044 00021 CALL 442011 ;FCB eröffnen 6021 206D 00022 JR NZ,errexit ;falls Fehler aufgetreten 6023 CDD54C 00023 CALL 4cd5h ;HL auf nächsten Befehlsparameter stellen 6026 2006 00024 JR NZ,getsys ;falls etwas folgt 6028 11C960 00025 LD DE,sysnmbr ;Text 'SYS-File ..." 6028 CD9560 00026 CALL getinpt ;ausgeben, SYS-Nr. einlesen 602E CD9F60 00027 getsys CALL getciph ;1. Ziffer binär umwandeln 5031 78 00028 LD AA ;Binärziffer 6032 2800 00029 JR Z,putsys ;falls Eingabe beendet (SYS1-9) 6034 0E0A 00030 LD C,Oah ;Faktor 10d für zweistellige Zahlen 00031 ; MLT BC ;BC = B * C: B <- 00, C <- 10*B 6036 ED 00032 DB 0edh,4ch ;Hex-Entsprechung des Befehls 6038 CD9F60 00033 CALL getciph ;2. Ziffer einlesen (muß letzte sein) 603B 2053 00034 JR NZ,errexit ;falls Eingabe noch nicht beendet 603D 78 00035 LD 6,5 ;neue Ziffer (binär) 603E 81 00036 ADD A,C ;+ 10mal 1. Ziffer 603F 3C 00037 putsys INC A ;+2, weil GDOS und INHALT keine Nr. haben 6040 3C 00038 INC A 6041 FE03 00039 CP 03h ;SYS1? ('kleinste' erlaubte SYS-Datei) 6043 3849 00040 JR C,illnmbr ;Fehler: Eingabe von SYSO 6045 FE20 00041 CP 1fh+1 ;SY529? ('höchste' erlaubte SYS-Datei) 6047 3045 00042 JR NC,illnmbr ;falls Quatsch wie etwa SYS4711 6049 07 00043 RLCA ;'2, weil 2 Bytes pro Eintrag im SYS-DIR 6044 08 00044 EX AF,AF' ;retten 6046 210040 00045 LD HL,4000h ;dort in Bank 0 das SYS-DIR 604E 110080 00046 LD DE,8000h ;Puffer dafür in Bank 1 6051 05 00047 PUSH DE ;für später 6052 45 00048 LD B,L ;BC <- 0040h = 64d, Länge des SYS-DIR 6053 4C 00049 LD C,H 6054 3E10 00050 LD A,10h ;von Bank 0 nach Bank 1 6056 CDBB35 00051 CALL dma ;SYS-DIR in den Puffer übertragen 6059 08 00052 EX AF,AF' ;aufbereitete SYS-Nr. 6058 5F 00053 LD E,A ;DE <- Adresse des Eintrags im SYS-DIR 6058 1A 00054 LD A,(DE) ;MSB der Adresse des SYS-Files in Bank 0 605C 328560 00055 LD (sysaddr),A ;dort ablegen 605F 13 00056 INC DE ;auf Längenbyte (Blockzähler) stellen 6060 14 00057 LD A,(DE) ;laden 6061 5F 00058 LD E,A ;DE <- Länge des SYS-Files (LSB) 6062 55 00059 LD D,L ;MSB . 00 (max. 35 Sektoren bei SYS6) 6063 2AEC60 00060 LD HL,(fcb+0ch) ;2. u. 1. EOF-Byte, gibt Länge in Skt. an 6066 7D 00061 LD A,L ;Zähler für zu ladende Skt. (LS8 genügt) 6067 3C 00062 INC A ;0.1, weil ab 0 gezählt, Cy lösch. wg. SSC 6068 47 00063 LD B,A ;B als Zähler aufsetzen 6069 328860 00064 LD (bytecnt),A ;als DMA-Bytezähler (MSB) patchen 606C E052 00065 SBC HL,DE ;beide Filelängen vergleichen 606E 3E3B 00066 LD A,3bh ;Fehlercode 'unzureich. Speicherplatz' 6070 301E 00067 JR NC,errexit ;falls Testfile zu lang 6072 EI 00068 POP HL ;Puffer ab 8000h in Bank 1 6073 11E060 00069 LD DE,fcb ;Zeiger auf den FCB 6076 22E360 00070 ldloop LD (fcb+03h),HL ;Pufferadresse in den FCB schreiben 6079 24 00071 INC H ;Pufferzeiger 256 Bytes weiterstellen 6074 CD3644 00072 CALL 4436h ;einen Sektor einlesen 607D 2011 00073 JR NZ,errexit ;falls ein Fehler auftrat 607F 10F5 00074 DJNZ ldloop ;bis alle Sektoren eingelesen sind 6081 2680 00075 LD H,8000h/256 ;HL <- Puffer 8000h in Bank 1 (LSB . 00) 6083 110000 00076 LD DE,0000h ;Zieladresse in Bank 0 (LSB immer 00) 6085 00077 sysaddr ECU $-1 ;MSB der SYS-Adresse in Bank 0 6086 010000 00078 LD BC,0000h ;Bytezähler (LSB immer 00) 6088 00079 bytecnt ECU $-1 ;MSB wird gepatcht 6089 3E01 00080 LD A,01h ;von Bank 1 nach Bank 0 6088 C38835 00081 JP dma ;neues SYS-File speichern und ENDE 00082 608E 3E29 00083 illnmbr LD A,29h ;Fehlercode 'unzul. log. Dateinummer' 6090 E67F 00084 errexit AND 7fh ;NZ-Bedingung (Fehler), keine Rückkehr 6092 C30944 03085 JP 4409h ;Fehlermeldung ausgeben und ENDE 00086 6095 EB 00087 getinpt EX DE,HL ;HL - Zeiger auf Text 6096 CD6744 00088 CALL 4467h ;Text anzeigen 6099 0620 00089 LD 8,206 ;max. 32d Zeichen (sehr reichlich) 6098 EB 00090 EX DE,HL ;HL - DOS-Eingabepuffer für Eingabe 609C C34000 00091 JP 0040h ;Eingabe einlesen und zurück 00092 609F 7E 00093 getciph LD A,(HL) ;Zeichen laden 60A0 FE30 00094 CP '0' ;kleinste erlaubte Ziffer? 6082 38EA 00095 JR C,illnmbr ;Fehler, falls kleiner 6044 FE3A 00096 CP '9'4.1 ;größte erlaubte Ziffer? 6046 30E6 00097 JR NC,illnmbr ;Fehler, falls größer 6088 E60F 00098 AND Ofh ;ASCII -) binär 60AA 47 00099 LD 8,A ;Eingabe binär puffern 6048 23 00100 INC HL ;Befehlszeiger nachstellen 60AC C3D54C 00101 JP 4cd5h ;nächsten Befehlsparam. holen und zurück 00102 00103 ;verschiedene Texte und Puffer 60AF 4E 00104 filespc DM 'Name des Testprogramms? ',0eh,03h ;Text, Churs., EOS 60C9 53 00105 sysnsbr DM 'SYS-File-Nr.',09h,'(1-29)? ',0eh,03h ;dto. mit TAB 00106 fcb ;Puffer für FCB 00107 6000 00108 END start 00000 Fehler Anhang Probleme mit den Illegals Geralds Trap-Programm ist eine wertvolle Hilfe, dennoch kein Allheilmittel. Von den vielen denkbaren Illegals, die im Code-Muster des Z80 stecken, sind längst nicht alle bereits entschlüsselt und dokumentiert. Die Trap-Routine müßte daher bei jeder neuen Entdeckung aktualisiert werden. Und der Z180 benutzt selber für seine neuen Befehle solche ehemals weißen Stellen in der Code-Matrix des Z80. Glücklicherweise beschieden sich seine Designer mit solchen Codes, die mit dem Switch-Byte EDh beginnen, so daß ein notwendiges Debugging verdächtiger Programme in Grenzen bleibt. Nämlich auch Illegals mit EDh werden schon irgendetwas beim Z80 bewirken, was auch immer. Die Illegal-Trap-Routine würde in diesem Falle überhaupt nicht angesprungen, denn es wäre für den Z180 ja ein sinnvoller Befehl. Einer dieser beiden Gründe wird es wohl sein, weshalb nach der Umrüstung des G3s auf den Z180 ausgerechnet mit ZEUS/CMD zahlreiche Abstürze auftraten. Aber vielleicht wurde auch Geralds Programm falsch abgetippt. Egal - es mußte etwas geschehen, denn mit ZEUS steht und fällt die Soft-Seite des ganzen Unternehnens: DSMBLR ist ein Disassembler, der gottlob keine Illegals akzeptiert, wie es z. B. ZEUS durchaus tut. Wenn man daher ein Programm disassembliert, das Illegals enthält, zuckt DSMBLR ratlos die Achseln und setzt DM-(DEFM-) Statements, wo er in seinem Vorrat keinen Z80-Befehl findet (DSMBLR und ZEUS behandeln DB und DM gleich, soweit es sich um einzelne Bytes handelt). So haben wir ZEUS ohne jegliches Screening disassembliert und nach DMs gesucht. An vier Stellen wurden wir fündig (Listing 6). In einem gesonderten File, mit dem wir seit jeher ZEUS patchen (ZAPZEUS/CMD, Listing 7), wurden Simulationen der Illegals programmiert, in ZEUS selbst CALLs nach dort gepatcht. ZAPZEUS (für diesen Zweck genügen die gelisteten Teile) kann so abgetippt und auf Papier assembliert werden. Die Bestandteile bis Zeile 46 werden etwa mit Hilfe von FED/CMD, mitten in ZEUS gezapt. Was dahinter liegt, muß im letzten Sektor von ZEUS angehängt werden. Der Ende-String (02-02-xy-xx) wird als neuer Record-Header (01-nn-yy-xx) geändert. Das Anhängsel-Programm bringt seinen eigenen Ende-String mit. Dafür ist es wichtig, daß seine Einsprungsadresse (END addr) die von ZEUS sein muß (s. Listing). Ob damit alles erledigt ist, muß die zukünftige Praxis zeigen. Ohne ein Screening-File für DSMBLR werden nämlich Texte und Tabellen wie Programmcode disassembliert. So ergeben sich Verschiebungen im "Programm"-Ablauf, die etwa ein Illegal-Switch-Byte wie einen harmlosen Bestandteil eines Sprungbefehls (Adresse, Distanz) erscheinen lassen können. Da das aber nur auftreten kann, wenn ein Illegal direkt an einen reinen Datenblock grenzt, darf man mit Recht auf Erfolg hoffen. Auch das Gegenteil wäre eine mögliche Fehlerquelle: Eine Tabelle, die ohne Screening ja nicht als solche behandelt wird, enthält ein verdächtiges Byte. Der Zufall will es, daß der Inhalt der Tabelle wie sinnvoller Programmcode aussieht. Ein dort gepatchter CALL würde die Tabelle verfälschen. Wir können nur raten, in solchen Fällen die betreffenden Stellen ganz besonders sorgfältig zu untersuchen ... ... und unbedingt das Ergebnis zur Veröffentlichung an Jens-80 Neueder zu schicken! 00001 ;Listing 6: Illegals in ZEUS/CMD 00002 ;ZEUS/CMD (hier nicht interessierende Teile sind mit LIST 0FF 00003 ; ausgespart - erkennbar an den springenden Zeilennummern) 00004 52E7 DD 00305 DM Oddh ;DD 7D:' 52E8 7D 00306 LD A,L ;LD A,LX 52E9 FE28 00307 CP '+' 00308 5809 CB 00694 DM Ocbh ;CB 31 06 01: 5800 310601 00695 LD SP,e0106 ;SLIA C - LD 8,01 00696 5045 C8 00731 DM Ocbh ;C3 31 06 01: 5846 310601 00732 LD SP,m0106 ;SLIA C - LD 8,01 00733 64E9 C3 00700 DM Ocbh ;CB 37: 6AEA 37 00701 SCF ;SLIA A 00702 00000 Fehler 00001 ;Listing 7: Illegal-Trap direkt in ZEUS/CMD 00002 ;ZAPZEUS/CMD (hier nicht interessierende Teile sind mit LIST 0FF 00003 ;ausgespart - erkennbar an den springenden Zeilennummern) 00034 52E7 00035 ORG 52e7h ;dort Illegal LD A,LX 52E7 CD2830 00036 CALL Id_a_lx ;simulieren 00037 5809 00038 ORG 5b09h ;dort Illegal SLIA C 5809 CD3330 00039 CALL slia_c ;simulieren 00040 5845 00041 ORG 5b45h ;dort Illegal SLIA C 5845 CD3330 00042 CALL slia_c ;simulieren 00043 6AE9 00044 ORG 6ae9h ;dort Illegal SLIA A 6AE9 37 00045 SCF ;Cy für Bit 0 setzen 6AEA 17 00046 RLA ;rotieren 00076 3000 00077 ORG 3000h ;wo es nicht stört 00106 3028 DDE5 00107 ld_a_lx PUSH IX ;auf den Stack 302A E3 00108 EX (SP),HL ;HL retten, HL - IX 3028 7D 00109 LD A,L ;A - LX 302C E3 00110 EX (SP),HL ;HL und IX restaurieren 302D DDE1 00111 POP IX 302F FEH 00112 CP 2bh ;überschriebenen Befehl nachholen 3031 1805 00113 JR return ;zurück zur Fortsetzung 00114 3033 CB21 00115 slia_c SLA C ;C shiften 3035 OC 00116 INC C ;Bit 0 setzen 3036 0601 00117 LD 8,01h ;überschriebenen Befehl nachholen 00118 3038 E3 00119 return EX (SP),HL ;HL - RET-Adresse 3039 23 00120 INC HL ;ein Byte später 3030 E3 00121 EX (SP),HL ;zurücktauschen 3038 C9 00122 RET ;an die neue Adresse zurückkehren 00123 5312 00124 END 5312h ;hier Einsprung in ZEUS 00000 Fehler