Posts mit dem Label CCP werden angezeigt. Alle Posts anzeigen
Posts mit dem Label CCP werden angezeigt. Alle Posts anzeigen

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.

Sonntag, 14. August 2011

CP/M 2.2

Es wird langsam :-) Wie man in diesem Screenshot sehen kann,
CP/M 2.2 auf meinem Z80-System
läuft ein rudimentäres CP/M auf meinem Z80. Ich hatte Probleme, geeignete CP/M-Systemdateien zu finden. Auf dieser Seite findet man Quellen zu Z80CCP und P2DOS, welches ein nachprogrammiertes CCP und BDOS ist mit kleinen Erweiterungen. Diese Quellen habe ich leicht angepasst, damit sie mit dem TNIASM assembliert werden können und ein einfaches BIOS mit den Funktionen CONIN, CONOUT, CONST, SETDMA, SELDSK geschrieben.

Mit meinem Windowsprogramm "Programmer" kann ich über den dsPIC auf der Z80-Platine in den RAM und ROM schreiben. So habe ich also CP/M in den RAM an die jeweiligen Adressen geladen. Ein kleines Monitorprogramm, welches auf dem Z80 läuft, gibt mir die Möglichkeit, CP/M auf eine CF-Karte zu schreiben oder CP/M von der Karte in den Speicher zu laden und CP/M zu starten.

CCP nimmt nun Eingaben entgegen, aber das BIOS ist noch nicht weit genug implementiert, um von CF-Karte zu lesen oder schreiben. Ich kann also keine Programme starten, es funktionieren nur die in CCP implementierten Befehle. Ich muss noch ein kleines Dateisystem auf der Karte erstellen, welches CP/M dann als Laufwerk zu sehen bekommt. Dazu muss ich aber erstmal verstehen, wie das alles so funktioniert :-)

Wenn es läuft, werde ich hier im Blog die entsprechenden Assemblerfiles posten, z.B. der IDE-Treiber, die UART-Routinen, die angepassten CP/M-Dateien, usw.