Hardver leírás
Gépi kódú programozás
Tartalom
Bevezető
Az angol SINCLAIR cég ZX Spectruma egyike a legelterjedtebb személyi számítógépeknek Magyarországon. Mint általában egy-egy iparcikk nagyobb népszerűségének, ennek is több oka van. Az egyik ok vitathatatlanul az, hogy a gép olcsó. Önmagában véve azonban nem elég, hogy egy személyi számítógép pusztán olcsó legyen, hiszen akkor napjaink legnépszerűbb típusa a ZX81 is lehetne. Amikor egy fogyasztó valamilyen iparcikket vásárol, azt is figyelembe veszi, hogy az árához képest mekkora teljesítményű, mennyire megbizható, és a hozzá hasonlóakhoz képest mennyive1 jobb vagy rosszabb a kiszemelt berendezés. Így van ez a személyi számítógépek esetében is.
Ebből a szempontból igen kedvező helyet vívott ki magának a ZX Spectrum. Van még egy külföldi gyártmányú személyi számítógép, amely népszerűség és elterjedtség tekintetében vetekszik vele hazánkban; ez a Commodore cég VIC-64-es típusa. A két berendezés azonban a sok hasonlóság és felhasználás ellenére jelentős mértékben eltér egymástól. Az alapgépek, tehát a két számítógép nyugat-európai ára perifériális (kiegészítő) eszközök nélkül összemérhető. Viszonylag nem kerül annyival többe a VIC-64, mint amennyivel többre képes hardver (gépi) adottságok szempontjából. Azonban egyetlen tényező alapján nem szabad kijelenteni azt, hogy egyik gép "jobb" a másiknál, legfeljebb akkor, ha hozzátesszük, hogy "mert az adott feladat megfelelőbb", vagy "mert nekem jobban tetszik" stb. A VIC-64-eshez ugyanis kapható a 1541-es hajlékony mágneslemezegység (floppy drive), amely gyorsabb és bizonyos szempontból egyszerűbb tárolóeszköz, mint a kazettás magnetofon, viszont jóval drágább. A VIC-64-eshez a programok többsége hajlékony mágneslemezen (floppy disken), míg a ZX Spectrumhoz szabványos magnetofonkazettán szerezhető be. Ez utóbbihoz ugyanis nem készül saját gyári fejlesztésű, vagy más okok miatt elterjedt lemezegység. (A ZX Spectrumhoz kapható MICRODRIVE nem helyettesíti a lemezes rendszert.) Ebből következik, hogy ha valaki könnyen, gyorsan hozzá szeretne férni VIC-64-es programokhoz, lemezegységet is kell vennie, ami viszont drágább, mint maga az alapgép. A ZX Spectrum ezzel szemben a Magyarországon kapható kazettás magnetofonok jelentős részével is működik.
Ilyen és ehhez hasonló érvek tucatjai mondhatók el, ha egy számítógépet egy másikkal hasonlítunk össze. A következőkben a legfontosabb összehasonlítási szempontokat soroljuk fel:
Az ÖTLET című hetilap 1983 végén sorozatot indított BITLET számítástechnikai mellékletében. A sorozat címe VALLATÓ volt, s célja, hogy Magyarország legkülönbözőbb felhasználói és számítástechnikai szakemberei összehasonlítsák, ill. egytől ötig osztályozzák az erre kiszemelt személyi számítógépeket, amelyek természetesen valamilyen okból a legelterjedtebbek vagy a legnépszerűbbek. A sorozatban a legtöbb gépre elhangzott valamilyen hasonlat. Az ABC 80-at pl. a "népmesék hőséhez", a VIC-64-et "nyakkendős üzletemberhez", a ZX Spectrumot pedig "jóindulatú hobóhoz" hasonlították. Könnyen megérthetik a hasonlat találó voltát azok az olvasók, akiknek egyik-másik géppel kapcsolatban személyes benyomásai is vannak.
Az osztályozáskor, nyugodtan mondhatjuk, a ZX Spectrum az egyik legjobb átlagot érte el. A szempontok között az ár, a perifériakezelés, a képernyőkezelés, a hang, a kazettás adattárolás, a gépi kódú programozás, a megbízhatóság, a billentyűzet, a dokumentáció, az editálás, a gép programnyelve, a tanulhatóság, az emberközelség és a szoftverellátottság szerepelt. Érdekes, újszerű, de mégis megalapozott és jogos szempont volt egy további osztályzat, a szubjektív vélemény. Aki valaha olvasott ehhez hasonló minősítéseket külföldi lapokban, nemigen találkozhatott hasonló szemponttal. Mégis vásárláskor talán éppen ez az egyik legfontosabb tényező. Az emberközelség és a szoftverellátottság mellett ebből érte el a legjobb átlagot a ZX Spectrum, 4,9-et, a legrosszabbat pedig abból, amit a legtöbb felhasználó és leendő vevő kifogásol, s ami talán mindennél jobban gátolta a gép nagyobb méretű közületi elterjedését, s ez a billentyűzet. A bírálók pontjainak átlaga itt mindössze 3,8 volt.
Néhány jellemző vélemény:
Teljes egészében jogosnak mondható a billentyűzet megítélése is, s talán csak azért nem kapott a gép itt még rosszabb átlagot, mert önkéntelenül adódik az összehasonlítás a ZX81-gyel a Sinclair személyi számítógépeket ismerők számára:
Egyéb szempontokkal kapcsolatban is szerepel néhány érdekes megállapítás:
Könyvünk írásakor három alapvető célt tartottunk szem előtt:
A gépi kódú programozás technikája és a gép áramköri tulajdonságai szorosan összefüggnek, e két témakör tárgyalásmódja azonban jelentősen eltér. Hogy az ebből adódó ellentmondásokat elkerüljük, könyvünk első részében a ZX Spectrum hardveradottságaival és az ezzel összefüggő alapvető áramköri problémákkal, míg a második részben a gépi kódú és assembly szintű programozással, valamint alapvető feladataival foglalkozunk.
A könyv témájából adódóan előfordulhat, hogy olvasóink egy része egy-egy feladat megoldásához csak néhány fejezetre lesz majd kíváncsi. Hogy mindenki lehetőség szerint leggyorsabbam jusson az őt érdeklő információhoz, arra törekedtünk, hogy a fejezetek önállóan is olvashatóak legyenek, s a programozási fejezet szubrutinjai is úgy készültek, hogy felhasználhatóak legyenek saját program írásakor is.
Reméljük, könyvünk nemcsak hasznos, de kellemes olvasmánynak is bizonyul.
A szerzők
Ez úton szeretnék, köszönetet mondani Tordai Istvánnénak és Keviczky Lászlónak, továbbá Szarvas Sándornak, Kovács Gézának és Tolnai Györgynek a nyomtatási munka során nyújtott segítségért.
Ada-Winter Dávid
Az 1. ábrán egy számítógép elvi felépítése látható. A szaggatott vonalon kívüli rész a tulajdonképpeni számítógép, az összes többi egység feladata a gép párbeszédének lehetővé tétele a külvilággal.
1. ábra: Egy átlagos számítógép elvi felépítése
A számítógép logikailag legfontosabb része a központi egység (CPU = Central Processor Unit). Ez végzi a vezérlést, a logikai és aritmetikai műveleteket. A ZX Spectrum esetében (2. ábra) a CPU feladata a működéshez szükséges és programvezérelhető folyamatok indítása és vezérlése.
A ROM (Read Only Memory = a CPU számára csak olvasható tár) tárolja a gép elindításához És a számunkra is használható működtetéshez szükséges alapvető információkat és programokat. A ZX Spectrum esetében a perifériális egységekhez tartozó kiszolgáló rutinokat (programrészeket) és a BASIC interpretert is tartalmazza.
A RAM (Random Access Memory = a CPU számára adatok beírására és kiolvasására egyaránt alkalmas tár) általános esetben saját adataink és programjaink tárolására alkalmas. A ZX Spectrumnál ebben található az a tárterület, amelynek tartalma megjelenik a képernyőn, valamint a BASIC interpreter (közvetlenül BASIC nyelvű programozási lehetőséget biztosító gépi kódú programrész) működéséhez elengedhetetlenül szükséges rendszerváltozók értéke is.
A megjelenítő és a billentyűzet feladata magától érthetődő: az előbbi a gépben lejátszódó folyamatok eredményeinek kijelzésére, az utóbbi saját információink bevitelére szolgál.
A háttértár a (ZX Spectrumhoz kazettás magnetofon ill. MICRODRIVE) azért szüséges, mert kikapcsolás után rövid idő elteltével a RAM "elfelejti" az információt.
2. ábra: A ZX Spectrum elvi felépítése
1.2. A ZX Spectrum rendszereelemei
A Spectrum hardverének felépítése a 2. ábrán látható. Kitűnik belőle, hogy megtalálhatók mindazok a belső és periféria-áramkörök, amelyek általában egy számítógép tartozékai:
1.2.1 A ZX Spectrum központi egysége, a Z80A
A ZX Spectrum központi egysége egy Z80A tipusú, az amerikai Zilog cég által kifejlesztett mikroprocesszor. A Z80, ill. annak gyors működésű változata, a Spectrumban is található Z80A a hetvenes évek végén kifejlesztett, napjainkban az egyik legelterjedtebb és legtöbb utasítást tartalmazó nyolcbites mikroprocesszor.
A Z80A kivezetései
Belső felépítése és az ehhez kötődő kivezetések Csoportosítva a 3. ábrán láthatók. Kitűnik belőle, hogy 40 kivezetéses ún. DIL (DIP) tokban kapható.
3.a. ábra: A Z80 (és Z80A) mikroprocesszor logikai szervezése
7 S |
6 Z |
5 |
4 H |
3 |
2 P/V |
1 N |
0 C |
Sign bit |
Zero bit |
X |
Half carry bit |
X |
Parity- oVerflow |
Substract bit |
Carry bit |
Előjel bit |
Nulla eredményt jelző bit |
Félátvitel jelző bit |
Párosság-túlcsordulást jelző bit |
Kivonást jelző bit |
Átvitelt jelző bit |
3.c. ábra: A Z80A mikroprocesszor státuszregisztere (jelzőbitkészlete)
3.d. ábra: a Z80 (és a Z80A) regiszterei
Feladata sokrétű:
A mikroprocesszor ismertetésekor először a kivezetések, ill. a rajtuk megjelenő jelek rendeltetéséről szólunk, mivel a belső szerkezeti egységek funkcióit csak ezek alapján követhetjük. A külső kapcsolatokat biztosító és a belső jelvezetékeken egyaránt - a bináris működési elvvel összhangban - csak kétféle: magas és alacsony feszültségszint lehetséges. Az előbbi 4,5 és 5,5 V
közé eső, az utóbbi 0 V körüli érték. A kettes számrendszer két számjegyét, az 1-et és a 0-t e két feszültségszint valamelyikével fejezhetjük ki. Ha H=1 és L=0 (H = High = magas feszültségszint), akkor pozitív, ellenkező esetben (L = Low = alacsony feszültségszint) negatív logikáról beszélünk. A jeleket (kivezetéseket) funkciójuk angol nyelvű rövidítésévez szokták jelölni. Ha a jel neve fölött felülvonás látható, akkor negatív, egyébként pozitív logikájú jelről van szó.
Ha valaki e könyvben találkozik először a Z80 mikroprocesszorral, talán nehéz lesz megértenie a jelek most következő tömör ismertetésekor fellépő új fogalmakat. A későbbi fejezetekből visszalapozva azonban bizonyosra vesszük, hogy az első olvasáskor homályos részletek is megvilágosulnak.
A jelek (kivezetések) tárgyalását két vezetékcsoport: az ADAT- és a CÍMSÍN (adat- és címbusz) áttekintésével kezdjük (jelük: D = data = adat(ok), A = address = cím). A SÍN nem más, mint egy párhuzamos vezetékrendszer, amelyben minden vezetéknek ugyanaz a feladata: címsín esetében a tárcím, adatsín esetében az utasítások és adatok továbbítása. A 3.b. ábrán látható, hogy 16 címvezeték (A0 ... A15) és 8 db. Adatvezeték (D0 ... D7) hagyja el a mikroprocesszort, így digitális rendszerről lévén szó, 2^16 = 65536 féle cím- és 2^8 = 256 féle adatkombináció továbbítása lehetséges. Feleltessünk meg az egyes vezetékeknek bináris helyértékeket a következő módon:
A0 A1 A2 ... A15 D0 ... D7 |
= 2^0 = 2^1 2^2 2^15 2^0 2^7 |
( =1 ), ( =2 ), ( =4 ). ( =32768) ( =1 ) ( =128 ) |
Így már az összes cím- és adatkombináció leírható akár tízes számrendszerbeli (decimális) számok formájában is. Az A. függelék p1. megmutatja tízes és tizenhatos (hexadecimális) számrendszerbeli számok formájában, hogy az egyes utasításoknak milyen kombináció fezez meg az adatsínen. A B. függelékben viszont éppen ellenkezőleg, a számokhoz tartozó utasításokat találjuk meg. Mindkettőre igen gyakran lehet szüksége a gépi kódú programozónak. Az adatként megjelenő bináris jelkombinációk jelentését a C. függelék foglalja össze.
A sínek jelforgalmát a központi egység vezérlőjelekkel szabályozza. Ezek két alapvető csoportra oszthatók:
A rendszervezérlő jelek feladata a Z80 köré kiépített elektronikai áramkörök vezérlése. Ezek a következők (részletesebb ismertetésükre még visszatérünk):
Az előbbi jelekkel a Z80-as vezérli a köré épített számítógépes rendszer működéséhez alapvetően szükséges áramköröket. Nyilvánvaló, hogy ez a vezérlőjelkészlet minden mikroprocesszornál adott, de hogy a felhasználó mit és hogyan használ ki belőlük, az a rendszertervezéstől függ. |
3.b. ábra: A Z80A mikrop. kivezetéseinek fizikai elrendezése |
Egy számítógép áramköreinek működési sebessége jelentősen eltérhet egymástól. A Z80-nál lassabb áramkörhöz tehát a Z80-nak "alkalmazkodnia" kell. Hogy ez megvalósítható legyen, szükség van a mikroprocesszort vezérlő jelekre. Ezek a következők:
A Z80-ast vezérlő jelek közé sorolhatjuk, bár rendszerint közéjük nem tartozóként kezelik a fennmaradó három jelet:
4. ábra: a Z80A órajelének feszültségfüggvénye
Z80A ciklusok
A 3.a. ábrán látható utasításregiszter feladata az utasítások ideiglenes tárolása. A központi egység ebben tárolja le az utasításokat, majd dekódolja. A vezérlő előállítja a szükséges rendszervezérlő és a mikroprocesszor belső működését biztosító jeleket.
A Z80-as működése hardver szempontból ciklusokból tevődik össze. Ezek a következők:
5. ábra: A központi egység működése
A központi egység működésének folyamata az 5. ábrán látható. Bekapcsolás, után egy utasításelérési ciklust hajt végre, s a tárból elsőként kiolvasott kódot így utasításnak értelmezi. Ha ez azt jelenti, hogy adatot kell hívni a tárból, akkor egy tárolvasási ciklust hajt végre a következő (az 5. ábrán pl. a 0001-es) tárcímről.
De ha pl. azt jelenti, hogy adatot kell kivinni egy periféria-áramkörre, akkor perifériaírási ciklus történik. Ha az utasítás kizárólag a mikroprocesszor belső működésére vonatkozott (pl. adatátvitelre vonatkozott a Z80-as egyik belső regiszteréből a másikba - 3.d. ábra -), akkor a következő, tehát az 5. ábrán a 0001-es címen lévő kódot is utasításnak értelmezi, így automatikusan egy utasításelérési ciklus hajtódik végre. Könnyen észrevehető, hogy a Z80-as bármely hardverfunkciója leírható ezen ciklusok valamelyikével (kivéve a HALT állapotból való kilépést). Ennek viszont az is következménye, hogy bármely Z8O-as utasítás összetehető a megfelelő ciklusok egymás után rakásából.
Az utasításelérési ciklus időzítése a 6.a. ábrán látható. A rajta szereplő idők értékei a következők:
Idö (ns) |
Min. |
Max. |
Idő (ns) |
Min. |
Max. |
A C E G I K M O Q S U W Y |
110 - 250 65 - - 110 - - - - - - |
- 30 - - 85 85 - 95 0 100 90 0 120 |
B D F H J L N P R T V X |
110 - - - 80 220 - 70 - - 35 - |
2000 30 1120 85 - - 85 - 95 100 - 130 |
(Az itt és a továbbiakban közölt adatok Z80A-ra vonatkoznak, így közvetlenül használhatók a ZX Spectrum mikroprocesszorának esetleges vizsgálatához. Nem használhatók viszont a Z80-ashoz és a Z80B-hez!)
6.a. ábra: A Z80A utasításelérési ciklusának időviszonyai
Utasításeléréskor az első órajelciklusban a PC regiszter tartalma a címsínre kerül. Mint látható, késleltetési ideje van, ezért nem alkalmas arra, hogy a kivitel pillanatában a dekódoló áramkör a tárba olvassa. Kb. fél órajellel később lesz aktív a MREQ. jel, így közvetlenül ez használható a ZX Spectrumban található tárak CE bemeneti feszültségeként. Az RD jel aktivizálása azért szükséges, mert jelzi a tárak számára, hogy csak adatkiolvasásról van szó. Késleltetési ciklus kizárólag akkor keletkezik, ha a WAIT vonal a 6.a. ábrán látható módon aktív. Szükség lehet rá kis sebességű perifériák csatlakoztatásakor. Az M1 azt jelzi, hogy a címsínen PC tartalom található. A ZX Spectrum nem használja ezt a jelet, így a többi ciklus ismertetésekor már nem térünk ki rá. A ciklusok időzítési diagramjaiból leolvasható, hogy miként használják - ha szükséges - perifériák vezérlésére. A harmadik és a negyedik órajelciklus a sínek felé a dinamikus tárak frissítési ciklusa. Az RD jel nem aktív, így tártartalom nem kerül az adatsínre. Még a második ciklusban eggyel nagyobb lesz a PC tartalma, ez azonban nem kerül rá a címsínre. Az adat (utasítás), ha nincs szükség WAIT periódusok közbeiktatására, a második órajel alatt jelenik meg az adatsínen. A harmadik periódus fezfutó élének hatására a RD és a MREQ passzív állapotba kerül vissza, s megjelenik a címsínen a frissítési cím. Stabilizálása után a MREQ jel ismét aktív, így lehetővé válik a dinamikus tárak frissítése. Közben szintén a harmadik órajel felfutó élének hatására a Z80 mintavételezi az adatsínt, és tartalmát az utasításregiszterbe helyezi. Hogy ezután mi történik, a többi ciklus ismertetése után egy példán mutatjuk be.
A tár- (adat-) író és -olvasó ciklus nagymértékben hasonlít egymásra, így adataikat is egyben közöljük:
Jel |
Min. (ns) |
Max. (ns) |
A B C D E F G H I J K L M N O P Q R |
- - - 80 65 70 - - - - 50 70 - 220 - - 80 60 |
110 85 85 - - - 0 95 85 80 - - 80 - 80 150 - - |
6.b. ábra: a Z80A tárírási és -olvasási ciklusának időviszonyai
Mivel az utasításelérési ciklusok a dinamikus tárak számára a legrosszabb esetben is a szükséges frissítési időn belül jelentkeznek, így erről -a kivételes esetektől eltekintve - a többi ciklusnál már nem kell gondoskodni. A táríró és -olvasó ciklusok rövidebbek is, WAIT állapotok nélkül három órajelnyi ideig tartanak. Az első periódusban a PC stabilizálódása után aktívvá válik a MREQ jel, s ezúttal is használható CE-ként, nem kívánva külön kapcsolási megoldást. olvasáskor az adat hasonló módon kerül a központi egységbe, mint az utasításelérési ciklusnál. Adatkivitelnél természetesen előbb stabilizálódik az adatsín tartalma, s csak utána adja ki a Z80 az írásengedélyező jelet a tárak számára. Ez a WR jel. A WAIT periódusok közbeiktatása tárírásnál az olvasáshoz hasonlóan alakul.
Perifériaírási és -olvasási ciklusok (l. a 6.c. ábrát ) szintén hasonlóak:
Jel |
Min. (ns) |
Max. (ns) |
A B C D E F G H I J K L M N O P Q |
- - - 180 70 - - - - 50 - - - - 10 - 60 |
110 75 85 - - 0 85 85 90 - 0 65 80 150 - 90 - |
6.c. ábra: A Z80A perifériaírási és -olvasási ciklusainak időviszonyai
Mind perifériaolvasási, mind -írási ciklus esetén automatikusan beiktatódik egy WAIT állapot. Emiatt ezek a ciklusok négy órajelnyi ideig tartanak minimális esetben, így a ZX Spectrumnál is. Ennek oka a Z80-as működésében rejlik. Az IORQ és a WAIT közti idő nagyon rövid lenne a bemeneti, vagy kimeneti eszköz vezérlésekor a portcím dekódolására és a WAIT aktivizálására. Kimeneti áramkör vezérlésekor a WR jel használható az adatsín tartalmának beírására (a tárírásnál látott CE-hez hasonlóan) az eszköz, vagy meghajtó áramkörének puffer- (ideiglenesen az információt tartalmazó) regiszterébe.
Itt talán még a táraknál is változatosabb az illesztési lehetőség, mivel ahány periféria-áramkör, annyi meghajtási módszer. Általános esetben (pl. személyi számítógépek billentyűzetének illesztésekor) a tervezők a Z80-ashoz gyártott PIO (Peripherial Input-Output circuit = bemenet / kimeneti áramköröket meghajtó integrált áramköri elem) áramkört használják, a ZX Spectrumban viszont nem így van, mivel erre a feladatra is kiválóan megfelelt az ULA, a gép berendezésorientált áramköre, s így helymegtakarítás vált lehetővé. Ennek ellenére amatőr áramkörök illesztéséhez érdemes vele foglalkozni.
A logikai működést biztosító ciklusok közül hátra van még három különböző megszakításkérési ás -elfogadási ciklus. Mivel ezek lényegesen eltérnek egymástól, a sínkérés / elfogadás, a nem maszkolható megszakításkérés / elfogadás és a maszkolható megszakításkérés / elfogadás időviszonyait külön megadjuk.
Sínkérés/elfogadás (6.d. ábra) esetén az időviszonyok:
Jel |
Min. (ns) |
Max. (ns) |
A B C D E F G |
50 0 - - - - - |
- - 100 100 90 90 80 |
6.d. ábra: A Z80A sínkérés / elfogadás ciklusainak időviszonyai
Nem maszkolható megszakításkérés / elfogadás (6.e. ábra) ciklus esetén:
Jel |
Min. (ns) |
Max. (ns) |
A B C D E F G H I J K L |
80 - - - - 110 - - - 220 - - |
- 110 100 100 85 - 85 95 85 - 130 120 |
6.e. ábra: A Z80A nem maszkolható megszakításkérés / elfogadás ciklusainak időviszonyai
A maszkolható megszakításkérés / elfogadásé (6.f ábra) pedig:
Jel |
Min. (ns) |
Max. (ns) |
A B C D E F G H I J K L M |
80 - - 180 - - - 65 70 - - 35 - |
- 0 110 - 100 85 85 - - 0 90 - 0 |
6.f. ábra: A Z80A maszkolható megszakításkérés / elfogadás ciklusának időviszonyai
A BUSRQ jelet a Z80 minden gépi ciklusa utolsó órajelének felfutó élénél mintavételezi. Ha aktív, a következő periódus felfutó élénél harmadik állapotba helyezi a síneket és a megfelelő vezérlőjeleket. Ekkor a Z80 teljesen felfüggeszti a rendszervezérlést: mind a dinamikus tárfrissítést, mind pedig a programvezérlést a megszakítást kérő eszköznek kell ellátnia. A BUSAK jelzi az eszköz számára, hogy átveheti a vezérlést. Megfelelő esetben ez nem okoz gondot a frissítésnél, mivel a dinamikus tárak általában 2 ms-ig bírják frissítés nélkül. Természetesen a Z80 ekkor másik két megszakítás bemenetét, az NMI és az INT jelzőket sem figyeli.
Nem maszkolható megszakításkérés jelzésére egy külön egybites tároló (NMI latch) van a mikroprocesszorban. Ha a bemenet aktív állapotba kerül, átállítja a tároló tartalmát, ami értelemszerűen csak két értéket vehet fel. Ezt minden ciklus végén, a sínkéréshez hasonlóan megvizsgálja a központi egység belső vezérlése. Ha aktív állapotban találja, elmenti PC tartalmát a verembe, letiltja a maszkolható megszakításkérés elfogadását, majd elugrik a 102-es címre (102 kerül a PC-be), azaz onnan folytatja tovább működését. Így ettől a címtől kell, hogy kezdődjön annak az eszköznek a működtetési rutinja, amelyik a megszakítást kérte. Ilyen eszköz azonban a ZX Spectrumban nincs. Ez a cím a ROM-ban található. Van ugyan itt egy rutin, amely kifejezetten külső, amatőr berendezések, eszközök NMI kérésének kiszolgálására készült, szoftverhiba miatt azonban nem használható.
A maszkolható megszakításkérés programból engedélyezhető, vagy tiltható oly módon, hogy a megfelelő utasítás (DI, EI) aktív, ill. passzív állapotba helyez egy egybites tárolót. Ez dönti el, hogy a Z80 elfogadhat-e megszakításkérést az INT bemeneten. Az is programutasítással dönthető el, hogy ha ilyen megszakításkérés érkezik, mit csináljon a mikroprocesszor (IM0, IM1 és IM2 utasítások), azaz hova ugorjon. Ezzel gyakorlatilag csak a belső tárkapacitás szab határt annak, hogy hány megszakítást kérő periféria-áramkör kapcsolható a Z80-ra. Lehetőség van arra, hogy ennek a megszakításkérésnek az elfogadását hardver úton jelezze a központi egység a perifériát vezérlő áramkör számára, mégpedig oly módon, hogy az M1 és az az IORQ jel egyszerre lesz aktív. Az eszköz számára ez pl. kapuáramkörök közbeiktatásával válhat értelmezhető jellé. Ha a Z80 a kérést elfogadja, csak akkor generálja a 6.f. ábrán bemutatott ciklust.
Az IORQ jelzi, hogy a címsín alsó nyolc bitje ezúttal a megszakításkérő eszközről jön.
A Z80 működésének része további két speciális ciklus is. az egyik ilyen (6.g. ábra) a HALT és a HALT-ból való kilépés ciklusa. Ha a programozó kiad a központi egység számára egy HALT utasítást, az mindaddig üres (NOP) utasításokat hajt végre, amíg maszkolható, vagy nem maszkolható megszakításkérés nem érkezik. Természetesen ekkor is folytatja a tárfrissítést, mivel a NOP ugyancsak egy utasításelérési ciklusból áll. Ebben az esetben aktív a HALT kimenet is. a 6.g. ábrán látható két idő értéke:
Jel |
Min. (ns) |
Max. (ns) |
A B |
- 80 |
300 - |
6.g. ábra: A Z80A HALT ciklusának időviszonyai
A másik speciális ciklus a RESET ciklus, amelynek végrehajtásához a RESET bemenetnek legalább három órajelen át aktívnak kell lennie, hogy a Z80 elfogadja. Ekkor a központi egység alapállapotba kerül, s a PC-be 0 íródik, így a Z80 onnan folytatja működését. Ha valaki a rendszerkimeneten ezzel a jellel kísérletezik, rájöhet, hogy azonos értékű egy RANDOMIZE USR 0 utasítással, ha BASIC, ill. egy JP o-val, ha pl. egy saját gépi kódú rutin éppen elérhető. Ezzel a módszerrel elkerülhetjük, hogy meg kelljen szakítani a tápfeszültség-ellátást valamelyik vezeték kihúzásával. Az előbbi megszakítás módnál említett szoftverhiba miatt ugyanazt a hatást érhetjük el NMI-vel is. A RESET ciklus időzítésének (6.h. ábra) fontosabb értékei:
Jel |
Min. (ns) |
Max. (ns) |
A B C D E F |
60 - - - - - |
- 0 90 90 110 100 |
6.h. ábra: a Z80A RESET ciklusának időviszonyai
A fejezet elején leírtuk, hogy minden utasítás összerakható ciklusokból, s az utasításelérési ciklusnál pedig megígértük hogy elmondjuk mi történik a negyedik órajel alatt. Nézzünk egy példát! Feltételezhetjük-e, hogy a SUB n utasítás esetében a kivonás az előtt kerül végrehajtásra, mielőtt a kivonandó bekerül a tárból a mikroprocesszorba csak azért, mert az utasításelérési ciklus megelőzi az adatbeolvasási ciklust? A válasz természetesen nem.
Nézzünk egy egyszerűbb utasítást: a LD D,E -t! Elméletileg ez egy gépi ciklusos (utasításelérési ciklusos) és - mivel a ZX Spectrumban nincs kívülről beiktatott WAIT állapot - négy órajelnyi processzoridőt kívánó parancs lenne. A gyakorlatban a helyzet a következő: az első órajel alatt a PC tartalma rákerül a (címsínre, a második alatt eggyel megnő. A harmadik órajel alatt kerül az utasítás a Z80-ba, de egyenlőre csak az utasításregiszterbe, és a dekódoló áramkör azonosítja. A negyedik alatt azonban az E regiszter tartalma egy ideiglenes belső regiszterbe kerül, s csak egy következő ciklus első órajelével egyidejűleg kerül be a D regiszterbe. A Z80, mint a legtöbb nagy bonyolultságú digitális áramkör, szekvenciális hálózat. Sorrendi változást pedig a tranzisztorok állapotában a jelváltozás, tehát jelen esetben az órajel periodikus változása hozhat létre. A 6. ábra diagramjaiból is egyértelműen kitűnik, hogy egy-egy folyamat közvetlenül az órajel lefutó, ill. felfutó élének hatására indul el, vagy - a Z80 belső szervezése miatt - az ehhez képesti minimális és maximális eltérést adják meg, ahol ez áramkörileg esetleg indokolt lehet. Nincs tehát kizárva, hogy egy órajelváltozásra több folyamat lejátszódjon a processzoron belül, csak esetleg nem szabad ugyanazt az áramköri elemet használniuk. Ez történik a LD D,E utasítás "ötödik" órajelénél is: miközben az ideiglenes regiszter tartalma átíródik D-be, a PC már kikerül a címsínre. Vegyük észre, hogy az alapvető ciklusok rendszerint úgy kezdődnek, hogy a PC tartalma a címsínre kerül. Így más ciklusoknak sincs módjában megzavarni a LD D,E utasítás befejezését.
Nézzünk egy másik példát! A SUB C utasítás már aritmetikai művelet végzését is előírja. Az első három órajel-periódus alatt ugyanaz történik, mint az előbbi példában: végrehajtódik az utasításelérési ciklus első három lépése. 4 negyedik alatt C tartalma az ideiglenes regiszterbe, A-é pedig egy átmeneti akkumulátorba kerül. Azt várnánk, hogy a következő órajelre, ami egyben az utána jövő ciklus első üteme is, az aritmetikai-logikai egység végrehajtja a kivonást. Nem így van: az ötödik órajel alatt nem történik semmi, s csak a következő órajel alatt fejeződik be az utasítás, amely ezáltal két órajellel lett hosszabb, mint sejthetnénk. Ennek már alaposabb belső okai vannak: a regiszterkészlet RAM-ként, írható-olvasható tárként viselkedik a Z80 belső áramkörei alkotta egyéb rendszerek felé. Ebből következik, hogy amíg a PC tartalma a belső sínrendszeren keresztül a címsínre kapuzódik, az aritmetikai-logikai egység nem érheti el. Pedig az ALU-ból kikerülő eredmény az A (Akkumulátor) regiszterben (l. 3.d. ábra) képződik, összefoglalva a SUB C utasítás órajeleire végbemenő változások (jelöljük T-vel az egyes órajelciklusokat):
T1: | a PC regiszter tartalma a címsínre kerül; T2 |
T2: | PC = PC + 1; |
T3: | az adatsín tartalma az utasításregiszterbe kerül, s a dekódoló egység "megfejti"; |
T4: | C tartalma az ideiglenes regiszterbe, A-é az ideiglenes akkumulátorba kerül; |
T5: | az utasítás végrehajtása szempontjából nem történik semmi; |
T6: | A = ideiglenes akkumulátor tartalma mínusz az ideiglenes regiszter tartalma. |
Több utasítást megnézve sok másféle megoldást is kapunk, s végezetül a legrészletesebbet akkor, ha ismerjük a Z80 tranzisztorszintű kapcsolását. Erre azonban nincs mód, de nem is szükséges a ZX Spectrum mint rendszer megismerése, sem a gépi kódú programozás szempontjából.
A Z80 utasításkészlete
Alapesetben egy 8 bit szélességű adatsínnel rendelkező mikroprocesszornál 256 féle adat továbbítása lehetséges, tehát 256 féle utasításé is. Ha azonban bevezetjük a sorrend tényezőt, tehát megjelölünk kitüntetett számot (számokat), akkor még egy utasításkódot vár a mikroprocesszor (több utasításelérési ciklussal hajtódik végre egy Z80 programutasítás), többszörösére nő a lehetséges utasításkódok száma. Ha pl. 256 szám közül csak egynek feleltetünk meg ilyen funkciót, 511-re, mivel ekkor az alapesetben 255, s a kitüntetett szám után még további 256 szám használható utasítás céljaira. A Z80-on négy ilyen kitüntetett szám van: a 203, a 221, a 237 és a 257. Így a kombinációk száma nemcsak egyszerűen négyszer lesz több, mint az előző esetben, hiszen egymás után rakhatunk két vagy három belépési kódot is. Hogy az A. függelékben csak 788 különböző Z80 utasítást soroltunk fel, annak az az oka, hogy a mikroprocesszor szüntelenül bővítés alatt áll, és a fejlesztéseket egy belső rendszer szerint viszik véghez. Alulról kompatibilis a Z80-nal az INTEL cég 8080-as mikroprocesszor-típusa, amely még kevesebb, mint 256 utasítással rendelkezik. Ezeknek egytől-egyig megfeleltethető a Z80-asban belépési kód nélküli (egy bájtos) utasítás, amelyet nem előz meg kitüntetett szám. A B. függelék az összes ilyen kódot tartalmazza.
Az utasításkódok legsokatmondóbbak bináris formában, hiszen ekkor sok adatot kapunk a Z80-as működésére vonatkozólag, s összevetve őket, gyorsan megállapíthatunk bizonyos összefüggéseket. Tömörebb leírásra, pl. felsoroláshoz (l. Novotrade Z80 programozási táblázatok) igen gyakran foglalják össze a kódokat hexadecimális számrendszerben. Pl.
B0110 0011 = H63 vagy
B1101 1001 = HD9 ,
ahol B a bináris, H a hexadecimális szám jelölésére szolgál. Megesik, hogy a ZX Spectrumon egy kódot közvetlenül kell bevinni a tár egy bájtjába (1 bájt = 8 bit). Ekkor a POKE utasítást használjuk, s a kódot közvetlenül tízes számrendszerbeli szám formájában visszük be. Ugyanez a helyzet, ha PEEK-kel meg akarjuk nézni egy tárrekesz (egy bájt) tartalmát. Az utasításkódokból azonban -különösen Z80-on - túl sok van ahhoz, hogy szám szerint megjegyezzük. A könnyebb programozás kedvéért más, funkciók szerinti csoportosításukra van szükség. Ezt biztosítja a Z80 assembler, az utasítások célszerű angol nyelvű rövidítések szerinti rendszerezésével. Csaknem annyiféle assembler létezik, ahány processzor.
Ezek közt az egyik leglogikusabb a Z80-é. "ADD A,L" pl. azt jelenti, hogy add hozzá A regiszter tartalmához L tartalmát. Általában az utasítások:
"MŰVELET" "1. operandus azonosítója", "2. op. az."
alakúak, de ha z80 assemblerben programozunk, tegyünk egyszerűen a következő szabály szerint:
ADD | A | ,L |
"mit" | "hová" | , "honnan". |
A "mit" jelen esetben műveletet jelent, a "hová" nemcsak azt, hogy a művelet eredménye ott képződik, hanem adott esetben értelemszerűen a művelet egyik operandusát is. Egy művelet után ismét annak funkciójától függően állhat egy operandus is, ill. egy se (pl. DJNZ d, ill. HALT).
Sajnos a Z80 assembler elődjében, a 8080 assemblerben a rövidítéseket még nem így állították össze, mivel ott nincs ennyi kód. Ennek néhány rövidítése változatlan, vagy "Z80-asíott" formában átkerült a Z80 assemblerbe. Ilyen pl. a SUB L utasítás, amely helyett - ha az előbbi szabály szerint jártunk volna el - SUB A,L -t kellene írni. Azonban minden olyan esetben, amikor a művelet két operandust kívánna, de csak egy van, a "hová" helyén az A regiszter áll.
Ha valamelyik operandus zárójelben van, címet jelent (az esetek túlnyomó többségében 16 biteset, mivel 16 bit szélességű a címsín, azonban a perifériacímek 8-bitesek). Pl. a
LD (HL),A
utasítás azt jelenti, "töltsd a HL regiszterben található számú tárcímre az A regiszter tartalmát", vagy az
OUT (C),A
azt, hogy "vidd ki a C-ben található számú portra az A tartalmát".
A Z80 regiszterei, veremkezelés
Itt csak azokkal a regiszterekkel foglalkozunk, amelyek valamilyen formában hozzáférhetőek a z80, így a ZX Spectrum programozói számára is. Ezek a 3.d. ábrán láthatóak.
Az A (akkumulátor) kitüntetett 8-bites regiszter. Benne képződik az összes 8-bites aritmetikai és logikai utasítás végeredménye. Az F (flag regiszter) 8-bites állapotregiszter. Funkciója olyan sokrétű, hogy önálló fejezetet igényel (l. a következő szakaszt). Néhány utasítás A-t és F-et együtt kezeli egy 16 bites regiszterként AF néven. A B, C, D, E, H és L regiszter belső tár, amellyel műveleteket lehet végezni a Z80 utasításkészlet szabályai szerint. Bizonyos esetekben ezekben is képződhetnek eredmények. Pl. a DJNZ d esetében a B számláló funkciót tölt be. A BC, DE és HL 16 bites regiszterek az előbbiek összerakásából jönnek létre AF-hez hasonlóan. Ennek az az értelme, hogy bizonyos műveletek csak két regiszterrel együttesen 16 biten végezhetők ez. Pl. ilyen az előbb említett LD (HL),A utasítás, de pl. az ADD HL,BC is, amely azt jelenti, hogy "add hozzá HL tartalmát BC-hez és az eredmény képezd HL-ben". Az IX és az IY két 16 bites regiszter, amelyek indexelt címzési módnál a báziscímet tartalmazzák. A későbbi fejlesztések során nyílvánosságra hozott utasítások lehetővé teszik, hogy külön felső és alsó nyolc bitjükkel is műveleteket lehessen végezni. (A ZX Spectrumhoz sokféle assembler van forgalomban. Ezeket a többletutasításokat az EDITAS 48K, az EDITAS 16K, vagy a MONEDITAS program fogadja el.) Az I regiszter tartalma, ha a Z80 IM2-ben (vektoros megszakítási üzemmódban) van, a címsín felső nyolc bitjére kerül, a megszakítást kérő eszköz pedig az alsó 8 bitet szolgáltatja.(Az I 8 bites regiszter.) Mindössze két utasítás van, amelyik ezzel a regiszterrel foglalkozik: a "LD A,I és a "LD I,A" utasítás. I azért szerepel a 3.d. ábrán R mellett, mert frissítéskor tartalma a címsín felső 8 bitjére kerül. (Emiatt jelölik néhány helyen "IR" regiszterként. Nincs azonban olyan Z80 utasítás, amely ilyen regisztert kezelne.) |
3.d. ábra: a Z80 (és a Z80A) regiszterei |
Az R regiszter ugyanúgy két utasítással használható: "LD A,R"-rel és "LD R,A"-val. 7-bites regiszter. Tartalma minden utasításelérési ciklus után eggyel nő (inkrementálódik). Noha programból kezelhető, csak speciális esetben, pl. hardverteszteléskor szokták használni. Frissítéskor tartalma a címsínen jelenik meg.
A PC (Program Counter) programszámláló regiszter szerepe legjobban az előző szakasz diagramjai és magyarázatai alapján érthető meg. Utasításeléréskor mindig az elérendő parancs címét tartalmazza, s még a cikluson belül meg is nő eggyel (inkrementálódik). Ugrásutasításkor (pl. JP) az ugrás címe felülírja a címsínt, azonban relatív ugráskor (JR) éppen az utasításelérési ciklus korai PC inkrementálását kell számításba vennie a programozónak.
Az AF' , BC' , DE' és HL' regiszterek alkotják az ún. alternatív regiszterkészletet, amely onnan kapta nevét, hogy programból szabályozható, hogy melyiket használjuk. Az EXX utasítás kicseréli BC tartalmát BC'-ével, DE-t DE'-vel HL-t H'-val, vagy legalábbis így viselkedik a programozó számára. Ezt azonban úgy is felfoghatjuk, hogy választási lehetőséget biztosit két regiszterkészlet között. Ilyen megvilágításban midig a használt regiszterkészlet a vessző nélküli. Az AF és az AF' közti választási lehetőséget az EX AF,AF' utasítás biztosítja, amely az előbbivel analóg módon felcseréli e két regiszterpár tartalmát. Legtöbbször szubrutinhívás előtt használjuk az aktuális regisztertartalmak elmentésére, ezért gyakran az alternatív regiszterkészlet "második veremnek" vagy "belső veremnek" is nevezik.
A belső verem mellett logikusan külső verem (stack) is van, amelynek az előbbihez hasonló a feladata, de a külső tárban helyezkedik el. Fel használásának egyik módja az, hogy regisztertartalmat mentünk el bele, majd bizonyos műveletek után visszahozzuk. Pl. a BC elmentése a verembe a
PUSH BC
utasítással történik. Ha az SP (Stack Pointer regiszter = veremmutató regiszter) tartalma a PUSH BC előtt egy (0 és 65535 közötti) tetszőleges egész szám, pl. z volt, utána z-2 lesz. Ennek oka, hogy a regiszterpár 16 bites adattárolási módjának megfelelően B tartalma a z-1-edik című, C-é pedig a z-2-edik című bájtba íródik.
Ezzel ellentétes a
POP BC
utasítás. Ezután SP tartalma - ha előtte z volt, - z+2 lesz, s z tartalma B-be, z+1-é pedig a C-be íródik. Az AF, BC, DE, HL, IX és IY regiszterek tartalma menthető el és hozható vissza ily módon. A tárolásnál érvényesül a LIFO (Last In First Out) elv, ami azt jelenti, hogy ha folyamatosan használjuk, annak a regiszternek kerül ki először a tartalma, amely utoljára beíródott. Innen a verem elnevezés.
A verem második felhasználási módja jelentősen eltér az előzőtől: minden szubrutinhíváskor ide mentődik el a PC tartalma (ez már az inkremertált tartalom), mielőtt a szubrutinra kerülne a vezérlés. Ilyen szubrutinhívó Z80 assembler utasítás pl. a CALL, amely a BASIC GOSUB-jának felel meg, míg vele szemben a JP-nek a GO TO. Általában kevés hasonlóságot találni a BASIC és a Z80 assembler közt, mivel az előbbi egy magas szintű programnyelv, a megfeleltetés azonban igen szemléletes. A GOSUB után RETURN kell, a CALL után RET, s ennek hatására a verem tetején lévő szám a PC-be kerül. Gépi kódban nemcsak a CALL, hanem az RST (ReSTart) utasítás is szubrutinhívás, csak fix címre. A maszkolható megszakítás szubrutinjából a RETI (RETurn from Interrupt), a nem maszkolhatóéból a RETN (RETurn -(rom Non-maskable interrupt) utasítással lehet visszatérni.
Meg kell jegyezni, hogy a ZX Spectrum ROM programozói igen gyakran használnak egy speciális visszatérési módot, amely nem más, mint a kétféle veremhasználat egyesítése. Egy rutinban PUSH utasítással a verembe raknak egy számot, majd RET utasítással ráadják a vezérlést. Természetesen az utóbbi használatkor is érvényes az, amit az adatok elmentésénél leirtunk.
Az állapotregiszter
Az állapotregiszter (flag register) az állapotjelző biteket (flageket), más néven az "egybites jelzőáramköröket" tartalmazza. Műveletek hatására ezek a bitek, felvesznek bizonyos értékeket, s vannak olyan utasítások, amelyek lehetővé teszik, hogy ennek alapján a vezérlés más területekre (tárcímekre) adódjon át, azaz a feltétel számára kiszolgálórutin készíthető legyen. A felsorolt jelzőbitek (3.c. ábra) leírásában a következő jelöléseket alkalmazzuk:
bsz | = bitszám, értéke 0-tól 7-ig változhat, |
g | = 8-bites operandus, |
s | = 16 bites operandus, |
r | = A, B, C, D, E, H és L regiszterek valamelyike. |
7 S |
6 Z |
5 |
4 H |
3 |
2 P/V |
1 N |
0 C |
Sign bit |
Zero bit |
X |
Half carry bit |
X |
Parity- oVerflow |
Substract bit |
Carry bit |
Előjel bit |
Nulla eredményt jelző bit |
Félátvitel jelző bit |
Párosság-túlcsordulást jelző bit |
Kivonást jelző bit |
Átvitelt jelző bit |
3.c. ábra: A Z80A mikroprocesszor státuszregisztere (jelzőbitkészlete)
Egységes 8-bites regiszterkészletként a jelzőkészlet, amely a felsorolt bitek mellett két határozatlan állapotú bitet is tartalmaz (3.c. ábra) , 3 utasítással kezelhető. Ezek:
PUSH AF
POP AF
EX AF,AF'
A 3.c. ábrán látható jelzőbiteket balról jobbra sorra véve:
S (Sign flag): előjel-jelzőbit. Lehetővé teszi, hogy a műveletek eredményeképpen kapott számokat kettes komplemensűként értelmezzük, mivel az akkumulátor 7-es bitjének tartalmát veszi át. A rá vonatkozó feltételes ugrás és szubrutinhívó utasítások: 7. ábra: számóra |
Az S-t befolyásoló utasítások:
ADC A,g | ADD A,b | ADC HL,s | CP g | DEC g |
DAA | CPR | CPIR | CPD | CPDR |
SBC HL,s | RL g | RLC g | RR g | RRC g |
SLA g | SRA g | SRL g | RLD | RRD |
SUB g | INC g | Xor h | OR g | AND g |
NEG | LD A,I | LD A,r |
Z (Zero Flag): zérus-jelzőbit. Értéke egy, ha az aktuális művelet eredménye nulla, egyébként nulla. Általában összehasonlító utasítások után használják: ha a változó értéke megegyezik az összehasonlított értékkel, Z=1, egyébként Z=0 lesz.
Hasznos a BIT utáni alkalmazás, amelynek eredményeképpen Z=1, ha a vizsgált bit értéke 0 és Z=0, ha a vizsgált bit értéke 1.
IN r,(C) utasítás után Z értéke 1, ha a beolvasott adat 0 és 0, ha nem.
IND, INI, OUTD és OUTI -nél Z=1, ha B-1=0 és 0, ha nem.
Ezenkívül a Z jelzőbitet befolyásoló utasítások:
NEG | LD A,r | LD A,I | INIR | INDR |
OUTR | OTDR | XOR g | INC g | DEC g |
ADC HL,s | SBC HL,s | RL g | RLC g | RR g |
RRC g | SRA g | SLA g | SRL g | BIT bsz,g |
CPI | CPIR | CPD | CPDR | INI |
DAA | ADC A,g | ADD A,g | AND A,g | SBC g |
SUB g | CP g | OR g | IN r,(C) |
H (Half carry flag): félátvitel- jelzőbit. A harmadik bitről a negyedikre történő átvitelt vizsgálja. Ha van átvitel, értéke 1, egyébként 0. Nincsenek olyan utasítások, amelyek H bit függvényében feltételesek. A H bit a BCD (Binary Coded Decimal = binárisan kódolt decimális) számokkal végzendő műveleteknél használatos. A BCD számok és bináris kombinációik szintén a C. függelékben találhatók. Adjunk össze két kis értékű BCD számot:
0001 0011 = |
D13 | |
+ 0001 1011 = |
D19 | |
0010 1100 = |
D32 | H=0. |
Programból ezt a következőképpen tehetjük meg: ha az egyik összeadandó az A, a másik a C regiszterben van, akkor:
10 ADD A,C
20 DAA
A DAA utasítás, ha az A regiszterben található szám felső négy bitjének értéke 0 és 9, míg az alsóé 10 és 15 közt van, s H bit nulla, akkor 6-ot ad hozzá az akkumulátor tartalmához, azaz ha
A = 0010 1100 DAA előtt, akkor
A = 0011 0010 (= D32) D4A után, mivel
0010 1100 |
+ 0000 0110 |
0011 0010 |
s így megkapjuk az akkumulátorban a helyes BCD eredményt. (BCD számoknál a felsorolásunkban az utolsó C átvitel-jelzőbit akkor 1, ha a felső négy bitről átvitel - tehát pl. a kapott BCD szám értéke 147. Ekkor a 100-as helyértéken lévő egyet C állapota jelöli.) Nézzünk most két nagyobb számot:
0001 1000 = |
D18 | |
+ 0001 1001 = |
D19 | |
0011 1100 = |
D37 | H=1. |
Az összeadás természetesen minden esetben az adott számrendszer helyértékeinek megfelelően történik, így - az előbbi összeadásokban is - bináris számokkal kettes, decimálisokkal tízes számrendszerben adunk össze. A bináris kódokat a Z80 aritmetikai műveletei - ellentétben néhány másik processzorral - minden esetben 0-tól 255-ig terjedő egész számoknak értelmezik. Az előbbi kétutasításos program most is megfelel arra, hogy helyes BCD eredményt kapjunk, az akkumulátorban. Ha A alsó négy bitjének értéke 0 és 3 közé esik, az előző esettel ellentétben van félátvitel. DAA ekkor ismét hatot ad az 4 regiszter értékéhez. Nézzük meg, hogy most is helyes eredményt kapunk-e:
0001 0001 = |
(A tart. DAA előtt) |
+ 0000 0110 = |
(hozzáadódik) |
0011 0111 = |
(A= D37) |
s ezzel megkaptuk a decimális összeadás helyes végeredményét.
P/V (Parity-oVerflow flag): paritást -(párosság-ellenőrzést) -, ill. túlcsordulást jelző bit. Már nevéből is látható, hogy funkcióját tekintve ez a legsokrétűbb.
Kezdjük a legegyszerűbb esettel: logikai műveletek után P/V = 1, ha az eredmény páros (even parity = páros paritás)és p/v = 0, ha páratlan (odd parity = páratlan paritás). Erre az esetre külön feltételjelölés van a Z80 assemblerben. Pl.:
JP PO,nn | (ugorj nn címre, ha P/V = 0, JumP on Parity Odd to nn) |
JP PE,nn | (ugorj nn címre, ha P/V = 1, JumP on Parity Even to nn). |
Másik esetben túlcsordulást jelez kettes komplemensű számokkal való műveletvégzéskor. A bináris kódok lehetséges kettes komplemensű jelentéseit a C. függelék foglalja össze. Az S bit kapcsán már volt róluk szó: ez a bit az ilyen számok előjele szerint veszi fel értékét, s ez természetesen -_aritmetikai műveletekről lévén szó - az akkumulátor 7. (balról az első) bitjének tartalma. A BCD számokhoz hasonlóan azonban itt sem kerülhetjük el a műveletvégzés problémáját, mivel ebben az esetben is érvényes, hogy az aritmetikai műveletek az operandusokat 0-tól 255-ig terjedő egész számként kezelik 8-bites esetben. A P/V jelzőbit feladata ekkor az, hogy jelezze, hogy a művelet eredményeképpen hibás szám keletkezett, mert kiesett a Z80 kettes komplemensű számábrázolási köréből. Ha egy szubrutinban (legyen a neve "COMPL") kizárólag erre vizsgálunk feltételt, elég, ha a következőt írjuk:
10 COMPL 20 30 40 50 ; |
ADD A,C RET PE ;hibás szám rutinja POP HL JP OKNUMB ;helyes eredmény rutinja |
Ebből az is következik, hogy P/V jelzőbit aritmetikai műveletek után négy esetben vesz fel 1 értéket:
A programból látható, hogy ha szubrutinként használják (azaz a 10-es sorszámú utasítástól pl. egy CALL-lal hívják meg), helyes eredmény esetén elugrik az OKNUMB rutinra, de előtte felszabadítja a vermet a CALL után letárolt PC értéktől, helytelen esetben pedig visszatér a szubrutinból, tehát a CALL után lehet elhelyezni ezt a rutint. Korrekciót nem végez, mint az előbbi esetben a DAA.
Nézzünk néhány példát:
0100 0000 = |
D64 |
+ 0100 0001 = |
D65 |
1000 0001 = |
D129 |
Sajnos korrekció csak programtechnikai úton érhető el. Ehhez pedig javarészt feltételes ugrásutasításokra ás logikai függvényekre van szükségünk. Nézzük az alapeseteket összeadásnál:
1. Két kis pozitív szám összeadása:
0100 0000 = |
D 3 |
+ 0011 0010 = |
D50 |
0011 0101 = |
D53 ( = 53) |
P/V=0 és C=0.
A C jelzőbittel azt vizsgáljuk, hogy ha a bináris kódokat 0 és 255 közötti számoknak fogjuk fel, a művelet eredményeképpen lesz-e túlcsordulás, Látható, hogy ez alapvetően másfajta túlcsordulás, mint a kettes komplemensű számoké. Azért közöljük, mert korrekciós rutinokhoz ennek ellenére igen jól használható.
2. Két nagy pozitív szám összeadása:
0111 1010 = |
D122 |
+ 0111 1011 = |
D123 |
1111 0101 = |
D245 ( = -11) |
P/V=1 és C=0.
3. Két kis negatív szám összeadása:
1111 1000 = |
- 4 |
+ 1111 1110 = |
- 2 |
1111 0101 = |
- 6 ( = -6) |
P/V=0 és C=1.
4. Két nagy negatív szám összeadása:
1000 0001 = |
- 127 |
+ 1000 0000 = |
- 128 |
0000 0001 = |
- 254 ( = +1) |
P/V=1 és C=1.
Van azonban a P/V bitnek néhány speciális alkalmazása is: CPD, CPDR, CPI, CPIR, LDD, LDDR, LDI és LDIR utasításoknál P/V=0, ha a számlálók értéke nulla. Mivel a számláló szerepét minden esetben a BC regiszter tölti be, P/V=0, ha (BC)-1=0.
Másik speciális alkalmazás az, amikor LD A,I és LD A,R utasításoknál P/V az ideiglenes megszakítás-jelzőbit tartalmát veszi fel. Ez pl. akkor használható, ha nem maszkolható megszakításrutin alatt szeretnénk megállapítani, hogy a processzor DI, vagy EI állapotban van-e, azaz egyébként elfogad-e maszkolható megszakításkérést. A ZX Spectrumban ez az alkalmazás a már említett ROM hiba miatt szóba sem jöhet.
A P/V bitet paritás (P) jelzőként használó utasítások:
SLA g | SRA g | SRL g | RR g | RRC g |
RL g | RLC g | RLD | RRD | DAA |
IN r,(C) | AND g | OR g | XOR g |
A jelzőbitet túlcsordulás (V) jelzőként használó utasítások:
ADC A,g | ADC HL,s | ADD A,g | ADD HL,s | CP g |
INC g | DEC g | NEG | SBC g | SBC HL,s |
SUB g |
valamint speciális módon használják a már előbb említett utasítások.
N (substract flag): kivonás-jelzőbit.
A DAA utasítás csak akkor ad helyes eredményt, ha a processzor jelzi számára, hogy a megelőző művelet összeadás, vagy kivonás volt. Értéke összeadás után 0, kivonás után 1. (A H-hoz hasonlóan N-re vonatkozó feltételes utasítások sincsenek.)
Az N-t -ra állító utasítások:
ADC A,g | ADC HL,s | ADD A,g | ADD HL,s | BIT bsz,r |
RR g | RRC g | RRCA | RL g | RLC g |
RLCA | RRA | RLA | RLD | RRD |
SRA g | SLA g | SRL g | IN r,(C) | LD A,I |
LD A,r | SVF | CCF | LDI | LDIR |
LDD | LDDR | AND g | XOR g | OR g |
Az N-t 1-re állító utasítások:
SBC g | SBC HL,s | SUB g | NEG | DEC g |
CP g | CPI | CPIR | CPD | CPDR |
INI | INIR | IND | INDR | OUTI |
OUTD | OTIR | OTDR | CPL |
C (Carry flag): átvitel-jelzőbit. Alapállapotban az átvitelt jelzi az akkumulátor 7. bitjéről a nem létező nyolcadikra, így pozitív bináris egész számokkal végzett műveleteknél túlcsordulásjelzőjeként lehet használni. Ez az aritmetikai utasításokban való használhatóságot jelenti. A C azonban nem emiatt a szinte leggyakrabban használt jelzőbit. A léptető- (shift) és forgató- (rotate) utasítások lényege, hogy a regiszterekből közvetlenül történhet bitátvitel a C-be és viszont a 8. ábrán látható módon. Igen sok esetben van erre szükség a ZX Spectrum gépi kódú programozásakor, s a ROM is sokat használja a C bitet ilyen formában. (Leggyakoribb a C-re vonatkozó feltételes utasítás, mivel C-re és Z-re van feztételes relatív ugrás is.)
8. ábra: A léptető és forgató Z80 utasítások funkciói
C értéke közvetlenül állítható utasításokból, mert SCF (Set Carry Flag) hatására 1-be, bármely logikai utasítás hatására 0-ba áll., Ilyen egybájtos utasítás pl. AND A, vagy OR A. Mindkettő 0-ba állítja a C bitet, de az akkumulátor tartalma nem változik, mivel pontos jelentése: AND A,A; vagy OR A,A lenne. A CCF (Complement Carry Flag) utasítás 1-be állítja C-t, ha előzőleg 0 volt, ill. 0-ba, ha 1.
Összefoglalva, a C jelzőbitet állító utasítások:
ADC A,g | ADC HL,s | ADD A,g | ADD HL,s | SUB g |
SBC g | SBC HL,s | AND g | XOR g | OR g |
SCF | CCF | DAA | NEG | RR g |
RRA | RRC g | RRCA | RL g | RLA |
RLC g | RLCA | CP g | SLA g | SRA g |
SRL g |
Címzési módok
A címzési módok ismerete nem szükséges elengedhetetlenül a Z80 programozásához, így a Zx Spectrum programozásához sem, viszont hasznos (pl. adatbázis-kezelő stb.) programok tervezésekor.
A ZX Spectrum címzési módjai (9. ábra):
9. ábra: Z80 címzési módok
Sajnos közvetlenül nem található meg, viszont programból előállítható az elméleti és gyakorlati szempontból egyaránt érdekes indirekt címzési mód (indirect addressing mode). Ekkor, mint a 10. ábrán látható, maga az operandus a változó, ami címet jelent. 10. ábra: Az indirekt címzés |
A Z80 utasításai
A Z80 utasításkészletét sokféle szempont alapján lehet csoportosítani. A két legfontosabb: a kód és az ábécé szerinti a B., ill. az A. fügelékben található. Funkció szerint a processzor utasításai a következő csoportokba sorolhatók:
A Z80 assembler lehetőséget nyújt, hogy ezeket funkcionális és mnemotechnikai alapon összegezzük. Ehhez a továbbiakban a következő jelöléseket alkalmazzuk:
r | az A, B, C, D, E, H és L regiszterek valamelyike; |
rr | a BC, DE, HL és SP regiszterek valamelyike; |
rrX | a BC, DE, IX és SP regiszterek valamelyike; |
rrY | a BC, DE, IY és SP regiszterek valamelyike; |
n | 0 és 255 közé eső 1-bájtos bináris konstans; |
nn | 0 és 65535 közé eső 2-bájtos bináris konstans; |
d | -128 és +127 közé eső 1-bájtos kettes komplemensű konstans; |
ii | az IX és az IY regiszterek valamelyike; |
iid | az (IX+d) és az (IY+d) címek valamelyike; |
xy | az XH, XL, XH és YL regiszterek valamelyike; |
bsz | bitcím (bitszám); |
op | operandus; |
cc | feltétel az S, Z, P/V és C jelzőbitekre; |
cc1 | feltétel csak a z és C jelzőbitekre. |
A jelzőbitekkel kapcsolatos rövidítések:
P | (positive number - pozitív szám) | S=0 |
M | (minus - negatív szám) | S=1 |
Z | (Zero - zérus) | Z=1 |
NZ | (Non-Zero - zérustól különböző szám) | Z=0 |
PO | (Odd Parity - páratlan szám) | P/V=0 |
PE | (Even Parity - páros szám) | P/V=1 |
C | (Carry -- van átvitel) | C=1 |
NC | (No Carry - nincs átvitel) | C=0 |
(A jelzőbiteknél már említettük, hogy nincs olyan utasítás, amellyel H vagy N jelzőbitre feltételt lehetne állítani, viszont bizonyos utasítások ezeket is használják belső működésükhöz.)
Az időzítési táblázatokban a mikroszekundumban megadott legutolsó értékek közvetlenül használhatók ZX Spectrumhoz, mivel a Z80A-ra vonatkoznak, 3,5 MHz-es órajel-frekvenciával.
Az op tetszőleges operandust jelöl (feladata az állapotregisztert bemutató szakasz g és s operandus jeleihez hasonló). Pontosabb tájékoztatást az "op:" felirat utáni leírásból kaphatunk.
A jelzőbitekre vonatkozó rövidítések:
1 | ha a művelet eredményeképpen a bit értéke egy |
0 | ha nulla; |
X | ha értéke a művelet eredményétől függ és |
? | ha a művelet után határozatlan állapotba kerül; |
- | ha értéke változatlan marad. |
A jelzőbitek együttesét F-fel jelöljük.
Táblázatunkban megadjuk az utasítások funkcióját, a jelzőbitek változását, a végrehajtáshoz szükséges gépi ciklusok és periódusok számát, ill. a Spectrumon való végrehajtásidejét mikroszekundumban kifejezve. Az utasításnevek az utasítás funkciójának angol nyelvű rövidítései. Kifejtésüket az A. függelékben közöljük.)
ADC A,op |
Add össze A-t, egy 8-bites operandust és a C jelzőbit értékét, s az eredményt képezd az akkumulátorban!
|
||||||||||||||||||||||||||||||||||||||||||||||||||
ADC HL,rr |
Add össze HL és az rr-ben foglalt regiszterpár, valamint a C bit aktuális értékét, s az eredményt képezd HL-ben!
|
||||||||||||||||||||||||||||||||||||||||||||||||||
ADD A,op |
Add össze A és egy 8-bites operandus értékét! Az eredmény keletkezzen az akkumulátorban!
|
||||||||||||||||||||||||||||||||||||||||||||||||||
ADD HL,rr |
Add össze HL és az rr-ben foglalt 16 bites regiszter tartalmát, s képezd az eredményt HL-ben!
|
||||||||||||||||||||||||||||||||||||||||||||||||||
ADD ii.op |
Add össze az ii-ben, valamint a másik 16 bites regiszterben található számot, s az eredményt képezd ii-ben!
|
||||||||||||||||||||||||||||||||||||||||||||||||||
AND op |
Képezz logikai ÉS kapcsolatot A és egy 8-bites operandus közt, s az eredményt képezd az akkumulátorban!
|
||||||||||||||||||||||||||||||||||||||||||||||||||
BIT bsz,op |
Vizsgáld meg a 8-bites operandus bsz-edik bitjének értékét és legyen Z=1, ha a bit nulla és Z=0, ha a bit egy.
|
||||||||||||||||||||||||||||||||||||||||||||||||||
CALL nn | Hívd meg az nn címen lévő szubrutint, s mentsd el a visszatérési címet a verembe! (RET vagy feltételes RET hatására töltsd a verem értékét a PC-be, s folytasd onnan a művelet végzését!) F: nincs változás.
|
||||||||||||||||||||||||||||||||||||||||||||||||||
CALL cc,nn | Végezz szubrutinhívást az előbbihez hasonló módon, ha cc teljesül! Ha nem, folytasd tovább a programvégrehajtást. F; nincs változás. Ha cc teljesül:
Ha cc nem teljesül:
|
||||||||||||||||||||||||||||||||||||||||||||||||||
CCF | Invertáld a C jelzőbitet! (Ha 0 volt, 1-be, ha 1 volt, 0-ba állítsd!)
(H felveszi C előző értékét.)
|
||||||||||||||||||||||||||||||||||||||||||||||||||
CO op | Hasonlítsd össze a 8-bites opedust az akkumulátor tartalmával, és Z legyen 1, ha megegyeznek és 0, ha nem! (A művelet A-ból kivonja az op-t és ideiglenes regiszterben tárolja. A jelzőbitek ennek megfelelően állnak be.) Op.: r, n, (HL), iid, xy
|
||||||||||||||||||||||||||||||||||||||||||||||||||
CPD | Összehasonlítás a "CP"-hez hasonlóan, de az operandus a HL című regiszter tartalma. CPD után BC és HL tartalma eggyel csökken. Op.: (HL)
(Z=1, ha A=(HL) és P/V=0, ha BC=0 utasítás végrehajtás után, különben 1.)
|
||||||||||||||||||||||||||||||||||||||||||||||||||
CPDR | Összehasonlítás a "CPD"-hez hasonló módon, azonban addig folytatódik, amíg vagy A=(HL), vagy BC=0. Itt BC = számláló (minden végrehajtás után eggyel csökken), HL = op címe (minden végrehajtás után eggyel csökken), A = összehasonlítási érték, ideiglenes regiszter = a CP-nél említett kivonás eredménye. (úgy is felfogható, hogy CPD csak egy CPDR ciklust hajt végre, s emiatt nincs szükség az időzítésnél is látható feltételek vizsgálatára.)
ZZ=1, ha A=(HL) és P/V=0, ha BC=0.)
Ha BC=0 vagy A=(HL):
|
||||||||||||||||||||||||||||||||||||||||||||||||||
CPI | Hasonlítsd össze A tartalmát a CP-hez hasonló módon (HL)-el, majd PC tartalmát csökkentsd, HL-ét növeld eggyel! Op.: (HL)
(Z=1, ha A=(HL) és P/V=0, ha BC=0)
|
||||||||||||||||||||||||||||||||||||||||||||||||||
CPIR | Összehasonlítás CP-hez és CPI-hez hasonló módon, azonban addig folytatódik, amíg vagy A=(HL), vagy BC=0. Itt: BC = számláló (tartalma minden végrehajtás után eggyel csökken.) HL = op címe (minden végrehajtás után eggyel nő), A = összehasonlítási érték, ideiglenes regiszter = CP-nél említett kivonás eredménye. (úgy is felfogható, hogy CPI csak egy CPIR ciklust hajt végre, s emiatt nincs szükség az utasításciklusokban az időzítéseknél is látható feltételek vizsgálatára.)
(Z=1, ha A=(HL) és P/V=0, ha BC=0)
Ha BC=0 vagy A=(HL):
|
||||||||||||||||||||||||||||||||||||||||||||||||||
CPL | Invertálja az A-t. (Ahol az akkumulátorban 0 volt, 1-et tesz, és ahol 1, oda 0-t.)
|
||||||||||||||||||||||||||||||||||||||||||||||||||
DAA | Ha BCD számokkal aritmetikai műveleteket végzünk, a kapott eredmény rossz lesz, mivel a Z80 kizárólag 0 és 255 közé eső egész számokkal képes közvetlenül ilyen műveleteket végezni. Ha azonban - mivel a 8-bites műveletek eredménye minden esetben A-ban képződik - a művelet végrehajtása után egy DAA utasítást írunk elő, korrigálja az eredményt a H és C jelzőbitek állásának megfelelően.
A hozzáadandó értékek táblázatát a G. függelék tartalmazza. |
||||||||||||||||||||||||||||||||||||||||||||||||||
DEC op | Az op értékét eggyel csökkenti. Op.: r, (HL), rr, ii, iid, xy F: ii és rr: nincs változás. A többi esetben:
|
||||||||||||||||||||||||||||||||||||||||||||||||||
DI | Megtiltja a Z80 számára a maszkolható megszakításkérés elfogadását oly módon, hogy minden megszakítás bitet nullába állit. Op: megszakításbitek (MB). F: nincs változás.
|
||||||||||||||||||||||||||||||||||||||||||||||||||
DJNZ d | B tartalmát eggyel csökkenti. Ha B=0, PC-hez hozzáadja a d előjeles konstanst és onnan folytatja az utasítások végrehajtását. (Így előre- és hátraugrás egyaránt lehetséges.) Ha B=0, akkor a DJNZ d utáni utasítástól folytatódik a programvégrehajtás. FONTOS! Említettük, hogy PC tartalma rendszerint a második órajelcik1us alatt nő eggyel. Emiatt DJNZ d után már PC értéke kettővel több, mint végrehajtásának megkezdése előtt. (Ennek egyik oka az, hogy az utasítás akkor is végrehajtódik, ha B=0.) Így a relatív ugrások értéke pozitív irányba 2-vel nő, negatív irányba pedig 2vel csökken, azaz -126 és +129 bájtnyi lehet, mivel -128 <= d >= + F: nincs változás. Ha BC nem nulla:
Ha BC=0:
|
||||||||||||||||||||||||||||||||||||||||||||||||||
DI | Lehetővé teszi a Z80 számára a maszkolható megszakításkérés elfogadását (DI-vel ellentétes értelmű utasítás) oly módon, hogy a maszkolható megszakításbiteket 1-be állítja. Op.: megszakításbitek (MB). F: nincs változás.
|
||||||||||||||||||||||||||||||||||||||||||||||||||
EX AF,AF' | Cseréld fel az AF regiszter tartalmát AF' -ével! Op.: AF és AF' . Jelölje ezeket "#"! F: nincs változás.
|
||||||||||||||||||||||||||||||||||||||||||||||||||
EX DE,HL | Cserézd fel HL regiszter tartalmát DE-ével! Op.: DE és HL. Jelölje ezeket "#"! F: nincs változás.
|
||||||||||||||||||||||||||||||||||||||||||||||||||
EX (SP),op | Cseréld fel a verem tetején lévő számot egy 16 bites operandussal! (SP tartalma term. nem változik.) Op.: HL, ii F: nincs változás.
|
||||||||||||||||||||||||||||||||||||||||||||||||||
EXX | Cseréld fel BC tartalmát BC', DE tartalmát DE' és HL-ét HL' tartalmával! Op.: az előbbi regiszterék. Jelölje ezeket "#"! F: nincs változás.
|
||||||||||||||||||||||||||||||||||||||||||||||||||
HALT | Hatására a Z80 NOP utasításokat hajt végre mindaddig, amíg maszkolható vagy nem maszkolható megszakításkérés nem érkezik. Ezután ennek megfelelően folytatja működését. Op.: biz. Z80 hardver. F: nincs változás.
|
||||||||||||||||||||||||||||||||||||||||||||||||||
IM0 | Nullás megszakítási módba állítja a Z80-ast (l. a megszakításos működésről szóló szakaszt). F: nincs változás.
|
||||||||||||||||||||||||||||||||||||||||||||||||||
IM1 | Egyes megszakítási módba állítja a Z80-ast (l. a megszakításos működésről szóló szakaszt). F: nincs változás.
|
||||||||||||||||||||||||||||||||||||||||||||||||||
IM 2 | Kettes megszakítási módba állítja a Z80-ast (l. a megszakításos működésről szóló szakaszt). F: nincs változás.
|
||||||||||||||||||||||||||||||||||||||||||||||||||
IN A,(n) | Olvasd be n port tartalmát az A regiszterbe! FONTOS! Beolvasáskor n a címsín alsó (A0-A7), A tartalma a felső (A8-A15) felén jelenik meg. Beolvasás pl. a ZX Spectrumban a 32766-os partról (= 127*256 + 254) a következőképpen történik: 10 LD A,127 20 IN A,(254) F: nincs változás
|
||||||||||||||||||||||||||||||||||||||||||||||||||
IN r,(C) | Olvasd be a c regiszterben megadott számú port tartalmát az r-ek valamelyikébe! FONTOS! Beolvasáskor a címsín alsó felén a C, a felsőn pedig a B regiszter tartalma jelenik meg. Az előbbi 32766-os port tartalmának beolvasása pl. az E regiszterbe a következőképpen történik: 10 LD BC,32766 20 IN E,(C)
|
||||||||||||||||||||||||||||||||||||||||||||||||||
INC op | Növeld meg eggyel op-t! Op.: r, (HL), rr, ii, iid, xy F: ii és rr esetében egyik sem változik. A többi esetben:
|
||||||||||||||||||||||||||||||||||||||||||||||||||
IND | Töltsd a BC című bemeneti / kimeneti áramkör tartalmát a (HL) című regiszterbe, majd csökkentsd eggyel HL és B tartalmát!
(Z=1, ha B=0, különben nulla.)
|
||||||||||||||||||||||||||||||||||||||||||||||||||
INDR | Végez IND utasításokat mindaddig, amíg B=0! Ha B=0, folytasd a programvégrehajtást az INDR utáni utasítással!
Ha B nem nulla:
Ha B=0:
FONTOS! Ez is tömbmozgató utasítás, mint a CPIR, CPDR, LDIR, LDDR, OTIR és OTDR, így: |
||||||||||||||||||||||||||||||||||||||||||||||||||
INI | Töltsd a BC című bemeneti / kimeneti áramkör tartalmát a (HL) című regiszterbe, majd HL tartalmát növeld, B-ét pedig csökkentsd eggyel!
(Z=1, ha B=0, különben nulla.)
|
||||||||||||||||||||||||||||||||||||||||||||||||||
INIR | Végezz INI utasításokat mindaddig, amíg B=0. Ha B=0 folytasd a programvégrehajtást az INIR utáni utasítással! HL = a beolvasott operandus letárolási címe, B = egyfelől számláló, másfelől a PC felső 8 bitjének tartalma a beolvasáskor, C = a PC alsó 8 bitjének tartalma a beolvasáskor.
Ha BC nem nulla:
Ha B=0:
|
||||||||||||||||||||||||||||||||||||||||||||||||||
JP cc,nn | Ugorj nn címre és folytasd onnan a programvégrehajtást, ha cc teljesül; ha nem, akkor térj át a JP cc,nn utáni utasításra! Op: PC (Ebbe kerül nn.) F: nincs változás.
|
||||||||||||||||||||||||||||||||||||||||||||||||||
JP op | Ugorj az op-ban foglalt címre és folytasd onnan a programvégrehajtást! Op.: nn, (HL), ii F: nincs változás.
|
||||||||||||||||||||||||||||||||||||||||||||||||||
JR cc1,d |
Ha cc1 teljesül, ugorj a PC+d címre , ha nem, folytasd az utasítások végrehajtását (a programvégrehajtást) a következő utasítással! Ha cc1 teljesül:
Ha cc1 nem teljesül:
|
||||||||||||||||||||||||||||||||||||||||||||||||||
LD A,op | Töltsd op-t az akkumulátorba! Op.: r, (BC), (DE), (HL), n, (nn), I, R, iid, xy F: nincs változás, kivéve I és R esetben. Ekkor:
(A P/V jelzőbit átveszi IFF2 tartalmát Erről bővebben a következő szakaszban szólunk.)
|
||||||||||||||||||||||||||||||||||||||||||||||||||
LD B,op | Töltsd op-t a B regiszterbe! Op.: r, (HL), n, iid, xy F: nincs változás.
|
||||||||||||||||||||||||||||||||||||||||||||||||||
LD BC,op | Töltsd a 16 bites op-t BC-be! Op.: nn, (nn) F: nincs változás
|
||||||||||||||||||||||||||||||||||||||||||||||||||
LD (BC),A | Töltsd A tartalmát a (BC) című tárrekeszbe! F: nincs változás
|
||||||||||||||||||||||||||||||||||||||||||||||||||
LD C,op | Töltsd az op-t a C regiszterbe! Op.: r, n, (HL), iid, xy F: nincs változás.
|
||||||||||||||||||||||||||||||||||||||||||||||||||
LD D,op | Töltsd D-be az op-t! Op.: r, n, (HL), iid, xy F: nincs változás.
|
||||||||||||||||||||||||||||||||||||||||||||||||||
LD DE,op | Töltsd a 16 bites op-t DE-be! Op.: nn, (nn) F: nincs változás
|
||||||||||||||||||||||||||||||||||||||||||||||||||
LD (DE),A | Töltsd az akkumulátor tartalmát a (DE) című regiszterbe! F: nincs változás
|
||||||||||||||||||||||||||||||||||||||||||||||||||
LD E,op | Töltsd op-t az E regiszterbe! Op.: r, n, (HL), iid, xy F: nincs változás
|
||||||||||||||||||||||||||||||||||||||||||||||||||
LD H,op | Töltsd op-t a Hregiszterbe! Op.: r, n, (HL), iid, xy F: nincs változás
|
||||||||||||||||||||||||||||||||||||||||||||||||||
LD HL,op | Töltsd a 16 bites op-t HL-be! Op.: nn, (nn) F: nincs változás.
|
||||||||||||||||||||||||||||||||||||||||||||||||||
LD (HL),op | Töltsd az op-t a HL című rekeszbe! Op.: r, n F.: nincs változás
|
||||||||||||||||||||||||||||||||||||||||||||||||||
LD I,A | Töltsd az akkumulátor tartalmát az I regiszterbe! F.: nincs változás.
|
||||||||||||||||||||||||||||||||||||||||||||||||||
LD ii,op | Töltsd a 16 bites op-t ii regiszterbe! Op.: nn, (nn) F: nincs változás
|
||||||||||||||||||||||||||||||||||||||||||||||||||
LD iid,op | Töltsd a 16 bites op-t az iid című rekeszbe! Op.: r, n F: nincs változás
|
||||||||||||||||||||||||||||||||||||||||||||||||||
LD L,op | Töltsd az op-t az L regiszterbe! Op.: r, n, (HL), iid F: nincs változás
|
||||||||||||||||||||||||||||||||||||||||||||||||||
LD (nn),op | Töltsd a 16 bites operandust az nn című tárrekeszbe! (először nn címre az alsó, majd (nn+1)-re a felső 8 bit kerül). Op.: A, (HL), rr, ii F.: nincs változás
|
||||||||||||||||||||||||||||||||||||||||||||||||||
LD op,A | Vegye fel az op A regiszter tartalmának értékét! Op.: r, (BC), (DE), (HL), I, R, iid, (nn), xy F: nincs változás
|
||||||||||||||||||||||||||||||||||||||||||||||||||
LD op,B | Vegye fel az op a B regiszterben tárolt értéket! Op.: r, (HL), iid, xy F: nincs változás
|
||||||||||||||||||||||||||||||||||||||||||||||||||
LD op,BC | Vegye fel op a BC 16 bites értékét! Op.: (nn) (Bővebbe lásd LD (nn),op -nál! |
||||||||||||||||||||||||||||||||||||||||||||||||||
LD op,(BC) | Vegye fel op a BC című bájt értékét: Op.: A (Bővebben lásd LD A,(BC) -nél.) |
||||||||||||||||||||||||||||||||||||||||||||||||||
LD op,C | Vegye fel az op a C regiszterben tárolt értéket! Op.: r, (HL), iid, xy F: nincs változás
|
||||||||||||||||||||||||||||||||||||||||||||||||||
LD op,D | Legyen op értéke azonos a D regiszter tartalmáéval! Op.: r, (HL), iid, xy F: nincs változás
|
||||||||||||||||||||||||||||||||||||||||||||||||||
LD op,DE | Vegye fel az op DE regiszter 16 bites értékét! Op.: (nn) (Bővebben lásd LD A,(DE) -nél!) |
||||||||||||||||||||||||||||||||||||||||||||||||||
LD op,(DE) | Vegye fel op a (DE) című bájt (tárrekesz) 8 bites értékét! Op.: A (Bővebben lásd LD A,(DE) -nél! |
||||||||||||||||||||||||||||||||||||||||||||||||||
LD op,E | Vegye fel op az E regiszter 8-bites értékét! Op.: r, (HL), iid F: nincs változás
|
||||||||||||||||||||||||||||||||||||||||||||||||||
LD op,H | Legyen op értéke H regiszter tartalmáé! Op.: r, (HL), iid F: nincs változás
|
||||||||||||||||||||||||||||||||||||||||||||||||||
LD op,HL | Op vegye fel HL regiszter 16 bites értékét! Op.: (nn), SP F: nincs változás
|
||||||||||||||||||||||||||||||||||||||||||||||||||
LD op,(HL) | Legyen op értéke azonos a (HL) című bájtéval! Op.: r F: nincs változás
|
||||||||||||||||||||||||||||||||||||||||||||||||||
LD op,I | Op vegye fel az I regiszter értékét! Op.: A (Bővebben lásd LD A,op -nál!) |
||||||||||||||||||||||||||||||||||||||||||||||||||
LD op,ii | op vegye fel az ii regiszter 16 bites értékét! Op.: (nn), SP F: nincs változás.
|
||||||||||||||||||||||||||||||||||||||||||||||||||
LD op,iid | Vegye fel az op az iid című rekeszben tárolt értéket! Op.: r F: nincsváltozás
|
||||||||||||||||||||||||||||||||||||||||||||||||||
LD op.L | Legyen op értéke azonos az L regiszterével! Op.: r, (HL), iid F: nincs változás
|
||||||||||||||||||||||||||||||||||||||||||||||||||
LD op,n | Vegye fel op az n értékét! Op.: r, (HL), iid F: nincs változás
|
||||||||||||||||||||||||||||||||||||||||||||||||||
LD op,nn | Vegye fel op az nn 16 bites értékét! Op.: rr, ii F: nincs változás
|
||||||||||||||||||||||||||||||||||||||||||||||||||
LD op,(nn) | Vegye fel op az (nn) című tárrekeszben tárolt értéket! Op.: A, rr, ii F: nincs változás
|
||||||||||||||||||||||||||||||||||||||||||||||||||
LD op,R | Vegye fel op az R regiszter értékét! Op.: A (Bővebben lásd LD A,R -nél.) |
||||||||||||||||||||||||||||||||||||||||||||||||||
LD op,SP | Vegye fel op az SP értékét! Op.: (nn) (Bővebben lásd LD (nn),op- nál.) |
||||||||||||||||||||||||||||||||||||||||||||||||||
LD op,XH | Legyen op értéke azonos XH regiszter 8 bites tartalmával! Op.: A, B, C, D, E, XH, XL F: nincs változás |
||||||||||||||||||||||||||||||||||||||||||||||||||
LD op,XL | Vegye fel op XL regiszter értékét! Op.: A, B, C, D, E, XH, XL F: nincs változás |
||||||||||||||||||||||||||||||||||||||||||||||||||
LD op,YH | Vegye fel op YH regiszter 8 bites értékét! Op.: A, B, C, D, E, YH, YL F: nincs változás |
||||||||||||||||||||||||||||||||||||||||||||||||||
LD op,YL | Vegye fel op YL regiszter értékét! Op.: A, B, C, D, E, YH, YL F: nincs változás |
||||||||||||||||||||||||||||||||||||||||||||||||||
LD R,A | Az R regiszter vegye fel A értékét! F: nincs változás (Bővebben lásd LD op,A -nál!) |
||||||||||||||||||||||||||||||||||||||||||||||||||
LD SP,op | Az SP vegye fel op értékkét ! Op.: HL, i i , nn, (nnn). F: nincs változás.
|
||||||||||||||||||||||||||||||||||||||||||||||||||
LD XH,op | XH vegye fel op értékét! Op.: A, B, C, D, E, n, XH, XL F: nincs változás. |
||||||||||||||||||||||||||||||||||||||||||||||||||
LD XL,op | XL vegye fel op értékét! Op.: A, B, C, D, E, n, XH, XL F: nincs változás. |
||||||||||||||||||||||||||||||||||||||||||||||||||
LD YH,op | YH vegye fel op értékét! Op.: A, B, C, D, E, n, YH, YL F: nincs változás |
||||||||||||||||||||||||||||||||||||||||||||||||||
LD YL,op | YL vegye fel op értékét! Op.: A, B, C, D, E, n, YH, YL F: nincs változás |
||||||||||||||||||||||||||||||||||||||||||||||||||
LDD | Töltsd a (HL) című tárrekesz tartalmát a (DE) című tárrekeszbe, s csökkentsd BC-t, DE-t és HL-t eggyel!
(Ha BC=0, akkor P/V=0, különben 1)
|
||||||||||||||||||||||||||||||||||||||||||||||||||
LDDR | Hajts végre LDD utasítást mindaddig, ami g BC=0! Ez is tömbmozgató utasítás, s így BC = számláló (counter), DE = új tömb kezdőcíme (destination - elhelyezés), HL = átmásolandó tömb kezdőcíme (source - forrás).
Ha BC nem nulla:
Ha BC=0:
|
||||||||||||||||||||||||||||||||||||||||||||||||||
LDI | Töltsd a (HL) című bájt tartalmát a (DE) címűbe, majd BC-t csökkentsd, DE-t és HL-t pedig növeld eggyel!
(Ha BC=0, akkor P/V is 0, különben P/V=1.)
|
||||||||||||||||||||||||||||||||||||||||||||||||||
LDIR | Végezz LDI utasításokat addig, amíg BC=0! Az LDDR-hez hasonlóan itt is BC = számláló (counter), DE = új tömb kezdőcíme (destination - elhelyezés), HL = átmásolandó tömb kezdőcíme (source = forrás).
Ha BC nem nulla:
Ha BC=0:
|
||||||||||||||||||||||||||||||||||||||||||||||||||
NEG | A tartalmát negálja, azaz kivonja 0-ból. (Ha A értéke előzőleg 128 volt, akkor nem változik semmi.)
(C=0, ha A a NEG utasítás előtt 0 volt és P/V=1, ha 128.)
|
||||||||||||||||||||||||||||||||||||||||||||||||||
NOP | Üres utasítás, hatására semmilyen műveletvégzés nincs. (Felhasználható pl. késleltetésre.) F: nincs változás.
|
||||||||||||||||||||||||||||||||||||||||||||||||||
OR op | Képezz az akkumulátor és az op között VAGY kapcsolatot! Az eredményt tárold A-ban! Op.: r, n, (HL), iid, xy
|
||||||||||||||||||||||||||||||||||||||||||||||||||
OTDR | Végezz OUTD utasításokat mindaddig, amíg B=0! A8-A15-re természetesen mindig az eggyel csökkentett B értéke kerül, s mivel tömbmozgató utasítás, ezért B = egyrészt számláló, másrészt a PC felső 8 bitje, C = a PC alsó 8 bitje, HL = a perifériára kiviendő adat címe.
Ha B nem nulla:
Ha B=0:
|
||||||||||||||||||||||||||||||||||||||||||||||||||
OTIR | Hajts végre OUTI utasításokat mindaddig, amíg B=0! Az OTDR-hez hasonlóan ez is tömbmozgató utasítás, s PC felső felére mindig az eggyel csökkentett B kerü. B = számláló és a kivitelkor a PC felső 8 bitjére (A8-A15) kerülő érték, C = kivitelkor a PC alsó 8 bitjére (A0-A7) kerülő érték, HL = a perifériára kiviendő adat címe.
Ha B nem nulla:
Ha B=0:
|
||||||||||||||||||||||||||||||||||||||||||||||||||
OUT (C),r | Rakd ki r tartalmát a (C) című perifériára! (PC felső 8 bitjét a B, az alsóét pedig a C regiszter szolgáltatja.) F: nincs változás.
|
||||||||||||||||||||||||||||||||||||||||||||||||||
OUT (n),A | Rakd ki az akkumulátor tartalmát az n című perifériára! PC alsó 8 bitjén n, a felsőn pedig az akkumulátor tartalma jelenik meg.) F: nincs változás.
|
||||||||||||||||||||||||||||||||||||||||||||||||||
OUTD | A (HL) című tárrekesz tartalmát rakd ki a (C) című perifériára! (A címsín alsó 8 bitjét C, a felsőt B szolgáltatja.) Ezután csökkentsd HL és B tartalmát eggyel!
(Z=1, ha B=0, különben 0.)
|
||||||||||||||||||||||||||||||||||||||||||||||||||
OUTI | A (HL) című tár tartalmát rakd ki a (C) című perifériára (a címsín alsó 8 bitjét c, a felsőt B szolgáltatja), majd B-t csökkentsd, HL-t pedig növeld eggyel!
(Z=1, ha B=0, különben 0.)
|
||||||||||||||||||||||||||||||||||||||||||||||||||
POP op | Vedd ki a 16 bites op-t a veremből (helyezd el a Z80 egy 16 bites regiszterében) és csökkentsd SP tartalmát kettővel! Op.: rr, ii. F: nincs változás.
|
||||||||||||||||||||||||||||||||||||||||||||||||||
PUSH op | Helyezd el op-t (a Z80 valamelyik regiszteréből) a veremben és adj SP aktuális értékéhez kettőt! Op.: rr, ii. F: nincs változás.
|
||||||||||||||||||||||||||||||||||||||||||||||||||
RES bsz,op | Írj nullát op bsz-edik bitjébe! (bsz értéke egy bájton belül jobbról balra 0-tól 7-ig növekszik.) Op.: r, (HL), iid. F; nincs változás.
|
||||||||||||||||||||||||||||||||||||||||||||||||||
RET | Térj vissz szubrutinból oly módon, hogy a verem tetején lévő számot írd be PC-be, és SP értékét csökkentsd kettővel! F: nincs változás.
|
||||||||||||||||||||||||||||||||||||||||||||||||||
RET cc |
Térj vissza szubrutinból RET-hez hasonló módon, ha cc teljesül! Ha nem, a RET cc utáni utasítással folytasd a programvégrehajtást! Ha cc teljesül:
Ha cc nem teljesül:
|
||||||||||||||||||||||||||||||||||||||||||||||||||
RETI | Térj vissza a maszkolható megszakítás szubrutinjából a RET-hez hasonló módon! F: nincs változás.
|
||||||||||||||||||||||||||||||||||||||||||||||||||
RETN | Térj vissza a nem maszkolható megszakítás szubrutinjából a RET-hez hasonló módon, s töltsd még IFF2 megszakításbit tartalmát IFF1-be. (Bővebben l. a megszakításos működésről szóló szakaszt.) F: nincs változás.
|
||||||||||||||||||||||||||||||||||||||||||||||||||
RL op | Forgasd balra a 8-bites op-t oly módon, hogy a bájt 0.bitje az 1. bit, első bitje a második stb. helyére kerüljön! A 7. bit tartalma kerül a C jelzőbitbe, s C-é a 0. bit helyére (l. a 8. ábrát).
(C az op 7. bitjének értékét veszi fel.) Op.: r, (HL), iid.
|
||||||||||||||||||||||||||||||||||||||||||||||||||
RLA | Forgasd balra az akkumulátor tartalmát a C jelzőbiten keresztül az RL op -al azonos módon (8. ábra).
(A C az A 7. bitjének értékét veszi fel.)
|
||||||||||||||||||||||||||||||||||||||||||||||||||
RLC op | Forgasd el a 8-bites op-ot oly módon, hogy a 0. bit értékét az 1.-be, az elsőét a másodikba stb. írd! A 7. bit tartalma mind a C jelzőbitbe, mind a 0. bitbe beíródik (l. a 8. ábrát).
(C az op 7. bitjének értékét veszi fel.)
|
||||||||||||||||||||||||||||||||||||||||||||||||||
RLCA | Forgasd körbe az A regiszter tartalmát az RLC op-hoz hasonló módon (l. a 8. ábrát.)!
(C az akkumulátor 7. bitjének értékét veszi fel a forgatás után.)
|
||||||||||||||||||||||||||||||||||||||||||||||||||
RLD | Másold át a HL című tárrekesz alsó négy bitjét a felső négybe, a felső négyet az A regiszter alsó 4 bitjének helyére, s A alsó 4 bitjének értékét pedig a (HL) című tárrekesz felső 4 bitjének helyére (l. a 8. ábrát) !
|
||||||||||||||||||||||||||||||||||||||||||||||||||
RR op | Forgasd jobbra a 8-bites op-ot oly módon, hogy 7, bitje a 6.-ba, 6. bitje az 5.-be stb. kerüljön! A 0. bit tartalma kerül a C jelzőbitbe és C-é pedig az op 7. bitjének helyére (l. a 8. ábrát)! Op.: r, (HL), iid.
|
||||||||||||||||||||||||||||||||||||||||||||||||||
RRA | Forgasd jobbra az akkumulátor tartalmát a C jelzőbiten keresztül az RR op-pal azonos módon (l. a 8. ábrát).
|
||||||||||||||||||||||||||||||||||||||||||||||||||
RRC op | Forgasd a 8-bites op-ot jobbra körbe oly módon, hogy a 7. bit tartalma a 6.-ba, a hatodiké az ötödikbe stb. kerüljön! A 0. bit tartalma a 7. helyére és a C jelzőbitbe egyaránt beíródik (l. a 8, ábrát). Op.: r, (HL), iid.
(A C bit op 0. bitjének értékét veszi fel.)
|
||||||||||||||||||||||||||||||||||||||||||||||||||
RRCA | Forgasd körbe jobbra az akkumulátor tartalmát az RRC op-pal azonos módon (l. a 8. ábrát)!
(C = A forg. előtti 0. bit értéke.)
|
||||||||||||||||||||||||||||||||||||||||||||||||||
RRD | Írd át a (HL) című tárrekesz alsó négy bitjének értékét az akkumulátor alsó 4 bitjébe, az akkumulátor alsó négy bitjének értékét a (HL) című tárrekesz felső négy bitjébe, s a (HL) felső négy bitjét pedig az alsó 4 bitbe (l. a 8. ábrát)!
|
||||||||||||||||||||||||||||||||||||||||||||||||||
RST op | Hívd meg az op címen lévő szubrutint, s mentsd el a visszatérési címet a verembe!RET vagy feltételes RET hatására töltsd a verem értékét PC-be, s folytasd onnan a műveletvégzést! Op.: 0, 8, 16, 24, 32, 40, 48, 56. F: nincs változás.
|
||||||||||||||||||||||||||||||||||||||||||||||||||
SBC op | A-ból vond ki a 8-bites op és a C jelzőbit értékét, s az eredményt rakd A-ba! Op.: r, n, (HL), iid, xy
|
||||||||||||||||||||||||||||||||||||||||||||||||||
SBC HL,rr | Vond ki HL-ből rr 16 bites értékét és a C jelzőbitet! Az eredményt képezd HL-ben!
(C=1, ha van, C=0, ha nincs átvitel, P/V=1, ha van, P/V=0, ha nincs túlcsordulás. H=1, ha van, H=0, ha nincs átvitel a 11. bitről a 12.-re.)
|
||||||||||||||||||||||||||||||||||||||||||||||||||
SCF | C jelzőbit értékét állítsd 1-be!
|
||||||||||||||||||||||||||||||||||||||||||||||||||
SET bsz,op | Állítsd 1-be op bsz.-ik bitjét! (op 8-bites, így bsz értelemszerűen 0 és 7 közé eshet.) Op.: r, (HL), iid F: nincs változás
|
||||||||||||||||||||||||||||||||||||||||||||||||||
SLA op | Léptesd op tartalmát eggyel balra oly módon, hogy a 7. bit értéke C jelzőbitbe, a 6.-é a 7.-be, az 5.-é a 6.-ba stb. kerüljön! A 0. bitbe írj nullát (8. ábra)! FONTOS! SLA ellentétes értelmű megfelelője SRL és nem SRA! Op.: r, (HL), iid.
(C az op 7. bitjének léptetés előtti értékét veszi fel.)
|
||||||||||||||||||||||||||||||||||||||||||||||||||
SRA | Léptesd az op-ot eggyel jobbra oly módon, hogy 7. bitje a 6.-ba, a 6. az 5.-be stb. íródjon! A 0. bit értéke SRA után a C jelzőbitbe kerül, a 7.-é pedig a 6.-ba, de megmarad a 7.-ben is (l. a 8. ábrát). SRA nem SLA ellentétes értelmű utasítása! Op.: r, (HL), iid
(C az op forgatás előtti 0. bitjének értékét veszi fel.)
|
||||||||||||||||||||||||||||||||||||||||||||||||||
SRL op | Léptesd op-ot eggyel jobbra oly módon, hogy a 0. bit értéke C jelzőbitbe, a 7.-é a 6.-ba, a 6.-é az 5.-be kerüljön! A 7. bitbe írj nullát! FONTOS! Az SRL SLA ellentétes értelmű utasítása! Op.: r, (HL), iid
|
||||||||||||||||||||||||||||||||||||||||||||||||||
SUB op | Vond ki a 8 bites op-ot az akkumulátor értékéből, s az eredményt képezd (tárold le) A-ban! Op.: r, n, (HL), iid, xy
|
||||||||||||||||||||||||||||||||||||||||||||||||||
XOR op | Képezz az akkumulátor tartalma és op között kizáró-VAGY (eXlusive OR) kapcsolatot! Az eredményt tárold le az akkumulátorban! Op.: r, n, (HL), iid, xy
|
Öt utasítás és ellentétes értelmű utasításaik kétféleképpen fordulnak elő a Z80 utasításkészletében. Ezek:
LD HL,nn RRA RRCA RLA RLCA |
LD (HL),nn (rr) RR A RRC A RL A RLC A |
(Az utolsó négynél a művelet eredményeképpen más jelzőbit kombináció alakul ki, ill. LD utasításnál értelemszerűen nincs ilyen.) Ennek oka, hogy a Z80 felülről kompatibilis az INTEL 8080 mikroprocesszorral, s tartalmazza utasításkészletének minden elemét. A bal oldali - az I8080-ban is szereplő -utasítások egyediek és egy-, ill. 3-bájtosak, míg a jobb oldaliak részben vagy teljes egészében beleértett címzési módúak, s egyebek közt olyan utasításokat is tartalmaznak, amelyek kódjába beleértett regiszterazonosítók végül is a bal oldali oszloppal azonos funkciót eredményeznek. Programozás során célszerű az egyedi utasításokat alkalmazni, mivel ezeknek nem kell belépési kód, s így rövidebbek.
Láthattuk, hogy messze a legtöbb az LD utasítás. Itt néhány kombináció kétszer fordul elő, ez viszont lehetővé teszi, hogy bármit, amire szükségünk van, megtaláljunk ábécésorrendben. Z80 assemblerben a programozó rendszerint kétféle szempont szerint keresheti az adatmozgató utasításokat. Pl.:
LD op,A vagy
LD A,op
azaz kereshet egy operandust, ahová az A regiszter tartalma átvihető, vagy egy másikat, amely az A regiszterbe vihető át. Az ábácé szerinti áttekintésre már csak a LD utasítások nagy száma miatt is szükség van.
A Z80 megszakítás rendszere
A periféria áramkörök működtetése miatt sokszor lehet szükség a mikroprocesszor ideiglenes felfüggesztésére, azaz megszakítására. Ez a 11. ábrán is látható módon alapvetően 3-féleképpen lehetséges:
A legegyszerűbb és egyben legnagyobb prioritású megszakítási mód a DMA (Direct Memory Access = követlen tárhozzáférés okozta megszakítás). Működésének mechanizmusára már utaltunk a kivezetések tárgyalásakor. A BUSREQ. jelet a Z80 minden ciklus végén megvizsgálja. Ha aktív állapotban van, a következő órajel elején (alacsonyról a magas feszültségszintre ugráskor) a már említett harmadik állapotba viszi a síneket és a megfelelő vezérlőjeleket. A BUSAK kimenet aktív állapota jelzi a megszakítást kérő eszköz számára, hogy átveheti a Z80 rendszerének vezérlését. Ha vannak, a dinamikus tárak frissítését is ennek az eszköznek kell ellátnia. A közvetlen hozzáférés végét a BUSREQ jel megváltozása, azaz passzív állapotba kerülése jelzi.
A másik két megszakítási mód lényegesen eltér a DMA-tól, ugyanis ezek a Z80-ban található két egybites tárral, az IFF1 és az IFF2 (Interrupt Flip-Flop 1 és 2) jelű megszakításkapcsolóval függnek össze. Ha IFF1 értéke 0, a Z80 letiltja az utóbbi két megszakításkérés elfogadását (l. 12. ábra).
Z80 műveletek |
A Z80 műveletek hatásai |
||
IFF1-re |
IFF2-re |
Egyéb hatások |
|
NMI elfogadása INT elfogadása RETN RETI és RET-ek DE EI LD A,I és LD A,R RESET ciklus |
0 0 IFF2 * 0 1 * 0 |
* 0 * * 0 1 * 0 |
- - (IFF1 átveszi IFF2 tartalmát.) (SP) PC (SP) PC - - (P/V átveszi IFF2 tartalmát) (I-be, R-be és a PC-be kerül, a Z80 IM0-ba áll.) |
* = nem változik 12 ábra: A megszakításos működéssel és az IFF-ekkel kapcsolatos Z80 műveletek |
Prioritását tekintve második az NMI (Non Maskable Interrupt = nem maszkolható megszakítás) üzemmód. Hardver működéséről már szóltunk a "Nemmaszkolható megszakításkérés / elfogadás" ciklusnál, így erre most részletesen nem térünk ki. Ha az NMI bemeneten megszakításkérés érkezik és a Z80 elfogadhatja, a PC regiszter értékét elmenti a verembe, és a 102 (=H66) címre ugrik. Itt kell lennie tehát annak a programrésznek, amely ilyen esetben biztosítja a rendszer m0ködését. A Z80 alapú rendszerekben sokszor ezt a megszakítási módot használják kritikus események, pl. feszültségingadozás elleni védelemre. A ZX Spectrumban ezt a védelmet másként oldották meg, így a gép ezt a bemenetet egyáltalán nem használja. A többi Z80 jellel együtt természetesen ez is megtalálható a rendszerkivezetések között , ám az amatőr készüléktervező az említett ROM hiba miatt nem használhatja üzemszerűen.
Prioritását tekintve második megszakítási üzemmódban az NMI jel hatására az IFF1 ugyanúgy 0 értéket vesz fel, ám előző állapota elmentődik a másik megszakítás-kapcsolóba, az IFF2-be. Kilépni ebből a megszakítási formából többféleképpen is lehet. A legegyszerűbb a programrész végére egy RETN utasítást írni, amelynek hatására IFF1-be átíródik IFF2 értéke, s visszaáll az NMI kérés előtti állapot. A PC-be a verem tetején lévő szám kerül, amely - ha előzőleg felszabadítottuk - az NMI kéréskor beirt korábbi programszámláló érték. A 12. ábrából azonban látható, hogy EI hatására IFF1-be és IFF2-be egyaránt 1 kerül. Ilyen utasítást természetesen a nem maszkolható megszakítást kiszolgáló programrészbe is tehetünk, s létrehozhatunk egyfajta "megszakítási láncot". A ZX Spectrum esetében ennek csak azon olvasóink számára van gyakorlati jelentősége, akik saját ROM-ot használnak, s így maguk írják a mikroprocesszor működését kiszolgáló rutinokat is. Ha ekkor adunk ki DI utasítást, az egyenértékű IFF2 0-ba állításával. LD A,I; LD A,R és RETN hatására IFF2 tartalma átíródik a P/V jelzőbitbe, így programból is vizsgálható.
A harmadik, a legkisebb prioritású, legbonyolultabb és egyben leggyakrabban használt az INT (maskabie INTerrupt = maszkolható megszakítás) üzemmód. Neve onnét ered, hogy míg az NMI-t minden esetben, az INT-et csak akkor fogadja el a mikroprocesszor, ha IFF1=1. Ez a 12. ábrán látható módon DI és EI utasítással szabályozható. Úgy is mondható, hogy IFF1 maszkolja a megszakításkérés elfogadásának lehetőségét. Ilyen megszakításkérés hatására PC tartalma ugyanúgy elmentődik a verembe, és ezt a megszakítást kiszolgáló programrész végén egy RETI utasítással ugyanúgy visszahozhatjuk, mint az előző esetben. (A RET-ek hatása is hasonló!) Az azonban, hogy hol legyen ez a rutin, már programból szabályozható: IM0-val a 0-ás, IM1-gyel az egyes és IM2-vel a kettes megszakítási módot állíthatjuk be.
A legegyszerűbb a nullás megszakítási mód, amely már az INTEL 8080-as mikroprocesszorban is megtalálható. bekapcsolás után vagy RESET hatására ezt veszi fel a Z80 A megszakításkérés után az adatsínen jövő jelkombinációt a Z80 utasításnak értelmezi. Az RST utasítás eredeti (i8080) funkciója az, hogy ez az egyetlen bájt szubrutinhívó utasítás is lehessen, de természetesen lehet más is. ZX Spectrumban ily módon azonban legfeljebb néhány RST-vel is elérhető fontosabb ROM rutint hívhatnánk, ha befolyásolhatnánk, hogy milyen jelkombináció érkezzen az ULA-ból az adatsínen, tehát IM0 használata esetünkben nem praktikus.
Annál fontosabb a ZX Spectrum számára viszont az egyes megszakítási üzemmód. A BASIC ugyanis ezt használja fel működéséhez. Inicializáláskor, amelyet a 4555-ös címen kezdődő rutin végez, ebbe az üzemmódba kerül a processzor. Ekkor - függetlenül az adatsín tartalmától - a PC-be 56 kerül, s az utasítások végrehajtása innen folytatódik. A BASIC ennek segítségével kezeli a billentyűzetet, s állít be bizonyos rendszerváltozókat (pl. az óra változót). Ha kiadunk saját programunkban egy DI utasítást és
RANDOMIZE USR kezdőcímből
RET-tel térünk vissza, tapasztalhatjuk, hogy noha a program megmaradt, a gép mégsem fogad el semmilyen utasítást sem a billentyűzetről. úgy is mondják, hogy ennek a megszakítási módnak a vektorozása automatikus.
Hogy miért, erre ad választ a második megszakítási mód szerkezete, amelyet vektoros megszakításnak is hívnak. Ez a Z80 leghatékonyabb, a programozó és a rendszertervező számára a legnagyobb szabadságot megengedő megszakítási módja, s igen jól használható ZX Spectrumban saját gépi kódú program készítésekor is. (Erre számos példát találhatunk a szoftver fejezetben. A példák egyben az alkalmazhatóság korlátait is megmutatják. A későbbiekben bemutatunk egy további korlátot is, amely sajnos igen nehézzé teszi alkalmazását 16 Kbájtos gépekben.) Ebben az üzemmódban az I regiszter és a megszakításkérő eszköz együttesen előállít egy címet a címsínen. Legyen ennek az értéke pl. aaaaa! Ezután a PC-be kerül az (aaaaa) és az (aaaaa+1) című bájtok tartalma oly módon, hogy
PC=(aaaaa) + 256*(aaaaa+1)
s az utasítások végrehajtása innen folytatódik, azaz itt helyezhető el a megszakítást kiszolgáló programrész.
Ezt leginkább akkor alkalmazzák, ha több megszakítást kérő eszköz van. Ekkor, ha az egyik 2-vel nagyobb kódot helyez a címsínre, mint a másik, s ez kettővel kevesebbet, mint a harmadik stb., akkor létrejön egy megszakítási (vektor-) táblázat. A vektor szót ebben az esetben ne azonosítsuk közismert matematikai fogalommal! A megszakítást kérő eszközről egy tárrekesz-kijelölő (=vektor) érték érkezik a címsínen, amely, noha fizikailag ugyanolyan 8-bites kód, mint pl. az IM0 esetében, az I regiszterrel együtt válik csak érvényes címkombinációva.
A maszkolható megszakításkérés / elfogadás ciklust kiszolgáló rutinból való visszatérés általában RETI-vel. történik, de lehet RET-tel is, hiszen ebben az esetben nincs szükség olyan műveletekre az IFF1-gyel és az IFF2-vel, mint a RETN esetében. Ha a megszakításrutin végrehajtási ideje hosszabb, mint amennyi idő a következő INT jel beérkezéséig rendelkezésre áll, ki kell adni a rutin elején egy DI utasítást.
Az ULA angol nyelvű rövidítés, jelentése: Uncommitted Logic Array, szó szerinti fordításban "kötetlen logikai elrendezés". Ez az elnevezés az ilyen áramkörök felhasználási módjára, s, nem a technológiai kialakítására utal. Gyakorlatban ugyanis az UL.A egy félkész integrált áramköri lapka, amelyen az áramköri elemeket már elkészítették, s azok összekötése a felhasználó feladata. Ebből következi k, hogy felhasználási területük teljes egészében a berendezésorientált áramköröké, mivel a katalógusokban szereplő tipikus, ún. katalógus áramkörök gyártására a legtöbb esetben gazdaságtalanok. Erre utal az ULA rövidítés magyar nyelvű változata, a BOÁK (Berendezés Orientált ÁramKör) is.
BOÁK gyártása elvileg azóta lehetséges, amióta egy lapkán több tranzisztor is készíthető. Gyakorlatilag természetesen sokkal több tényező indokolta létrejöttüket. A félvezetőeszközök fejlődése technológiailag egyre bonyolultabb, változatosabb, és funkcióiban is sokrétűbb áramkörök kialakítását tette lehetővé, s ez visszahatott a felhasználói tervezésre is, amely egyre inkább a katalógus áramkörökre épült, s épül még nagyrészt ma is. Sok esetben azonban a tervező igénye olyan speciális, hogy katalógus áramkörök felhasználása mind a tervezést, mind a gyártást igen körülményessé teszi. Minél speciálisabb egy berendezés, annál kevésbé alkalmazkodik felépítéséhez a katalógus áramkör. Ilyen esetekben a tervező válaszút elé kerül: vagy több katalógus áramkört alkalmaz, vagy csökkenti készüléke funkcióinak számát, ill. ront a műszaki paramétereken. Ebből a problémából jelent kiutat jelentős részben a BOÁK alkalmazása. A félvezető eszköz gyártója félkész lapkákat bocsát a felhasználó rendelkezésére, aki ehhez beszerzi azt a technológiát, amellyel kialakítja rajta a legutolsó fémréteget vagy rétegeket. Ezek természetesen nem egy adott áramkörhöz , legfeljebb csak egy áramkörtípushoz vannak méretezve. Ez különösen kedvez a digitális alkalmazásnak.
Az eddig említett gazdasági szempontok megszabják az BOÁK gazdaságos felhasználásának alsó és felső határát. 1000 db, alatt általában - eltekintve néhány speciális alkalmazástól - csak a katalógus áramkörökből való építkezés jön szóba. Milliós tételben viszont már messze megér az áramkört kész formában, katalógus áramkörként gyártani. Fontos szempont lehet, hogy a technológia gyakorlatilag megóvja a BOÁK-kal készített berendezéseket attól, hogy valaki lemásolja őket és eladja, mivel - épp úgy, mint elkészítésük - ez is speciális technológiát igényel.
A Sinclair cég ZX80-asa volt az első BOÁK-kal gyártott személyi számítógép.
A ZX Spectrumban BOÁK (amelyet angol gyártmányról lévén szó, a ZX gyártmányismertetőkkel való egyezés érdekében a továbbiakban ULA-nak nevezünk) állítja elő a videoáramkör számára a kék-sárga, a piros-sárga különbségi, valamint szinkron-fényerő jelet, kezeli a billentyűzetet, meghajt egy kisteljesítményű hangszórót, ki- és bemenetet biztosit kazettás adattároló számára, a mikroprocesszoros rendszer felé biztosítja a megszakítást 50 Hz-es frekvencián, ellátja a Z80A vezérlési, valamint a rendszervezérlési és bizonyos multiplexálási funkciók egy részét. Mielőtt azonban rátérnénk a funkciók részletes ismertetésére, tekintsük át a Spectrum ULA felépítését!
A Spectrum ULA szerkezete
A Spectrum ULA bipoláris tranzisztorokból és félvezető alapú ellenállásokból áll. Szerkezeti felépítése a 13. ábrán látható.
13. ábra: A Spectrum ULA mátrixcellái
A belső kis négyzetek az un. Mátrixcellák. Mindegyiken belül a tranzisztorok, a vezetékek, ill. átvezetési lehetőségek majdnem vagy teljesen azonosak. A mátrix elnevezés az ábrán látható elrendezésből ered, míg a cella abból, hogy ilyen tranzisztorokból, ellenállásokból és ilyen vezetékekből álló egységekkel dolgozik a tervező. Közöttük, ill. az áramköri elemek közt található kis üres területeken vannak a vezetékek, ill. hozható létre az un. saját vezetőréteg. A szélén nagyobb négyzetek, az ún. perifériacellák kaptak helyet. Funkciójukat nevükben hordozzák: ezek feladata, hogy belőlük olyan illesztőáramkört lehessen készíteni, amely alkalmas a belső áramkör nagyobb - ULA-n kívüli - áramkörbe való biztonságos bekapcsolására, pl. az ULA-nak a ZX Spectrum áramkörébe való bekötésére.
A Spectrum ULA-t a világ egyik legnagyobb BOÁK gyártója, az amerikai Ferranti cég készíti. A Ferranti ULA-k katalógusszámozása - szemben pl. a Texas Instruments 74-es sorozatával - nem közismert. Ha valaki kinyitja a Magyarországon legnagyobb számban fellelhető második kiadású (Issue 2) Spectrumot, az ULA tetején egyebek közt pl. az "ULA5C112E" kódkombinációt láthatja. Az ULA jelzés ebben az esetben az áramkör típusát jelenti (type prefix), hogy megkülönböztethető legyen más gyártmányú áramkörtől. Az "5" a Ferranti ULA-k sorozatjelzete (ULA series identification), amelynek jelentése a 14, ábrán látható. Ennek alapján ULA-k az 5000-es sorozat tagja, a benne található cellák száma minimum 440, maximum 484, s ha az összeset kapuáramkörökhöz használnánk fel, átlagosan és maximálisan 1000 kapu lenne készíthető.
Sorozatjelzet |
Sorozat |
Cellák száma |
Átlagos maximális kapuszám |
1 2 5 |
1000 2000 5000 |
100 - 150 225 - 256 440 - 484 |
300 500 1000 |
14. ábra: a Ferranti ULA-k sorozatjelzete
A "C" betűjelzet az alapvető műszaki jellemzőket foglalja össze (1. 15. ábra) . Eszerint DIGILIN (DIGItal-LINear) ULA-ról van szó, amely igen nagy sebességű áramköri elemeket tartalmazó félvezető lapkán készült, s maximálisan 20 MHz frekvenciával működtethető. Spectrumbeli frekvenciája 14 MHz.
Betűjelzet |
Műszaki jellemzők |
Kapuáram |
Határfrekvencia |
Ált. DIGILIN ULA |
0,42 mA |
3 MHz |
|
L |
Alacsony telj. (low power) DIGILIN ULA |
36 nA |
250 kHz |
U |
Nagyon kis telj. (very low power) DIGILIN ULA |
4 nA |
800 kHz |
H |
Nagy sebességű (high speed) DIGILIN ULA |
0,53 mA |
10 MHz |
C |
Igen nagy sebességű (very high speed) digit. ULA |
0,19 mA |
20 MHz |
N |
Normál sebességű, kis teljesítményű digit. ULA |
60 nA |
6 MHz |
15. ábra: A Ferranti ULA-k alapvető műszaki jellemzőinek katalógusjelzései
Jobbra a következő az áramkör sorszáma a tervezés sorrendjében (Circuit Design Number). ULA-nké ebben az esetben 112, de ez korántsem azonos valamennyi Spectrumban. A legkorábbi, első kiadású (Issue 1) gépekben még 102-es sorszámúakat is találhatunk, ami magától érthetődően a tervezés egy korábbi fázisának eredménye. Az "E" jelentése a 16. ábrán látható, s az ULA-t tartalmazó tokra jellemző. Az 5000-es sorozatú ULA-kat 24, 28 és 40 kivezetésű tokozással gyártják, a ZX-é 40 kivezetésű.
tok típusa | tokozás módja |
E J G F |
Műanyag DIL tok Kerámia DIL tok Műanyag FLAT-PACK tok Kerámia FLAT-PACK tok |
16. ábra: A Ferranti ULA-k tokozásának katalógusjelölése
Az 5C000 sorozatú ULA-k logikai típusának jelölése CML (Current Mode Logic). Ez a mátrix- és perifériacellákban egyaránt megtalálható multiemitteres tranzisztorra utal, amelyek áramgenerátorként működnek inverz-aktív üzemmódban. A cellák tápfeszültsége 5 V, üzemi hőmérséklete 25 C. A teljes disszipáció gyakorlatilag a cellák disszipációinak összege. Működtetésük a felhasználástól függően kétféleképpen lehetséges: egy tápfeszültség bekötésekor a két tápvezeték közösített. Két tápfeszültség alkalmazása kisebb hődisszipációt eredményez sebességveszteség nélkül. Annak ellenére, hogy a beköthető perifériacellák száma kb. 50, s ezek mindegyike kivezethető, a Ferranti ULA-it legfeljebb 40 kivezetésű tokban hozza forgalomba. Ennek oka a tervezés és a kialakítás geometriájában van.
Az ULA kivezetéseinek természetesen önálló funkcióik vannak a rendszer szempontjából, s erről kapták nevüket is. A kivezetések bekötésükre utaló elnevezéseikkel együtt a 13.b. ábrán láthatók. Az egyes kivezetések funkciói:
D0 - D7 |
Adatsín, amelyet rendes körülmények között a Z80A generál. Közvetlenül az alsó 16 Kbyte RAM IC-ibe és 470 ohmos ellenállásokon keresztül az egész rendszert átfogó adatsínbe van bekötve. Erre azért van szükség, hogy amíg az ULA a képernyőtárból olvassa ki az adatokat, a Z80A más tárterületekkel kommunikálhasson, és ne zavarják egymás működését. Így adott esetben mindkettő maximális sebességgel működhet. |
DRAM0 - DRAM6 |
Az ULA címvezetékei az alsó 16 K tár felé. Közvetlenül a tár-IC-kbe csatlakoznak, nem úgy, mint a z80-tól jövő jelek, amelyeket a multiplexerből kijövet 330 ohmos ellenállásokon keresztül kötöttek be. Ha ezeket a vezetékeket az ULA kimenetként használja a videotár címzésére, képes felülírni a CPU címzését. Emellett védelmi feladatokat is ellát, s bemenetként ellenőrizheti, melyik címet választotta ki a Z80A egy bizonyos határon belül. |
ROMCS |
680 ohmos ellenálláson keresztül csatlakozik a BASIC ROMCS (Chip Select) bemenetére. Ha ezt meg akarjuk szüntetni, a rendszerkivezetéseken a ROMCS-t +5 V-ra kell kötni. Az ULA felöl jövő jel ekkor az ellenállás miatt már nem tudja aktív állapotba hozni a ROM IC bemenetét. Ez igen hasznos, ha saját ROM-mal kíván valaki dolgozni anélkül, hogy a BASIC tárat kiemelné a gépből. Mindemellett az A14 és az 415 bemeneteken keresztül az ULA figyeli, hogy mikor melyik 16 K-t címzi a Z80, így párhuzamos működés valósul meg; |
MREQ |
Közvetlenül a Z80-ról jövő bemenet: jelzés az ULA-nak, hogy tárírási vagy -olvasási ciklust hajt végre a mikroprocesszor. |
IORQGE |
Bemenet. Ha aktív állapotba kerül, az ULA mint portkezelő egység működik. A második sorozatú (Issue 2) gépeknél ez csak akkor következik be, ha mind a címvezeték, mind pedig a Z80A IORQ kimenete aktív állapotban van. |
KBD9 - KBD13 | Bemenetek a billentyűzetről. |
WR és RD | Közvetlen bemenetek a Z80A-ból: jelzi, hogy mikor ír, ill. olvas. |
CLK |
A Z80A 3,5 MHz-es órajelét állítja elő oly módon, hogy meghatározott időközökben ráengedi a tápfeszültséget az órajelbemenetre. |
INT | Ezen a kimeneten ad az ULA másodpercenként 50 megszakításjelet a Z80A INT bemenetére. |
DRAM WR |
Kimeneti jel, amely meghatározza, hogy írhat-e a Z80A az alsó 16 K RAM-ba. (Ezt teljes egészében az ULA dönti el). |
DRAM CAS | Oszlopcím-engedélyező jel az alsó 16 K tár integrált áramkörei számára. |
RAS |
Sorcím-engedélyező jel szintén az alsó 16 K RAM áramkörök szemára. |
u | A kék-sárga különbségi jel kimenete; |
v | a piros-sárga különbségi jel kimenete; |
y | fényerő és szinkronjelek az összetett videojel előállításához; |
XTAL | A 14 MHz-es órajel bemenete. |
0 és +5V: | Tápfeszültség-bemenetek. |
CASSETTE AND BUZZER |
Kétirányú be- és kimenetként funkcionáló kivezetés. Vezérli a hangszaró és a kazettás magnetofon-csatlakozó Áramköreit. Noha egy kimenetként több funkciót is ellát, sosincs zavar, mivel analóg feszültségszintekkel működik. Ha egyik készüléket sem hajtja meg, a kimeneti feszültségszint 0,75 V, ha a magnetofon MIC kimenetet, 1,3 V, és ha csak a hangszórót, akkor 3,3 V. Ennek több következménye is van, amely előnyösen használható gépi kódú programozásnál! |
Az ULA portkezelése kimenetként
A kimenetként való programozás annyit jelent, hogy az ULA-ra mint portra adatot viszünk ki. Kiválasztani az ULA-t az A0 bit nullába állításával lehet, így címe a 254-es. A kivitel az
OUT (254),n
assembler utasítással történik, ahol a 254 azért van zárójelben, mert, noha 8-bites, de portcím, az n pedig egy kiviendő 8-bites konstans.
Ennek a konstansnak az alsó három bitje a háttérszint állítja be. Ez több szoftverproblémát is felvet, így ennek három bitnek a programozására, a 2. fejezetben egy teljes szakaszt szentelünk.
Az 5. hit a hangszóró vezérlését látja el. Hangeffektusokat a bit tartalmának megfelelő frekvenciával történő változtatásával kapunk. A ROM-ban közvetlenül a hangszórót vezérlő szubrutin:
949 950 951 953 955 956 958 959 961 965 967 970 972 973 974 975 977 978 979 980 981 982 983 985 987 988 991 993 995 996 997 999 1001 1002 1003 1005 1006 1007 1008 1010 1011 1012 1014 1015 |
243 125 203 61 203 61 47 230 3 79 6 0 221 33 209 3 221 9 58 72 92 230 56 15 15 15 246 8 0 0 0 4 12 13 32 253 14 63 5 194 214 3 238 16 211 254 68 79 203 103 32 9 122 179 40 9 121 77 27 221 233 77 12 211 233 253 201 |
DI |
A program bemenetként DE egy időre, HL pedig egy frekvenciára jellemző mennyiséget visz magával. Ebből DE megértése a legkönnyebb: minél rövidebb, annál rövidebb ideig tart a hang kibocsátása. Azt, hogy milyen hang menjen ki, egy függvény segítségével ~ számíthatjuk. Ha f a hang frekvenciája, akkor
HL = (((1/2*f)*3,5*10^6)/4)-30,125
Próbáljuk most ki a következő kis BASIC programot:
10 OUT 254,16: GO TO 10
Ha elindítjuk, hallhatjuk, hogy az indítás után a hangszóró egyet kattan, majd csendben marad. Ha viszont a
10 OUT 254,16: OUT 254,0: GO TO 10
programot próbáljuk ki, folyamatos berregő hangot kapunk. Ennek a portnak a programozása tehát nem hasonlít más portok vagy pl. a hanggenerátoros gépek programozásához. Kísérletezzünk most saját assembler programmal:
10 20 30 40 50 60 70 80 90 100 110 120 130 140 150 160 170 180 190 200 210 220 230 240 250 |
RUT ; DELAY ; |
ORG 60000 |
A program tízes számrendszerbeli számok formájában:
60000 60005 60010 60015 60020 60025 60030 60035 |
243 1 234 1 234 31 120 250 |
62 188 62 188 62 56 77 |
17 2 1 2 127 229 200 |
211 205 211 205 219 252 11 |
254 126 254 126 254 201 24 |
Bevinni tízes számrendszerbeli számok formájában a
10 CLEAR 59999: LET a=60000
20 INPUT b: PRINT a;TAB 15;b: POKE a,b: LET a=a+1: GO TO 10
kis BASIC programmal lehet. (A tízes számrendszerbeli formákhoz az egyértelműség kedvéért minden esetben közlünk bevivő programot vagy kiegészítéseket!) A program indítása
RANDOMIZE USR 60000
utasítással lehetséges. Ekkor összefüggő, aránylag elég mély hangot hallunk. Ha a 60. és 100. sorban a BC regiszterbe 700 helyett 100-at írunk, lényegesen magasabb hang lesz az eredmény, ha 50-et, még magasabb, ha 25-öt, még magasabb és így tovább. A BC itt azt adja meg, hogy a program mennyi ideig tartózkodjon a késleltetőrutinon. Minél rövidebb ez az idő, annál többször következik be váltás, vagyis annál magasabb lesz a hang frekvenciája. Ha pl. BC-be mindkét sorban 1500-at töltünk, a hang már kivehetően "darabos", azaz halljuk a váltásokat.
A portra kivitt 8-bites konstansban balról a második biten adatok kazettás magnóra való kivitelét írhatjuk elő. Ez az a rész, amelyet talán leginkább meghatároz a ROM-ban található program, hiszen bármely más (pl. gyorsbeolvasó stb.) beleütközik abba a problémába, hogy a programok legtöbbje az itt meghatározott formában van felvéve. Nézzük tehát a programfelvevő programrészt a BASIC tárban:
1218 1221 1222 1225 1227 1229 1232 1233 1234 1236 1237 1239 1240 1242 1244 1246 1248 1249 1251 1252 1253 1256 1258 1260 1262 1264 1266 1268 1270 1273 1274 1275 1248 1279 1280 1282 1285 1286 1287 1288 1290 1291 1294 1295 1297 1298 1300 1302 1304 1306 1308 1310 1312 1314 1315 1316 1317 1319 1322 1323 1325 1327 1329 1331 1332 1333 1334 1335 1338 1340 1342 |
33 63 5 229 33 128 31 203 127 40 3 33 152 12 8 19 221 43 243 62 2 71 16 254 211 254 238 15 6 164 45 32 245 5 37 242 216 4 6 47 16 254 211 254 62 13 6 55 16 254 211 254 1 14 59 8 111 195 7 5 122 179 40 12 221 110 0 124 173 103 62 1 55 195 37 5 108 24 244 121 203 120 16 254 48 4 6 66 16 254 211 254 6 62 32 239 5 175 60 203 21 194 20 5 27 221 35 6 49 62 127 219 254 31 208 122 60 194 254 4 6 59 16 254 201 |
LD HL,1343 |
A 17. ábrán a rutin folyamatábrája, a 18, és 19. ábrán pedig az időzítési viszonyok láthatók.
Alapvetően két különböző jelforma kerül kivitelre:
18. ábra: A "fej" (piros-világoskék azonosítójel) időzítése
19. ábra: A (sárga-sötétkék) adatbitjelek időzítése
Természetesen az adatkivitel bitenként történik, hiszen a vonal is, az adattároló jelbefogadása (a vezeték) is soros. Bemeneti adatként az IX regiszter á kiviendő blokk kezdőcímét, DE a hosszát tartalmazza. Az A regiszterbe kell írni az ún. adattípust. Ha ez "fej" (header block = BASIC azonosító), akkor A=0, ha adatblokk (pl. egy BASIC vagy egy assembler program bájtjai, esetleg a képernyő-bájtok - screen - tartalma), akkor A=255. Ha BASIC-ből lépünk be, mert pl. saját programunkat szeretnénk lemásolni, nyugodtan tehetjük a regiszterek feltöltése után CALL 1218-cal. A következő kis program rövid, fej nélküli felvételt eredményez:
10 20 30 40 50 60 70 80 90 100 |
ORG 60000 ENT $ DI LD A,255 LD DE,6912 LD IX,16384 CALL 1218 EI RET END |
(Ez a kis program a képernyőtár tartalmát küldi ki a magnetofonra, fej nélkül.) Ha azonban egy gépi kódú program része, akkor sosem fog a megfelelő címre visszatérni, ugyanis a legelején 1343-at ment el a verembe, ami a továbbiakban visszatérési cím. (Ez az a kombinált veremhasználati forma, amelyről korábban röviden szó volt, s amelyet előszeretettel használ a Sectrum BASIC).
A megoldás az, hogy ezután lépünk be a rutinba, vagyis a 70. sorba CALL 1222 kerül CALL 1218 helyett.
Az ULA portkezelése bemenetként
Bemeneti portként az ULA kétféle feladatot lát el:
A 20. ábrán a billentyűzet elrendezése, a 21. ábrán a portkiosztása látható.
20. ábra: a ZX Spectrum billentyűzete
21. ábra: A ZX Spectrum billentyűzetének portkiosztása
A vásárláskor a számítógéphez adott gépkönyv 23. fejezete foglalkozik a billentyűzet portkezelésével BASIC-ből, mintegy az INKEY$ függvény kiegészítéseként. Assemblerben természetesen ez is egy kicsit másként történik. A bevitel az IN n,(254) alakú utasítással történik. (Ez már szerepelt az előző szakasz programjaiban is.) A következő kis program visszatér BASIC-be, ha megnyomjuk a CAPS SHIFT billentyűt:
10 20 30 40 50 60 70 80 90 100 110 120 130 140 150 160 |
DELAY KEY |
ORG 60000 |
Tízes számrendszerbeli számok formájában:
60000 60005 60010 60015 |
243 177 249 31 |
1 40 62 56 |
16 3 254 249 |
39 11 219 251 |
120 24 254 201 |
Ha a 100. sorban kicseréljük a 254-et pl. 252-re, akkor már mind a CAPS SHIFT-re, mind az A-ra visszatér BASIC-be a program, hiszen olyan kombinációt hoztunk létre, hogy bármelyik billentyűről beolvassa és ellenőrzi a szükséges egy bitet. Ezt felhasználva megvalósítható egy érdekes és hasznos funkció: a Spectrum BASIC-ből sajnos hiányzó GET utasítás funkciója. A következő program bármely billentyűre megvalósítja ezt:
10 20 30 40 50 60 70 80 90 100 110 120 130 140 150 160 170 |
DELAY KEY |
ORG 60000 |
Tízes számrendszerbeli számok formájában:
60000 60005 60010 60015 60020 |
241 177 249 31 251 |
1 40 175 254 201 |
16 3 219 31 |
39 11 254 40 |
120 24 230 247 |
A maszkozás értéke a
31 = B 0001 1111
összefüggésből származik. A két program a tár bármely területén elhelyezhető, így - különösen ez utóbbi - hatékonyan alkalmazható BASIC programok, p1. DATA-val beírt kisegítő gépi kódú rutinjaként a GET helyett. Természetesen a BASIC ROM-nak is van egy billentyűzetleolvasó rutinja, amely a megszakítás rutinban helyezkedik el. A 2. fejezetben a rajzolóprogram fel is használja működéséhez. Kimenetként az E regiszterben megtalálható a lenyomott billentyű kódja, ill. 255, ha egyetlen billentyűt sem nyomtak meg. Ezt a felhasználásnál számításba kell venni, s szükség esetén visszaadni a rutinra a vezérlést. A ROM billentyűzetkezelő rutinja:
654 656 659 662 664 665 667 669 670 671 672 673 675 677 679 680 683 684 686 688 689 690 691 693 694 696 697 698 699 700 702 |
LD L,47 LD DE,65535 LD BC,65278 IN A,(C) CPL AND 31 JR Z,683 LD H,A LD A,L INC D RET NZ SUB 8 SRL H JR NC,673 LD D,E JR NZ,671 DEC L RLC B JR C,662 LD A,D INC A RET Z CP 40 RET Z CP 25 RET Z LD A,E LD E,D LD D,A CP 24 RET |
Az egyes billentyűk kódjai az E regiszterben:
B | 0 |
H | 1 |
Y | 2 |
6 | 3 |
5 | 4 |
T | 5 |
G | 6 |
V | 7 |
N | 8 |
J | 9 |
U | 10 |
7 | 11 |
4 | 12 |
R | 13 |
F | 14 |
C | 15 |
M | 16 |
K | 17 |
I | 18 |
8 | 19 |
3 | 20 |
E | 21 |
D | 22 |
X | 23 |
SYMBOL SHIFT | 24 |
L | 25 |
O | 26 |
9 | 27 |
2 | 28 |
W | 29 |
S | 30 |
Z | 31 |
SPACE | 32 |
ENTER | 33 |
P | 34 |
O | 35 |
1 | 36 |
Q | 37 |
A | 38 |
CAPS SHIFT | 39 |
A magnóról való betöltés rutinjára ugyanaz vonatkozik, mint az előző fejezetben a felvételre:
1366 1367 1368 1369 1370 1372 1374 1377 1378 1380 1381 1383 1385 1386 1387 1388 1391 1393 1396 1398 1399 1400 1401 1403 1406 1408 1410 1413 1415 1417 1418 1420 1421 1423 1425 1428 1430 1431 1433 1435 1438 1439 1440 1442 1443 1445 1447 1449 1450 1452 1454 1457 1459 1461 1462 1463 1464 1465 1466 1467 1469 1472 1473 1474 1476 1477 1478 1480 1482 1485 1486 1488 1489 1491 1493 1496 1497 1498 1499 1500 1501 1503 1504 1506 |
20 8 21 243 62 15 211 254 33 63 5 229 219 254 31 230 32 246 2 79 191 192 205 231 5 48 205 33 21 4 16 245 43 124 181 32 249 205 227 5 48 235 6 156 205 227 5 48 228 62 198 184 48 224 36 32 241 6 201 205 251 5 48 213 120 254 212 48 224 205 231 5 208 121 238 3 79 38 0 6 176 24 31 8 32 7 48 15 221 117 0 24 15 203 17 173 192 121 31 79 19 24 7 221 126 0 173 192 221 35 27 8 6 178 46 1 205 227 5 208 62 203 184 203 21 6 176 210 202 5 124 173 103 122 179 32 202 124 254 1 201 |
INC D |
a legfontosabb töltő szubrutin:
1507 1510 1511 1513 1514 1516 1517 1518 1519 1521 1523 1524 1525 1526 1528 1530 1531 1532 1533 1535 1537 1539 1540 |
205 231 5 208 62 22 61 32 253 167 4 200 62 127 219 254 31 2 8 169 230 32 40 243 121 47 79 230 7 246 8 211 254 55 201 |
CALL 1511 |
A program meghívásakor a töltőrutinhoz hasonlóan IX a kezdőcímet, DE a programhosszt és a kimenő jelek típusát jelöli. Azonban még egybe kell állítani a C jelzőbit értékét is, mivel ha 0, akkor csak VERIFY-ol a program. Ha BASIC programból irányítva pusztán rövid kódrutinnal akarjuk meghívni a programot:
10 20 30 40 50 60 70 80 90 |
ORG 6000 ENT $ LD IX,16384 LD DE,6912 LD A,255 SCF CALL 1366 RET END |
Ha az előbbi gépi kódú programot pl. egy nagyobb gépi kódú program részeként szeretnénk alkalmazni, - a felvételhez hasonlóan a veremfeltöltési probléma miatt - a következőképpen kell módosítanunk:
10 20 30 40 50 60 70 80 90 100 110 120 130 140 |
ORG 6000 ENT $ DI LD IX,16384 LD DE,6912 LD A,255 SCF INC D EX AF,AF' DEC D CALL 1378 EI RET END |
Ekkor saját programunk végzi el a ROM rutin egy egész kis részét, majd kihagyva a háttérszínváltást és a verem átírását, a rutinra adja a vezérlést.
A tároló áramköröknek az idők során számos fajtáját fejlesztették ki. A legalapvetőbb csoportosítás szerint két csoportra oszthatók:
Az előbbire elsősorban azért van szükség, hogy legyen hol tárolni programjainkat és adatainkat, míg az utóbbira azért, hogy biztosítsa a számítógép minimális működését (ehhez nem tartozik feltétlenül hozzá egy BASIC interpreter úgy, mint a ZX Spectrumban). Mindkét áramkörtípus megtalálhat ó számítógépünkben.
Az egyik legegyszerűbb tároló áramkör a 22. ábrán látható, mindössze egy bitnyi információ tárolására alkalmas. Ha mindkét bemenete egyszerre van magas (H) vagy alacsony (L) feszültségszinten, határozatlan állapotba kerül. Ám ha V(R)=H és V(S)=L, akkor Q=L, ill. ha V(R)=L és v(S)=H, akkor Q=H.
27. ábra: Az egyik legegyszerűbb tároló áramkör
A tároló áramkörök számtalan fajtája létezik részben áramköri, részben pedig ehhez kapcsolódóan technológiai eltéréssel. A ZX Spectrum 4116 típusjelű RAM IC-ket, ill. egy speciális Sirclair ROM IC-t tartalmaz.
A 4116 dinamikus RAM
A 4116 dinamikus RAM MOS LSI technológiával készült tároló áramkör. Összesen 128*128 = 16384, egyenként egy bit tárolására képes egységet, un. cellát tartalmaz. Mivel 16384/8 = 2048, ez 2 Kbájtnyi tárolókapacitást jelent (1 Kbájt = 1024 bájt). Az integrált áramkör kivezetései a 23. ábrán láthatók.
Mint az ábra is mutatja, a 4116 működéséhez három különböző tápfeszültségre, +5 V-ra, -5 V-ra és +12 v-ra van szükség.
Az egyes üzemmódok diagramjai a 25., 26., és 27. ábrán láthatók. Minden sort legalább 2 ms-onként egyszer el kell érni, azaz frissíteni, kell különben elvész a tartalma. Ez a 27. ábrán látható módom, a RAS bemenet és a címvezetékek felhasználásával történik. |
23. ábra: A 4116 kivezetései |
24. ábra: A 4116 belső felépítése
25. ábra: A 4116 olvasási ciklusának időzítése
26. ábra: A 4116 írási ciklusának időzítése
27. ábra: A 4116 frissítési ciklusának időzítése
A Sinclair ROM integrált áramköre
A Sinclair ROM kivezetéseinek elhelyezkedése a 28. ábrán látható. 16 Kbájt, azaz 16384 bájtnyi információt tárol oly módon, hogy az a gép kikapcsolása után sem vész el. Ebben található a BASIC és a működést biztosító programok sora, amelyek közül néhányat bemutattunk az ULA-ról szóló fejezetben. Szerkezetéről és a gépi kódú programozó számára használható rutinokról a szoftver fejezetben lesz szó. Most csupán az áramkör bemutatására szorítkozunk. 2*14 soros DIL tokozásban található. Az adatsín mind a 8 vezetékhez közvetlenül csatlakozik, a címvezetékek száma pedig 14. Ez nem véletlen, mivel 2^14=16384 bájtnyi információ megcímzése lehetséges ily módon. Azért csatlakozik: éppen az A0-tól az A13-ig jelölt címvezetékeken, mert a Z80A a bekapcsolási RESET ciklus után a 0000 címről kezdi a tárcímek és tartalmaik olvasását. Fizikailag a tár csak olvasásra való, így, a Z80A-nak is mindössze két kimenetére csatlakozik. Az OE (Output Enable) a RD (ReaD), a CS (Chip Select) bemenet pedig a központi egység MREQ kimenetéhez csatlakozik. Amatőr áramkör építők számára igen hasznos a Sinclair Rom CE (Chip Enable) bemenete. Ezt ugyanis a rendszerkivezetések ROMCS (ROM Chip Select) kimenetének. a +5 V-os vezetékkel való összekapcsolásával passzív állapotba helyezhetjük, s ezután saját készítésű ROM áramkörünket olvassa a Z80A az alsó 16 Kbájton. A bemenet ezen kívül egy 680 ohmos ellenálláson keresztül az ULA ROMCS kimenetéhez kapcsolódik, amely ezáltal semmilyen körülmények közt nem tudja a bemenetet aktív állapotba hozni, azaz a Z80A számára olvashatóvá tenni. Saját ROM kártya tervezésekor - különösen 48 K-s gépeknél - ügyeljünk a teljesítményfelvételre is! (A Sinclair ROM tápfeszültsége +5 v.) A prog. fesz. a ZX Spectrumban nincs bekötve! |
28. ábra: A Sinclair ROM és a 27128-as kivezetései |
Saját ROM NYÁK készítése helyett a Sinclair ROM helyébe ültethetünk vele kompatibilis EPROM-ot, amelyet saját eszközökkel programozhatunk. Ilyen pl. az INTEL cég 27128 típusjelű áramköre. Belső fezépítése a 29. ábrán látható.
29. ábra: A 27128 belső felépítése
131072 bitet képes tárolni, ami nem véletlen, mivel ez 16 Kilobájt, azaz
16384*8 = 131072
bit. A Z80A maximális sebességénél nagyobb frekvenciájú mikroprocesszorok is használhatják az igen rövid hozzáférési idő miatt. (Az INTEL cég speciális, nagy sebességű NMOS technológiával készíti.) A CE bemenet jelentőségét az adja, hogy ha magas feszültségszintre kapcsolják, a 27128 un. "készenléti" üzemmódba kerül, így az áramfelvétel lényegesen kisebb, s lecsökken a teljesítménydisszipáció (a hozzáférési idő lelassulása nélkül).
1.2.4. A ZX Spectrum videoáramköre
Könyvünknek ebben a szakaszában a televíziós kép előállításával foglaltazunk, feltételezve azonban a televíziózás áramköri megoldásainak legalább alapfokú ismeretét. E témában járatlan olvasóink az irodalomjegyzékben felsorolt művek között több hasznos forrásmunkát találhatnak.
A videojel
Egy átlagos fekete-fehér televíziókészülék felépítése a 30. ábrán látható.
30. ábra: Egy fekete-fehér TV-készülék elvi felépítése
A ZX Spectrum képe a televíziókészülékek 36-os UHF csatornájában fogható, azaz itt jelentkezik be. A Spectrumból kijövő jel közvetlenül a 75 ohmos, közösített antennabemenetre csatlakoztatható.
Az antenna által vett és továbbított jelet az illesztő-transzformátor szimmetrizálja, majd a nagyfrekvenciás erősítő felerősíti. A keverő egy oszcillátor segítségével valamivel kisebb, középfrekvenciájú jelet állit elő. A videodemodulátor ebből visszafejti a televízió vezérléséhez szükséges videojelet és a hangkülönbségi jelet (amelynek frekvenciája a magyar szabvány szerint 6,5 MHz). A videoerősítő a képcső vezérléséhez szükséges szintre erősíti a videojelet, amely ezután már a képcsőáramkörre kerül. Ezenkívül a legtöbb tv-ben a hangkülönbségi jelet is a videoerősítő erősíti. Ez a jel különbségi erősítés, FM demoduláció és hangfrekvenciás erősítés után kerül a hangszóróra.
A 30. ábrán látható AGC egység neve angol nyelvű rövidítés, jelentése Automatic Gain Control, azaz automatikus erősítésszabályozás. Feladata, hogy az antennára jutó jel nagyságától függetlenül a videoerősítő kimenetén megjelenő jelet állandó értéken tartsa. Az előbbi változásainak igen sok oka lehet: különböző adóállomások vétele, az antennajel mozgó tárgyról való visszaverődése, különböző minőségű antennák használata, a vételi körülmények változása stb.
Egy sor videojelének felépítése a 31. ábrán látható. Függőleges irányban a 0 a fekete szint feszültségértékének felel meg, a 100 pedig ehhez képest a fehér szinté százalékban. Látható, hogy minden sorátvitelhez tartozik egy ún. sorszinkronjel. Ennek célja, hogy biztosítsa az üzemszerű működést a sorváltásoknál, visszafutáskor ne hagyjon csíkot maga után az elektronsugár. Rögtön érthetővé válik a sorszinkronjel szerepe, ha megnézzük a 32. ábrát, amely egy televíziókép kialakítását mutatja be.
31. ábra: Egy sor szabványos videojele színinformáció nélkül
32. ábra: Egy TV-kép létrehozása félképváltásos módszerrel, a váltás videojeleinek relatív feszültségváltozás függvénnyel
Tegyük fel, hogy a kép az ernyő tetejének közepéről indul! Ekkor az elektronsugár létrehozza az összes páratlan számú sort, majd a képcső aljáról az ernyő bal felső sarkába ugrik, és kialakítja a páros számúakat is. Az egyes félkép végi sorok jelében már nem hasznos képinformáció, hanem szinkron- és kiegyenlítőjelek találhatók, amelyek feladata - a sorszinkron jeléhez hasonlóan - a helyes tv-kép előállításának biztosítása áramköri szempontból. (A szinkronszint mindig ugyanaz, azonban a képszinkron időtartama hosszabb a sorszinkronénál.)
Az LM1889-es video-IC
A ZX Spectrum videoáramkörének felépítése a 33. ábrán látható. Az ULA veszi ki a videotárból a megfelelő kép- és színinformációt, s a 15-ös kimenetén a kék-sárga, a 16-oson a piros-sárga különbségi jelet, a 17-esen pedig szinkron- és fényerőjelet (fekete-fehér videojelet) bocsát ki a videoáramkör felé. Ez utóbbi csaknem teljes egészében az LM1889 típusjelű IC köré épül.
Az LM1889 egy teljes tv-videomodulátor IC, amelynek segítségével a PAL színjelet állítja elő a ZX Spectrum. Belső egységeinek elhelyezkedése a 34.a. ábrán, kivezetései pedig a 34.b, ábrán láthatók.
34.b. ábra: Az LM1889 kivezetései
A színmoduláció legegyszerűbb módja itt a kvadratúrafázisok rögzítése az 1-es és 18-as bemeneteken keresztül mindkét különbségi jelre. Az LM1889 2*9 kivezetéses DIL tokozású IC. Az egyes kivezetések angol nyelvű rövidítéseinek jelentése a következő:
A 2-es színsegédvivő a modulátorról a 4-eshez képest 90-fokos fáziseltolódással jelenik meg. A nullás egyenszintet a 3-as bemeneten keresztül lehet beállítani. Ha-pl. a 2-es bemeneten a 3-ashoz képest pozitív, 1 V-os jel van, akkor U (out peak to peak) = 0,6 V, s a fázistolás 90 fok. Ha ugyanilyen, a 3-ashoz képest negatív feszültség kerül a 2-es bemenetre, a kimenő jel fáziseltérése 270 fok lesz. Ha a 2-esen és a 4-esen egyszerre van jelen, a segédvivő kimeneti szintje és fázisa a kvadratúrakomponensek vektori összege lesz. Negatív jel a burst kapuzási periódus alatt 180 fokos burst színszinkront eredményez. Az egyenfeszültség nulla szintje mindkét jelnél azonos.
Tekintsük át az LM1889 belső felépítését! A színoszcillátor egy invertálóerősítőből és egy Darlington emitterkövetőből áll. Külső kvarcoszcillátoros RC áramkör gondoskodik a fáziskésleltetésről a 17-es és 18-as bemeneten keresztül, hogy az oszcilláció a kristály rezonanciafrekvenciáján álljon be. Visszacsatolt jele egy vezérlőkésleltető körbe csatlakozik az 1-es és 18-as bemeneteken keresztül, és a segédvivő referenciajelet állítja elő a színjelmodulátor számára. Az u és v modulátor két-két szorzóból áll, s együttesen egy összegzőerősítőn keresztül kapcsolódnak a rádiófrekvenciás modulátor bemenetéhez, s ugyanez a jel jelenik meg a 13-as kimeneten. Az előbbit a ZX Spectrum azonban már nem használja. Akár a 2-es, akár a 4-es bemenet offszetje tér el a hármastól, megfelelő fázisú segédvivő áram jelenik meg a 13-as kimeneten.
Egyéb kapcsolások a videoáramkörben
Mint a 33. ábrán látható, az LM1889-ből kijövő színjel rákeveredik az ULA y szinkron- és fényerőjelére, s így alakul ki az összetett videojel, amely Tr2 emitterkövetőn keresztül egy UM 1233 E36 típusú, ASTEC gyártmányú nagyfrekvenciás modulátorra kapcsolódik. Ez utóbbi modulálja a jelet olyan frekvenciára, hogy televíziókészülékünk antennabemenetére csatlakoztatva a jelet értelmes képet kapjunk.
Az ULA kimenő jeleit úgy alakították ki, hogy a videoáramkör a lehető leggazdaságosabb legyen. Ezek a jelek azonban nem teszik lehetővé, hogy a ZX Spectrumot közvetlenül RGB bemenettel rendelkező monitorra csatlakoztassuk. A Spectrum csak olyan monitorral köthető össze, amelyek bemenetükön összetett videojelet igényelnek. A 33. ábrán az is látható, hogy négy hangolható áramköri elem is található a videoáramkörben. P1 az u, P2 a v jel relatív erősségét szabályozza. Ezzel a két potenciométerrel állíthatjuk be az egyes színek minőségét vagy éppen a fekete-fehér állapotot. Mindkettőhöz, csakúgy, mint a két változtatható értékű kapacitáshoz, kisebb csavarhúzóval nyúljunk! Ez utóbbiak a két frekvencia szabályozására szolgálnak. C(v1)-gyel az ULA 14 MHz-es frekvenciáját változtathatjuk, amivel pl. csökkenthetjük a karakterek vibrálását a képernyőn. C(v2), amely a videoáramkörnek közvetlenül a harmadik állítható eleme, az LM1889 egyetlen frekvenciáját, a színsegédvivő jel frekvenciáját szabályozza. (Ez PAL rendszerben igen pontos kell, hogy legyen.)
FONTOS!
A videoáramkörnek ez a része harmadik kiadású, (Issue 3) Spectrumok esetében néhány változtatáson ment át!
1.2.5. A ZX Spectrum alapáramköre
A ZX Spectrum alapáramkörének a Z80A, az ULA, a 27128-as ROM és a 8 db. 4116-os RAM IC - más -áramkörök segítségével összehangolt - együttesét tekinthetjük (l. 35. ábra) . A videotár az alsó 16 K RAM-ban, azaz a 4116-osokban helyezkedik el, s mind a Z80A-nak, mind pedig az ULA-nak hozzé kell férnie. Minthogy az ULA céláramkör, amelyet a ZX Spectrumhoz terveztek, érthető, hogy mindenféle közbenső kapcsolás nélkül, közvetlenül csatlakozik a RAM-okhoz.
A Z80A hozzáférése a 4116-os IC-khez
A 35. ábrán látható, hogy egy-egy adatvezeték egy-egy 4116-oshoz csatlakozik, annak be- és kimenetén keresztül. Ehhez természetesen a címvezetékeknek is igazodniuk kell, amelyek szemlátomást a Z80 logikához, s nem a tárkiépítéshez alkalmazkodnak. Ezért a Z80A multiplexeren keresztül címzi az alsó 16K RAM-ot. A multiplexer feladata "összehangozni" a tárak címzését a Z80A-éval. Természetesen ez is integrált áramkör, típusszáma SN74LS157, amelyből 2 db-ot alkalmaztak. Ez az IC is DIL tokozású, felépítése a 36.a., kivezetései a 36.b. ábrán láthatók. Az inverz engedélyező bemenet állandóan aktív állapotban van. A kijelölő (select) bemenet az ULA-hoz egy ellenálláson keresztül a RAS kimeneten át, a Z80A-hoz még egy további 330 ohmos ellenálláson keresztül a RFSH kimeneten át csatlakozik. Ez mindkét elem számára lehetővé teszi a hozzáférést. 36.b. ábra: Az SN74LS157 kivezetései: |
36.a. ábra: Az SN74LS157 logikai szervezése
A Z80A-ULA-video együttműködése
A 35. ábrán látható, hogy a központi egységet vezérlő bemenetek legnagyobb része - így az NMI, a WAIT és a BUSREQ - passzív állapotban van. Az 5 v-os tápfeszültség ugyan közvetlenül a feszültségforrás áramköréről jön, ám két igen fontos vezérlőbemenet, a CLK és az INT jelét egyenesen az ULA-tól kapja. Ugyanakkor Z80A állapotára jellemző rendszervezérlő kimenetek csaknem mindegyike (pl. a RD, a WR, a MREQ és az IORQ) az ULA-hoz is csatlakozik. Látható tehát, hogy nemcsak a központi egységnek, hanem az ULA-nak is vannak rendszervezérlési feladatai. Minderre azért van szükség, hogy a videoáramkör megfelelően működjön. Ehhez azonban az ULA-nak még egy adatra szüksége van a központi egység állapotán kívül: arra, hogy a Z80A a tár mely területén kívánja végrehajtani az adott feladatot. Ezért az ULA vezérlőbemeneteként működik a Z80A 14-es és 15-ös, azaz a két legfelső címvezetéke is. vizsgáljuk meg a két legfelső címbit szerepét:
0011 1111 1111 1111 = |
16383 |
0100 0000 0000 0000 = |
16384 |
1000 0000 0000 0000 = |
32768 |
1100 0000 0000 0000 = |
49152 |
Látható, hogy ezek megmutatják, hogy a teljes (16 K-s gépek esetében feltételezett) 64 Kbájt tárterület melyik negyedében kíván dolgozni a Z80A. Ha A15=0 és A14=1, akkor a központi egység ugyanabban a tárnegyedben - az alsó 16 K RAM-ban - kíván dolgozni, ahonnan az ULA rendszeresen kiveszi a videoinformációt.
Felmerül a kérdés, hogy nem lehetne-e a videoáramkör vezérléséhez kevesebb jelet felhasználni, pl. a BUSRQ segítségével a DMA-hoz nyúlni, s letiltani a Z80A működését, amíg a videoáramkör megszerzi a szükséges információt. Lehet, csakhogy ilyen esetekben a vezérlésnél vagy a központi egységé, vagy a videoáramköré az elsőbbség. Az előbbi esetben "hópelyhek" jelennek meg a képernyőn, amelyek azt a videoinformációt "mutatják", amely a központi egység miatt nem került kijelzésre, az utóbbi esetben pedig az egész számítógép működése lelassul. Napjaink legsikeresebb személyi számítógépei, mint pl. a ZX Spectrum vagy a Commodore 64 más és más módon, de valamennyien megoldották ezt a problémát. így azt mondhatjuk, hogy a "kijelzés-gyorsaság ellentmondás" feloldására nincs egyedül üdvözítő megoldás; a ZX Spectrumé egy a sok közül.
Az adat- és a címsínt, amelyek a Z80A és az ULA felől egyaránt csatlakoznak az alsó 16 Kbájt RAM-hoz, a központi egység felöl 330, ill. 470 ohmos ellenállások zárják le, míg az ULA felől nem. Ez biztosítja azt, hogy amikor a Z80A a ROM-ban, vagy a 48 K-s gépek felső 32 K RAM-jában dolgozik, párhuzamosan működhessen az ULA-val. Ha viszont a Z80A is és az ULA is az alsó 16 K RAM-ban szeretne dolgozni, az ULA - olyan rövid időre, hogy ezt még a központi egység ne vegye észre -letiltja az órajelek kiadását. (Ezt a Z80A egyrészt gyártási technológiája miatt, másrészt azért nem veszi észre, mert egyetlen időmérő eszköze annak feltételezése, hogy az órajel frekvenciája állandó.) Amikor egy kis szünet van a videoinformáció kiadásakor, az ULA megengedi a Z80A számára, hogy néhány ns időre hozzáférjen az alsó 16 K RAM-hoz. Erről rendkívül könnyen meggyőződhetünk, ha a "HUNGARIAN COLOURS" nevű programot átírjuk (az abszolút címekkel együtt!) erre a tárterületre, és lefuttatjuk. A RFSH jel - a többi rendszervezérlő jellel ellentétben - azért csatlakozik közvetlenül is az alsó 16 Kbájthoz, mert a video-szinkronjelek kiadásakor, amikor előfordulhat, hogy a dinamikus RAM-okat akár 5 ms-ig vezérlés sem éri el, a Z80A - rövid időre - átveszi a frissítési. feladatokat.
Különleges ULA jelkombinációk
Korábban részletesen szóltunk a Z80A megszakításos működtetésének lehetőségeiről. Mi történik akkor, ha 16 Kbájtos gép áll a gépi kódú programozó rendelkezésére, s programjához 2-es megszakítási módba (IM2) szeretné állítani a központi egységet? Sajnos többször is meg kell gondolnia, hogy ezt egyáltalán megtegye-e. Az I regiszter tartalma ugyanis minden frissítési ciklusban az A8 ... A15 címvezetékekre kerül, s A14 és A15 az ULA vezérlő bemeneteként is működik. Így mivel
B 0100 0000 = |
64 és |
B 0111 1111= |
127 |
64 és 127 közötti számok nem kerülhetnek az I regiszterbe. Ez viszont éppen az alsó 1 K RAM.
Frissítési ciklusban, ha egy ilyen szám a címvezetékre kerül, a MREQ jellel együtt érvénytelen vezérlési kombinációt jelent az ULA számára. Írjuk be a szokásos módon a következő kis programot:
10 | ; GET CONFUSED! | |
20 30 40 50 60 70 80 90 100 110 120 130 140 150 160 170 180 190 200 210 220 230 |
DELAY INKEY |
ORG 60000 |
A program tízes számrendszerbeli számok formájában:
60000 60005 60010 60015 60020 60025 60030 |
243 1 40 175 31 62 201 |
62 16 3 219 254 63 |
100 39 11 254 31 237 |
237 120 24 31 40 71 |
71 177 249 230 246 251 |
Vigyük be a következő kis BASIC rutint majd RUN-nal indítsuk el a programot:
10 FOR i=1 to 704: PRINT "A";: NEXT i
20 RANDOMIZE USR 60000: STOP
Az ULA megzavarodása szemmel látható a képernyő alsó részen. A jelenség oka az áramkör felépítésében keresendő, amelyet a Sinclair cég nem közöl. Ha töröljük a 40-es és a 210-es sorban található (DI és EI) utasításokat (POKE 60000,0 és POKE 60029,0), láthatjuk, hogy az egésznek semmi köze a megszakításrendszerhez, mivel az alapvibrálás megmarad. Ha töröljük a képernyőt, s a programot ezúttal GO TO 20-szal indítjuk, a vibrálás nem látszik, mivel csak egy szín szerepel.
1.2.6. A 48 K-s gépek felső 32 K tárának használata
A 48 K-s gépek felső 32 K RAM területét és az azt kiszolgáló áramkört azért tárgyaljuk külön pontban, mert úgy kapcsolódik a rendszerhez, mintha az alapáramkörhöz semmi köze sem lenne (kivéve persze az egész számítógép teljesítményfelvételét).
A 37. ábrán látható, hogy ezt a tárterületet 8 db., 4532 típusú integrált áramkörrel valósították meg. Ezek olyan leselejtezett, 64-szer 1 kilobites áramkörök, amelyek 32-szer 1-eskénst még működnek. (A hibátlan IC típusszáma 4564.) A típusszám utáni L, ill. H betű jelzi, hogy az IC alsó vagy felső 32 kilobites tára használható. Igen sokféle 64-szer 1 kilobites tároló integrált áramkör kapható a piacon, nagyjából ugyanolyan logikai szerkezettel. Ilyenek pl. a 2164, 3764, 4164, 4864, 4564 és 8264.
Belső felépítésük - méreteiktől eltekintve - igen hasonló a 4116-oséhoz. A 37. ábrán látható, hogy itt a vezérlőjeleket teljes egészében a Z80A szolgáltatja, így ezeket is multiplexelik, mégpedig két igen egyszerű logikai áramkör, egy SN74LS00 és egy SN74LS32 segítségével. Az előbbi 4 db. NAND (NEM-ÉS), az utóbbi. 4 db OR (VAGY) logikai kapuáramkört tartalmaz, kivezetéseik a 4164-eséhez hasonlóan a 38. ábrán láthatók.
Az SN74LS00 és az SN74LS32 kivezetései
Ha a központi egység a felső 32 Kbájt RAM-ból kíván olvasni, az A15 címvezeték 1-es szintre kerül, s a Z80A RD és MREQ rendszervezérlő kimenetei is aktív állapotban vannak. Az R71-ből és C63-ból álló RC-kör késlelteti a MREQ jel lefutását, ugyanakkor a multiplexerek, amelyek itt is SN74LS157-esek, mint az alsó 16 K-nál, az A0 ... A7 címvezetékek tartalmát közvetlenül továbbítják a tárakhoz. Ez biztosítja azt, hogy A0 ... A7 címvezetékek tartalma ne legyen a multiplexervezetékeken amikor az előbbiek már A8 ... A15 tartalmát továbbítják. Az R70-ből és C64-ből álló RC kör az előbbi RC áramkörhöz hasonlóan a CAS jel lefutását késlelteti. Amikor már mindkét címrész a tárakban van, rövid késleltetés után megjelenik a kívánt információ az adatsínen.
Íráskor a különbség annyi, hogy RD = H és WR = L. A15 értéke ugyanúgy 1, s a MREQ jelszint is alacsony. A 37. ábrán az is látható, hogy a tároló áramkörök - a 4116-hoz hasonlóan - az RD bemenetükre adott aktív szintből tudják, hogy a központi egység írni vagy olvasni kíván-e információt.
Frissítéskor mind a RD, mind a WR szintje magas, ugyanakkor MREQ=L. Ez utóbbi alacsony szintre állítja a tárak RAS bemeneteit. A ZX Spectrum áramköri viszonyait figyelembe véve a frissítéshez ennyi elegendő.
A felső 32 K RAM bekötése a ZX Spectrum rendszerbe szemlátomást hagyományosabb. A 26-os számú SN74LS157-es 3B bemenetének földvezetékre vagy tápfeszültségre kötése mutatja meg, hogy a tárak melyik cellája működőképes.
E ponthoz kívánkozik, hogy a Rádiótechnika c. folyóirat 1984. októberi számában "Memóriabővítő áramkörök a ZX81 és ZX Spectrum mikroszámítógépekhez" címmel Csanády György, Kövesdi Kálmán és Mag Pál közölt kapcsolási rajzot, s írt cikket arról, hogy a kiselejtezett, 64-szer 1 kilobites áramkörök működőképes, de a Spectrumban ki nem használt rész segítségével hogyan bővíthetjük 16 és 48 kilobájtos gépünk tárkapacitását 80 kilobájtra. (Ez számos problémát vet fel áramkörileg, hiszen a Z80 közvetlenül legfeljebb csak 64 Kbájtnyi tárat tud megcímezni. Ráadásul a BASIC sem támogatja a 80 Kbájtnyi hardver kezelését.)
1.2.7. A hangszóró és a kazettás magnetofon áramköre
Az ULA kivezetéseinél és portkezelő funkciónál volt már szó a hangszóró és a kazettás magnetofon kezeléséről. Az áramkör egyszerűsége és a hagyományostól - az ULA miatt -- eltérő jellege miatt érdemes a leglényegesebb információt elmondani róla (l. 39. ára.).
39. ábra: A hangszóró és a kazettás magnetofon áramköre
Noha az ULA egy be- és kimenete, a 28-as kivezetés három feladatot is ellát: kezeli a kazettakimenetet, beolvas kazettáról és vezérli a hangszórót, ezek a funkciók egyáltalán nem zavarják egymást. Ha éppen egyik feladatot sem látja el a kivezetés, feszültségszintje 0,75 v; ha a MIC kimenetet hajtja meg, 1,3 v; ha pedig a hangszórót akkor 3,3 V. Emiatt, ha éppen a MIC kimenetet hajtja meg a 28-as kivezetés, a hangszóró nem szól, mivel 1,4 V-ig a D9 és D10 diódán leesik a feszültség. Ugyanakkor, ha folyamatos állapotváltoztatásokkal hangokat, hangeffektusokat generálunk, s közben a kazettás magnetofont felvevő üzemmódba kapcsoljuk, jó minőségű hangfelvételt készíthetünk. Az ULA adatbájtjában D3 a MIC, D4 a hangszóró programozásának bitje.
A hangszóró és a kazettás magnetofon áramkörének szerkezete önkéntelenül is felveti azt a programozási lehetőséget, hogy egy szalagon lévő analóg hangjelet megfelelő sűrűséggel mintavételezve beolvassunk a tárba, majd a program kódoló részének segítségével visszahallgassunk a hangszórókimeneten. Ma már igen sok "beszélő" szoftver és kiegészítő hardver kapható a piacon, mint pl. az ETX játékprogram. A hangszóró és a magnetofon áramkörének programozási lehetőségeit már részben bemutattuk az ULA portkezlési lehetőségeinek felsorolásakor, részben pedig lesz még róla szó a szoftver részben.
1.2.8. A tápfeszültségek áramkörei
A hálózati tápegység áramköre a 40, ábrán látható. Maga a tápegység csak egy transzformátort, egy Graetz-egyenirányítót és egy, a kimeneti szintet stabilizáló kapacitást tartalmaz. (Ez utóbbi két db. elektrolit kondenzátor C1 eredő kapacitással.) 240 V-os, 50 Hz-es színuszos bemeneti feszültség esetén kimenetén 9 V egyenfeszültség jelenik meg 1 A áramerősség mellett.
40. ábra: A ZX Spectrum tápegységének áramköre
Sajnos a ZX Spectrumnak erre a feszültségre még sehol sincs szüksége, így tovább kell alakítani. Három, egymástól csaknem független tápfeszültség található az alapgépben: +12 v, +5 V és -5 V. A 4116-osokból, álló 16 Kbájt mindhárom szintet igényli egyszerre, míg pl. a Z80A csak a + 5 V-ot, vagy az LM1889-es tv-videomodulátor IC csak +12 V-ot.
A +5 V-os tápfeszültség előállítása
A ZX Spectrum +5 V-os tápfeszültségét egy 7805 típusú -- az amatőrök által jól ismert - feszültségszabályozó (stabilizátor) integrált áramkör ál1ítja elő. Három csatlakozóvezetéke van: a bemeneti feszültség, a kimeneti feszültség és a közös pont. A bemeneti feszültség +7 V és +25 V között változhat, a kimeneten stabilizált +5 V jelenik meg. Sajnos az IC igen könnyen és gyorsan melegszik (gyakorlatilag leginkább ez az áramkör okozza a ZX Spectrum melegedését), így közös pontján keresztül egy alumínium hűtőlapkára erősítették.
A Spectrum melegedése ellen sokféleképpen védekeznek. Aki már valamelyest jártas áramköri szelésekben, annak számára a legegyszerűbb megoldás az, hogy ha ezt az integrált áramkört kiszereli, s az alapgépen kívül, pl. egy alumíniumdobozkában helyezi el. Ha valaki ezt nem vállalja, vigyázzon arra, hogy a gép alul-felül egyaránt szellőzhessen! Ne tegyük pl. a Spectrumot meleg, levegőtlen szobában műanyag terítőre! Sajnos a tapasztalat azt mutatja, hogy ha a gép pl. túlmelegedés miatt tönkremegy, rendszerint több drága alkatrészt - köztük az ULA-t is! - cserélni kell.
A +12 V-os tápfeszültség előállítása
A +5 V előállítása egyszerűnek tekinthető annyiban, hogy van egy integrált áramkör, amely bizonyos határon belül a megfelelő szintre csökkenti a feszültséget, s a maradék energiát hődisszipáció formájában eltávolítja. A +12 V előállítása nem ilyen könnyű (41. ábra) .
41. ábra: A +12 V-ot és a -5 V-ot előállító áramkörök
Az L1 induktivitás, a Tr4 (ZTX-650 típusú) teljesítményvezérlő tranzisztor, az R61 ellenállás és a C64 kondenzátor együttesen egy blocking-oszcillátort képez, amelynek Tr5 (ZTX-213 típusú) pnp tranzisztor az áram-visszacsatoló eszköze. Az oszcillátor kimenetén megjelenő feszültség - mint a legtöbb televíziózás-technikában ismert blocking-oszcillátoré - a teljesítménytranzisztor kollektorfeszültsége. Az L1 által minden ciklusban indukált ellentétes értelmű feszültség 9 V fölé, maximum +13 V-ra növeli Tr4 kollektorfeszültségét. Ezen a szinten a D15 nagyteljesítményű szilícium-dióda feltölti a C44 elektrolit kondenzátort, amelyet tovább biztosít C45, s így adódik ki a terhelhető +12 V. Ha esne a szint, Tr5 vezetése megnő, s visszahúzza a tápvonalat +12 V-ra.
A -5 V-os tápfeszültség előállítása
A -5 V előállítása részben a +12 V-t előállító áramkörhöz kötődik (l. 41. ábra) . A Tr4 kollektora gyakorlatilag +13 V és 0 V között oszcillál. Amikor ez eléri a pozitív feszültségmaximumot, a C46 elektrolit kondenzátor D11-en keresztül kb. +12 V-ra töltődik. Amikor pedig Tr4 kollektorfeszültsége 0 v-ra esik, C16 negatív fegyverzete -12 V lesz (töltéspumpa elv). A C47 elektrolit kondenzátor a D12 diódán és az R55 ellenálláson keresztül kapja meg C46-ról a megfelelő töltésmennyiséget. A -5 v-os feszültséget D17 Z-dióda tartja állandó szinten.
A gép nyomtatott áramköri lemezének kivezetései, az ún. rendszerkivezetések a gép hátulján helyezkednek el (l. 42. ábra) . Tágabb értelemben ezek közé számit a kazettás egységhez tartozó MIC kimenet és az EAR bemenet is.
alsó oldal |
felső (billentyűzet felöli) oldal |
* = bevágás helyes csatlakoztatáshoz 42. ábra: A ZX Spectrum rendszerkivezetései |
A ZX Printer a Sinclair gépekhez gyártott nyomtató. Előnye. hogy igen olcsó, hátránya viszont, hogy egyrészt drága, hőérzékeny metall-papírral működik, másrészt a nyomtatási kép minősége nem túl jó. Mivel a ZX Printer nemcsak a Spectrumhoz, hanem az összes Sinclair típushoz használható, a gépekhez közbeiktatott illesztőáramkör nélkül közvetlenül csatlakozik. A belső vezérlést, s az ehhez kapcsolódó logikát a nyomtatón belül is egy ULA látja el. A Sinclair cég egyébként más ZX kiegészítő hardverjeiben is szívesen, alkalmaz ULA-t (l. Sinclair joystick interface).
A nyomtató két üzemmódja: lassú ás gyors nyomtatás. Ez szoftverrel szabályozható. A kinyomtatandó információt grafikusan, programból kell kivinni bitenként. Ehhez minden bit kiküldése után meg kell várni, míg az állapotjel (a nyomtatóról érkező foglaltsági jel) "szabadot" nem jelez. Hogy ez hogyan történik, arról részletesen szó lesz a 2. fejezetben. (Erre a célra található a ROM-ban egy gyakorlatilag minden fizikailag lehetséges nyomtatóalkalmazást megvalósító programrész.)
1.5. További perifériális egységek illesztése
A ZX Spectrum az egyik legolcsóbb és legközkedveltebb gép Európában, amely ugyanakkor Z80A mikroprocesszorral működik. Ez utóbbi azért lényeges, mert a Z80A-hoz illesztőáramkörök egész sora kapható (pl. a Zi1og perifériaillesztő-áramkör családja).
A legegyszerűbb perifériaillesztés egy RESET gomb csatlakoztatása. Ez gyakorlatilag nem más, mint a Z80A rendszerkivezetéseknél is kihozott RESET bemenete és a földvezeték összekötése rövid időre, kapcsoló segítségével. Igen sok számítógép hátulján található olyan gomb, amellyel a tárat törölve vagy annak tartalmát megtartva hardversegítséggel állíthatjuk meg a program futását, ha ez pl. már a BREAK billentyű segítségével nem lehetséges. ZX Spectrumon az eredeti ROM alkalmazásával csak az előbbi módszer képzelhető el, hiszen az INT bemenet billentyűzetkezelési és rendszercélokra szolgál, az NMI bementre adott pozitív jel pedig az említett ROM-szoftver hiba miatt egy RESET bemenetre adott pozit1v jellel lesz egyenértékű. Magyarországon igen sok amatőr gyakorlatilag közvetlenül kapcsolja össze a RESET és a földvezetéket pl. mikrokapcsolóval, biztonságosabb azonban a tápfeszültséges megoldás bementi ellenállás és közbeiktatott kondenzátor segítségével.
Hogy a billentyűzetnek megfelelő gombokat hogy illesszük, ez kiderül az ULA portkezelő funkcióiról és az alsó 16 K működéséről szóló szakaszok ábráiból. Ami a különböző szabványú, kódolt billentyűzeteket illeti, számos illesztés van forgalomban, ill. képzelhető el.
Ugyanez érvényes a digitális (gyakorlatilag kapcsozó elven működő) botkormányok (joystick-ek) illesztésére is, mivel a billentyűzet összes szükséges vezetéke megtalálható a rendszerkivezetéseken. (Analóg botkormány illesztéséhez A/D átalakító vagy illesztőáramkör szükséges.) Hogy mely billentyűket választjuk, azt a bekötésekkel vagy a logika megválasztásával dönthetjük el. Magyarországon már kapható olyan botkormányillesztő áramkör, amely mikrokapcsolók segítségével bármely játékhoz használható. (Sajnos egyik illesztőáramkör-fajta - beleértve a Sinclair saját áramkörét - sem terjedt el olyan mértékben, hogy a játékok többsége azt vette volna át.)
Külön magnetofonillesztő-áramkörre csak akkor van szükség, ha - pl. a HT-1080Z-hez hasonlóan - vezérelni szeretnénk a be- és kikapcsolást is. Önálló, RS-232 szabványú interfészt igényel viszont a ZX Microdrive-ok illesztése, A microdrive egy kb. 80 KBájt tárkapacitású, kis méretű finommechanikával felszerelt végtelenített mágnesszalag, amely emiatt használható gyors, tömbkezelő utasításokkal, annak összes előnyével. Magyarországon egyrészt az ára, másrészt a hajlékony mágneslemezegységek jobb és tágabb alkalmazási lehetőségei miatt nem tudott az alapgéppel vagy akár csak a ZX printerrel arányos mértékben elterjedni. Az RS-232 interfész a Microdrive-ok meghajtásakor az A3, A4 és A5 címvezetékeket használja port üzemmódban.
Megint más jellegű probléma a sok üzemmóddal rendelkező intelligens nyomtatók illesztése, amelyek - noha jóval drágábbak - sokkal több és magasabb színvonalú szolgáltatást nyújtanak, mint a ZX nyomtató, ráadásul többnyire valamilyen szabványos leporellóval vagy írógéppapírral működnek. Az ilyen nyomtatók logikájukat tekintve ugyanis maguk is kisszámítógépek. Programozásukról és illesztésükről, más fontosabb paramétereikről a hozzájuk adott gépkönyvből tájékozódhatunk. Magyarországon a ZX Spectrumhoz leginkább az EPSON RX-80, az EPSON FX-80 , ill. a Seikosha nyomtatók terjedtek el. Illesztésükkor a fő feladat nem a hardvercsatolás. Ez igen egyszerűen, pl. Intel 8255 típusú perifériaillesztővel , s valamilyen logikai áramkörrel az esetek többségében megoldható. A lényeg a szoftverillesztés, azaz a BASIC LPRINT, LLIST és COPY funkciók használhatóvá tétele az adott berendezésben (nem beszélve az egyes nyomtatók saját többletszolgáltatásairól). Intelligensebb, de drágább illesztőáramkörök már eleve tartalmazzák ezt a programot, míg olcsóbb, de kényelmetlenebb áramkörök esetében bekapcsolás után ezt kazettáról kell beolvasni, amelyet a gyártó vagy az üzlet mellékel. Sok illesztőáramkör nemcsak az előbb említett BASIC parancsokat tartalmazza, de lehetővé teszi pl. a képek nagyítását, kicsinyítését vagy forgatását is.
A ZX SPectrum az egyik legkönnyebben fejleszthető rendszer, emiatt amatőrök és kisebb-nagyobb cégek kiegészítő áramkörök egész sorát készítik hozzá. Hazánkban ezeket túlnyomórészt szövetkezetek és GMK-k forgalmazzák. Ugyanakkor az újságok is egyre másra közölnek kapcsolásokat a ZX Spectrumhoz a világító LED sortól a telefonos illesztésig.
2. A ZX Spectrum gépi kódú programozása
Ebben a fejezetben a Spectrum gépi kódú programozásának alapjait kívánjuk áttekinteni. Sokféle véleménnyel találkozhatunk a mikroszámítógépek gépi kódú programozásával kapcsolatban. Az egyik szélsőséges álláspont szerint a gépi kódú programozás,a magas szintű programnyelvek korában már elavult, míg a másik szerint a BASIC nem jó semmire, mert lassú és nehézkes.
Természetesen egyik álláspont képviselőinek sincs teljes mértékben igazuk: hiszen számos feladatot felépítése, időzítése, sebesség- és tárigénye stb. miatt nem lehet vagy igen nehézkes BASIC-ben megoldani. Ugyanakkor azt is el kell ismerni, hogy a BASIC az egyik legkönnyebben érthető és programozható nyelv, a ZX Spectrum BASIC változata pedig különösen sokoldalú.
Gépi kódú programot sokféleképpen lehet bevinni a gépbe:
Programtechnikailag a legelső a legegyszerűbb. Nem kell mást csinálni, mint BASIC-ben írni egy két-három soros segédprogramot, amely gépi kódú programok (a továbbiakban röviden kódprogramok) bevitelére szolgál. Még erre sincs azonban szükség, hiszen egy CLEAR utasítással lejjebb helyezve a RAMTOP-ot , azaz a BASIC számára engedélyezett programtároló és -végrehajtó RAM terület utolsó bájtját, egyszerűen, POKE utasítással bevihetjük és PEEK-kel ellenőrizhetjük a megfelelő számokat. Nagyban megnehezíti azonban ezt a látszólag egyszerű módszert, hogy olyan sok utasításkód és kódkombináció van a Z80-on, hogy megjegyzésük és megfelelő alkalmazásuk - legalábbis belátható időn belül - csaknem lehetetlennek látszik.
Valamivel kifejezőbb - elsősorban gyakorlott gépi kódú programozók számára - a hexadecimális számrendszerbeli szám formájában történő bevitel. A hexadecimális forma egyrészt gyors, másrészt könnyebben áttekinthető, harmadrészt sokkal jellemzőbb a kettes számrendszerbeli kódokra, mint a decimális alak. A hexadecimális forma nagy segítség a régi gépeket gépi kódban programozó vagy gyakorlott mikroprocesszor-programozó szakemberek számára. Egyébként a Spectrum BASIC bináris átalakító függvénye lehetővé teszi, hogy egy-egy adatot közvetlenül kettes számrendszerbeli szám formájában vigyünk be, pl. a következő módon:
POKE 60000,BIN 01001110
Különösen gyorsan ismerhető fel a hexadecimális alakban néhány alapvető bináris struktúra, mint pl. a 127-nél nagyobb szám stb. A kényelmetlenség alapvető forrása azonban megmarad: a szám formában közölt utasításfunkció szerint továbbra is dekódolnia kell a programozónak pl. táblázat segítségével. A legtöbb Spectrum-tulajdonos számára azonban még ennyi segítséget sem jelent a hexadecimális programozás, hiszen többségük életében először találja magát szemben a mikroprocesszor-programozás problémájával.
A számokkal végzett programozási munka áttekinthetetlenségét és nehézségét oldja fel a fejezetünk elején harmadik megoldásként említett assembler nyelv alkalmazása. Ekkor az utasítások funkcióit leíró angol nyelvű rövidítésekből építhetjük fel programunkat. Áttekinthetősége miatt az assembler nyelvet még akkor is célszerű alkalmazni, ha nem áll rendelkezésre assembler fordítóprogram, vagyis olyan program, amely ezeket a rövidítéseket közvetlenül gépi kóddá alakítja át, s a megfelelő címtől kezdve sorrendben elhelyezi a tárban.
2.1. A Z80 assembler használata
Mivel az egyes processzortípusok utasításkészlete más és más, érthetően típusonként változik az ezeket kifejező assembler nyelv is. Minthogy az assembler nyelv a processzorokhoz (a központi egységhez) kötődik, az azonos típusú mikroprocesszort alkalmazó számítógépek assembler-e is azonos. Így nem Spectrum-assemblerről, hanem Z80 assemblerről beszélhetünk, amely valamennyi , Z80-ra épülő rendszerben közös.
Z80 assemblerben egy gépi kódú műveletet a művelet jellegére "emlékeztető" rövidítés (mnemonik) és a művelet operandusa(i) együttesen jellemez(nek). Pl. a LD A,B utasításban a művelet az LD, az operandusok az A, és B, amelyek a két regiszter tartalmát mint változók jelölik. Ez az utasítás egybájtos, azaz a tárból mindössze egy megfelelő nyolcbites adatkombinációt kell kivenni a művelet kiváltásához. A Z80 mikroprocesszor számára egy-, két-, három- és négybájtos utasítások léteznek, ebben a megjelölésben azonban nincs benne az, hogy hány bájt ebből a tényleges utasításkód. Pl. egy hárombájtos utasítás összeállhat úgy is, hogy egy bájt az utasításkód, s a mögötte álló kettő egy operandus abszolút tárcíme.
A Z80 assembler utasításkészletét a hardver fejezetben már részletesen tárgyaltuk. Különféle szempontok szerinti összefoglalása - melyre gyakran lehet szüksége Z80 programozónak - a függelékekben is megtalálható.
Fejezetünkben olyan kiegészítő (gyakran direktívának nevezett) utasításokról szólunk, amelyek a fordítóprogram működését vezérelve (plusz szolgáltatásként) segítik a Z80 assembler nyelv használatát. Az ilyen utasítások szükségességét könnyen beláthatjuk.
Igen sokszor előfordul pl., hogy munkánknak ténylegesen csak egy része a program, és jelentékeny hányadát a tárban elhelyezett adattáblázat alkotja, amelynek "jelentését" csak a mi programunk "érti". Ha egy Z80 assembler fordítóprogram csak a mikroprocesszor gépi kódjaira jellemző utasításkészlettel rendelkezne, az adatok beviteléhez ki kellene lépnünk a fordítóprogramból, s munkánkat BASIC-ben kellene folytatnunk. Szerencsére nem ez a helyzet. Létezik néhány olyan Z80 assembler utasítás, amely nem közvetlenül a Z80-nak, hanem az assembler fordítónak szól, mégis elengedhetetlenül szükséges gyors és hatékony programozáshoz. Míg a Z80 utasításkészlete minden Z80-at alkalmazó hardverrendszerben közös, a most következő utasítások alkalmazhatósága attól függ, milyen assembler fordítóval dolgozunk!
FONTOS!
Az "ENT $" csak a GENS assembler fordítóprogram családdal való egy az egybeni alkalmazhatóság kedvéért szerepel a programokban, mivel ez az egyik legelterjedtebb és legközkedveltebb assembler a magyarországi Spectrum-tulajdonosok köréhen. Aki más fordítóval dolgozik, az annak a direktíváit vegye figyelembe Az ENT (ENTER) csak GENS programoknál használatos direktíva, így itt nem foglalkozunk vele.
ORG nn
Jelentése: definiáld az ezt követő program legelső bájtjának kezdőcímét! A mögötte lévő szám (az 1.2.1. pont jelöléseit használjuk) értéke 0 és 65535 közt változhat, s megadja azt, hogy hol kezdődjön az assembler nyelvű (forrás-) program gépi kódú változata (a tárgyprogram). Általában egy programban csak egy ORG utasítás fordulhat elő, s ez érvényes a ZX Spectrumra jelenleg forgalomban lévő fordítók mindegyikére.END
Jelentése assembler program vége. A gyakorlatban a fordítás úgy történik, hogy az ORG után álló szám értékét veszi fel egy ún. assembler programszámláló. Jelölése Z80 assemblerben $; szemmel láthatólag igen hasonló a feladata a Z80 PC regiszteréhez. Az END-nél a fordítás abbamarad, s az esetleges utána következő programrészek már nem kerülnek lefordításra. A legtöbb ZX Spectrumhoz kapható assembler fordító a fordítási parancs után azonnal hibát jelez, ha a program végén vagy bárhol nem található ilyen utasítás.DEFB n
Jelentése: írd be a fordításkor a következő bájt helyére az n számot (DEFine Byte)! pl.:
10
20
30
40
50ORG 60000
ADD A,B
DEFB 45
LD A,B
ENDA fordítóprogram a "fordíts" utasítás kiadása után az ADD A,B egybájtos kódját a 60000-es, a 45-öt a 60001-es és a LD A,B szintén egybájtos utasítás kódját a 60002-es címre teszi. (A Neumann-elv értelmében a 45 lehet akár utasítás, akár adat.) Ezzel a módszerrel nemcsak egyes bájtok, de egész adatblokkok is bevihetők egy programrészleten belül bináris formában. Persze ügyelnünk kell arra, hogy az így bevitt számokat programfuttatáskor valóban adatként értelmezze a mikroprocesszor. Az előző kis programban - ha lefuttatnánk - utasításként értelmezné a mikroprocesszor.
DEFW nn
Jelentése: fordításkor írd be a következő két bájt helyére az nn számot (DEFine Word)!nn = n1 + 256*n2
Ahol n1 és n2 nyolcbites bináris egész szám. Ha az előbbihez hasonló mintaőrogramot tekintjük:
10
20
30
40
50ORG 60000
ADD A,B
DEFW 511
LD A,B
ENDa 60000-es címre az ADD A,B egybájtos utasításkódja, a 60001-esre 255, a 60002-esre 1, a 60003-asra pedig a LD A,B (szintén egybájtos) utasításkódja kerül. Ennek oka az, hogy
511 = 255 + 1*256
DEFM "karakterlánc"
Jelentése: fordításkor írd be a bájtokba sorrendben balról jobbra a karakterlánc egyes betűinek ASCII kódját (DEFine string)! Nézzünk egy példát:
10
20
30
40
50ORG 60000
LD BC,511
DEFM "STRING"
DEC H
ENDA fordítás eredménye a következő lenne:
60000
60001
60002
60003
60004
60005
60006
60007
60008
600091
255
1
83
84
82
73
78
71
37; LD BC,511
; "S" ASCII kódja
; "T"
; "R"
; "I"
; "N"
; "G"
; DEC HDFB l
Jelentése: hozzárendeli a bájthoz egy betű (l) ASCII kódját. Ha az előbbi program a következőképpen módosul:
10
20
30
40
50ORG 60000
LD BC,511
DFB "A"
DEC H
ENDAkkor a fordítás után a tár tartalma a következő:
60000
60001
60002
60003
600041
255
1
65
37; LD BC,511
; l ASCII kódja itt "A"
; DEC HDEFS nn
Jelentése: hagyj ki nn-nyi helyet a fordításkor. Vizsgáljuk meg ezt is egy mintaprogramon:
10
20
30
40
50ORG 60000
LD BC,511
DEFS 4
DEC H
ENDHa előzőleg minden bájt értéke nulla volt, a tár tartalma a fordítás után:
60000
60001
60002
60003
60004
60005
60006
600071
255
1
0
0
0
0
37; LD BC,511
; a kihagyott 4 bájt helyén
; benn maradnak a nullák
; DEC HIgen hasznos direktíva pl. táblázatok helyénekkihagyására.
MACRO
Jelentése: egy-egy programrészhez hozzárendel egy-egy nevet. Felhasználása, lehetséges jelentései szélesebb körűek is lehetnek, a ZX Spectrumhoz azonban sajnos alig használja egy-két fordítóprogram.ENDM
Jelentése: MACRO-hoz rendelt programrészlet vége (END of Macro). Csak a MACRO-val együtt fordul elő. Nézzünk egy alkalmazási példát:
PROG1 MACRO LD A,4
ADD A,B
ENDMEzután a programban szereplő valamennyi PROG1 helyére a fenti kis programrészlet fordítódik be, s nem kell többször ugyanazt leírni, ha pl. nem rakható szubrutinba.
EQU nn
Jelentése: hozzárendeli egy abszolút cím (nn) értékét egy címkéhez a következő formában:20 CIMKE EQU 47000
Ezzel a címke értéke 47000 lesz, s a fordítás során akárhányszor előfordul a címkeváltozó, mindig a 47000 abszolút címet fogja jelenteni. Így pl.
70 LD A,(CIMKE)
Egyenértékű lesz EQU-val való definiálás után a
70 LD A,(47000)
Utasítással. Az EQU utasítással egy programon belül csak egy érték rendelhető hozzá egy címkéhez. Pl. a
60
70...
CIMKE
CIMKE
...
EQU 47000
EQU 60000esetben fordításkor a program hibát jelez.
Érdemes itt röviden kitérnünk az assembler és a BASIC címkehasználatának eltérésére. A címke egy utasítás megjelölésére szolgál, pl. azért, hogy az illető utasításra a címke megkeresésével ugorhassunk vissza. Nézzük pl. a következő BASIC programot:
10 LET a=100
20 IF a<>0 THEN LET a=a-1: GO TO 20
30 STOP
Ennek a programnak az assembler változata a következő:
10 20 30 40 50 60 |
CIMKE |
ORG 60000 |
A fordítóprogram lefoglal magának egy tárterületet, ahol az előző programnak megfelelő szöveget tárolja. A sorszámok csak arra szolgálnak, hogy az utasítások bevitelének sorrendjét határozzák meg erre a tárterületre, az ún. szövegállományba (text file - forrásprogramlista tárhelye). Nem jelentenek azonban ténylegesen ugró vagy szubrutinhívó címeket, mint a BASIC-ben. Erre a tárgyprogram az abszolút címeinek védelme miatt van szükség. Ehelyett erre a címkék szolgálnak. A ZX Spectrumhoz kapható valamennyi assembler fordító használ sorszámot, ám vannak olyan, Z80-nal működő számítógépes fejlesztőrendszerek, ahol nincs ilyen. (Az előző program már futtatható ZX Spectrumon is, nem csak mintaprogram.)
DEFL nn
Jelentése: hozzárendeli egy abszolút cím értékét egy címkéhez (DEFline Label). Hasonló tehát az EQU-hoz, de fontos különbség, hogy egy programon belül egy címkéhez többször is hozzárendelhetünk nn értékeket. Különösen fontos lehet bizonyos programstruktúrák felépítésekor.
2.2. Assembler fordítók ZX Spectrumhoz
A ZX Spectrumhoz több assembler fordítóprogram is kapható (pl. GENS1 ... 3, EDITAS, uv, ASPECT, ZEUS stb.), ezek azonban bizonyos jellemzőikben eltérőek, tehát nincs olyan egységes programformátum, amelyikben úgy dolgozhatunk, hogy programunkat bármelyik fordító módosítás nélkül megértse. Szerencsére létezik Magyarországon egy "kedvenc" amely a legközkedveltebb és a legelterjedtebb, s ez a GENS programcsalád. Ennek tagjai, a GENS1, GENS2 és GENS3 lényegesen nem térnek el egymástól. Természetesen ennek is vannak eltérő tulajdonságai a szokásos Z80 assembler formától. Ilyen pl. az ENT utasítás megléte, amelyről röviden már szóltunk a direktívák ismertetése előtt. Ha közvetlenül az ORG után kiadunk egy ENT utasítást argumentumában az aktuális PC jellel ($), eredményül helyes fordítást kapunk. Sajnos az egyes fordítóknál a címkék megengedett maximális hossza is változó. A GENS programok maximálisan 6-betűs címkéket engednek meg, így mi ehhez alkalmazkodunk. Sajnos magával a GENS fordítóprogram-családdal részletesen foglalkozni nincs módunk, de ajánljuk a vásárláskor hozzáadott leírás alapos tanulmányozását. Sajnos ez angol, ill. német nyelvű, s nagykereskedelmi forgalomban magyar fordításuk egyenlőre nem szerezhető be.
2.3. Programozás gépi kódban és Z80 assemblerben
A következőkben a Spectrum Z80 assemblerben való programozásába egy a képernyőre ható grafikus példán keresztül szeretnénk bevezetni az Olvasót. Az elég nagy terjedelmű rajzolóprogram előtt azonban tekintsük át a Spectrum képernyőkezelésének legfontosabb jellemzőit!
A 43. ábrán - ha eltekintünk a BASIC ROM használatától - tisztán hardverszempontú tárkiosztás látható. 0-tól 16383-ig helyezkedik el a CPU számára csak olvasható BASIC ROM. A 16384-es címtő1 a 22527-esig található a grafikus képernyőtár.
Látható, hogy egy különös szabály szerint elsötétül (ill. a beállított INK és PAPER-nek megfelelően kivilágosodik). A 44. ábrán a Spectrum teljes grafikus felbontása látható, amely vízszintes irányban 256 képpont, függőlegesen pedig 192. A teljes felbontás tehát
képpont.
bájt hosszú a képernyőtár. Minden bájt 8 bitből áll, így
azaz minden képponthoz egy bit tartozik.
függőlegesen pedig
|
43 ábra: A ZX Spectrum tárkiosztása |
44. ábra: A ZX Spectrum grafikus felbontása
45 ábra: A ZX Spectrum színfelbontása
Minthogy
32 * 24 = 768,
minden 8*8-as grafikus egységre, ill. betűre jut egy szintárbeli bájt. Ennek: szerkezete a 46. ábrán látható.
46. ábra: a színtár bájtjainak és a 22528-as című színtárbájt által lefedett grafikus bájtok a képernyőn
Mivel a 8*8-as egységen belül minden bit 0 vagy 1 lehet, a szintár bájtjainak 0., 1. és 2. sorszámú bitje az l-es értékű grafikus tárbeli bitek színét határozza meg. Azért csak ez a három bit, mert a Spectrumon összesen csak 8-féle szín alkalmazása lehetséges, s három bitben a lehetséges kombinációk száma:
2^3 = 8
A 3., 4. és 5. helyértékűek a 0 értékű grafikus bitek színét határozzák meg. (Az 1-es értékű grafikus bitek BASIC-ben az INK, a 0 értékűek a PAPER színnek felelnek meg.) Ha a 6. helyértékű színbeli bit értéke 1, az adott 8*8-as egység fényesebben világít. (A BASIC-beli BRIGHT függvény két lehetséges értéke ugyancsak 0 és 1.) Ha pedig a 7. színtárbeli bit értéke 1, akkor a hozzá tartozó 8*8-as egység villogni kezd. (BASIC-ben FLASH 0 ill. 1-gyel adható meg.)
A.1. Függelék: Az utasításnevek angol jelentése
ADC ADD AND BIT CALL CCF CP CPD CPDR CPI CPIR CPL DAA DEC DI DJNZ EI EX EXX HALT IM IN INC IND INDR INI INIR JP JR LD LDD LDDR LDI LDIR NEG NOP OR OTDR OTIR OUT OUTD OUTI POP PUSH RES RET RETI RETN RL RLA RLC RLCA RLD RR RRA RRC RRCA RRD RST SBC SCF SET SLA SRA SRL SUB XOR |
- add with carry |
D. Függelék: A ZX Spectrum grafikus képének kezdőcíme a ROM-ban
Karakter | ASCII kód | Kezdőcím | Karakter | ASCII kód | Kezdőcím | |
(szóköz) | 32 | 15616 | P | 80 | 16000 | |
! | 33 | 15624 | Q | 81 | 16008 | |
" | 34 | 15632 | R | 82 | 16016 | |
# | 35 | 15640 | S | 83 | 16024 | |
$ | 36 | 15648 | T | 84 | 16032 | |
% | 37 | 15656 | U | 85 | 16040 | |
& | 38 | 15664 | V | 86 | 16048 | |
' | 39 | 15672 | W | 87 | 16056 | |
( | 40 | 15680 | X | 88 | 16064 | |
) | 41 | 15688 | Y | 89 | 16072 | |
* | 42 | 15696 | Z | 90 | 16080 | |
+ | 43 | 15704 | [ | 91 | 16088 | |
, | 44 | 15712 | \ | 92 | 16096 | |
- | 45 | 15720 | ] | 93 | 16104 | |
. | 46 | 15728 | ^ | 94 | 16112 | |
/ | 47 | 15736 | _ | 95 | 16120 | |
0 | 48 | 15744 | £ | 96 | 16128 | |
1 | 49 | 15752 | a | 97 | 16136 | |
2 | 50 | 15760 | b | 98 | 16144 | |
3 | 51 | 15768 | c | 99 | 16152 | |
4 | 52 | 15776 | d | 100 | 16160 | |
5 | 53 | 15784 | e | 101 | 16168 | |
6 | 54 | 15792 | f | 102 | 16176 | |
7 | 55 | 15800 | g | 103 | 16184 | |
8 | 56 | 15808 | h | 104 | 16192 | |
9 | 57 | 15816 | i | 105 | 16200 | |
: | 58 | 15824 | j | 106 | 16208 | |
; | 59 | 15832 | k | 107 | 16216 | |
< | 60 | 15840 | l | 108 | 16224 | |
= | 61 | 15848 | m | 109 | 16232 | |
> | 62 | 15856 | n | 110 | 16240 | |
? | 63 | 15864 | o | 111 | 16248 | |
@ | 64 | 15872 | p | 112 | 16256 | |
A | 65 | 15880 | q | 113 | 16264 | |
B | 66 | 15888 | r | 114 | 16272 | |
C | 67 | 15896 | s | 115 | 16280 | |
D | 68 | 15904 | t | 116 | 16288 | |
E | 69 | 15912 | u | 117 | 16296 | |
F | 70 | 15920 | v | 118 | 16304 | |
G | 71 | 15928 | w | 119 | 16312 | |
H | 72 | 15936 | x | 120 | 16320 | |
I | 73 | 15944 | y | 121 | 16328 | |
J | 74 | 15952 | z | 122 | 16336 | |
K | 75 | 15960 | { | 123 | 16344 | |
L | 76 | 15968 | | | 124 | 16352 | |
M | 77 | 15976 | } | 125 | 16360 | |
N | 78 | 15984 | ~ | 126 | 16368 | |
O | 79 | 15992 | © | 127 | 16376 |
E Függelék: Hexadecimális összeadótáblázat
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F | |
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F | 10 |
2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F | 10 | 11 |
3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F | 10 | 11 | 12 |
4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F | 10 | 11 | 12 | 13 |
5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F | 10 | 11 | 12 | 13 | 14 |
6 | 7 | 8 | 9 | A | B | C | D | E | F | 10 | 11 | 12 | 13 | 14 | 15 |
7 | 8 | 9 | A | B | C | D | E | F | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
8 | 9 | A | B | C | D | E | F | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
9 | A | B | C | D | E | F | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
A | B | C | D | E | F | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 |
B | C | D | E | F | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 1A |
C | D | E | F | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 1A | 1B |
D | E | F | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 1A | 1B | 1C |
E | F | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 1A | 1B | 1C | 1D |
F | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 1A | 1B | 1C | 1D | 1E |
F. Függelék: A ZX Spectrum alkotóelemei
Integrált áramkörök
IC1: | Ferranti 5C... (Sinclair chip) |
IC2: | Z80A központi egység |
IC3, IC4, IC25, IC26: | SN74LS157 multiplexer |
IC5 | Sinclair ROM (ekv. tipus: 27128 EPROM) |
IC6 - IC13: | 4116-os 16*1-es RAM |
IC14: | LM1889-es video-modulátor |
IC15 - IC22: | 4532-es 32*1-es RAM |
IC23: | SN74LS37 logikai kapuáramkörök |
IC24: | SN74LS00 logikai kapuáramkörök |
IC25: | 7805-ös 5 V-os stabilizátor |
Kristály-frekvenciaforrások
X1: | 14 MHz-es jelforrás az ULA-nak |
X2: | 4,4336 MHz-es jelforrás az LM1889-nek |
Tranzisztorok
Tr1, Tr2, Tr3, Tr6: | ZTX 313 (Ferranti) |
Tr4: | ZTX 650 telj. tranzisztor (Ferranti) |
Tr5: | ZTX 213 pnp (Ferranti) |
Diódák
D1 - D14: | IN 4148 |
D15: | BA 175 (nagy teljesítményű dióda) |
D17: | Z-dióda |
Kondenzátorok
C1 - C8: | 47 nF |
C9 - C23: | (illesztések) |
C25: | 22 mF, 16 V |
C26: | 47 nF |
C27: | 1 mF, 63 V |
C28: | 22 mF, 16V |
C29: | 47 nF |
C30: | 47 nF |
C31: | 100 nF |
C32: | 10 nF |
C33: | 47 nF |
C34: | 22 mF, 16V |
C35: | 10 nF |
C36: | 47 nF |
C37: | 33 pF |
C38: | 33 pF |
C39: | 10 nF |
C40 - C42: | 47 nF |
C43: | 100 nF |
C44 - C45: | 100 mF, 16V |
C46: | 1 mF, 50 V |
C47: | 22 mF, 16V |
C48 - C49 | 47 nF |
C50 - C62: | (esetleges illesztések) |
C63 - C64: | (csatolás az extra 32K-ban) |
C65: | (csatolás a tv-áramkörben) |
Ellenállások
R1 - R8: | 470 ohm |
R9 - R16: | 8,2 Kohm |
R17 - R23: | 330 ohm |
R24: | 3,3 Kohm |
R25: | 180 ohm |
R26 - R27: | 680 ohm |
R28: | 10 Kohm |
R29: | 1,5 Kohm |
R30: | 1 Kohm |
R31: | 220 Kohm |
R32: | 100 ohm |
R33: | 680 ohm |
R34: | 15 ohm |
R35: | 10 Kohm |
R36: | 680 ohm |
R37: | 1 Kohm |
R38 - R39: | 3,3 Kohm |
R40: | 1 Kohm |
R41: | 1,5 Kohm |
R42: | 1 Kohm |
R43: | 3 Kohm |
R44: | 5,1 Kohm |
R45 - R46: | 1 Kohm |
R47: | 120 ohm |
R48: | 4,7 Kohm |
R49: | 18 Kohm |
R50: | 4,7 Kohm |
R51 - R52: | 2,2 Kohm |
R53: | 390 ohm |
R54: | 100 Kohm |
R55: | 56 ohm |
R56: | 220 ohm |
R57: | 330 ohm |
R58: | 1 Kohm |
R59: | 1,8 Kohm |
R60: | 100 ohm |
R61 - R62: | 15 ohm |
R63: | 220 ohm |
R64: | 15 ohm |
A ZX Spectrum jelentősebb integrált áramköreinek fontosabb paraméterei
A Z80A fontosabb adatai
Th: -65 °C ... +150 °C
Bemeneti feszültség: - 0,3 V ... + 7 V Telj. disszipáció: 1,5 W
Bem. kapacitás: 5 pF
Kim. kapacitás: 10 pF
órajel kapacitása: 35 pF
órajel fesz. alacsony szint: tápfesz. - 0,6 V
órajel fesz. magas szint; tápfesz. + 0,3 V
Bem. áram: 200 mA
Bem. fesz, alacsony szint: -0,3 V ... + 0,8 V
Kim. fesz. alacsony szint: max. 0,4 V (Ha árama 1,8 mA)
Bem. fesz. magas szint: min. 2 V
Kim. fesz. magas szint: min. 2,4 V (ha árama -250 mA)
A Sinclair ULA fontosabb adatai
(Határadatok 5 V-os tápfeszültség és 25 °C-os működési hőmérséklet mellet.)
Tápfeszültség: min. 3,5 V, max. 5,5 V
Áram: (ált.) 610 mA
Bemeneti áram (ha a bemeneti ellenállás 4 Kohm): min. 0 A, max, 40 nA
Alacsony szint bem. árama: min. 0 A, max. -1,6 mA
Bem. fesz. magas szint: min. 2 V, max. 5,5 V
Bem. fesz. alacsony szint: min. 0 V, max. 0,8 V Maximális órajel-frekvencia: 20 MHz
Kapuk késleltetési ideje: 8 ns
Perifériacella disszipációja: 11 mW
A 27128 fontosabb adatai
Tápfeszültség: 5 V (plusz-mínusz 10%)
Standard elérési idő: 250 ns
Aktív áramfelvétel: 150 mA
"Készenléti üzemmód" áramfelvétele: 45 mA
Az SN47LS157 fontosabb adatai
Tápfeszültség: min. 4,75 V, max. 5,25 V
Alacsony szint kim. árama: max. 16 mA
Magas fesz. szint kimeneti árama: max. -800 mA
Áramfelvétel: max. 48 mA
Magas szint bem. árama: max. 40 mA
Alacsony szint bem. árama: max. -1,6 mA
Kimeneti rövidzár: min. -18 mA, max. -55 mA
Bem. fesz. alacsony szint: max. 0,8 V
Bem. Fesz. magas szint: min. 2 V
Működési hőmérsékleti tartomány: min 0 °C, max. 70 °C
Az SN47LS32 fontosabb adatai
Tápfeszültség: min. 4,75 V, max. 5,25 V
Max. áramfelvétel: 9,8 mA
Alacsony fesz. szint kim. árama: max. 8 mA
Magas fesz. szint kimeneti árama: max. -400 mA
Magas fesz. szint bem. árama: max. 20 mA
Alacsony fesz. szint bem. árama: max. -0,4 mA
Kimeneti rövidzár: min. -20 mA, max. -100 mA
Alacsony bem. fesz. szint: max. 0,8 V
Magas bem. fesz. szint: min. 2 V
Az SN74LS00 fontosabb adatai
Tápfeszültség: min. 4,75 V, max. 5,25 V
Max. áramfelvétel: 4,4 mA
Alacsony kim. fesz. szint árama: max. 8 mA
Magas kim. fesz. szint árama: max. -400 mA
Magas bem. fesz. szint árama: max. 20 mA
Alacsony bem. fesz. szint árama: max. 0,4 mA
Kimeneti rövidzár: min. - 20 mA, max. -100 mA
Alacsony bem. fesz. szint: max. 0,8 V
Magas bem. fesz. szint: min. 2 V
Működési hőmérséklet: 0 °C ... 70 °C
A 7805 fontosabb adatai
Bemeneti feszültség: min. 7 V, max. 25 V
Kimeneti feszültség: min. 4,8 V, max. 5,2 V
Kimeneti áram: max. 500 mA
Vonalszabályozás (25 °C-on bem. hat.): max. 50 mV
Fesz. esés 1 A-en és 25 °C-on: max. 2,5 V
Rövidzár (25 °C-on, 35 V-on): max. 1,2 A
Kim. ellenállás (1 kHz vk.): 17 Mohm
Bemeneti kapacitás: 0,33 mF
Kimeneti kapacitás: 0,1 mF
Működési hőmérséklet: -55 °C ... +150 °C
G. Függelék: Korrekciós értékek DAA után
ADC, ADD és INC tipusúak után: | |||||
Az A felső 4 bitje |
Az A alsó 4 bitje |
C |
H |
Az A-hoz hozzáadandó |
C bit Daa után |
0 - 9 0 - 8 0 - 9 10 - 15 9 - 15 10 - 15 0 - 2 0 - 2 0 - 3 |
0 - 9 10 - 15 0 - 3 0 - 9 10 - 15 0 - 3 0 - 9 10 - 15 0 - 3 |
0 0 0 0 0 0 1 1 1 |
0 0 1 0 0 1 0 0 1 |
0 6 6 96 102 102 96 102 102 |
0 0 0 1 1 1 1 1 1 |
DEC, NEG, SBC és SUB tupusúak esetén: | |||||
0 - 9 0 - 8 7 - 15 6 - 15 |
0 - 9 6 - 15 0 - 9 6 - 15 |
0 0 1 1 |
0 1 0 1 |
0 250 160 154 |
0 0 1 1 |
(Az előbbi esetben N=0, az utóbbi esetben N=1.)