Erweiterungsmodule für robotron-Drucker

Die Drucker-Modelle K6311, K6312, K6313 und K6314 haben eine baugleiche Interface-Kassette. Sie unterscheiden sich im wesentlichen durch ihre ROM- und RAM-Bestückung. Als Exportvariante gab es diese Drucker unter der Bezeichnung Präsident Printer 6320, 6325 usw.

Diese Drucker gab es mit folgenden Interface-Kassetten, soweit ich weiß:

Schaltpläne und Fotos

Download Schaltplan IFSS

USB-Interface

Will man mit der Zeit gehen und eine USB-Interfacekassette entwickeln, stellt sich die Frage, ob man mit einem heutigen Mikrocontroller die Z80-PIO einsparen kann, d.h. den Mikrocontroller direkt am Z80-Bus betreiben kann. So ein Z80-Bus ist ja verglichen mit heutigen Mikrocontrollern „quasistatisch“, und die Drucker liefen IMHO mit U880B, also max. 2,5 MHz Taktfrequenz. Da dauern Lese- und Schreibzyklen (mit 3..4 Takten) über 1 µs, kein Problem mehr.

Ein ATmega32U4, etwa auf einem Board „Pro Micro“ erscheint schnell genug, und es sind auch genug Pins verfügbar. Er kann sich dediziert um den Z80-Bus kümmern, da die USB-Seite hardware-unterstützt ist. Auf der USB-Seite wird man wohl die Drucker-Klasse (inklusive PnP) und/oder die CDC-Klasse (serielle Schnittstelle) implementieren. Auch eine PIC, etwa PIC18F25K50 bietet sich zur Implementierung an, da es diesen Chip im bastelfreundlichen Durchsteckgehäuse gibt, der das Zwischenboard auf der Lochrasterplatine erspart und keinen (!) Quarz benötigt. 16- und 32-Bit-Controller machen sich hier nicht so gut, weil es keine Typen mit 5-V-E/A-Spannungen gibt. Folgende Signale sind abzugreifen:

BusleitungRichtung am µCBedeutungPortlesenPortschreibenIntvektor lesenInt-EndeReset
D7..D0bidirektionalDatenbusoutinoutin (ED-4D)Z
CSEingangChipselectLLxxx
C/DEingangAdressbit 1auswertenxxx
B/AEingangAdressbit 0auswertenxxx
M1EingangBefehlslesen (Opcode)HHLLx
IORQEingangEin-/AusgabeanforderungLLLHx
RDEingangLesenLHLLx
RESETEingangRücksetzenHHHHL
CentfälltTaktxxxxx
IEIEingangInterruptfreigabeeingangxxHHx
IEOAusgangInterruptfreigabeausgangIEI & (internes) INTH
INTAusgang (L oder Z)Interruptanforderungje nachdemH
Z80-Bussignale, die auszuwerten sind

RESET kann man demnach rotzfrech mit dem Reset-Eingang des Mikrocontrollers verbinden und spart so ein Pin sowie die Auswertung. Das ergibt folgende in Software zu implementierende Kombinatorik:

SignalD7..D0CSC/DB/AM1IORQRDIEI
Daten-AusgabeanlegenLauswertenHLLx
Daten-EingabeauslesenLauswertenHLHx
Interruptvektor-AusgabeanlegenxxxLLLH
Interrupt-Ende (1)0xEDxxxLHLH
Interrupt-Ende (2)xxxxHHHH
Interrupt-Ende (3)0x4DxxxLHLH
Kombinatorik; INT ist davon unabhängig

Am schwierigsten macht sich die Auswertung der Interruptgeschichten. Während die Standardzyklen überall im Web publiziert sind, findet es sich schlecht für die Interruptannahme und erst recht für das Interruptende. In beiden Fällen darf der Mikrocontroller nur bei IEI = H aktiv werden. Da hier IEO nicht verwendet wird (d. h. das Interface-Modul ist das letzte Glied der Interruptprioritätskette) kann man dieses Signal einsparen. Da die Interruptanforderung INT bereits bei Ausgabe des Interruptvektors zurückgenommen werden kann und IEO nicht benötigt wird, kann man sich das Dekodieren von RETI sparen. Der Mikrocontroller benötigt somit exakt 16 „normale“ Pins für die Buskommunikation. Da reicht der „Pro Micro“ aus, und man hat sogar noch RxD und TxD frei.

Es ist zu vermuten, dass die RETI-Dekodierlogik bei jeder Z80-Peripherie durcheinanderkommt, wenn ein Mehrbytebefehl ohne Datenlesephase mit 0xED (beispielhaft CB-ED = SET 5,L) endet und danach ein Befehl 0x4D (= LD C,L) kommt.

Die Hauptarbeit ist dann nur noch die Emulation der Z80-PIO (aka U855D) in der Firmware des ATmega32U4 oder PIC18F25K50. Wie man sieht genügt eine ISR, die pegelgetriggert mit IORQ = L oder flankengetriggert mit IORQ = ↓ aufgerufen wird.

TODO