Der DMA-Controller des HD64180 Helmut Bernhardt Der On Chip DMAC (Direct Memory Access Controller) des HD64180 bietet gegenber einem eigenständigen DMAC (z.B. Z80-DMAC) gewisse Vorteile 1) beim RESET liegen definierte Einstellungen vor; ein Hängen des Sys- tems kommt nicht vor 2) entsprechend den Adressierungmöglichkeiten der CPU kann auch der DMAC 512K adressieren 3) da CPU und DMAC auf einem Chip und dadurch beide auf dem CPU-Bord sitzen, kann eine aufwendige DMA-fähige Steuerung der Bustreiber entfallen, ohne auf DNA verzichten zu müssen Der DMAC des HD64180 verfügt über 2 Kanäle mit unterschiedlichen Eigenschaften: Kanal 0 kann Speicher <-> Spejcher - Speicher <-> I/O - und Speicher <-> memory mapped I/O - Transfers durchführen Dabei kann bei jedem Speicherzugriff die Adresse inkrementiert, dekrementiert oder unverändert belassen werden. Dje Speicher <-> Speicher - Übertragung kann im Burst- oder im Cycle Steal Mode er- folgen. Die beiden Chip-internen seriellen Schnittstellen (ASCI) können über den DMA-Kanal 0 mit Handshake bedient werden Kanal 1 kann nur Memory <-> I/O - Transfers durchführen. Dabei Xenn die Speicheadresse nach jedem Zugriff inkrementiert oder dekremen- tiert werden. Die Ports des DMA-Controllers Kanal 0 20H SAROL Source Address Register Channel 0 low A0 - A7 21H SAROH Source Address Register Channel 0 high A8 - A15 22H SAROB Source Address Register Channel 0 bank A16 - A18 23H DAROL Destination Address Register Channel 0 low A0 - A7 24H DAROH Destination Address Register Channel 0 high A8 - A15 25H DAROB Destination Address Register Cnannel 0 bank A16 - A18 26H BCROL Byte Count Register Channel 0 low D0 - D7 27H BCROH Byte Count Register Channel 0 high D8 - D15 Kanal 1 28H MAR1L Memory Address Register Channel 1 low A0 - k7 29H MAR1H Memory Address Register Channel 1 high A8 - A15 2AH MAR1B Memory Address Register Channel 1 bank A16 - A18 2BH IAR1L I/O Address Register Channel 1 low A0 - A7 2CH IAR1H I/O Address Register Channel 1 high A8 - A15 2DH reserved 2EH BCR1L Byte Count Register Channel 1 low D0 - D7 2FH BCR1H Byte Count Register Channel 1 high D8 - D15 für beide Kanäle 30H DSTAT Status Register 31H DMODE Mode Register 32H DCNTL DMA/WAIT Control Register Für Kanal 0 ist vorgegeben, wo die Adressen für 'Quelle' und 'Ziel' einzutrage sind. Dabei ist es in beiden Fällen möglich, Speichera- dessen oder Ports anzugeben. Bei Ports ist dann der Inhalt des Zu- satzadreßregisters (A16-A18) ohne Bedeutung. Memory mapped I/O unter- scheidet sich von normalen Speicheradressen nur dadurch, daß dort auch ein Hardware-Handshaking möglich ist. Kanal 1 legt fest, daß unabhängig von der Funktion 'Qelle' oder 'Ziel' die Speicheradresse in die Ports 28H-2AH und die I/O-Adresse in die Ports 2BH, 2CH eingetragen wird. Die Übertragungsrichtung sowie der Modus (Inkrementieren, Dekrementieren oder feste Adresse für Ziel und Quelle) werden in Port 32H (DCNTL), Bits O-3 festgelegt. Für beide Kanäle kann durch die Vorgaben in den jeweiligen Byte Count Registern (16 Bit) eine Übertragung von bis zu 64K am Stück vorgegeben werden. Für allgemeine Steuervorgaben (write) und Statusinforationen (read) sind die Ports 30H-32H zuständig: DMA Status Register, DSTAT, Port 30H Bit 7 6 5 4 3 2 1 O Name DE1 DE0 /DW1 /DWE0 DIE1 DIE0 - DME Zugriff R/W R/W W W R/W R/W R DE1 : DMA Enable Channel 1 Ein DMA-Transfer über Kanal 1 wird durch Ausgabe von DE1=1 ge- startet. Um DE1 zu setzen, muß gleichzeitig /DWE1 ausgegeben werden; nur dann wird der Wert für DE1 übernommen. Wenn DE1=1 gesetzt wird, wird automatisch gleichzeitig auch DME gesetzt. DE0 : DMA Enable Channel 0 Um einen DMA-Transfer über Kanal 0 zu starten, müssen gleich- zeitig DE0=1 und /DEW0=0 an DSTAT ausgegeben werden. DME wird dabei automatisch gesetzt. Der DMA-Transfer läßt sich (im Cycle Steal Mode) bei beiden Kanälen unterbrechen, wenn DEx=0 und /DWEx=0 an DSTAT ausgegeben werden. Mit der Ausgabe von DEx=1 und /DWEx=0 kann der Transfer dann weitergeführt werden. Nach beendetem Transfer wird DEx automatisch =1 gesetzt. /DWE1, /DWE0: DMA Bit Write Enable Channel 1, -Channel 0 Um DE1 oder DE0 zu setzen oder zu löschen, muß gleichzeitig das entsprechende Bit /DWE1 bzw. /BWE0 low ausgegeben werden. DIE1, DIE0: DMA Interrupt Enable Channel 1, -Channel 0 Wenn DIEx für Kanal x als 1 gesetzt wird, erfolt nach Beenden des DMA-Tansfers ein CPU-Interrupt. DIEx = 0 (nach RESET vor- eingestellt) verhindert den Interrupt. DMA Mode Register, DMODE, Port 31H Bit 7 6 5 4 3 2 1 0 Name - - DM1 DM0 SM1 SM0 MOD - Zugriff R/W R/W R/W R/W R/W Über DODE wrrd derÜbertraungs-Modus für ausschließlich Kanal 0 vorgegeben. DM1 und DM0 geben für das Ziel und SM1 und SM0 für die Quelle die Übertragungsbedingungen vor: DM1 DM0 Ziel und Bedingungen --------------------------------------------- 0 0 Memory mit Adreßinkrement 0 1 Memory mit Adreßdekrement 1 0 Memory mit feststehender Adresse 1 1 I/O mit feststehender Adresse SM1 SM0 Quelle und Bedingungen --------------------------------------------- 0 0 Memory mit Adreßinkrement 0 1 Memory mit Adreßdekrement 1 0 Memory mit feststehender Adresse 1 1 I/O mit feststehender Adresse DM1, DM0, SM1 und SM0 werden bei RESET auf 0 gesetzt. KMODE hat keine Funktion, wenn Quelle oder Ziel als I/O festgelegt werden. Dann bestimmt der Triggerimpuls am Pin /DREQ0 das Timing. Bei Memory <-> Memory-Transfers bestimmt KMODE die Transferart. MMOD=0 : Cycle Steal Mode; Nach jedem DMA-Transfer darf die CPU einen Zyclus ausführen. MMOD=1 : Burst Mode; die CPU erhält die Kontrolle über den Bus erst dann wieder, wenn die gesamte DMA-Übertragung beendet ist. DMA/WAIT Control Register, DCNTL, Port 32H Bit 7 6 5 4 3 2 1 0 Name MWI1 MWI0 IWI1 IWI0 DMS1 DMS0 DIM1 DIM0 Zugriff R/W R/W R/W R/W R/W R/W R/W R/W MWI1, MWI0, IWI1 und IWI0 steuern die Anzahl WAITs für Memory- und Port-Zugriffe durch die CPU und den DMAC.Diese Bits wurden bereits im im letzten Teil besprochen. DMS1, DMS0, DIM1 und DIM0 sind Steuerbits für den Kanal 1 der aus- schließlich Memory <-> I/O- und I/O <-> Memory-Übertragungen steu- ert. Diese Übertragungen werden durch DERQ1 getriggert. Da auch beim Kanal 0 getriggerte Übertragungen möglich sind, kann mit DMS0 auch hier die Triggerart festgelegt werden. DMS1, DMS0 : DMA Request Sense legen die Art des Triggerns für DERQ1 (Kanal 1) und DERQ0 (Kanal 0) fest. Wenn das Bit auf 0 gesetzt ist,wird durch einen Low-Pegel am DERQ-Pin getriggert. Der DERQ-Pin wird zu Beginn des zweiten Taktes eines CPU-Maschinen-Zyklus übernommen. Wenn zu diesem Zeitpunkt am DERQ-Pin Low-Pegel anliegt, wird der Maschinen-Zyklus noch beendet und dann ein DMA-Transfer durchgeführt. Wenn DMSx auf 1 gesetzt ist, wird die DMA-Übertragungdurch eine negative Flanke am DERQx-Pin getriggert. DIM1, DIM0 : Channel 1 I/O and Memorx Mode Festlegen von Quelle und Ziel und Inkrementieren/Dekrementieren von Speicheradressen. DIM1 DIM0 Transfer-Richtung Inc./Dec. ---------------------------------------------- 0 0 Memory -> I/O Inkrementieren 0 1 Memory -> I/O Dekrementieren 1 0 I/O -> Memory Inkrementieren 1 1 I/O -> Memory Dekrementieren Die I/O-Adresse wird in allen Fällen nicht verändert. Programmieren der DMA-Kanäle Kanal 0, Memory <-> Memory Die reine Memory<->Memory- Übertragung wird nicht durch den DERQ0-Pin getriggert. Das Timing erfolgt je nach Modus (Burst- oder Cicle Steal) inzwei verschiedenen Arten. In beiden Fällen hält die DMA-Übertragung an, bis der Byte Count Zähler auf 0 heruntergezählt. Im Burst Mode werden alle Bytes nacheinander übertragen und die CPU erhält erst dann wieder die Kontrolle über den Bus. Im Cycle Steal Mode wird immer ab- wechselnd ein Maschinen-Zyklus der CPU und eine Übertragung des DMAC durchgeführt. Es werden nacheinander folgende Register programmiert: 1) Laden der Memory Adress Source- und Destination-Register 2) in DMODE: Memory<->Memory und Adreß-Inkrement/Dekrement über SM1, SM0, DM1, DM0 festlegen 3) Anzahl zu übertragender Bytes in die Byte Count Regjster schreiben 4) Burst- oder Cycle Steal Mode in MMOD von DCNTL vorgeben 5) Übertragung mit DE0=1 und geichzeitig /DWE0=0 in DSTAT starten Kanal 0, Memory <-> I/O oder memory mapped I/O Das Timing des DMA-Transfers wird durch die Pins /DREQ0 und /TEND0 des HD64180 gesteuert. /DREQ0 : über diesen Eingang wird ein DMA-Transfer getriggert. TEMD0 : über diesen Ausgang wrrd das Ende eines DMA-Blocktransfers (BRC0=OOH) angezeigt. Diese Pins sind mit den Clock Inputs/Outputs CKA0 und CKA1 der ASCI- -Schnittstelle gemultiplext. Wenn der DMA-Kanal 0 für Memory <-> I/O oder memory mapped I/O programmiert wird, fungieren diese Pins als DMA Handshake-signale. CKA1D in CNTLA1 wird automatisch high gesetzt. Wenn vor der ansteigenden Flanke von T3 eines CPU-Maschinenzyklus eine fallende Flanke von /DREQ0 auftrat (wenn taktflanken-getriggert pro- grammiert) bzw. bei der steigenden Flanke von T3 Low-Pegel an DREQ0 vorliegt (wenn pegel-getriggert programmiert), wird anstelle des nächsten CPU-Maschinenzyklus ein DMA-Transfer ennes Bytes (Lesen und Schreiben) durchgeführt. Initialisierung: 1) Memry- und (memory-mapped) I/O- Quell- und Ziel-Adressen in SAR0 und DAR0 eintragen. I/O-Adressen sind 16 Bit breit, A16 und A17 sind als 0 einzutragen. 2) durch Setzen von SM0, SM1, DM0 und DM1 in DMODE vorgeben, ob Memory <-> I/O oder Memory <-> memory mapped I/O und ob Adressen inrementiert oder dekrementiert werden sollen. 3) Anzahl zu übertragender Bytes in CCR0 einragen 4) durch DMS0 in DCNTL flanken- oder pegelgetriggert an /DREQ0 vor- geben 5) durch DIE0 in DSTAT DMA-Ende-Interrupt freigeben oder sperren 6) DE0=1 und gleichzeitig /DWE0=0 in DSTAT eintragen /DREQ0 steuert dann die DMA-Übertragung. Kanal 0, Memory <-> ASCI Bei Übertragungen über die 2-Kanal-ASCI-Schnittstelle wird das Timing; nicht über /DREQ0 gesteuert. Die ASCI-Statusbits erzeugen intern ein /DREQ0. Es sind dies die Bits TDRE (Transmmt Data Register Empty) und RDRF (Receive Data Register Full). Initiaisierung: 1) Quell- und Ziel-Adressen in SAR0 und DAR0 vorgeben. Die I/O-Adresse- ist ein ASCI-Register (06H-09H), das mit A0 - k7 vorgegeben wird. A8 - A15 sind low zu sezten. A18 ist ohne Bedeutung. 16 und A17 steuern das Timing über die ASCI-Statusbits: bei Empfangen über ASCI: ' A17 A16 D-Transfer-Request durch ------------------------------------------------ 0 0 /DREQ0 bei Übertragung nicht über ASCI 0 1 RDRF (ASCI, Kanal 0) 1 0 RDRF (ASCI, Kanal 1) 1 1 reserviert bei Senden über ASCI A17 A16 DMA-Transfer-Request durch ------------------------------------------------ 0 0 /DREQ0 bei Übertragung nicht über ASCI 0 1 TDRE (ASCI Kanal 0) 1 0 TDRE (ASCI Kanal 1) 1 1 reserviert 2) durch SM0, SM1, DM0 und DM1 in DMODE Memory <-> I/O - Transfer und Inkrementieren oder Dekrementielen der Memory-Adressen vorgeben 3) Anahl zu übertragender Bytes in BCR0 vorgeben 4) DMS0 in DCNTL muß für "flankengetriggert" programmiert werden 5) DIE0 in DSTAT kann DMA-Ende-Interrupt zulassen oder sperren 6) Mit DE0=1 und gleichzeitig /DWE0=0 an DSTAT wird der DMA-Transfer Jnitialisiert und dann durch die ASCI-Statusbits gesteuert Die ASCI-Empfänger/ -Sender müssen initialisiert werden, um den ersten DMA-Transfer zu starten. Der ASCI-Empfänger muß leer sein (RDRF=0) bzw. der ASCI-Sender muß mit einem ersten Byte geladen sein (TDRE=0). Das erste Byteß muß von der CPU an den ASCI-Sender gegeben werden; alle weiteren Bytes werden per DMA übertragen. Kanal 1, Memory <-> I/O bis auf einige unterschiedliche Register und Status-/Control-Bits funktioniert ier DMA-Transfer über Kanal 1 wie der Memory <-> I/O Transfer über Kanal 0 Initialisierung: 1) Memory-Adresse (19 Bit) in MAR1 ff eintragen 2) I/O-Adresse (16 Bit) in IAR1 ff eintragen 3) mit DIM0 und DIM1 von DCNTL Quelle und Ziel sowie Dekrementieren oder Inkrementieren der Memory-Adresse festlegen 4) in DMS1 von DCNTL vorgeben, ob /DREQ1 flanken- oder pegel-getrig- gert arbeiten soll 5) über DIE1=1 in STAT einen DMA-Ende-Interrupt zulassen oder sperren 6) DE1=1 und gleichzetig /DWE1=0 in DSTAT eintragen Das Timing wird dann über /DREQ1 gesteuert; /TEMD1 gibt das Ende eines DMA-Blocktransfers dem I/O-Gerät bekannt. Diese kurze Übersicht der Programmierng berücksichtig die Reihen- folge der eizelnen Schritte, wie sie von Hitachi im HD64180-Datenbuch vorgechlagen ist. Solange man das Register DSTAT immer zuletzt be- schreib, kann in der Reihenfolge des Befüllens der anderen Ports eine sinnvollere Ordnung eingebracht werden. So lassen sich z.B. beim Memo- ry <-> Memory DMA-Transfer über Kanal 0 die hintereinander liegenden Ports für Qell- und Zieladressen und Übertrgungslänge mit dem Befehl OTIMR aus einer entsprechenden Tabelle im Speicher befüllen und nur noch DMODE und DSTAT sind mit einelnen OUT0-Befehlen zu versorgen. Die Nutzung der DMA-Kanäle für Memory <-> I/O oder memory mapped I/O Übertragungen setzt voraus, daß die Hardware die Signale /DREQ0 bzw. /DREQ1 unu /TEND0 bzw. /TEND berücksichtigt. Der Prof180 wickelt z.B. den Datenaustausch mit dem µPD765-Floppy-Controller über den DMA-Kanal 1 ab und hat entsrrechend die Signale /DREQ1 und /TEND1 über Inverter zwischen CPU und FDC verbunden.