Zilog Z80

(Z80 szócikkből átirányítva)
Ez a közzétett változat, ellenőrizve: 2024. november 23.

A Zilog Z80 az Intel sikeres 8 bites processzorának, a 8080-nak a Zilog cég által készített utódja volt. (A Zilog-ot az Inteltől kilépett mérnökök alapították.) A Z80 hatására adta ki az Intel a 8085 jelű processzorát (amely azonban továbbra is a 8080-as utasításkészletével rendelkezett, pár kisebb bővítéssel[1]).

Zilog Z80
Gyártó
ElődIntel 8080
Utód
A Wikimédia Commons tartalmaz Zilog Z80 témájú médiaállományokat.
Az NEC által készített Z80 klón (NEC D780C) a Sinclair Spectrum alaplapján

A két processzor belső felépítésben eltérő, de a Z80 felülről kompatibilis a 8080-nal, a bővítések a 8080 által nem definiált gépi kódokat használják (pl. a CB, ED, DD, FD hexadecimális kódok). Számos új utasításon kívül két új index-regisztere is van (IX és IY), illetve az alap regiszterkészletnek egy "másodpéldánya" is létezik (AF', BC', DE', HL'). A Z80-as saját assembly nyelvvel rendelkezik, amely az i8080-asénál felhasználóbarátabb.

Fejlődése

szerkesztés
 
A Z80 eredeti DIL40 (dual in-line, 2×20 kivezetés) tokozású változatának lábkiosztása. A ponttal jelölt láb az 1-es, a számozás felülről nézve az óramutató járásával ellenkező irányban növekszik.

A Z80 első verziója 2,5 MHz órajellel üzemelt, DIL40 tokban, egyetlen tápfeszültséggel (+5V). Széles körű ismertségét a Sinclair ZX 80, ZX81, Timex gépeknek, később a ZX Spectrumnak, illetve ezek utódainak (Magyarországon az ABC 80 iskolaszámítógépnek is) köszönhette. A CPU mellé készítettek PIO (16 bites programozható párhuzamos I/O portot), SIO (soros vonali illesztő), CTC (számláló, időzítő) és DMA (közvetlen memóriavezérlő) csipeket is. A processzor az akkoriban megfizethető dinamikus memóriák frissítését megoldotta, nem kellett külön frissítő, memóriakezelő csipeket használni. Ezzel sokkal egyszerűbben alkalmazható, tervezhető, olcsóbb felhasználást tettek lehetővé.

A volt szocialista blokk is másolta, ugyanis akkoriban a COCOM lista miatt nem engedték importálni, ezért készült az U880 (a volt NDK-ban, ezt építették a magyar fejlesztésű PRIMO gépcsaládba is), de volt szovjet és bolgár megfelelője is. Később megjelentek gyorsabb változatok, valamint utángyártottak is, pl japán CPU-k voltak az újabb Spectrum sorozatokban is. A Z80A 4, Z80B 6, a Z80H pedig 8 MHz-es maximális órajellel működött.

Az 1980-as években kiterjedten használták méréstechnikai célokra is. A magyar MOMCOLOR színmérő számítóegysége Z80-as processzorral működik.

A maga idejében nagyon jól programozható, sokat tudó, és gyors processzor volt. A gyártó még 2008 végén is ajánlotta (több mint 20 évvel az első kiadása után), beágyazott rendszerekbe. Mikrokontrollerekbe a mai napig beépítik.

2024. április 15-én a Zilog bejelentette, hogy 2024. június 14-től a Z80 gyártása megszűnik.[2]

Műszaki leírás

szerkesztés
 
A Z80 felépítése

A Z80-as egy 8 bites CISC mikroprocesszor; adatbusza 8 bites, címbusza 16 bites. Little-endian bájtsorrendet használ.

Általános jellemzők

szerkesztés

A processzor a CISC kategóriába tartozik: utasításai változó bájthosszúak, 1–4 bájtot foglalhatnak a memóriában; megengedett a memória-operandus, az utasítások között vannak pl. komplex blokkmozgató utasítások is. Utasításkészlete egy részhalmazként tartalmazza az Intel 8080-as processzor utasításkészletét, azzal felülről kompatibilis. A bővített utasításokat CB, DD, ED vagy FD prefixek jelölik az utasításkészletben.

A külvilággal a Z80 16 bites címbuszon, 8 bites adatbuszon, és a vezérlőbuszon keresztül tartotta a kapcsolatot. A 16 bites címtartomány 64 kibibyte (KiB) közvetlen címzést tesz lehetővé. Ez akkoriban elég nagynak számított, de különböző technikákkal ez tovább bővíthető; pl.: a címtartomány alsó felét 16 KiB ROM és 16 KiB DRAM, a felső felét 2 vagy több 32 KiB DRAM használja.

A Z80 nagyban támogatta a DRAM-ok frissítését: minden utasítás végrehajtási ciklusba egy (esetenként két!) 'frissítési ciklust' épített be, ilyenkor a címbusz alsó hét bitjén egy automatikusan növelt számlálót (az R regiszter alsó hét bitjét) adott ki, ami az úgynevezett 'RAS-only' frissítést igénylő DRAM-ok esetén maximum 16 KiB-os memóriachipek (pl. 4116) frissítésére volt elegendő, ennél nagyobb kapacitású chipek (pl. 4164 (64 KiB), 41256 (256 KiB)) esetén további számláló áramkörökre volt szükség.

A processzor aritmetikai egysége (ALU) szorozni nem tudott, de ezen felül minden szokásos aritmetikai, logikai és léptetési művelet elvégzésére képes volt. Teljes regiszterkészlete a 8080-tól örökölt és megduplázott 3 regiszterpárból (16 bitesnek összefogható, de 8 bitenként külön-külön is elérhető regiszterből), az IX, IY indexregiszterekből, az SP veremmutató regiszterből, a PC programszámláló regiszterből, valamint két 8 bites regiszterből – I (megszakítás) és R (memóriafrissítés) – állt. Utóbbi egyébként gyors változása miatt álvéletlenszámok előállítására is alkalmazható volt.

Az alapregiszterek két sorozata két külön, váltható bankba van szervezve; az előtérben lévő ill. aktív bank regiszterei elérhetőek, a háttérben lévő regiszterek tartalma nem változik (ld. regiszterek).

Van indexelt címzése, mellyel valamelyik indexregiszterben tárolt címhez képest a -128 – +127 tartományban lehet elérni a memóriát.

Fejlett multiprocesszoros üzemmódot támogató lehetőséggel látták el.

Érdekes újítás volt akkoriban a blokkos adatmozgató művelet, amikor egy-egy regiszterpárt használtak a forrás és a cél cím tárolására és egy regiszterpárt darabszámlálónak. Automatikusan ismétlő megfelelőik is vannak, és a felhasználó is tudott ciklust készíteni. 8 bites lévén volt 8 bites cikluskezelő utasítás is.

Programozási modell és regiszterek

szerkesztés
A Z80 processzor regiszterei
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 (bitpozíció)
Fő regiszterek
A Flag regiszter AF *
B C BC
D E DE
H L HL (közvetett cím)
Alternatív regiszterek
A' Flag' regiszter AF' *
B' C' BC'
D' E' DE'
H' L' HL' (közvetett cím)
Indexregiszterek
IX Index X
IY Index Y
SP Veremmutató **
Egyéb regiszterek
  I Megszakításvektor ***
  R Frissítési számláló ****
Állapotregiszter
  S Z - H - P N C Jelzőbitek (flag-ek)
Utasításszámláló
PC Program Counter
* AF: akkumulátor és jelzőbitek
** SP: Stack Pointer
*** Interrupt vector
**** Memóriafrissítési számláló, Refresh counter

A programozási modell és regiszterkészlet konvencionális, és hasonlít a rokon x86 családéra. A Z80 regiszterei egy összesen 208 bites területet foglalnak el, amelyen 18 darab 8 bites és 4 darab 16 bites regiszter található.[3] A 8080-kompatibilis regiszterek: AF, BC, DE, HL – a Z80-ban két példányban találhatók, két regiszterbankban kaptak helyet,[4] és ezek között a processzor igen gyorsan tud átkapcsolni (egyikről a másikra, oda-vissza);[5] ez a tulajdonság igen hasznos az egyszintű, magas prioritású megszakítások kezelésénél. Ez a képesség már létezett a Datapoint 2200 programozható terminálban (az x86, 8080 és Z80 architektúrák ősében), azonban az Intel ezt nem valósította meg a 8008-as processzorban (ami az Intel próbálkozása volt a terminál egyetlen integrált áramköri lapkán való megvalósítására). A kettős regiszterkészlet jelentősége főképpen abban áll, hogy a Z80-as processzort, miként a korabeli processzorok többségét is, beágyazott rendszerekben történő használatra tervezték, nem pedig a még fel sem talált otthoni vagy személyi számítógépekhez. Sima Maszatosi, a processzor egyik tervezője szerint a korabeli piac a nagy teljesítményű nyomtatókra, felső kategóriás pénztárgépekre és intelligens terminálokra koncentrált. A tulajdonság kapóra jött (nagyon hasznos volt) a kézi assembly kódolásban is, nagymértékben optimalizált kódok készítésénél. Egyes szoftverek, különösen az MSX, Sinclair ZX Spectrum és más Z80 alapú számítógépek szoftverei, a Z80-as assembly optimalizációt egészen szélsőséges szintre vitték, amelynek egyebek közt része volt a megduplázott regiszterek használata is.

A regiszterek

szerkesztés

[3][6]

A 8080-as processzorhoz hasonlóan, a 8 bites regiszterek párokban is használhatók, 16 bites regiszterekké kapcsolhatók össze. A 8080-kompatibilis regiszterek a következők:

  • AF: 8 bites akkumulátor (A) és jelzőbitek (F): átvitel (carry), nulla (zero), negatív, paritás/túlcsordulás, félátvitel (ezt a BCD műveletek használják), és az (N jelű) összeadás/kivonás jelzőbit, szintén a BCD műveletekhez
  • BC: 16 bites adat/cím regiszter vagy két 8 bites regiszter
  • DE: 16 bites adat/cím regiszter vagy két 8 bites regiszter
  • HL: 16 bites accumulator/cím regiszter vagy két 8 bites regiszter
  • SP: veremmutató, 16 bites
  • PC: programszámláló, 16 bites

A Z80-nál bevezetett új regiszterek a következők:

  • IX: 16 bites index vagy bázis regiszter a 8 bites közvetlen eltolásokhoz (offset)
  • IY: 16 bites index vagy bázis regiszter a 8 bites közvetlen eltolásokhoz
  • I: megszakítási vektor bázisregiszter, 8 bites
  • R: DRAM frissítési számláló, 8 bites (legmagasabb helyiértékű bitje nem változik)
  • AF': alternatív (vagy árnyék-) akkumulátor és jelzőbitek (az EX AF,AF' utasítás váltja)
  • BC', DE' és HL': alternatív (vagy árnyék-) regiszterek (az EXX utasítás váltja őket)
  • Négy bit a megszakítási állapot és mód jelzésére
Akkumulátor és jelzőbitek
szerkesztés

Az A akkumulátor-regiszter és párja, az A', 8 bites regiszterek, közülük mindig csak az előtérben lévő elérhető. Aritmetikai és logikai műveletek egyik operandusát tartalmazza és ebben képződik a művelet eredménye is.

Az F regiszter és párja, az F', 8 bites regiszterek, a jelzőbitek elérésére szolgál: a belső jelzőbitek tartalmát a processzor az F-be másolja. Az A és F regiszterek egy 16 bites párt alkotnak, ami a kétbájtos műveletekkel kezelhető.

Általános célú regiszterek
szerkesztés

Ezek a B, C, D, E, H, L 8 bites, vagy a BC, DE, HL párokba állított 16 bites regiszterek. Alternatív párjaik a BC', DE', HL' készlet. A két készlet egyetlen utasítással cserélhető.

Alternatív regiszterkészlet
szerkesztés

Az alternatív regiszterkészlet közvetlenül nem elérhető, ehelyett két speciális utasítás, az EX AF,AF' és az EXX,[6] teszi lehetővé ennek kezelését; mindkettő csak egy multiplexer flipflop állapotát változtatja. Ez gyors kontextusváltást tesz lehetővé a megszakítások kiszolgálórutinjainak: az EX AF,AF' önmagában is használható (például egy nagyon egyszerű és gyors megszakításkezelőben) vagy együtt az EXX utasítással, amely lecseréli az egész BC, DE, HL készletet; ez még így is sokkal gyorsabb, mint a regiszterek verembe mentése (lassabb, alacsonyabb prioritású vagy több szintű megszakítások rendesen a veremben tárolják el a regisztereket). Az alternatív regisztereket árnyék-regiszterekként is említik (shadow registers).

Speciális regiszterek
szerkesztés

A speciális regiszterek a PC programszámláló, SP veremmutató, IX, IY indexregiszterek, I és R regiszter.

A PC programszámláló regiszter egy 16 bites regiszter, a végrehajtandó utasítás memóriacímét tartalmazza. Közvetlenül nem elérhető, tartalma minden utasítás beolvasásakor automatikusan növekszik az utasítás hosszával; ugróutasítások után értéke a relatív címkülönbséggel változik, vagy abszolút ugráskor az új cím értékét veszi fel. Reset alkalmával 0 értéket kap.

Az SP veremmutató regiszter egy 16 bites regiszter, a verem tetejét címzi. A programokban a PUSH utasítással két bájtos adatot lehet a verem tetején elhelyezni, és a POP utasítással onnan a regiszterekbe írni; ilyenkor a veremmutató értéke automatikusan növekszik / csökken 2-vel.

Az IX és IY két független 16 bites indexregiszter, amelyek indexelt címzési mód esetén a memória báziscímet tartalmazzák; a tényleges cím az indexregiszter és egy 8 bites eltolási érték összegeként áll elő.

A memóriafrissítő regiszter vagy R regiszter (R mint refresh) nem 8, hanem valójában 7 bites regiszter, a 8. bitje soha nem változik – ez azzal függ össze, hogy a korabeli memóriák egy 7 bites frissítési ciklust igényeltek. Elsődleges szerepe a processzorhoz csatlakozó dinamikus memóriák frissítése: a processzor az utasításdekódolás és végrehajtási fázis alatt tartalmát a címsín alsó felére helyezi. Tartalma eggyel növekszik a CPU minden utasításlehívási ciklusakor, tehát amint a CPU elővesz egy utasítást (vagy utasításkód-prefixet), ezáltal egyfajta bonyolult kapcsolatban van a programvégrehajtással. Ezt gyakran álvéletlen számok generálására használják a programokban. Bizonyos rendszerekben „hardveres” számlálóként is alkalmazták, ennek egyik példája a ZX81-es gép, amely ennek segítségével követte nyomon a karakterpozíciókat a TV-képernyőn, egy megszakítás segítségével.

Az I megszakítási vektorregisztert a Z80 speciális 2-es módú megszakításai használják – ezt a megszakítási üzemmódot az IM 2 utasítással lehet kiválasztani. A Z80-as processzornál a maszkolható megszakítások kezelésének háromféle üzemmódja létezik (0, 1, 2). A 2-es mód a vektoros megszakításkezelést valósítja meg. Ebben az üzemmódban az I regiszter szolgáltatja a megszakítási vektorcím felső 8 bitjét (míg az alsó 8 bitet a megszakítást kérő periféria helyezi a sínre); az így előállt 16 bites címnek egy 128 elemű táblázatba kell mutatnia, ahol a megszakításkezelő szubrutinok kezdőcímeinek kell elhelyezkedniök.[7] Az I gyakorlatilag egy megszakítási lapcím-regiszter. A mutató alkalmas egy adott periféria (-csip) megfelelő funkciójának vagy eseményének azonosítására, ahol a perifériák daisy-chain-be, egyfajta füzérbe vannak szervezve, amely meghatározza az eszközök (megszakításkérelmeinek) prioritását. A frissítőregiszterhez hasonlóan ezt a regisztert is lehet „kreatívan” használni, pl. a 0-s és 1-es megszakítási módokban közönséges 8 bites adatregiszterként használható.

A 4 bites ALU

szerkesztés

Az aritmetikai-logikai egység (ALU) a CPU-ba integrált modul, amely az aritmetikai és logikai műveletek végrehajtásáért felelős. Más korabeli CPU-kkal (például a MOS 6502-vel vagy az Intel 8080-assal) ellentétben a Z80 ALU-ja 4 bites, azaz nibble-nek is nevezett 4 bites értékekkel végez számításokat. Mivel a CPU akkumulátor-regisztere 8 bites, az akkumulátorban lévő számon történő számítás elvégzéséhez a Z80 ALU-jának két lépést kell végrehajtania ezen a regiszteren. Annak érdekében, hogy ez ne befolyásolja a CPU teljesítményét, a Z80 tervezői egy olyan belső ciklusrendszert dolgoztak ki, amely "gépi ciklusokra" vagy "M-ciklusokra" oszlik, ahol minden M-ciklus több órajelciklusból áll, és az utasításokat úgy optimalizálták, hogy a CPU képes legyen az egyes utasítások minimális átfedő műveleteit végrehajtani: ezt az eljárást „fetch/execute overlapping”-nek nevezik, és lehetővé teszi, hogy az egyik utasítás végrehajtása folytatódjon, miközben a CPU a következő utasítás opkódját olvassa be a memóriából. Például a SUB r utasítás, amely az 'r' jelű 8 bites regiszterben lévő értéket kivonja az akkumulátorból, 1 M-ciklus alatt hajtódik végre, amely 4 órajelciklusból áll. Az utasítás végrehajtása a következő lépésekre osztható:

AKTUÁLIS UTASÍTÁS: "N" (SUB r)
M1 / T1 : cím beállítása, ahonnan az "N" végrehajtandó utasítást beolvassa
M1 / T2 : az "N" utasítás lehívása a memóriából
M1 / T3 : a műveleti kódot "SUB r"-ként értelmezi: A az "ACU" belső regiszterbe töltődik (*)
M1 / T4 : az "r" regiszter tartalma a "TEMP" belső regiszterbe töltődik (*)
KÖVETKEZŐ UTASÍTÁS: "N+1"
M1 / T1 : cím beállítása, ahonnan az "N+1" végrehajtandó utasítás olvasása történik;
: ezzel egyidőben az ALU kiszámítja az előző művelet alacsony nibble-ét
M1 / T2 : az "N+1" utasítás előhívása a memóriából;
: ezzel egyidőben ALU kiszámítja az előző művelet magas nibble-ét,
: az eredményt 8 bites értékké állítja össze és az akkumulátorba helyezi
*: ld.fent, CPU belső felépítésének vázlatán („A Z80 felépítése”)

Így a Z80 nem mutat lassulást egy teljesen 8 bites ALU-val rendelkező CPU-hoz képest. Ez azért is lehetséges, mert az utasítás memóriából való behívása mindig az utasítás első M-ciklusának (M1-nek nevezett) első "T" ciklusa alatt történik.[8][9][10][11]

A Z80 assembly nyelv

szerkesztés

A Datapoint 2200 és az Intel 8008

szerkesztés

Az első Intel 8008 assembly nyelv a Datapoint 2200 termináltól örökölt nagyon egyszerű, ám szisztematikus szintaxison alapult. Később, még ugyanennél a csipnél, az eredeti szintaxist később egy hagyományosabb assembly nyelvi forma váltotta fel. Ezzel körülbelül egyidőben az újabb assembly nyelvet kiterjesztették, hogy alkalmas legyen a fejlettebb Intel 8080 csip által hozzáadott címzési módok jelölésére (a 8008 és a 8080 egy közös nyelvi készleten osztozott, anélkül, hogy binárisan kompatibilisek lettek volna, bár a 8008-as binárisan kompatibilis volt a Datapoint 2200-assal).

Az átalakítás során a LOAD, „betöltés” műveletre alkalmazott L mnemonikot felváltották a LOAD, STORE és MOVE szavak különféle rövidítései, egyéb szimbolikus betűkkel keverve. Az M az utasítást jelölő mnemonikus betűk csoportjából átkerült az operandusokat jelölő betűk közé, ahol a (a HL által címzett) memória jelölésére szolgált, míg a regiszterek és azok kombinációi nagyon következetlenül, változatos jelöléseket kaptak, akár rövidített operandusokként (MVI D, LXI H és társai), akár az utasításkódon belül (LDA, LHLD és a többi), vagy mindkét módon egyszerre (LDAX B, STAX D s.í.t.).

Datapoint 2200 és i8008 i8080 Z80 i8086/i8088
~1973 előtt ~1974 1976 1978
LBC MOV B,C LD B,C MOV BL,CL
-- LDAX B LD A,(BC) MOV AL,[BX]
LAM MOV A,M LD A,(HL) MOV AL,[BP]
LBM MOV B,M LD B,(HL) MOV BL,[BP]
-- STAX D LD (DE),A --
LMA MOV M,A LD (HL),A MOV [BP],AL
LMC MOV M,C LD (HL),C MOV [BP],CL
LDI 56 MVI D,56 LD D,56 MOV DL,56
LMI 56 MVI M,56 LD (HL),56 MOV byte ptr [BP],56
-- LDA 1234 LD A,(1234) MOV AL,[1234]
-- STA 1234 LD (1234),A MOV [1234],AL
-- -- LD B,(IX+56) MOV BL,[SI+56]
-- -- LD (IX+56),C MOV [SI+56],CL
-- -- LD (IY+56),78 MOV byte ptr [DI+56],78
-- LXI B,1234 LD BC,1234 MOV BX,1234
-- LXI H,1234 LD HL,1234 MOV BP,1234
-- SHLD 1234 LD (1234),HL MOV [1234],BP
-- LHLD 1234 LD HL,(1234) MOV BP,[1234]
-- -- LD BC,(1234) MOV BX,[1234]
-- -- LD IX,(1234) MOV SI,[1234]

A négyfajta szintaxis illusztrációja, megegyező vagy (a 8086-nál) hasonló mintájú betöltő és tároló utasításokon bemutatva[12]

Az új szintaxis

szerkesztés

Mivel az Intel assembly utasításkódjai (mnemonikjai) szerzői jogi védelem alá estek,[13] a Zilognak egy új assembly szintaxist kellett kifejleszteni. Ezt a feladatot azonban már sokkal szisztematikusabban oldották meg:

  • Minden regisztert és regisztepárt a teljes nevével jelölnek
  • A zárójelek következetesen a „memóriatartalom” jelölésére szolgálnak (indirekt címzés, ill. mutatóval történő hivatkozás), néhány ugróutasítás kivételével.[14]
  • Minden betöltő és kiíró utasítás ugyanazt a mnemonikus nevet használja: LD (a LOAD rövidítése, visszatérve a Datapoint 2200 szóhasználatához); a többi közös utasítás, mint az ADD vagy INC, mindig ugyanazt a mnemonikot használja, a címzési módtól vagy az operandus méretétől függetlenül. Ez lehetséges, mert maguk az operandusok elég információt hordoznak.

Ezekből az elvekből szinte egyenesen következett az összes új Z80-as utasítás neve és formája, ráadásul a régi utasítások ortogonális formái; például: LD BC,(1234).

Eltekintve az elnevezési különbségektől és az eltérésektől a regiszterstruktúra felépítésében, a Z80 és az Intel 8086 szintaxis virtuálisan izomorf az utasítások túlnyomó többségére vonatkozólag. A 8080 és a 8086 assemblerek között csak nagyon felületes hasonlóságok mutatkoznak (pl. a MOV szó vagy az X betű használata a kiterjesztett regiszterekre), bár a 8080-as programok speciális assembler segítségével lefordíthatók 8086-os tárgykódra, vagy egy forráskód-fordító segítségével átalakíthatók 8086-os assembly nyelvre.[15][16]

Az utasításkészlet és kódolása

szerkesztés

A Z80 a rendelkezésre álló 256 kódból 252-t használ egybájtos opkódként (ezek az ún. „gyökérutasítások” v. alaputasítások); a fennmaradó négy kódot opkód-prefixumként (előtagként) használja:[17] a CB és ED kiegészítő utasításokat tesz elérhetővé, a DD és FD pedig az IX+d vagy IY+d címzési módokat választja ki (néhány esetben a d eltolás nélkül) a HL helyett. Ez a séma a Z80 számára nagyszámú utasítás- és regiszter-kombinációt biztosít; a Zilog ezeket 158 „utasítástípus”-ba sorolja, amiből 78 megegyezik az Intel 8080 utasításaival,[17] ami lehetővé teszi a 8080-as programok Z80-as processzoron való működését. A Zilog dokumentáció további kategóriákba sorolja az utasításokat:

  • 8 bites aritmetikai és logikai műveletek
  • 16 bites aritmetikai műveletek
  • 8 bites betöltő utasítások (load)
  • 16 bites betöltő utasítások
  • Bit beállítás, törlés és teszt
  • Hívás, visszatérés és újraindítás (call, return, restart)
  • Cserélő, blokkmozgató és kereső utasítások
  • Általános célú aritmetikai és CPU-vezérlési utasítások
  • Bemenet és kimenet
  • Ugró utasítások
  • Eltolás, ciklikus eltolás (shift, rotate)

Az eredeti Z80-nak nincs szorzó utasítása.[18] A különböző méretű és változatú összeadás, eltolás és körkörös eltolás (elforgatás, rotálás) utasítások valamennyire eltérő hatással vannak a jelzőbitekre, mert ebben a 8080-as viselkedését másolták. A betöltő utasítások nincsenek hatással a jelzőbitekre (a speciális I és R legiszterek betöltését kivéve).

Az IX/IY indexregisztereket használó utasítások hasznosak rögzített struktúrákban tárolt adatok elérésénél és a kódméretet is csökkentik, mivel sok rövidebb, alapregisztert használó utasítást helyettesíthetnek. Bár néhány kontextusban ezek növelik a sebességet, hosszú vagy bonyolult, egyszerűbb utasításokból álló „egyenértékű” kódsorozatokhoz képest, ezek az utasítások költségesebbek, végrehajtásuk több CPU-időt vesz igénybe (pl. egy memóriahely indexelt elérése 19 T-állapot, míg ugyanaz a HL regiszterrel és INC utasítással a következő bájt címzésére 11 T-állapot alatt hajtható végre). Így pl. az egyszerűbb vagy lineárisan elhelyezkedő adatokhoz való hozzáférés az IX vagy IY címzéssel általában lassabb. Ezek mégis hasznosak lehetnek, ha az alapregiszterek mind foglaltak, mert elkerülhető azok (verembe-) mentése és visszaállítása. Az indexregiszterek alsó és felső bájtjai külön-külön is elérhetők (ld. alább), bár ez hivatalosan nem volt dokumentálva. Ez különösen hasznos lehet, mivel használatuk nem lassítja annyira a végrehajtást. Hasonlóképpen, a 16 bites összeadási utasítások sem rendkívüli gyorsaságukkal tűnnek ki (11 órajelciklus) az eredeti Z80-asnál; mégis, a 8 bites műveletek használatával a megfelelő eredmény kétszer lassabban érhető el, és a 16 bites utasítások csökkentik a regiszterhasználatot is.

A 10 évvel fiatalabb mikrokódolt Z180 kialakítás nagyobb lapkaterület használatát tette lehetővé (pl. szélesebb ALU használatát, többek között), ezáltal a megvalósítás kissé hatékonyabbá vált; ugyanezeket lehet elmondani a Z800, a Z280 és a Z380-ról is. Mégis 2001-ig, a teljesen futószalagos végrehajtású eZ80 megjelenéséig tartott, hogy ezek az utasítások végül megközelítették az órajelciklusok kihasználásának technikailag lehetséges határát, tehát az adott Z80 kódkészlettel, egy 8 bites írás vagy olvasás művelet végrehajtását minden órajelciklus alatt.

Nem dokumentált utasítások

szerkesztés

Az IX és IY indexregiszterek alapvetően a 16 bites mutatók használatát könnyítik a programokban, amelyeket általában a memória, a veremkeretek és egyéb összetett adatstruktúrák elérésére használnak. Hivatalosan ezek a regiszterek oszthatatlanul 16 bitesek. A valóságban ezek is két 8 bites regiszterként vannak megvalósítva, de a 8 bites használatot lehetővé tevő utasításokat a gyártó nem tette közzé.[19] Ezek a regiszterek a HL-hez hasonlóan kezelhetők, 16 bites vagy két külön 8 bites „felső” (high, H) és „alsó” (low, L) regiszterként. Még az utasítások bináris opkódjai is megegyeznek a H, L regisztereket használó utasítások kódjaival, csak a prefixeik különböznek.[20] A Zilog csak a szándékosan megvalósított funkciók opkódjait tette közzé, de nem dokumentálta azt a tényt, hogy minden opkód, amely a H vagy az L regisztereket használja, hasonlóképpen érvényes az IX vagy IY regiszterek megfelelő (magasabb vagy alacsonyabb helyiértékű) 8 bites részeire is. Például a 26h opkód, melyet egy közvetlen érték követ a LD H,n utasítást reprezentálja, amely az n értékét a H regiszterbe tölti. Ha ezt az utasítást pl. az IX regiszter használatát jelző prefix – DDh bájt – előzi meg, akkor az utasítás az n értékét az IX regiszter magasabb helyiértékű bájtjába (felébe) tölti be. Ez alól kivétel az LD H,(IX+d)-hoz hasonló utasítások csoportja, amelyek egyszerre használják az HL és IX vagy IY regisztereket,[20] ebben az esetben a DD prefix csak az utasítás (IX+d) részére érvényes.

Több egyéb nem dokumentált utasítás is létezik.[21] A nem dokumentált vagy illegális opkódok a Z80-as processzorban változatos eredményeket adnak, amelyek között akadnak hasznosak is. Azonban, mivel ezek a kódok nem részei a processzor formális definíciójának, nem biztos, hogy a különböző Z80-as megvalósításokban ugyanúgy működnek vagy ugyanazt a mellékhatást váltják ki (a dokumentált utasítások hatása garantált, ezeké azonban nem).

Az alábbi Z80 assembler forráskód egy memcpy nevű alprogramot mutat be, amely egy megadott méretű adatblokkot másol a memóriában az egyik címről a másikra. Az adatblokk másolása bájtonként történik, a másolás egy ciklust használ, abban pedig 16 bites műveleteket. Érdekesség, hogy a lefordított kód binárisan kompatibilis az Intel 8080-as és 8085 processzorokkal.

		; memcpy --
		; Egy memóriaterület másolása egyik helyről a másikra.
		;
		; Bemenő regiszterek
		; BC - másolandó bájtok száma
		; DE - forrás memóriacím
		; HL - cél memóriacím
		;
		; Visszatérő regiszterek
		; BC - nulla

1000	                org     1000h   ; Kód kezdőcíme 1000h
1000           memcpy	public
1000 78        loop     ld      a,b     ; BC tesztelése:
1001 B1	                or      c       ; A := ( B or C )
1002 C8                 retz            ; visszatérés, ha nulla
1003 1A                 ld      a,(de)  ; A betöltése (DE) címről
1004 77                 ld      (hl),a  ; A írása (HL) címre
1005 13                 inc     de      ; DE növelése
1006 23	                inc     hl      ; HL növelése
1007 0B	                dec     bc      ; BC csökkentése
1008 C3 00 10           jp      loop    ; ciklus vége, ismétlés
100B                    end

Felhasználás

szerkesztés

A Z80 processzor (és másolatainak) néhány alkalmazása:

  1. Intel Corporation: 8080 8085 Assembly Language Programming Manual (PDF). Intel Corporation, 1981. [2012. április 17-i dátummal az eredetiből archiválva]. (Hozzáférés: 2012. szeptember 7.)8085 processor differences: TRAP, 3 maszkolható megszakítás, RIM, SIM utasítások
  2. Benj Edwards: After 48 years, Zilog is killing the classic standalone Z80 microprocessor chip, 2024. április 22. (Hozzáférés: 2024. június 8.)
  3. a b Krizsán György. ZILOG Mikroprocesszor Családok I-II., lektor: Dr. Kovács Magda (magyar nyelven), Budapest: LSI Alkalmazástechnikai Tanácsadó Szolgálat, 1–453. o. (1985). ISBN 963-592-351-1. Hozzáférés ideje: 2013. 
  4. Kilobaud. 1001001, 22. o. (1977) 
  5. Zaks, Rodnay. Programming the Z80, 3rd, SYBEX, 62. o. (1982). ISBN 978-0-89588-069-7 
  6. a b Steve Heath.. Embedded systems design (angol nyelven). Oxford: Newnes, 21. o. (2003). ISBN 978-0-7506-5546-0 
  7. Wai-Kai Chen. The circuits and filters handbook (angol nyelven). CRC Press, 1943. o. (2002). ISBN 978-0-8493-0912-0 „interrupt processing commences according to the interrupt method stipulated by the IM i, i=0, 1, or 2, instruction. If i=1, for direct method, the PC is loaded with 0038H. If i=0, for vectored method, the interrupting device has the opportunity to place the op-code for one byte . If i=2, for indirect vector method, the interrupting device must then place a byte . The Z80 then uses this byte where one of 128 interrupt vectors can be selected by the byte.” 
  8. Ken Shirriff: The Z-80 has a 4-bit ALU. Here's how it works
  9. Electronic – How to z80 uses a 4-bit ALU and return results in a single clock cycle. [2021. augusztus 16-i dátummal az eredetiből archiválva]. (Hozzáférés: 2022. szeptember 18.)
  10. Z80 CPU Architecture
  11. Federico Faggin; Federico Faggin, Masatoshi Shima, Ralph Ungermann, Michael Slater (mod.) (2007). „Zilog Oral History Panel on the Founding of the Company and the Development of the Z80 Microprocessor” (pdf). Oral History of the Zilog Z80 Microprocessor, Mountain View, California, 27 aprile 2007 Computer History Museum. [2012. február 14-i dátummal az eredetiből archiválva]. 
  12. Frank Durda IV: 8080/Z80 Instruction Set. [2016. február 11-i dátummal az eredetiből archiválva]. (Hozzáférés: 2013. június 8.)
  13. Az ugró – JP – utasítások, amelyek a célutasítás címét töltik be a programszámlálóba, nem jelentenek memóriahozzáférést. Az ugróutasítások abszolút vagy relatív formái ezt fejezik ki a zárójelek elhagyásával. A regiszteralapú ugróutasítások, mint pl. a „JP (HL)” megtartják a zárójelet, ami nyilvánvalóan ettől a konvenciótól való eltérés Z80 Relocating Macro Assembler User's Guide. [2011. július 20-i dátummal az eredetiből archiválva]. (Hozzáférés: 2013. június 8.)
  14. Scanlon, Leo J.. 8086/8088/80286 assembly language. Brady Books, 12. o. (1988). ISBN 978-0-13-246919-7 „The 8086 is software-compatible with the 8080 at the assembly-language level.” 
  15. Nelson, Ross P.. The 80386 book: assembly language programmer's guide for the 80386. Microsoft Press, 2. o. (1988). ISBN 978-1-55615-138-5 „An Intel translator program could convert 8080 assembler programs into 8086 assembler programs” 
  16. a b Z80 CPU Introduction. Zilog, 1995. „Nyelve 252 alaputasításból áll és a maradék 4 bájt segítségével előtagként használva, még 308 utasítás érhető el.”
  17. Sanchez, Julio. Software Solutions for Engineers And Scientists. Taylor & Francis, 65. o. (2008). ISBN 978-1-4200-4302-0 „The 8-bit microprocessors that preceded the 80x86 family (such as the Intel 8080, the Zilog Z80, and the Motorola) did not include multiplication. – a 80x86 családot megelőző 8 bites processzorok (mint az Intel 8080, a Zilog Z80 és a Motorola) nem tartalmazták a szorzást.” 
  18. Froehlich, Robert A.. The free software catalog and directory. Crown Publishers, 133. o. (1984). ISBN 978-0-517-55448-7 „Undocumented Z80 codes allow 8 bit operations with IX and IY registers.” 
  19. a b Bot, Jacco J. T.: Z80 Undocumented Instructions. Home of the Z80 CPU. „If an opcode works with the registers HL, H or L then if that opcode is preceded by #DD (or #FD) it works on IX, IXH or IXL (or IY, IYH, IYL), with some exceptions. The exceptions are instructions like LD H,IXH and LD L,IYH”
  20. Robin Nixon The Amstrad Notepad Advanced User Guide ,Robin Nixon, 1993 ISBN 1-85058-515-6, pages 219-223

További információk

szerkesztés

Kapcsolódó szócikkek

szerkesztés