Hallo,
Das Board an sich ist schon ziemlich funktionsfähig. Es ist komplett auf Lochraster aufgebaut und wurde rund um eine alte Z80-CPU in CMOS-Ausführung gestrickt.
Ach, du bist doch gemein.
Ich hab in meiner Bastelkiste einen Z80A gefunden und wollte im Verlauf des Sommers eine ähnliche Sache auf die Beine stellen (derzeitige Planung: 4 MHz, 256 KB DRAM geteilt in 64 Banks@4K und ein AVR für Taktgenerator, Bootstrap, Console und sonstige Hardware). Darauf sollte dann (mind.) CP/M 2.2 laufen. Was für einen Z80 hast du eigentlich benutzt?
Eine funktionierende Treiberschnittstelle gibt es mit dem CP/M BIOS. Damit kannst du zwei Character- (CON, AUX) und mehrere Blockdevices abbilden. Viel mehr Hardware dürftest du sowieso nicht haben, oder du erweiterst das BIOS. Der Vorteil ist, dass du CP/M laufen lassen oder sogar einigermaßen emulieren kannst (das schenkt dir Assembler und Compiler für C-artige Sprachen und Pascal). Allerdings liegt das BIOS "oben" im Adressraum und die Blockdevices sind auf je 32 MB beschränkt.
Die unterste Bank ist fest mit Seite 0 des RAMs verbunden und dient als Kernel-Page. Das ist gut für Multitasking, ...
Damit sind deine Anwendungen auf eine Startadresse von 0x4000 und maximal 48 KB Größe beschränkt. Overlay-Systeme werden hässlich, weil du insgesamt nur 3 Pages gleichzeitig für deine Anwendung halten kannst.
Besser wäre, du kopierst bei jedem Programmstart die Interrupt-Handler und einen minimalen Bankswitcher in die untersten Bytes und linkst deine Programme z.B. an 0x100. Dann muss der Kernel während der Programmausführung nicht gemappt sein. Damit sind bis zu 63 KB pro Anwendung direkt möglich (C-Compiler für CP/M machen das gerne). Du hast nur 64 Pages insgesamt im System (mit Swapping evtl. mehr), da möchtest du so wenig Pages wie möglich für Overhead verschwenden. Das heißt möglichst wenig Tasks und möglichst volle Pages. Da glänzen monolithische Kernel (und der Vorteil von Mikrokerneln mit der Sicherheit ist hinfällig, da du sowieso keine Speicherschutzmechanismen hast).
Darauf basierend wäre dann dringend ein Festplatten- und Dateisystemtreiber, sowie ein PS/2-Treiber und zum Schluss ein VGA-Treiber nötig.
Du könntest PS/2- und VGA-Treiber zu einem Konsolentreiber zusammenfassen und gemeinsam in eine Page stecken. Der Festplattentreiber müsste da eigentlich auch reinpassen. (Das wäre dann ein BIOS.)
Ein Syscall wäre einfach ein Sprung an eine bestimmte Adresse unterhalb von 0x100 (also ähnlich gelöst wie IRQ/NMI), wobei die Werte in den Registern übergeben werden können. Dieser Stub mappt BIOS und Kernel, die dann das tun, was getan werden muss und stellt danach den Task wieder her. Messages könnte man synchron implementieren, d.h. der sendende Task blockiert, bis der empfangende Task die Message verarbeitet hat.
Für die Treiber bin ich leider selbst noch ziemlich Ahnungslos. Das einzige, was mir bereits eingefallen ist, ist, dass jeder Treiber mehrere Schnittstellen registrieren können muss, da einzelne Geräte mehrere Funktionen haben können (z.B. eine RS232/PS2-Kombikarte).
Das ist Overkill. Du hast kein Hotplug-fähiges PCIe, an dem deine Hardware hängt. Das sind nur eine Handvoll I/O-Adressen, mit denen du ein paar Register ansprichst. Autokonfiguration wird von deiner Hardware nicht angeboten, also brauchst du die in der Software auch nicht vorsehen (im Gegenteil, manuelles Probing ist sogar gefährlich). Zudem ist es egal, auf welcher Karte sich deine Hardware befindet, da alle Geräte direkt am Bus hängen. (Das gilt vermutlich sogar für den RAM selbst.)
Was würdet ihr besser/anders machen?
Du hast da ein 8-Bit-System, ein Unikat, mit kräftiger Speicher- und Adressraumknappheit und statischer Konfiguration. Da brauchst du nicht mit den Waffen der mächtigen Hotplug-fähigen General-Purpose-Systeme drauf schießen. Schau dir mal ein altes Unix (System III oder so) an, wie die das gelöst hatten, aber das ist alles schon 16-Bit-Technik.
Für 8-Bit-Maschinen kenne ich nur:
- (ROM-)Monitore zum Programme laden und starten, kaum/wenig Funktionen (z.B. dem KC85 sein CAOS, Gameboy-BIOS)
- CP/M und Abkömmlinge (gibt es auch in Multitasking- und Multiuser), die als Treiberschnittstelle das oben beschriebene BIOS nutzen
- geniales Zeug:
--- UZI (
Download), ein angeblich recht vollständiges unixoides System
--- UZI180 (
Architekturbeschreibung), kann Bankswitching
--- Chromix (kommerzielles, für die hauseigenen Maschinen gebautes an Unix orientiertes System, aber kein Unixoid)
--- SymbOS (
Webseite), ein an Windows orientiertes System, aber kein Windows
Mich würde auch interessieren wie Du DMA umgesetzt hast, denn da müssen sich ja die CPU und der/die DMA-Controller den Speicherzugriff teilen.
Der Z80 hat keine Prefetch Queue, daher blockiert ein DMA-Zugriff immer die CPU. In meinem Design wird der AVR den Bus zwar übernehmen können und DMA ermöglichen, aber das werde ich nur für den Bootcode und I/O benutzen.
Gruß,
Svenska