Ajuriohjelmat

<

VGA-kortin toiminnan perusteet

VGA-TV-muuntimieni ajuriohjelmilla on yksi tehtävä: asettaa näyttökortti lähettämään sellaisessa muodossa ja oikealla päivitystaajuudella. PC:n näyttökorttien perusrakenne perustuu IBM:n kehittämään VGA-standardiin. Tässä perusratkaisussa grafiikkakortti koostuu koko kortin toimintaa ohjaavasta videokontrollerista, videomuistista, kellogeneraattorista sekä analogisen monitorisignaalin tuottavasta RAMDAC-piiristä. Näiden lisäksi kortilla on muistipiiri, joka sisältää tietokoneen BIOSin laajennuksen, joka käisttää videokortin käsittelyn perusrutiinit (mm. eri grafiikkatilojen alustusrutiinit ja tekstin tulostusrutiinit). Kuva 19 esittää tyypillisen nykypäivän PC:n grafiikkakortin rakenteen

Kuva 19

Kuva 19: PC:n grafiikkakortin rakenne

Nykyaikaisissa videokorteissa ulostulevan videon ajastuksen määräävät videokontrollerin ajastusasetukset sekä käytettyn kellogeneraattorin tuottaman piksellikellon taajuudesta. Ohjelmoitava kellogeneraattori on monessa kortissa sisäänrakennettuna RAMDAC-piiriin, mutta voi olla myös täysin erillinenkin piiri.

Videoajastuksen ohjelmointi

VGA-kortin rakenne on sellainen, että näyttökortin videoajastukset ohjelmoidaan videokontrollerin rekistereillä ja valitsemalla sopiva piksellikello. Alkuperäisessä VGA-kortissa oli vain muutama kidekello, joiden taajuuksia voitiin käyttää suoraan sellaisenaan tai jakaa kahdella tai neljällä. Näillä keinoilla pystyttiin hyvin muodostamaan kaikki tavalliset VGA-tilat sekä haluttaessa erikoisempiakin grafiikkatiloja.

Nykyaikaississa PC:n grafiikkakorteissa on tyypillisesti ohjelmoitava kellogeneraattori, joka pystyy synnyttämään hyvin suuren määrän eri kellotaajuuksia. Tälläisen kellopiirin tuottama kellotaajuus voidaan säätää ohjelmallisesti kellopiirin rekisterejä säätämällä. Markkinoilla olevissa grafiikkakorteissa on käytösäs hyvin monia erilaisia kellopiirejä, joita ohjataan eri tavoin. Monet kellogenerattoreista on erillisiä piirejä, mutta myös moni nopeista RAMDAC-piireistä sisältää ohjelmoitavan kellogeneraattorin.

Ajurin toiminta eri näyttötiloissa

PC:n näyttökortit perustuvat IBM:n VGA-näytönohjaimeen. Tässä näytönohjaimessa on kaksi toiminnoiltaan hyvin erilaista toimintatilaa: tekstitila ja grafiikkatila. Näiden tilojen toiminnan erilaisuudesta johtuen niitä kannattaa käsitellä ajurissa eri tiloissa.

Toiminta tekstitilassa

Standardi VGA-näytön 80x25 tekstitila käyttää 16x8 piksellin kokoisia fontteja. Tässä tilassa näytön resoluutio on siis 400 vaakaviivaa. Tälläinen määrä vaakajuovia ei mahdu yhteen television puolikuvaan. Lomittelun käyttö ei kannata tekstitiloissa, koska se tekee tyypillisistä tekstifonteista väriseviä. Paras ratkaisu saada normaali 25-tekstirivinen näyttötila näkyviin televisioruudulle on siirtyä käyttämään 8x8 pikselin fontteja, joiden avulla juovamäärä saadaan pudotetta 200 juovaan, mikä mahtuu hyvin normaalin television näkyvälle ruutualuelle. Näin ei tarvita lomittelun käyttöä ja ruudun teksti on vapaa. 8x8 pikselin fontin käyttäminen on kätevä, koska tämä fontti löytyy vakiona VGA-kortteista. Fortin vaihtaimisen lisäksi pitää VGA-kortin piksellikello jakaa kahdella sekä muuttaa synkronointisignaaleita säätäviä ajastusrekistereitä. siten, että pyyhkäisytaajuus ja päivitystaajuus ovat niin tarkkaan televisiostandardien mukaisia kuin mahdollista.

Grafiikkatilat joissa 200 vaakajuovaa

VGA-kortin 320x200 piksellin tilassa jokainen piksellirivi pyyhkäistää normaalitilassa kahdesti VGA-monitorille. Tämä näyttötila on helppo saada televisiruudulle kun ensin poistetaan juovantuplaus ja jaetaan piksellikellon taajuus kahdella. Näin juovamäärä on riittävän pieni mahtuakseen telesion yhteen kenttään ja vaakapyyhkäisytaajuus saadaan television haluamaan arvoon. Kun nämä on tehty, niin tarvitsee enää säätää ruudun päivitystaajuus ja juovien määrä sopivaksi, mikä onnistuu lisäämällä ruudun ylä- ja alareunaan tarvittava määrä mustaa reunusta.

Grafiikkatilat joissa 480 vaakajuovaa

480-linjaiset 60 Hz tilat näkyvät suoraan NTSC-televisiossa kunhan näyttökortin piksellikello jaetaan kahdella ja lomittelu laitetaan päälle. Näin saadaan näyttötila, jossa muutama pisrerivi menee näkyvän televisioruudun alueen yli. PAL-television tapauksessa lisätään riittävä määrä mustaa reunusta, että PAL:in näkyvät 560 linjaa tulevat täyteen. Näin kuvan ylä- ja alareunoihin jää pienet mustat palkit.

Grafiikkakorteissa, joissa lomittelua ei ole mahdollista saada toimimaan (ei tuettu ominaisuus tai ei ohjelmointitietoa saatvana) 480-linjaiset tilat voidaan toimimaan ilman lomitusta seuraavalla tavalla: esitetään lomittelematonta kuvaa televisioon ja jätetään joka toinen pisterivi grafiikkatilasta näyttämättä. Tämä onnistuu määrittelemällä näyttökortin kasvattamaan näyttömuistin lukemisen aloitusosoitetta kahden pisterivin mitan verran jokaisen pisterivin kohdalla.

Grafiikkatilat joissa 600 juovaa

600-linjaiset tilat saa näkyviin PAL-televisioon kun lomittelu laitetaan päälle ja piksellikellon arvo säädetään sopivaksi. Näin saadaan näyttötila, jossa muutama pisterivi menee näkyvän televisioruudun alueen yli, koska vain noin 560 linjaa mahtuu television näkyvälle alueelle.

Jos näyttökortti ei tue lomittelua, niin grafiikkatila voidan esittää myös jättämällä joka toinen pisterivi näyttämättä.

Kuvan koon säätö vaakasuunnassa

Kuvan koon säätäminen vaakasuunnassa onnistuu näyttökortin piksellikelloa säätämällä. Kasvattamalla piksellikellon taajuutta ja samalla leventämällä kuvan reunuksia sen verran että pyyhkäisytaajuus pysyy vakiona näkyvää kuva-alaa saa kavennettua. Vastaavalla tavalla piksellikelloa hidastamalla kuvasta saa leveämmän. PerusVGA-kortissa ei ole kovin laajaa valikoimaa erilaisia kellotaajuuksia, mutta lähes kaikissa nykyisin markkinoilla olevissa edistyneemmissä grafiikkakorteissa on ohjelmoitava kellogenerattori, jolla voi tuottaa hyvin suuren valikoiman erilaisia piksellikellon arvoja.

DOS-ajurit

DOS-ajurien toimintaperiaatteena on korvata näyttökortin BIOSissa sijaitsevat näyttökortin tilan alustusrutiinit sellaisilla, jotka alustavanäytön taajuudet normaalista poikkevalla kuvataajuudelle. Mihinkään muuhun näyttökortin BIOS-rutiineihin ei tarvitse koskea.

Ajuri voidaan hyvin toteuttaa muistinvaraisella (TSR) ohjelmalla, joka korvaa BIOSin rutiinit linkkautumalla keskeytysvektoriin 10h. Ajuriohjelma toimii siten, että jos käytetään mitä tahansa muuta kuin ruututilan alustusrutiinia, ajuriohjelma kutsuu alkuperäistä BIOS-rutiinia. Ruututilan alustusrutiinia (keskeytysvektori 10h alirutiini 00h) kutsuttaessa ajuohjelma kutsuu ensin alkuperäistä BIOS-rutiinia ja tämän jälkeen kirjoittaa omat erikoisarvonsa VGA-kortin ajastusta ohjaaviin rekistereihin. Kutsumalla alkuperäistä BIOS-rutiini voidaan kaikki korttikohtaiset ja muuten hankalat alustusrutiinit hoitaa varmsti toimivalla tavalla ja sen jälkeen ainoastaan muutetaan niitä rekisterejä, joita on pakko muuttaa.

Toteutin ajurin konekieltä käyttäen, koska näin ajurista saa mahdollisimman pienen sekä tekemään juuri ne asiat joita on tarpeen tehdä. Jos ajuriohjelman olisi kirjoittanut millä tahansa korkean tason ohjelmointikielellä assembly-kielen sijasta, olisi ohjelmasta tullut kooltaan paljon suurempi sekä alttiimpi odottamattomille yhteensopivuusongelmille. Kirjoittamalla ohjelman suoraan konekielelle, voi olla varma mitä ohjelma tarkalleen tekee ja mihin se koskee.

Edellä kuvatulla menetelmällä on kohtuullisen helppoa tehdä toimia ajuriratkaisu, joka toimii hyvin lähes kaikkien DOS-ohjelmien kanssa. Tämän tyyppinen ajuriohjelma valitettavasti toimi sellaisten ohjelmien kanssa, jotka itse alustavat jonkin standardeista poikkeavan näyttötilan.

Ajureissa käytetyt VGA-kortin ajastusrekisterien arvot olen saanut tutkimalla mitä kaupallisten tällä tekniikalla toteutettujen VGA-TV-muuntimien ajurit tekevät VGA-kortille. Näiden ajurieden lähdekoodia ei ole tarvinnut tutkia, koska kaikki VGA-kortin normaalit rekisterit on luettavissa ohjelmallisesti, joten riittä kun käynnistää valmiin ajurin ja sen jälkeen oman rekisterien arvojen tallennusohjelman. Koska kaikki markkinoilla oleet tälläiset muuntimet ovat olleet USA:n markkinoille, ne tuottavat NTSC-standardin mukaista kuvaa. Käyttäen näitä rekisteriarvoja mallina ja hiukan muokkaamalla VGA-kortin rekisterien arvoja sain näistä aikaan PAL-näyttötilat.

Liitteessä 1 löytyy kirjoittamani ajuriohjelman assembler-kielinen lähdekoodi.

Ajurin ohjelmoinnin eräänä ongelmana on, että VGA-kortissa on määritely hyvin monia erilaisia näyttötiloja, joista jokainen täytyy ajurissa huomioida ja käsitellä erikseen. Vielä normaalin VGA-kortin parikymmentä perustulaa hyvin hallitseekin, mutta kaikkia korttikohtaisia superVGA-tiloja ja niiden erityisasioita on melko mahdotonta tukea. Näiden korttikohtaisten ominaisuuksien tukeminen on erityisen vaikeaa, koska korttivalmistajilta on tyypillisesti hyvin hankala saada tarvittavia ohjelmointitietoja heidän korttiensa ohjelmointiin. Ainoa valmistaja, jolta sain käyttöön kunnollista teknistä tietoa oli Matrox, jolta sain tarvitsemiani ohjelmointitietoja vasta kun otin heihin yhteyttä mainiten yhteydenotossani projektisssa mukana olevan korttivalmistajan kanssa jo yhteistyötä tekevän ihmisen nimen.

Windows 3.1 ajurit

Windows 3.1 varten ei ollut tarvetta kirjoittaa mitään erillisiä ajureita, koska nornaalissa perusVGA-tilassa se käyttää ruututilojen alustamiseen BIOS-rutiineja muidenkin DOS-ohjelmien tapaan. Jos DOS-ajuri ladataan muistiin ennen Windowsin käynnitämistä, niin se tekee hommansa niin kuin pitää, jos se tukee sitä ruutilaa, joka Windowsin on asennettu. Toimivuus on hyvä esimerkiksi peruVGA-ruudulla (640x480 resoluutio 16 värillä). Windowsin tapauksessa kapeat ikkunan reunaviivat aiheuttavat häiritsevää värinää.

Windows 95 ajurit

Windows 95:n kanssa on mahdollista rajoitetusti käyttää DOS-ajureita, kunhan ne laitetaan latautumaan ennen varsinaisen Windowsin käynnistämistä. Tämä ratkaisu ei ole kuitenkaan mitenkään toimintavarma, koska sen toimivuus riippuu käytetyistä näyttökortin ajureista.

Eräs ratkaisu ongelmaan olisi kirjoittaa oma ajuriohjelma Windows 95:een, mutta se ei vaikuttanut hyvälle ajatukselle, koska suuren määrä erilaisia näyttökortteja tukevan ajurin kirjoittaminen on hyvin hankala, koska jokainen tarvitsee omanlaisensa koodin ajastusten ohjelmoimiseen. Lisäksi tälläisen ajurin kirjoittamista varten olisi tarpeen hankkia sopiva C-kääntäjä sekä ajurinkirjoituksen kehityspaketti, mikä vaikutti turhan kalliille hankinnalle hyötyihin nähden.

Koska ajurin kirjoittaminen vaikutti liian hankalalle ja kalliille projektille, päätin katsoa vaihtoehtoa olemassaolevian ajurien yödyntämiseen. Normaali Windowsin vakiomonitoriajuri tarjoaa erilaisia vaihtoehtoja ruudun päivitystaajuuden säätämisene monitorien asetustiedostoja muttamalla. Tekemällä oman erikoismonitorityypin on mahdollista saada aikaa normaalista poikkeavia päivitystaajuuksia, mutta tässä projektissa tarvittavia lomitettuja ja tarkaan oikealla taajuudella toimivia ruututiloja ei tällä tavoin voinut saada aikaan.

Scitech softwaren (www.scitechsoft.com) kauppaama Scitech Display Doctor -apuohjelmalla on mahdollista saada tavallisia Windowsin asetuksia monipuolisemmat säädöt eri ruututiloille. Tämä ohjelma tarjosi melkein kaikki tarvittavat säätömahdollisuudet, mutta välttämätöntä lomituksen tukea tästäkään ohjelmasta ei löytynyt.

Lopputuksena päätin tyytyä näyttökorttivalmistajakohtaiseen ratkaisuun. Matrox toimittaa ainakin Millenium, Mystique ja Millenium II -grafiikkakorttiensa kanssa Powerdesk-nimisen apuohjelman, jonka avulla on mahdollista säätää hyvin tarkkaan millaista signaalia näyttökortit lähtettä monitorille. Tämän ohjelman avulla on mahdollista laittaa lomitus päälle, säätää tarkkaan piksellikellon taajuus sekä synkronointisignaalien sekä ruudun reunusten leveys. Kuva 20 esittää Powerdesk-apuohjelman tarjoamia säätömahdollisuuksia.

Kuva 20

Kuva 20: Matrox Powerdesk -ohjelman tarjoamat ajastuksen säätömahdollisuudet ja eräät esimerkkiasetukset eräälle tietokonemonitorille.

Ohjelmalla tehdyt asetukset tallettuvat ASCII-muotoiseen monitorien tietokokantaan. PAL-televisolle käyttämäni asetukset 640x480 resoluutiolle ovat seuraavat (ote monitoritietokantatiedostosta MGA.MON):

[User-Defined.PAL]
640X480  =     I, *User-Defined_PAL_,(640X480)

[*User-Defined_PAL_,(640X480)]
PIXEL_CLK   =   14319
H_DISP   =   640
H_FPORCH   =   80
H_SYNC   =   40
H_BPORCH   =   160
H_SYNC_POL   =   1
V_DISP   =   240
V_FPORCH   =   35
V_SYNC   =   5
V_BPORCH   =   30
V_SYNC_POL   =   1
INTERLACE_ENABLE  =   1

Linux ajurit

Linuxissa käytetty Xfree86-ikkunointijärjestelmä tarjoaa hyvät mahdollisuudet näyttökortin asetusten viritykseen, koska kaikkia näyttökortin ajastuksene liittyviä asetuksia on mahdollista säätää Xconfig-nimisen asetustiedoston asetuksilla. Tässä asetustiedostossa jokaista ruututilaa varten on yksi asetusrivi, joka määrittää ruutilan resoluution ja ajastukset. Käytettävien ruututilojen resoluutiot eivät ole rajoittuneet yleisesit käytettyihin (640x480, 800x600, 1024x768 jne.), vaan resoluutio on mahdollista määrittää hyvin vapaasti kulloinkin tilanteeseen sopivimmaksi. Seuraava esetustiedoston rivi muodostaa hyvin televisossa toimivan PALi-nimisen resoluution 704x552 pistettä:

ModeLine "PALi"       13.5  704 720 792 864  552 572 605 625 Interlace
Tämä resoluutio on hyvin käytännöllinen, koska se täyttää hyvin normaalin television kuva-alan mutta ei mene häiritsevästi näkyvän alueen reunojen yli. Lisäksi tämä resoluutio tarjoaa melko neliönmuotoiset pikselit.

Televisiossa näkyvä tyypillisempi 640x480 resoluutio saadaan aikaan seuraavilla asetuksilla:

Modeline  "640x480xTV"  15.00   640 728 792 960  480 509 517 573 Interlace

Tomi Engdahl <Tomi.Engdahl@iki.fi>

Takaisin sisällyslyetteloon