Sonntag, 20. Mai 2012

CP/M 2.2

In der letzten Zeit habe ich mich wieder etwas mit CP/M beschäftigt. Vor einem Jahr ungefähr hatte ich auf meiner anderen Selbstbauplatine ja auch ein rudimentäres CP/M laufen. Nun habe ich die Arbeit wieder ausgegraben, das BIOS auf mein neues System angepasst und einen anständigen Bootloader programmiert. CP/M startet nun von der Compact Flash-Disk und kann nur-lesend auf ein 8 MB Dateisystem zugreifen.
CP/M 2.2 startet auf meinem Z80-System
Schreibzugriffe habe ich noch nicht implementiert. Das ist nicht ganz so einfach zu handeln, da CP/M 2.2 mit 128 Byte-Sektoren arbeitet, auf der Compact Flash-Disk die Sektoren aber 512 Byte groß sind.

CP/M besteht im wesentlichen aus drei Teilen: Das BIOS, BDOS und CCP. Um CP/M auf einen Rechner (mit kompatiblen Prozessor) zu portieren, muss man die BIOS-Routinen entsprechend anpassen. Das Betriebssystem benutzt dann die BIOS-Routinen und muss nicht wissen, wie die Hardware des Computers funktioniert. Das BIOS ist also eine Sammlung einfacher Treiber für Ein-/Ausgabe, Diskettenlaufwerkszugriff usw. Hier ist eine Übersicht der Funktionen.
BDOS ist das Betriebssystem an sich, welches u.A. das CP/M-Dateisystem versteht. Und CCP ist der Kommandozeileninterpreter, eine Art rudimentäres COMMAND.COM bzw. CMD.EXE.

Als erstes braucht man also eine BDOS- und CCP-Version, von der man auch weiß, an welche Stelle im Speicher es kopiert werden muss. Ich habe dieses hier verwendet. Es gibt dort sogar Assembler-Quellcode zu CP/M.
Als zweites nimmt man ein BIOS-Grundgerüst (die findet man zu Hauf im Netz) und passt die wichtigsten Routinen an das eigene System an. Funktionen für Lochkarten kann man glücklicherweise weglassen :-)
Neben den I/O-Funktionen für Bildschirm und Massenspeicher ist die BOOT-Funktion zu implementieren. Sie kopiert die Systemspuren von Diskette in den Speicher. In den Systemspuren stecken BDOS und CCP. Danach wird der CCP gestartet, der sich mit dem A0> Prompt meldet. Die CP/M 2.2 Meldung zuvor ist im BIOS implementiert und kann beliebig geändert werden.

Der Prompt A0> steht übrigens dafür, dass aktuell auf Laufwerk A mit Benutzer 0 gearbeitet wird. CP/M kennt keine Verzeichnisse, aber die Dateien auf einer Diskette können in Benutzerbereiche aufgeteilt werden.
Wie bei MS-DOS bzw. Windows kann mit der Eingabe von B: auf Laufwerk B gewechselt werden. Tatsächlich ist CP/M hier das Vorbild für MS-DOS und somit auch für Windows gewesen. Durch die Eingabe von user 1 kann auf Benutzer 1 gewechselt werden. Lässt man die Dateien auf Diskette auflisten (DIR), werden nur die Dateien des aktiven Users angezeigt.

Nun hat man also ein einfaches BIOS mit BOOT-Routine geschrieben. Jetzt stellt sich nur noch die Frage, wie das BIOS beim Einschalten in den Speicher gebracht wird. Dazu muss ein Bootloader-Programm geschrieben werden, welches zusammen mit dem BIOS üblicherweise im ROM liegt. Der Bootloader kopiert nun das BIOS an das Ende des RAM-Speicherbereichs. Bei mir ist das ab Adresse 0xFA00. Dann wird das ROM abgeschaltet, an die Stelle RAM gesetzt und der BIOS gestartet. Ab jetzt hat CP/M die Kontrolle über das System.

In den Screenshots stammt die Meldung "Loading CP/M..." vom Bootloader, der das BIOS in den RAM kopiert. Die Meldungen "Z80 Homebrew Computer" und "CP/M 2.2 Copyright (c) by Digital Research" stammen vom BIOS. Der Prompt A0> wird von CCP (mit Hilfe der BIOS-Funktion CONOUT) getätigt.

Da das System noch keine VGA-Schnittstelle oder sonstiges Display hat, findet Bildschirmein-/ausgabe über ein serielles Terminal statt. Im Folgenden ein paar Screenshots vom System in Aktion. Die CP/M-Software stammt von der Seite http://www.retroarchive.org/.

Microsoft BASIC 5.21 vom 28.07.1981 :-)

Noch ein Microsoft BASIC, von 1977!

Tiny-C Compiler

Turbo Pascal 1.0 von Borland
Ich habe ja damals Programmieren in Turbo Pascal unter MS-DOS gelernt, deswegen muss ich mir Turbo Pascal 1.0 mal genauer anschauen!

Ein CP/M-Dateisystem-Image kann man mit cpmtools erstellen. Es lassen sich damit Dateien rein- und rauskopieren. So wird ein einfacher Dateiaustausch zwischen CP/M und der modernen Computerwelt auf Dateiebene möglich. Um dieses Image auf die CF-Karte zu bringen, habe ich (unabhängig von CP/M) ein kleines Programm geschrieben, welches Daten im Intel-Hex-Format empfängt und als Binärdaten auf CF-Karte schreibt. Da aus 16 Byte Binärdaten im Hex-Format ungefähr 40 Byte werden, wurde aus dem erzeugten (nicht vollen) Dateisystem von 800 kB ca. 2,2 MB. Um das über die serielle Schnittstelle mit 19200 Baud zu übertragen, braucht es schon eine Weile. Da muss ich mir noch etwas Besseres überlegen.

Damit CP/M den Diskzugriff korrekt durchführt, muss im BIOS der Disk Parameter Header und Disk Parameter Block entsprechend der Disk-Geometrie konfiguriert werden. Auf dieser Seite steht, wie man die BIOS-Konfiguration bestimmt.
Da CP/M 2.2 nur mit 128-Byte Sektoren arbeitet, wie es damals bei 8"-Disketten üblich war, mein System aber eine CF-Karte über IDE anspricht, welche mit 512-Byte Sektoren arbeitet, muss hier eine Übersetzung stattfinden. Digital Research hat dafür ein Grundgerüst für das sogenanntes Blocking/Deblocking vorbereitet, das genau dieses "Sektormapping" durchführt. Diese Dokumentation findet man hier. Es funktioniert bei meinem System allerdings noch nicht.

Keine Kommentare:

Kommentar veröffentlichen