Siirry pääsisältöön

IBM 1800 - Arkkitehtuuria osa 2


Aiemmassa arkkitehtuuria käsitelleessä osassa käytiin läpi CPU:n ydintä, nyt vuorossa se muu rekvisiitta: DMA (sen aikaisin termein Cycle-Steal) sekä keskeytykset. Ja pahoitteluni blogin pitkää hiljaiseloa, töitä yrityksen parissa on ollut sen verran paljon, että harrastukset kärsivät (...pitäisi varmaan harkita oikeisiin töihin menemistä ;) ...mutta pitkän tauon jälkeen tulee sitten toistakymmentä sivua enemmän tai vähemmän täyttä asiaa. Yritän pitää tämänkin jutun selkokielisenä, jotta muutkin kuin asiaan vihkiytyneet voivat tästä saada jotain irti. Itselläni meni tovi tämän keksinnön toiminnan selvittämisessä, sillä Heilin I/O:n konsepti on melkoisen sekava kokonaisuus. Otetaan alkuun ensin I/O:n perusrakenne rautatasolla.

I/O-väylä

Edellisessa osassa sivusin lyhyesti DMA:n toimintaa, mutta mennään syvemmälle toimintaan. CPU on yhdistetty B-rekisterin (muistipuskurin) kautta "datakanavaan", joka näyttelee siis I/O-väylän (Input / Output) osaa. Tähän I/O-väylään kytketään oheislaitteet.

Kertauksen vuoksi CPU:n sisusta. I/O-väylä (kuvassa In Bus / Out Bus) ei kuitenkaan ole ihan niin yksinkertainen kuin tässä kuvassa esitetään.

Fyysinen I/O-väylä koostuu 16-bittisistä tulo- ja lähtöväylistä sekä kontrollilinjoista, jossa kulkevat johtimet niin konesynkalle, keskeytyksen kyselylle, keskeytys- ja DMA-pyynnöille.

Tässä sitten hiukan tarkempi kuva.

I/O-väylä on jaettu kolmeen osaan (käytännössä yksi ja sama väylä, kuvan I/O Channel Origin on nippu TAI-portteja) ja niihin on sitten kytketty laiteadapterit eri laitteille. Jokaiseen kolmeen väylään voidaan kytkeä 8 laiteadapteria, joilla sitten voi olla useita laitteita perässään. 1801 keskusyksikkökaapin sisältö on suurimmalta osin juurikin noita laiteadaptereita, kuten nopealle kirjoittimelle, nauha-asemalle tai plotterille. Nämähän eivät luonnollisesti riitä isoissa kokoonpanoissa, sitä varten I/O-väylää on mahdollista jatkaa keskusyksikön ulkopuolelle. Nämä adapterit ovat kylvetty esimerkiksi 1826 (Data Adapter) -kaappeihin.

Keskusyksikön sisältöä. CPU :n ydin vie vähemmän tilaa kuin DMA ja keskeytykset (Channel). Loput lohkoista ovat pelkästään I/O:n laiteadaptereita tai muistia.


Gate B:n A1- ja B1-lohkot. Näissä lohkoissa on mm. DMA:n 16 CAR-rekisteriä.

Juju näissä adaptereissa on se, että CPU voi XIO/IOCC-käskyllä käskyttää adaptereita, esimerkiksi plotteria siirtämään kynää kaakkoon ja laiteadapteri hoitaa pulssituksen plotterille. Homma toimii kanssa toisin päin, jos vaikka jonkin laiteadapteri on lukenut puskurin täyteen, tuuppaa se sen tietokoneen muistiin DMA:n avulla.
Osa adaptereista - kuten keskeytysten hallinta - on sulautettu osaksi CPU:n sisäistä kaksisuuntaista väylää (Channel Data Bus).

Muutama erikoislaiteadapteri on sulautettu osaksi CPU:n sisäistä I/O-väylää. Nämä ovat keskeytystenhallinta, sense-kytkimet/huoltotaulu ja ajastimet. Ajastimet ovat erityisen mielenkiintoiset, ohjelmoijalla on käytettävissä kolme ajastinta: A, B ja C. Nämä ajastimet voidaan ohjelmoida kutsumaan keskeytys, mutta niiden aika pitää määrittää kiinteästi johdotuksella. Ajastimet tarvittaessa myös tallentavat sen hetkisen arvonsa DMA:n avulla muistipaikkoihin 0004h, 0005h, 0006h. Käytännössä konsepti on hyvin samanlainen kuin jossain Arduinon mikrokontrollerrisa nykyään (...paitsi johtoja ei tarvitse enää vaihdella intervallien mukaan).

Kaikki laiteadapterit omaavat yksilöllisen rakenteen, mutta adapterit näkyvät CPU:lle samanlaisina; jokaisella adapterilla on tarvittaessa kyky pyytää keskeytystä tai DMA:ta ja niillä on komento- ja tilarekisterit (joihin kirjoitetaan tai luetaan XIO/IOCC-käskyllä).

I/O-väylän driverit. Looginen yksi on maahan vedettynä, siitä syystä pullup-vastukset linjojen päissä.

Pullup-vastukset ovat aina I/O-väylän viimeisessä adapterissa, tässä tapauksessa 1826 "Data Adapter" -kaapin sisällä olevassa Selector Channel:ssa (jonka tarkoitus on toimia 2840 kiintolevyohjaimen liitäntänä). Vastuskortit näkyvät IO-väylän lattakaapelien välissä.


Keskeytykset

Keskeytys on jonkin laitteen pyyntö CPU:lle lopettaa sen hetkinen ohjelmansuoritus ja keskittyä laitteen palvelemiseen. Tästä voisi antaa esimerkkinä näppäimistön, jonka nappia painetaan. CPU tällöin hyppää keskeytysvektoritaulukon kautta aliohjelmaan, joka käsittelee näppäimistön lukemisen, yleensä tallentamalla merkin (käyttöjärjestelmän) puskuriin. Ilman keskeytystä CPU joutuisi kyselemään näppäimistöltä toistuvasti "painettiinko nappia?", joka luonnollisesti tuhlaisi järjettömän kallista aikaa 60-lukulaisesta CPU:sta.

Keskeytyksiä on eri tason prioriteeteilla, ihan kuin oikeassa elämässä; puhelinmyyjän soitto ei ole yhtä tärkeä kuin juuri tuleen syttynyt savusauna. Tietokonemaailmassa puolestaan näppäimistön pyyntö ei ole ehkä se kaikken akuutein tapahtuma, huomattavasti korkeamman prioriteetin keskeytys on vaikkapa laiton käsky suoritettavassa ohjelmassa. 1800 kykenee juurikin priorisoimaan keskeytykset rauta- että softatasolla.

Taulusta löytyvät valot jokaiselle (rautatason) keskeytykselle.

Yhteensä rautatason keskeytystasoja on 27, joista 3 on varattu erikoistarkoituksiin. Loput 24 voidaan köyttää kiinni laiteadaptereihin, joilla jokaisella omat alitasot keskeytyksille: keskeytysten tilarekisteri (ILSW, Interrupt Level Status Word) sekä laitteen tilarekisteri (DSW, Device Status Word). Nämä keskeysten ja laitteen tilat luetaan softatasolla ja softa päättää mitä asialle tehdään. Käytännössä 1800:ssa voi olla satoja erilaisia ja ja eritasoisia keskeytyksiä.

Osa 1800:n laiteadapterien ILSW ja DSW. Esimerkiksi jos 1816 Printer-Keyboard pyytää keskeytyksen, ohjelma lukee ILSW:n (mustilla pallukoilla merkityt) ja tämän jälkeen tilarekisterin DSW ongelmalaadun selvittämiseksi. Kuitenkaan kaikkien laitteiden kanssa molempien rekisterien tarkastelu ei ole tarpeen, etenkään jos laiteadapterin perässä on vain yksi laite ja sillä yksi mahdollinen keskeytys.

Jos vaikka tulostin ilmoittaisi suorittaneensa hommansa loppuun ja haluaa lisää tulostettavaa, saisi CPU ensin pyynnön tulostimia ohjaavalta laiteadapterilta, tämän jälkeen CPU hyppäisi tulostimen keskeytystä hallitsevaan aliohjelmaan ja lukisi keskeytyksen tilarekisterin tulkitakseen keskeytyksen syyn. Sitten ohjelma tarkistaa jokaisen tulostimen tilarekisterin, josta selviää mikä tulostimista ilmoitti saaneensa tulostuksen valmiiksi.

Mutta entäpä jos tulostin tulee nykimään CPU:ta hihasta kesken jonkin tärkeämmän keskeytyksen palvelun? Tällöin tulostin odottaa - kuten kaikki alemman keskeytysprioriteetin omaavat laitteet - kunnes sen hetkinen korkeimman keskeytyprioriteettin aliohjelma on palveltu loppuun.

Keskeytysten prioriteetit (pienempi numero = korkeampi prioriteetti) ja hyppyosoitteet keskeytyksille.

Aliohjelmat joihin keskeytykset pakottavat CPU:n hyppäämään ovat kiinteät. Nämä ovat muistin alussa sijainneissa 00008h...00022h ja tätä taulukkoa kutsutaan keskeytysvektoritaulukoksi, kansankielellä siis nippu hyppyosoitteita. Esim. tason 9 keskeytys pakottaa CPU:n suorittamaan BSI-käskyn (Branch and Store I-Register, hyppää ja tallenna ohjelmalaskuri), joka puolestaan hakee osoitteen johon hypätään muistipaikasta 0014h. Yksi poikkeus löytyy ja se on huoltotilan (CE) keskeytys; sen hyppyosoite sijaitsee paikassa 0001h sen paluuosoite osoitteessa 000Ah. Tähän on syynä hieman erikoisempi rautatason järjestely ja kirjoitan siitä arkkitehtuurin kolmannessa osassa.

CPU osaa palata takaisin edelliseen ohjelmaan (josta se pakottiin hyppäämään) erikoisella metodilla, sillä 1800:ssa ei ole (rauta)pinoa millään asteella. Hyppy tallentaa sen hetkisen ohjelmalaskurin (siis osoitteen josta hypättiin) aliohjelman alkuun. Aliohjelma itsessään alkaa vasta seuraavasta muistipaikasta, joten paluusoite löytyy aina aliohjelman alusta. Paluu tapahtuu BSC/BOSC-käskyllä, joka nollaa myös sen hetkisen keskeytystason.

Ensimmäinen hyppy menee keskeytystason mukaan, seuraava ohjelman päättämänä (kuvassa Branch Table, keskeytysvektoritaulukon piirtäminen on unohtunut IBM:ltä).

Kuten mainittua, mitään pinoa ei ole, joten aliohjelmien pitää itse huolehtia indeksirekistereiden ja muun tilatiedon tallentamisesta, CPU ei tule sitä tekemään omatoimisesti.

Keskeytykset saa tarvittaessa päälle ja pois XIO/IOCC-käskyllä. Ainoa poikkeus on CPU:n oma sisäinen keskeytys (Memory Violation, Illegal Op Code, Parity Error, CAR Check Error), joita ei saa pois päältä. Lisäksi samaisella XIO-käskyllä voidaan ohjelmallisesti liipaista jokin keskeytyksistä aktiiviseksi.

Keskeytysten kysely.

Toisin kuin DMA-pyynnöt (jotka käsitellään alempana), keskeytykset kysellään kahdessa ryhmässä laiteadaptereilta, signaalein Poll A (0-13) ja Poll B (14-23), joista kumpikin kestää 1µs ajan. Mikäli jokin laite vastaa, molemmat A- ja B-signaalit blokataan pakotetun BSI-käskyn ajaksi, jotta pyydetyn keskeytyksen aliohjelman kutsu saadaan alkuun ja paluuosoite talteen. 


Poll A ja Poll B luodaan CPU:n T0...T3 ja T4...T7 -kellojaksoista. Tästä syntyy yksi ongelma WAIT-käskyn kanssa, käskyn idea kun on pysäyttää CPU ja odottaa (jotain) keskeytystä. Mutta CPU:n pysähtyminen tarkoittaa myös T-kellon pysäyttamistä, joten miten "pollaus" tehdään? Luovana ratkaisuna IBM on laittanut WAIT-käskyn ohittamaan T-kellon ja luomaan keskeytyskyselyn erillisellä 4µs oskillaattorilla (...eli keskeytykseen reagointi WAIT-käskyn kanssa pahimmillaan on 4 kertaa hitaampaa).


Keskeytyksistä vastaava lohko Gate A:ssa.



XIO-käsky

Edellisestä kappaleesta jotkin voivat varmasti päätellä, etteivät asiat eivät hirveästi ole muuttuneet, mutta yksi merkittävä ero vaikkapa mikroajan tietokoneisiin on: I/O-laitteet eivät sijaitse normaalissa osoiteavaruudessa, vaan niillä on erillinen väylä ja osoiteavaruus, joten tarvitaan I/O:n käsittelyyn tarvitaan oma käsky. Sen nimi on XIO (Execute I/O).

Käskyllä itsellään ei määritetä vielä mitään, vaan käskyllä kerrotaan muistipaikka, joka sisältää sen-ihan-oikean-IO-käskyn, kahden sanan mittaisen IOCC:n (I/O Control Command).



IOCC koostuu muutamasta osasta:

Area - I/O-laitteen osoite (I/O-muistiavaruudessa).
Fun - toiminto joka suoritetaan laite adapterille
         000 CE (Customer Engineer Mode) - pudottaa laiteadapterin huoltotilaan
         001 Write - kirjoittaa laiteadapteriin sanan
         010 Read - lukee laiteadapterista sanan
         011 Sense Interrupt - lukee laiteadapterin keskeytysrekisterin
         100 Control - asettaa laiteadapterin kontrolli rekisterin
         101 Initialize Write - alustaa laiteadapterin tiedonsiirron (kirjoitus)
         110 Initialize Read - alustaa laiteadapterin tiedonsiirron (luku)
         111 Sense Device - lukee laiteadapterin tilarekisterin
Mod - laiteadapterikohtainen lisäkuvain
Address - siirrettävän tiedon rekisteri, esim. Cycle-Steal -taulukon sijainti (CPU:n muistiavaruudessa)

IOCC:llä ohjataan laiteadapterin toimintaa. IOCC:n funktio (Fun) pysyy samana laiteadapterista riippumatta, mutta lisäkuvain (Mod) vaihtelee adapterikohtaisesti, kuten myös tilarekisterin informaatio.



DMA (Cycle-Steal)

1800:ssa ei ollut maailman ensimmäistä DMA (Direct Memory Access), mutta melko tuoreesta keksinnöstä oli silti kyse reilu 40 vuotta sitten. Idea DMA:ssa on se, ettei CPU siirrä dataa ohjelmallisesti laitteesta/laitteeseen, vaan se tekee laite itse. Laite (tässä tapauksessa tarkalleen ottaen laiteadapteri) varastaa muistijaksoja CPU:lta ja siirtää dataa muistiin tai muistista pois.

On helppo ymmärtää kuinka paljon tehokkaammaksi koneen toiminta muuttuu, jos vaikka ajatellaan tulostamista. Ilman DMA:ta CPU joutuisi jokaisen merkin siirtämään yksi kerrallaan laitteeseen ja odottamaan, että tulostin saa merkin paperille ja on valmis lukemaan seuraavan merkin. Käytännössä koko CPU olisi jumissa lähes koko tulostuksen ajan, ruokkimassa pelkästään tulostinta. Vaikka tulostin käyttäisi keskeytyksiä, veisi keskeytysrutiini aikaa kohtuuttoman paljon.

Huomattavasti tehokkaampaa on kertoa tulostimelle muistialue, joka sen pitää tulostaa. Tulostin hakee sitten omaan tahtiin dataa muistista, kunnes on saanut koko alueen tulostettua ja pyytää vasta sen jälkeen keskeytyksen: "tulostus tehty, anna lisää".

1800:n tapauksessa DMA todellakin varastaa muistinkäytön kokonaan ja siitä nimikin: Cycle-Steal. CPU:n osat synkkaava sisäinen T0...T7-kello jäätyy ja DMA:n X0...X7-kello käynnistyy. Mikä on mielenkiintoista, DMA käynnistyy heti; CPU pysähtyy vaikka keskelle kertolaskua. Vasteaika pyynnöstä toteutukseen on tällä muistilaajennetulla 1800:lla 2.50µs ja saavuttaa jopa 1MB/s tiedonsiirtonopeuden.

Koska näinkin moderni laite sisältää useita muistia suoraan käyttäviä laitteita, on laiteadapterien DMA-pyynnöillä prioriteetit kuten keskeytyksillä. Esimerkiksi tulostin ei ole niin tärkeä kuin kiintolevy, jonka data on pakko lukea tietyn aikaikkunan sisällä tai se on menetetty.

Laiteadapterien keskeytys ja DMA-prioriteetteja ei voi ohjelmallisesti muuttaa, sillä ne määritetään I/O-väylän johdotuksilla.

Ylläolevan kuvan "Mixer Board (H Gate)" koneen takana.

DMA:lle on varattu osoiterekisteri CAB (Channel Address Buffer), jonka avulla DMA pystyy osoittamaan keskusmuistia. Jokaisella 16:sta DMA-pyynnön prioriteetilla on oma rekisteri CAR (Channel Address Register), johon määritetään osoite josta/johon ollaan kirjottamassa/lukemassa.
DMA:n yksinkertaistettu lohkokaavio.

CAR-rekisteriä tarvitaan useiden DMA-prioriteettien takia. Laite jolta jää tiedonsiirto kesken korkeamman DMA-prioriteetin takia, on pystyttävä jatkamaan siitä mihin se jäi.

CAB- ja CAR rekisterit sijaitsevat "keskusyksikössä", jokaisella laiteadaptereilla on puolestaan oma 16-bittinen DMA-kontrollirekisteri, joka on jaettu 2- ja 14-bitin osaan. Ensimmäinen osa on SCR (Scan Control Register) ja toinen WCR (Word Count Register). Jälkimmäisen merkitys selviää jo nimestä, se laskee kuinka monta sanaa on vielä siirrettävänä. Koska laskuri on 14-bittinen, se rajoittaa myös suurimman mahodllisen kertasiirron DMA:n avulla 16 kilosanaan (tai 32 kilotavuun). SCR:n virka on määrittää mitä tehdään, kun tiedonsiirto on loppu; ketjutetaanko tiedonsiirto ja/tai päätetäänkö se keskeytykseen (joka on luettavissa ILSW/DSW-rekistereistä).

SCR/WCR-kontrollirekisteri

DMA:n alustus tapahtuu XIO/IOCC-käskyllä ja siinä määritetyllä Initiazile Read / Initialize Write -toiminnolla, joka käynnistää tapahtumaketjun CPU:n, IO-laiteadapterin ja muistin välillä. 

DMA:n alustus.

XIO hakee IOCC:n osoitetusta muistopaikasta. IOCC määrittää laiteadapterin, sen toiminnon (Area, Fun, Modifier) sekä osoitteen, josta DMA-taulukko alkaa. Sama osoite siirretään laitetta vastaavaan CAR-rekisteriin.


DMA-taulukko(t).

DMA-taulukon ensimmäinen sana sisältää laiteadapteria varten SCR/WCR:n tiedot, mitä tehdään kun tiedonsiirto päättyy ja kuinka monta sanaa siirretään laitteen ja muistin välillä. Lisäksi jos taulukkojen ketjuttaminen on asetettu SCR:ssä, taulukon viimeinen sana sisältää osoitteen josta seuraava taulukko alkaa.
DMA:n ketjuttaminen.

CPU vertaa CAR-rekisteriä ja muistipuskuria, toisin sanoen B-rekisteriä, jossa on IOCC:n osoiteosa (...melko turha tarkistus, mutta tehtävissä "turhalla" ajalla). Tämän jälkeen itse DMA alkaa: ensin siirretään taulukon ensimmäinen sana laiteadapterin SCR/WCR:ään. CAR siirretään CAB:iin ja siihen lisätään yksi, jotta CAB osoittaa taulukon ensimmäistä siirrettävää osoitetta. 

Laiteadapteri siirtää tiedon B-rekisterin avulla ja vähentää WCR:stä yhden. Kun WCR on nollassa ( = kaikki siirretty), tapahtuu joko keskeytyspyyntö CPU:lle, seuraavaan DMA-taulukon nouto tai ei mitään, riippuen mitä ohjelmoija SCR:ään määritti. 



Vielä loppuun

Kuten voimme tästä melko kaaottisesta kuvauksesta todeta, ettei 1964 julkaistun tietokoneen vertaaminen nykyajan taskulaskimeen/rannekelloon/leivänpaahtimeen ole ihan oikeutettua. 1800:n oheislaitehallinnasta ei vieläkään ole mennyt parasta ennen -päiväys umpeen. Ensijulkaisusta kesti yli parikymmentä vuotta, ennen kuin kuolevainen pystyi ostamaan jotain yhtä pitkälle vietyä omalle pöydälleen.

Seuraavassa osassa sitten kovalevyn ja kovalevyohjaimen anatomiaa sekä joitain 60-luvun arkkitehtuurin outouksia.

Kommentit tervetulleita!


Ps. Kiitokset taas kerran Carl Claunchille vinkeistä!



Lähteitä:
Bitsavers (1800) : http://bitsavers.trailing-edge.com/pdf/ibm/1800/
ALD (kytkikset) : https://drive.google.com/open?id=0B_DR111cK6W-Yms3TURrWmkzSVk

Kommentit

Lähetä kommentti