===== Z80-DMA ===== DMA je čip, který navrhla stejná firma jako procesor Z80, firma **Zilog**. Navrhla ho jako pomocníka k procesoru Z80. Jeho hlavní funkce je blokový přenos dat bez asistence procesoru. Má ještě speciální funkce jako například vyhledávání ve velkém bloku dat. Jeho výhoda je především v rychlosti, přenáší bloky několikrát rychleji, než samotný procesor Z80 a jeho bloková instrukce LDIR. Jak rychle, o tom rozhoduje vlastní konstrukce počítače, ve kterém je použit. === Z80-DMA a ZX Spectrum === DMA čip standardně v ZX Spectru použitý nebyl. Objevil se jen jako přídavný interface, například v **MB02+**, nebo v **DataGear**. Pokud se aktivuje přenos pomocí DMA, procesor Z80 mu přenechá všechen strojový čas, a sám stojí, dokud DMA přenos nedokončí. DMA se ovládá pomocí jediného portu, u MB02+ je to port 11, u DataGearu je to port 107. LnxSpectrum ho emuluje na portu 11. Nejvýhodnější by samozřejmě bylo DMA použít pro scrollování obrazovky. Jenže v tomto případě není konstrukce ZX Spectra k využívání DMA příliš nakloněna. Díky svému rozložení VideoRam lze DMA použít jen pro horizontální scroll, a to ještě jen v případě scrollování vždy celých třetin obrazovky. Vertikální scroll není pro jistotu možný vůbec, nebo by spotřeboval větší množství strojového času, než jaký by potřeboval ke stejnému přenosu samotný procesor Z80. V čem je problém? Vždyť přenos jednoho bajtu trvá DMA 6 taktů, a nejrychlejší přenos Z80 (LDI) sežere 16 taktů na 1 bajt. Problém je v inicializaci DMA čipu, která se pro přesun malých bloků prostě nevyplatí. U vertikálního scrollingu potřebujeme přenášet bloky o velikosti 32 bajtů: |Přenos 32 bajtů |taktů | |DMA |575 | |LDIR |697 | |LDI |532 | |POP/PUSH |408 | Při tomto přenosu jen inicializace DMA čipu trvá 400 taktů. Vlastní přenos pak trvá jen 192 taktů. Pro přenos větších bloků však DMA nemá v ZX Spectru konkurenta. DMA přenese kopii obrazovky za 41472 taktů, procesor Z80 to zvládne za 110592 taktů, tedy skoro 3x pomaleji. === Jak v Z80 Assembleru přenést blok pomocí DMA === V tomto příkladu přeneseme z adresy 0 do VideoRam 2048 Bajtů včetně barev: ; Created by LnxSpectrum emulator (www.ilnx.cz) org 50000 start: ld hl,0 ;z adresy 0 ld (odkud),hl ld hl,2047 ;o délce 2048 (-1) ld (delka),hl ld hl,16384 ;na adresu Videoram (16384) ld (kam),hl ld hl,dma ld b,len_initblok ;délka inicializačního bloku DMA ld c,11 ;DMA je na portu 11 otir ;pošli inicializační blok do DMA, ;tím se i DMA spustí ;tady se procesor Z80 zastaví, a nebude provádět žádné instrukce, dokud ;DMA nedokončí přenos všech bajtů. ld hl,0 ;opět z adresy 0 ld (odkud),hl ld hl,255 ;o délce 256 bajtů (-1) ld (delka),hl ld hl,22528 ;na adresu barev ve videoram (22528) ld (kam),hl ld hl,dma ld b,len_initblok ;délka inicializačního bloku DMA ld c,11 ;DMA je na portu 11 otir ;pošli inicializační blok do DMA, ;tím se i DMA spustí ;tady se procesor Z80 zastaví, a nebude provádět žádné instrukce, dokud ;DMA nedokončí přenos všech bajtů. ret ;hotovo, návrat ;Inicializační blok DMA: dma: defb #C3,#C7,#CB,#7D ;inicializační instrukce pro DMA odkud: defw 0 ;adresa bloku urceneho pro prenos delka: defw 0 ;delka prenaseneho bloku defb #14,#10,#C0,#AD ;instrukce pro DMA kam: defw 0 ;adresa kam se ma prenest defb #92,#CF,#B3,#87 ;instrukce pro DMA len_initblok: equ $-dma