A blokkséma minden részéből találhatók itt kapcsolások, azok működésének leírásai és a szemléletesség kedvéért az adott kapcsolásnak megfelelő layoutképek.

                                      Órajel generátor

A Cp0 órajel bemenetből (980 kHz) a processzor saját maga állitja elő a Cp1 és Cp2 fázisjeleket, melyek nem lapolnak át, tehát élesen két időszeletre osztják az óraciklusokat. Ez nem csak a regiszterek írasánál hasznos, külső egységeknek is szükségük lehet erre, ezért két lábra ki is vannak vezetve. Az órajel generátor működésének lényege, hogy két ellenütemű inverterpár, melyek nagy áramot adnak (mindenhova el kell juttatni a fázisjeleket) és lassúak, mint késleltetők használhatók fel a jelek időbeli csúsztatgatására a lenti ábrának megfelelően. Maga a kapcsolás nagyon egyszerű, kevés tranzisztort használ, viszont sok helyet foglal el szilíciumon, hasonlóan a buszmeghajtó áramkörökhöz.

Utasításdekódoló

Légyegi része a PLA, mely NOR kapukból áll, és a bemeneteit az utasitás regiszterből és az időzítőtől kapja. Kimenetei közvetlenül meghajtják a regiszterblokkot. Ezen kívül fontos feladata még az utasításhatárok megállapítása: ez a fetch jel kiadásához és a sync láb vezérlésehez szükséges, valamint az interrupt logikához is (megszakítás csak utasításhatáron). Az, hogy mikor kell új opkódot betölteni (fetch), az előző opkódtól függ, mert az utasítások nagy része adott óraciklust igényel, függetlenül attól, hogy van-e BCD korrekció, vagy nincs. Kivételesek a feltételes vezérlésátadások esetei, melyekben a feltétel teljesülésétől függően vagy vézérlésátadás, vagy fetch következik.

A layouton az oszlopok a NOR kapuk kimenetei, a sorok a bemenetek ponáltjai és negáltjai. Az elrendezés meglehetősen praktikus, mert 1 kontaktus két bit információt is hordozhat: az egyik sor negált bemenetét és az alatta levő sor ponált bemenetét. A 8 adatbit bemenet egyébként nem sorban van, hanem össze-vissza. Az oszlopok között előfordul olyan is, amelyik sehova nincs lekontaktusozva, mert például nem is az utasításdekódolóhoz tartozik, hanem az IRQ kérést szállítja.

A PLA kimeneteit egy kombinációs hálózat fogadja, mely nem csak a PLA-ból dolgozik, hanem jó néhány belső vezérlőjelet is felhasznál, például ilyen a belső Ready jel, a Sync jel, az időzítő egyik kimetete is. A PLA kimenetek komplex kapukon áthaladva ellenütemű inverterekre jutnak, melyek egy hosszú poliszilícium vezetéket és 8 transzfer gate-et meghajtva közvetlenül befolyásolják a regiszterek írását / olvasását, az ALU működését, valamint a buszmeghajtó áramkörök, cím és adat vezetékek tartalmát.

A bal oldali ábrán egy egyszerű eset látható, az akkumulátor írásának a vezérlése. A 61-estől a 66-os számú PLA kimenetig a következő műveletek vannak kikapuzva: X vagy Y írása A-ba, logikai műveletek, összeadás - kivonás, akkumulátor bitléptetése, betöltése veremből. Vannak azonban ennél jóval bonyolultabb kapcsolások, melyek szintén a regiszterblokk transzfer gate-jeit vezérlik: például mikor kell egyik belső sín tartalmát a másikra írni, honnan kapja az ALU a bemeneteit stb... Sokbemenetű kapuk dolgozzák fel a PLA olyan kimeneteit, melyek nem teljesen specifikáltak: a műveleti kód néhány bitje se 0-ra, se 1-re nincs lekötve. Emiatt a nem használt opkódok egészen érdekes működést produkálhatnak. Mivel nincs ellenőrizve, hogy egy opkód megfelelő-e, valami mindenképpen történik. A PLA néhány kimenete aktivizálódik, a regiszterblokk ennek hatására csinál valamit. Az úgynevezett "tiltott kódokat" három csoportba lehet besorolni:

  • Üres utasítás, mint a NOP: beolvassa az operandusát, egy sínre kiírja, ám ekkor be is fejezi a működését, az eredményt ottfelejti”. Valamely későbbi utasítás fogja felülírni, így elvész.
  • Értelmes utasítás, mely komplex is lehet, több műveletet is elvégezhet, mint például az ANE: A = (A | #$EE) & X & #byte A beépített konstans sem garantált!
  • Fagyást okozó utasítás. Ha több regiszter tartalmát ugyanarra a sínre írjuk, vagy az ALU egy menetben kiszámolt logikai függvényeiből többet is a kimenetére kényszerítünk, akkor logikai kapuk egymás ellen dolgozhatnak, nem alakul ki éles 0 vagy 1 szint, amit ugyan a következő kapuk elfogadnak, csinálnak belőle valamit, de mindenképpen lassabban kapcsolnak. Az előírt időzítések felborulnak, a processzor működésképtelen állapotba kerül.

A tiltott kódoknak egyébként fontos alkalmazása volt a programvédelem: egy módszer volt a sok közül arra, hogy egy szoftver írói megnehezítsék a kódtörők munkáját. Eleinte ugyanis a disassemblerek nem ismerték a tiltott kódokat, azokat érvénytelen opkódnak mutatták, ezért rosszul állapították meg az utasításhatárokat is: a tiltott kódokkal megírt program így egy nehezen módosítható, zavaros byte-halmaznak tűnt.

Időzítő vezérlő

 

Fő feladata, hogy az utasításdekódolónak megadja azt az információt, hogy a végrehajtás alatt levő utasítás hányadik óraciklusban jár. Az utasítások legalább 2, legfeljebb 7 óraciklus alatt futnak le, az első óraciklus mindig fetch (műveleti kód betöltése az utasításregiszterbe). Az időzítő vezérlő 1-1 kimenetén adja ki 6 ciklus információját (ez közvetlenül a PLA bemeneteire jut). Az utolsó négy ciklust egy olyan shift regiszterrel oldották meg, amelyben egy végigfutó 1-es bit jelenti az információt, és RDY=0 esetben a shift regiszter 4 bites tárolóként működik. A regiszternek ezen kívül van egy nullázó bemenete is, melyet az utasításdekódoló vezérel.


Interrupt logika

 

Feladata az IRQ, NMI vonalakon érkező megszakításkérések fogadása, engedélyezés eldöntése, és a megfelelő vektor által meghatározott címre történő vezérlésátadás, amennyiben utasításhatárra ér a processzor, valamint RESET esetén a reset vektor betöltése. Mindhárom eset lényegében egy indirekt vezérlésátadás, melyhez memóriaolvasási ciklusok kellenek. IRQ es NMI eséten veremműveletekre is szükség van, menteni kell a flag-et és az utasításszámlálót. Megszakítás elfogadásakor az interrupt logika szimulál egy BRK (szoftver megszakítás) utasítást az utasításdekódolónak, a különböző események között csupán annyi a különbség, hogy milyen címen van az ugrásvektor. A vektor címének beállításakor közvetlenül meghajtja a címkimeneteket, ehhez óraciklusokat "foglal le", és a belső READY jellel (Rdy0 a kapcsolási rajzon) várakoztatja a processzor többi részét. Ezt a többi blokk úgy észleli, mintha egy külső, lassú egység húzta volna le a processzor RDY lábát, plusz óraciklusokat igényelve. A három vektor, az NMI, RESET és az IRQ rendre a következő: FFFA, FFFC, FFFE. Vektor betöltésekor tehát a felső 13 címbit 1, az alsó 3 pedig attól függ, milyen esemény van. Az alsó bit mindig 0, mely nem csak arra szolgál, hogy meghajtja a címkimenetet, hanem arra is, hogy jelzi, hogy interrupt végrehajtás van folyamatban. Az alábbi áramkör ezt a jelet, és annak óraciklusokkal késleltetettjeit használja fel arra, hogy óraciklusokat foglaljon le a kérés teljesítéséhez:

A fenti kapcsolásra ugyan látszólag csak az NMI-nek a Schmitt triggeres bemenete van közvetlenül rákötve, de IRQ és RESET esetében is ugyanúgy működik, hiszen a legalsó címbit mindhárom esetben 0, és ennek a jelnek az 1 és 2 óraciklussal késleltetett jelei meghajtják ezt a kapcsolást.

Regiszterblokk, utasításszámláló

 

8 bites processzoron belül egy 16 bites regiszter: két 8 bites darabban valósították meg, 2 óraciklus kell az értékadáshoz. Előnyös az olyan címzésmód, mely az úgynevezett nulláslapon dolgozik (a memória alsó 256 byte-ja), mert ekkor 1 óraciklus megtakarítható. Az utasításszámlálóval végzett leggyakoribb művelet a növelés ehhez külön áramkör van beépítve, így nem kell igénybe venni az ALU-t, és a növelés a processzor többi területétől függetlenül zajlik. A tárolók olyan inverterpárok, melyek a növelőn keresztül vannak visszacsatolva: ha a carry 0, akkor az eredeti bit íródik vissza, ha 1, akkor az inverze.

A transzfer gate-ek jelentése a következő:

  • x1: írás a DATA1 sínre, ahonnan az adatlábakra és az ALU-ba kerülhet az IP egyik 8 bites fele
  • x2: IP értékadás ADDR1-ről (carry = 0 esetben)
  • x3: visszacsatolás
  • x4: írás ADDR1-re (ALU vagy a címkimenetek felé)

 

Stack pointer, X és Y indexregiszterek

 

Ezekben a regiszterekben a tárolás egy fázisjellel vezérelt transzfer gate-tel megszakított, keresztbe csatolt inverterpárral valósul meg. Cp1 alatt a parazita kapacitások feltöltése, Cp2 alatt visszacsatolás, az információ tartása történik. A stack pointer annyival tud többet X-nél és Y-nál, hogy értékét a címkimenetre is lehet írni.

 

  • x1: Stack pointer írása ADDR2-re (és onnan címkimenetre)
  • x2, x5, x7: írás ADDR1-re (többi regiszter írása, vagy ALU bemenet)
  • x3, x4, x6: olvasás ADDR1-ről

 

Akkumulátor, BCD korrekció

 

Az akkumulátor egy BCD korekciós kapcsoláson keresztül kaphat értéket. (Binary Coded Decimal, ez egy olyan számábrázolás, mélynél például a 33-as byte, a hexadecimális 21 értéke decimális 21-ként kerül feldolgozásra, tehát a byte 2 darab 4 bites fele tárol egy-egy decimális számjegyet.) Összeadásnál és kivonásnál kell korrigálni a kapott eredményt, mert az ALU bináris összeadást végez. Ekkor mindkét dekádot meg kell vizsgálni, hogy nagyobb-e 9-nél, és ha igen, hozzá kell adni 6-ot (így lesz a decimális 10-ből hexadecimális 10). Az alábbi korrekciós áramkör úgy végzi el az összeadást, hogy nem használ bitenként végigfutó carry-t, mert az lassú, 1 óraciklusba kerülő eljárás lenne, hanem az ALU logikai függvényeiből előre számítja az összeadás hatását. A kapcsolás jobb oldali oszlopa az összehasonlítást végzi, jobbról a második oszlop a 6-tal való növelést, amennyiben a dekád nagyobb 9-nél, és a BCD engedélyezett, bal oldalon pedig az 1 bites tárolók és összeadók láthatók.

Aritmetikai és logikai egység

 

Az aritmetikai és logikai egység egy nagyon kompakt kapcsolás. A regiszterblokkban helyezkedik el, ugyanazokat a belső síneket használja, mint a regiszterek. Két bemenő operandusa van, a kapcsolási rajz jobb oldalán látható az az 5 transzfer gate, melyekkel kiválasztható, hogy a három sín, az egyik negáltja, valamint a 0 közül melyek kerüljenek a bemenetekre. Az ALU az aktuális utasítástól függetlenül előállítja az összes logikai függvényt, a carry-t, az összeget. Hogy ezek közül mi kerül a kimenetre, azt a transzfer gate-ek döntik el.

  • Összeadás: x12-vel jut a kimenetre, ehhez carry is kell, mely váltott logikával halad végig a 8 biten.
  • Kivonás: a kivonandó inverzének hozzáadása, az alsó helyiértéken carry=1 kell.
  • Összahasonlítás: kivonás, csak x12 nem nyit
  • Növelés: egyik bemenet 0, összeadás carry=1 beállításával
  • AND, OR, EOR: x8, x6, x9 kapcsolók
  • Bitléptetés jobbra: x7-tel jut a NAND kapu kimenete az eggyel kisebb helyiérték ALU-kimenetének negált vonalára. Ehhez az kell, hogy mindkét bemenet ugyanaz legyen (azaz az operandus két sínen is rendelkezésre álljon).
  • Bitléptetés balra: ez egy 2-vel való szorzás, ami összeadás két megegyező bemenetre.

 

 

Bevezetés