Järjestelmän toteutuksen kuvaus

v1.2
22.04.96

Osien koodaus tehdään ennalta sovitun tyylin mukaisesti.

Toteutus on jaettu seuraaviin tiedostoihin:

fys/autodata.h		  tietoja auton ominaisuuksista
fys/fmauto.cpp		  fysiikkamallin auto-luokan toteutus
fys/fmauto.h		  määrittelyt fysiikkamallin luokasta auto
fys/vektori.cpp		  vektoriluokan toteutus
fys/vektori.h		  vektoriluokan määrittelyt
fys/FmRata.h	          ratavektorien tutkimisen optimointiin käytettävä luokka
fys/FmRata.cpp		  ratavektorien tutkimisen optimointiin käytettävä luokka
laitteet/nastat.h	  tiedot toimilaitteiden nastajärjestyksestä
laitteet/tlanturi.h	  määrittelyt luokalle TlAnturi
laitteet/tldata.h	  tietoja toimilaitteiden ominaisuuksista
laitteet/tlfotodi.cpp	  TlFotodiodi-luokan toteutus
laitteet/tlfotodi.h	  määrittelyt luokalle TlFotodiodi
laitteet/tlkaynni.cpp	  toteutus luokalle TlKaynnistysnappi
laitteet/tlkaynni.h	  määrittelyt luokalle TlKaynnistysnappi
laitteet/tlkulmap.cpp	  toteutus luokalle TlKulmapotentiometri
laitteet/tlkulmap.h	  määrittelyt luokalle TlKulmapotentiometri
laitteet/tllaitte.cpp	  TlLaitteet-luokan toteutus
laitteet/tllaitte.h	  TlLaitteet-luokan määrittelyt
laitteet/tlledika.cpp	  toteutus luokalle TlLedikampa
laitteet/tlledika.h	  määrittelyt luokalle TlLedikampa
laitteet/tlmooser.cpp	  toteutus luokalle TlMoottoriservo
laitteet/tlmooser.h	  määrittelyt luokalle TlMoottoriservo
laitteet/tlmootto.cpp	  toteutus luokalle TlMoottori
laitteet/tlmootto.h	  määrittelyt luokalle TlMoottori
laitteet/tlnopeus.cpp	  toteutus luokalle TlNopeusanturi
laitteet/tlnopeus.h	  määrittelyt luokalle TlNopeusanturi
laitteet/tlohjser.cpp	  toteutus luokalle TlOhjausservo
laitteet/tlohjser.h	  määrittelyt luokalle TlOhjausservo
laitteet/tlservo.cpp	  toteutus luokalle TlServo
laitteet/tlservo.h	  määrittelyt luokalle TlServo
laitteet/tltoimil.h	  määrittelyt luokasta TlToimilaite
laitteet/prosu/prosu.cpp  auton käsiohjauksessa prosessoria matkivan osan toteutus
laitteet/prosu/prosu.h	  auton käsiohjauksessa prosessoria matkivan osan määrittely
kayttoliittyma/KlKonsoli.cpp    käyttöliittymän luokan KlKonsoli toteutus
kayttoliittyma/KlKonsoli.h      määrittelyt luokalle KlKonsoli
kayttoliittyma/KlPaataso.cpp    käyttöliittymän KlPaataso-luokan toteutus
kayttoliittyma/KlPaataso.h      määrittelyt luokalle KlPaataso
kayttoliittyma/KlRekisterit.cpp käyttöliittymän KlRekisterit-luokan toteutus
kayttoliittyma/KlRekisterit.h   määrittelyt luokalle KlRekisterit
kayttoliittyma/uCC.cpp          pääohjelma
kayttoliittyma/uCC.h            ohjelman yhteisiä määrityksiä
kayttoliittyma/KlMuisti.cpp     käyttöliittymän KlMuisti-luokan toteutus
kayttoliittyma/KlMuisti.h       määrittelyt luokalle KlMuisti
kayttoliittyma/KlRata.cpp       käyttöliittymän KlRata-luokan toteutus
kayttoliittyma/KlRata.h         määrittelyt luokalle KlRata
kayttoliittyma/pixmaps/         käyttöliittymän pixmap-hakemisto
kayttoliittyma/auto/KlAkselit.cpp          KlAkselit-luokan toteutus
kayttoliittyma/auto/KlAkselit.h            määrittelyt luokalle KlAkselit
kayttoliittyma/auto/KlAutonKomponentti.cpp tässä luokassa on auton eri piirrettävien osien yhteiset ominaisuudet
kayttoliittyma/auto/KlAutonKomponentti.h   määrittelyt luokalle KlAutonKomponentti
kayttoliittyma/KlDisassembler.h	           disassemblerin määrittelyt
kayttoliittyma/KlDisassembler.cpp	   disassemblerin toteutus
kayttoliittyma/auto/KlNopeus.cpp           KlNopeus-luokan toteutus
kayttoliittyma/auto/KlNopeus.h             määrittelyt luokalle 
kayttoliittyma/auto/KlAnturi.cpp           KlAnturi-luokan toteutus
kayttoliittyma/auto/KlAnturi.h             määrittelyt luokalle KlAnturi
kayttoliittyma/auto/KlKitka.cpp            KlKitka-luokan toteutus
kayttoliittyma/auto/KlKitka.h              määrittelyt luokalle KlKitka
kayttoliittyma/auto/KlRenkaat.cpp          KlRenkaat-luokan toteutus
kayttoliittyma/auto/KlRenkaat.h            määrittelyt luokalle KlRenkaat
kayttoliittyma/auto/KlAuto.cpp             KlAuto-luokan toteutus
kayttoliittyma/auto/KlAuto.h               määrittelyt luokalle KlAuto
kayttoliittyma/auto/KlMoottori.cpp         KlMoottori-luokan toteutus
kayttoliittyma/auto/KlMoottori.h           määrittelyt luokalle KlMoottori
kayttoliittyma/auto/Koordinaatti.cpp       Koordinaatti-luokan toteutus
kayttoliittyma/auto/Koordinaatti.h         määrittelyt luokalle Koordinaatti
68hc11/CPU.h                       MkCPU-luokan (mikrokontrollerin CPU)
                                   määrittelyt
68hc11/CPU.cpp                     MkCPU-luokan toteutus
68hc11/IO-laitteet.h               MkIO_laitteet-luokan (muisti, timer, AD-
                                   muunnin, pulse accumulator, keskeytykset)
                                   määrittelyt
68hc11/IO-laitteet.cpp             MkIO_laitteet-luokan toteutus
68hc11/liitantarima.h              MkLiitantarima-luokan (prosessorin ja auton
                                   välinen liitäntärima) määrittelyt
68hc11/liitantarima.cpp            MkLiitantarima-luokan toteutus
mkohjaus/ohjaus.h                  luokan MkOhjaus määrittelyt
mkohjaus/ohjaus.cpp                luokan MkOhjaus toteutus
mkohjaus/breakpoint.h              luokan MkBreakpoint määrittelyt
mkohjaus/breakpoint.cpp            luokan MkBreakpoint toteutus
mkohjaus/loki.h                    luokan MkLoki määrittelyt
mkohjaus/loki.cpp                  luokan MkLoki toteutus
mkohjaus/rekehdot.h                MkRekEhdot luokan määrittelyt
mkohjaus/rekehdot.cpp              MkRekEhdot luokan toteutus
mkohjaus/ehto.h                    luokan MkEhto ja siitä periytyvien luokkien määrittelyt
mkohjaus/ehto.cpp                  luokan MkEhto ja siitä periytyvien luokkien toteutus
mkohjaus/lista.h                   luokkien MkLista_alkio ja MkLista määrittelyt
mkohjaus/lista.cpp                 luokkien MkLista_alkio ja MkLista toteutus
mkohjaus/pino.h                    luokan MkPino määrittelyt
mkohjaus/pino.cpp                  luokan MkPino toteutus
rata/Deque.cpp                     kahteen suuntaan linkitetyn listan toteutus
rata/Deque.h                       määrittelyt luokalle Deque
rata/Rata.cpp                      radan toteutus
rata/Rata.h                        määrittelyt luokalle Rata
rata/OptRata.h                     riisuttu versio radasta (optimointia varten)
rata/OptRata.cpp                   riisuttu versio radasta (optimointia varten)
rata/VektoriDeque.cpp              luokan VektoriDeque toteutus
rata/VektoriDeque.h                määrittelyt luokalle VektoriDeque

MkCPU

Mikrokontrollerisimulaattoriin löytyi valmista koodia Motorolan www-sivujen kautta paikasta ftp://nyquist.ee.ualberta.ca/pub/motorola/68hc11/6811sim/sim6811.shar. Valmiissa simulaattorissa oli toteutettu itse prosessorin toiminta, mutta ei I/O-laitteita. Simulaattoriin on toteutettu lisäksi output comparet, pulse accumulator ja A/D-muunnin sekä sisäiset keskeytykset. Kuluneiden prosessorin kellojaksojen laskeminen on toteutettu valmiiksi, samoin rekisterien arvojen muuttamiseen tarvittavat funktiot. Myös disassembler on jo toteutettu, mutta tässä simulaattorissa sitä ei tarvita, koska ajettava koodi tehdään C-kielellä.

Keskeytyksiin liityvät käskyt wai, swi ja rti on lisätty. Stop-käskyssä on otettu huomioon stop disabled-bitti, mitä ei valmiissa koodissa ollut tehty. Lisäksi valmiiseen koodiin on tehty huomattava määrä erilaisia korjauksia, koska siinä oli aika paljon virheitä.

Keskeytykset tarkistetaan jokaisen käskyn suorituksen jälkeen. Output comparet, pulse accumulator ja AD-muuntimen arvot päivitetään liitäntärimaan aina käskyn suoritusten välillä, jolloin virhe ohjauspulssien pituudessa on pahimmillaan 41 kellojaksoa = n. 20 us (FDIV, IDIV). Tästä ei aiheudu kovin suurta virhettä, koska ohjauspulssien ja nopeusanturin pulssien pituudet ova millisekunteja.

Suojattujen kontrollirekisterien muuttamista ei tarvitse toteuttaa, koska ei ole mitään tarvetta voida vaihtaa rekisterien ja muistin osoitteita. Niiden arvoja ei siis voi muuttaa manuaalissa kerrotun 64 ensimmäisen kellojaksonkaan aikana. COP watchdog -systeemiä ei ole toteutettu.

Simulaattori toimii normal expanded -moodissa ja suorittaa yhden käskyn kerrallaan. Resetin jälkeen PC:n alkuarvo haetaan reset-vektorista (0xFFFE, 0xFFFF).

Valmiista C-koodista on tehty pienehköillä muutoksilla oma luokkansa, jossa on toteutettu CPU:n toiminta. Kuluneet kellojaksot, rekisterien arvot ja tilaliput ovat prosessorin tilaa kuvaavassa tietueessa.

Testaus on suoritettu kahdella Tampereelta saadulla valmiilla ohjausohjelmalla, sekä näistä itse tehdyillä muunnelmilla. Satunnainen heksakoodi (esim. ohjelman data-alueen suorittaminen) pysäyttää simulaattorin niin kuin pitääkin. Testauksessa käytettiin mm. ohjelmaa, joka kääntää pyörät ääriasentoon ja moottorin tehon täysille sekä ohjelmia, jotka ainakin yrittävät seurata rataa. Pelkän CPU:n testauksessa on käytetty simulaattorin alkuperäisestä käyttöliittymästä tehtyä testiohjelmaa, jossa näkyvät rekisterien ja muistin sisältö ja seuraavaksi suoritettava käsky. Aivan yhtä hyvin testaamisen voi suorittaa nykyisellä käyttöliittymällä nyt kun se on valmis.

Debuggaus-osa

Toteutuksessa on muutamissa kohdissa tingitty modulaarisuudesta ja koodin tyylikkyydestä, jotta ohjelman toimintaa saataisiin nopeutettua.

MkOhjaus

Ohjaus-luokan tehtävänä on lähinnä olla Prosessori osasysteemin ja Käyttöliittymän välinen rajapinta. Suurin osa luokan funktioista on lähinnä vain kutsuja muiden luokkien funktioille, jotka sitten tekevät varsinaisen työn. Luokan tärkein funktio on SuoritaKasky. Funktio käskee CPU:ta suorittamaan yhden käskyn, muuntaa CPU:lta saamansa kellojaksot ajaksi ja välittää sen enintään 20 kellojakson välein Toimilaitteet osasysteemille. Sen jälkeen funktio tarkastaa onko lokiintulostus tai breakpointien tutkiminen päällä ja tarvittaessa kutsuu edelleen tarvittavien luokkien funktioita. Koska funktiota kutsutaan jokaisen käskyn suorittamisen yhteydessä, on siitä pyritty tekemään mahdollisimman yksinkertainen, ettei ohjelman toiminta tarpeettomasti hidastuisi.

// MkOhjaus::SuoritaKasky
// Funktio kutsuu luokan MkCPU funktiota Suorita_kasky. Jos Suorita_kasky
// palauttaa ilmoituksen jonkunlaisesta virheestä, ilmoitus palautetaan heti
// käyttöliittymälle, eikä tehdä muuta. Jos CPU suoritti käskyn virheettömästi :
// - Käyttöliittymälle välitetään alusta (CPU:n luomisesta) asti kulunut aika
// sekunneissa.
// - Toimilaitteille välitetään alusta asti kulunut aika sekunneissa jos siitä, kun
// toimilaitteita viimeksi kutsuttiin on kulunut vähintään 20 kellojaksoa.
// - Tarkastetaan onko lokitulostus päällä ja jos on, kutsutaan funktiota
// MkLoki::Kirjota, joka kirjottaa tarvittavat tiedot lokiin.
// - Tarkastetaan onko breakpoint-tarkastus päällä ja jos on kutsutaan funktiota
// MkBreakpoint::Tarkasta, joka huolehtii tarvittavista tarkastuksista
// Funktion paluuarvot:
// 0 käsky suoritettu onnistuneesti, ei breakpointia
// 1 breakpoint
// 2 CPU ilmoitti virheestä

Tiedostojen ohjaus.h ja ohjaus.cpp ja niissä toteutetun luokan MkOhjaus kautta tapahtuu suurin osa Debuggaus-osasysteemin ja muiden osasysteemeiden välisestä kommunikoinnista. Tiedostossa ohjaus.cpp on globaalit muuttujat acpu ja aio. Näiden arvoksi alustetaan luokan MkOhjaus konstruktorissa CPU-olion ja IO-laitteet olion osoitteet. Olioiden osoitteet haetaan kerran MkOhjaus luokan konstruktorissa sen sijaan, että niitä kysyttäisiin ko luokkien Osoite-funktioilta aina uudelleen. TlLaitteet-luokan funktiota kutsutaan ainoastaan luokasta MkOhjaus ja siellä ainoastaan funktiosta SuoritaKasky. TlLaitteet-olion osoite haetaan uudestaan jokaisen MkOhjaus-luokan SuoritaKasky-funktion suorittamisen yhteydessä, koska TlLaitteet-olio on voitu tuhota välillä ilman, että MkOhjaus-oliota on myös luotu uudelleen.

MkLoki

Lokitulostukset kirjoitetaan MysseLog.out nimiseen tiedostoon. Jos tiedostoa ei ole valmiiksi olemassa se luodaan samaan hakemistoon, missä ajettava ohjelma on. Kaikki arvot kirjoitetaan lokiin heksadesimaalimuodossa (paitsi jokaisen kirjoituskierroksen aluksi lokiin kirjoitettava kellojaksojen määrä on tietysti desimaalimuodossa). Luokan Loki funktioita on tarkoitus kutsua vain luokasta Ohjaus.
Lokitulostus voidaan asettaa päälle funktiolla Set ja ottaa pois päältä funktiolla Reset. Jos lokitulostus on päällä, sinne kirjoitetaan halutut tiedot jokaisen käskyn suorituksen jälkeen. Lokiin voidaan valita tulostettavaksi rekisterit ja/tai muisti halutulta väliltä. Kirjoitettavat tiedot asetetaan funktioilla Alku, Loppu ja Rekisterit. Jos rekisteritulostus on valittuna lokiin kirjoitetaan kaikki M68HC11:n rekisterit. Akkuja A ja B ei kuitenkaan kirjoiteta erikseen, vaan niiden tilalta kirjoitetaan kaksoisakku D. CCR Tilarekisterin kahdeksan bittiä kirjoitetaan kahdeksan numeron (ykkösen tai nollan) jonona.
Funktio Kirjoita tarkastaa mitkä tiedot on valittu kirjoitettaviksi ja kutsuu tarvittaessa funktioita KirjoitaRekisterit ja KirjoitaMuisti. Funktioista on tehty mahdollisimman yksinkertaiset, jotta ohjelman suoritus ei hidastuisi kohtuuttomasti lokitulostuksen ollessa päällä.

Lokiintulostus toiminto on toteutettu erittäin yksinkertaisesti. Jos käyttäjä välttämättä haluaa tulostaa koko muistin lokiin, tuloksena on erittäin nopeasti hillittömän iso tiedosto... Tiedostoon kirjottaminen on toteutettu C++:n I/O kirjastosta löytyvän ofstream luokan avulla ja esim. tiedoston luominen ja tiedostoon kirjoittamisen puskurointi on jätetty täysin em. luokan huoleksi.

MkBreakpoint

Luokassa on yksinkertaiset erilliset funktiot kaikkien eri breakpointien (eli rekisteriehtojen, data-alueen alun ja lopun ja ennen pysähdystä suoritettavien käskyjen määrän) asettamista varten. Funktio rekisteriehtojen asettamiseksi ei kuitenkaan tee muuta kuin kutsuu luokan RekEhdot funktiota, koska rekisteriehdoista kaikkine toimintoineen tehtiin oma luokkansa. Sen sijaan yksinkertaiset ehdot tietyn käskymäärän suorittamiseksi ja ohjelmalaskurin data-alueelle pääsyn estämiseksi toteutettiin Breakpoint luokassa.
Breakpointit saa tarkastettua yhdellä funktiolla Tarkasta, joka tarkastaa vuorollaan kaikki eri breakpointit, jotka ovat päällä, eli joihin käyttäjä on määritellyt jonkun hyväksytyn arvon tai ehdon. Funktio tarkastaa ensin askel-breakpointin ja vasta jos se ei ollut päällä tai breakpointia ei oltu saavutettu, tarkastetaan data-alue ja mahdollisesti edelleen rekisteriehdot ellei data-aluekkaan ollut päällä tai ohjelmalaskuri ei ollut data-alueella.
Erittäin oleellinen ominaisuus on, että luokalla on funktiot Set ja Reset, joilla breakpoint tarkastukset saa päälle tai kokonaan pois päältä. Kun breakpointit ovat pois päältä, ei joka käskyn suorituksen yhteydessä tarvitse suorittaa käskyä Tarkasta, vaan riittää, että Ohjaus-luokan funktio SuoritaKasky saa inline funktiolta IsSet vastauksen false.

Askel-breakpoint on toteutettu niin, että kun haluttu määrä käskyjä on suoritettu, ilmoitetaan breakpointista ja asetetaan automaattisesti ohjelman suoritus pysähtymään kun seuraavan kerran on suoritettu sama määrä käskyjä. Jos Askel-breakpointin haluaa pois päältä (niin että muut breakpointit voivat vielä olla päällä), on funktiolle AsetaAskelBreakpoint annettava argumentiksi nolla tai negatiivinen luku.
Data-alue asetetaan kahdella erillisellä funktiolla AsetaDataAlku ja AsetaDataLoppu, jotka kummatkin ottavat argumentikseen merkkijonon, jonka pitää esittää heksalukua. Argumenttina annettava alueen alku- tai loppuarvo lasketaan kuuluvaksi data-alueeseen. Data-alueen tarkastus menee päälle (jos breakpoint tarkastus on päällä) automaattisesti jos joko alku- tai loppuarvoksi antaa hyväksyttävän arvon (hyväksyttävä arvo on heksaluku ja sen lisäksi suurempi kuin nolla, mutta pienempi kuin muistin koko). Data-alueen tarkastuksen saa pois päältä antamalla alku- tai loppuarvoksi jonkun ei-hyväksyttävän arvon.

MkRekEhdot

Luokan MkRekEhdot funktioita on tarkoitus kutsua vain luokasta MkBreakpoint. Luokan julkiset jäsenfunktiot ovat Aseta ja Tarkasta.
Aseta ottaa argumentikseen osoittimen merkkijonoon. Jokaisesta yksittäisestä rekisteri-operandi-arvo yhdistelmästä tehdään oikean tyyppinen ehto-olio. Ehto olioiden ja and ja or operandien muodostama lauseke muunnetaan postfix muotoon ja talletetaan luokan jäsenmuuttujaan lista. Jos Ehto oli laillinen ja sen muuntaminen listaan onnistui palautetaan 0, virhetilanteessa palautetaan 1.
Ehdoissa käytettävät sallitut rekistereiden ja lippujen tunnukset ovat seuraavat:
Rekisterit:
A akku A
B akku B
D kaksoisakku D
IX indeksirekisteri IX
IY indeksirekisteri IY
SP pino-osoitin
PC ohjelmalaskuri
Liput:
S stop disable
X x interrupt mask
H half-carry
I i interrupt mask
N negative
Z zero
V overflow
C carry
Lisäksi ehdoissa voi käyttää merkkejä <, >, = ja # (erisuuri) sekä heksadesimaali-muodossa olevia lukuja. Luvut on annettava ilman 0x-alkuliitettä. Yksittäisten ehtojen välillä voi olla and ja or operaattoreita sekä ( ja ) merkkejä, eli ehtojen laskujärjestystä voi muuttaa suluilla.

Postfix muotoon muuntaminen:
And operaattorilla katsotaan olevan korkeampi presedenssi kuin or operaattorilla.
-Rekisteriehto luetaan ja laitetaan heti listaan.
-Vasen sulku laitetaan pinoon.
-Kun vastaan tulee oikea sulku, sitä ei laiteta mihinkään, mutta pinosta siirretään merkkejä listaan kunnes vastaan tulee vasen sulku (joka myös poistetaan pinosta, mutta jota ei laiteta mihinkään)
-Kun vastaan tulee and tai or operaattori, pinosta poistetaan alkioita ja siirretään ne listaan, kunnes löydetään alempaa presedenssiä oleva operaattori. Sen jälkeen käsiteltävänä ollut alkio laitetaan pinoon.

Funktio Aseta käyttää apunaan luokan yksityisiä jäsenfunktioita Rekisteri ja AndOr. Kun Aseta huomaa syötejonossa merkin a (and), o (or), ( tai ), se kutsuu funktiota AndOr, joka huolehtii näiden symbolien käsittelystä.
Funktio MkRekEhdot::Tarkasta laskee luokan jäsenmuuttujassa lista olevan postfix-lausekkeen arvon seuraavasti:
Listaa lähdetään käymään alusta alkio kerrallaan. Jos alkio on tyyppiä EHTO kysytään sen arvoa, joka on joko 1 tai 0. Tämä arvo laitetaan pinoon. Jos alkio ei ole EHTO (eli se on tyyppiä MERKKI), pinosta nostetaan kaksi arvoa ja operaattoria käytetään niihin, jonka jälkeen tulos laitetaan pinoon.

MkEhto

Luokka MkEhto on tehty luokan MkRekEhdot käytettäväksi. Luokka MkEhto on virtuaalinen kantaluokka luokille MkSuurempi, MkPienempi, MkErisuuri ja MkYhtäsuuri. Kukin neljän edellä mainitun luokan instanssi esittää yhtä 68hc11:n rekisteriin tai lippuun kohdistuvaa ehtoa. Kullakin luokalla on jäsenmuuttujat joihin sijoitetaan ehdossa käytettävä lukuarvo ja osoitin oikeaan kohtaan m6811_s structia. Luokilla on jäsenfunktio Arvo, joka hakee CPU:n sen hetkisistä rekisterin- tai lipunarvoista sen, johon olion rekisteri- tai lippuosoitin osoittaa ja vertaa sen jälkeen haettua arvoa kullekkin luokalle ominaisella tavalla olioon talletettuun lukuarvoon. Funktion paluuarvona on false, jos ehto ei toteutunut ja true, jos se toteutui. Luokalla MkEhto on kaksi erilaista staattista jäsenfunktiota Tee, joita käyttämällä voi tehdä uuden instanssin oikean tyyppisestä ehdosta. (Toinen funktioista ottaa argumenttinaan osoittimen rekisteriin ja toinen lippuun. Kumpikin funktio käyttää op-argumenttinaan saamaansa merkkiä valitessaan minkä luokan instanssi argumentteja käyttäen luodaan.)

MkPino

Pino luokka on tehty luokan RekEhdot käytettäväksi. Pino tietotyyppi on toteutettu linkitettynä listana, jonka alkiot muodostuvat "alkio"-structeista. (alkio on määritelty luokan määrittelyn yhteydessä tiedostossa pino.h) Pinoon voi laittaa ja sieltä voi ottaa kerrallaan joko merkin tai boolean arvon. Luokalla on tietotyypille kuuluvat toiminnot Pop, Push, Empty ja Topp sekä lisäksi toiminto Tyhjenna.

MkLista_alkio

Lista_alkio on yksityinen luokka, joka on ainoastaan luokan Lista käytettävissä. Lista tekee talletettavasta asiasta Lista_alkio olion. Oliota luotaessa sille voidaan antaa argumenttina joko osoitin tyyppiä MkEhto olevaan olioon tai merkki, eli listaan voidaan tallettaa näitä kahta tyyppiä olevia alkioita.

MkLista

Lista luokka on tehty luokan RekEhdot käytettäväksi. Luokassa on toteutettu tyypillinen linkitetty lista tietorakenne. Lista koostuu nollasta tai useammasta tyyppiä lista_alkio olevasta oliosta. Listan loppuun voi lisätä osoittimen tyyppiä MkEhto olevaan olioon tai merkin (molemmista tehdään ensin tyyppiä Lista_alkio oleva olio). Lista voidaan tyhjentää kokonaan tai siitä voidaan poistaa vain ensimmäinen alkio. Sen lisäksi alkioita voi käydä läpi yksi kerrallaan, ilman, että niitä poistetaan listasta.

Debuggausosan testaus

Toteutuksessa on muutamissa kohdissa tingitty modulaarisuudesta ja koodin tyylikkyydestä, jotta ohjelman toimintaa saataisiin nopeutettua.
Debuggaus-osan testauksessa on käytetty pääasiassa "koodin läpikäynti" menetelmää, eli koodista on seurattu kaikkien eri tilanteiden kulku. Lisäksi funktioita on testattu yksinkertaisilla ajurifunktioilla, jotta saatiin tarkastettua että funktiot antavat tietyllä syötteellä halutun paluuarvon. Lokitulostuksen toiminta saatiin tarkastettua vertaamalla lokiin tulostuneita arvoja arvoihin, jotka käyttöliittymä haki näytölle suoraan CPU:lta.
Debuggaus-osaa varten oli oma testihakemisto, jossa oli vain Mk-alkuisten luokkien koodi, eli debuggaus-osan lisäksi CPU ja IO-laitteet, mutta ei käyttöliittymä- fysiikkamalli- eikä toimilaiteosan koodia. Yksinkertaisella ajurifunktiolla saatiin asetettua breakpointeja ja tulostettua testiajojen tulokset näytölle.Rekisteriehtojen toimivuutta testattiin niin, että asetettiin ohjelman suoritus pysähtymään johonkin rekisteri- tai lippuehtoon ja tarkistettiin lokista, että ohjelma pysähtyi oikeassa kohdassa ja palautti käyttöliittymälle (näytölle) oikean ilmoituksen breakpointista. Näin testatessa Breakpointien tarkastus osuus selvisi mm. seuraavista syötteistä oikein:
Edellisen kaltaisilla ehdoilla testattiin kaikkiin lippuihin ja rekistereihin kohdistuvat erityyppiset ehdot ja erilaisia ehtoyhdistelmiä.

MkIO_laitteet

MkIO_laitteet sisältää prosessorikortin I/O-laitteet (RAM, EEPROM, timer, AD-muunnin, keskeytykset, ulkoinen muisti). IO-laitteet toteutetaan omana luokkanaan. Se sisältää julkiset funktiot muistin lukemista ja kirjoittamista varten ja I/O-laitteiden tilojan päivitystä varten sekä kooditiedoston lataamisen EEPROMiin. Ladattavat tiedostot ovat S19-formaatissa olevia binääritiedostoja. Koodin lataus oli toteutettu valmiiksi. Muisti toteutetaan merkkitaulukkona. Kaikki IO-laitteet sisältyvät muistiin, eli niiden ohjausrekistereillä on oma muistiosoite käytössä olevalla muistialueella. Muistin käsittelyyn on lisätty kirjoitussuojatut kontrollirekisterit ja ulkoisen muistin toteutus. Sisäinen muisti on jo toteutettu.
Muistialue $C000 - $FFFF on ROM-aluetta, johon ei voi kirjoittaa.

Timer on 16-bittinen rekisteri (TCNT), jonka arvoa kasvatetaan joka kellojaksolla. Rekisterin ylivuoto asettaa timerin ylivuotolipun (TOF), josta tulee keskeytys (9), jos timerin ylivuotokeskeytys on sallittu (TOI asetettu). Timerissa on 5 output compare -rekisteriä ja 3 input capture -rekisteriä. Timerin arvon voi lukea, mutta siihen ei voi kirjoittaa. Output compareen kuuluu 5 16-bittistä rekisteriä (TOCn), joihin talletetaan haluttu timerin arvo, jolloin outputnastan pulssi muuttuu automaattisesti (kääntyy, ei muutu, muuttuu 0:ksi tai 1:ksi). Muutosta ohjataan 8-bittisellä rekisterillä (TCTL1). Output compare 1 voi ohjata kaikkia viittä output comparea. Rekisteri OCM1 kertoo, mihin pinneihin output compare vaikuttaa ja OC1D, mitä porttiin kirjoitetaan. Lähdöt muuttuvat, kun timerin arvo on sama kuin OC1. Jos kaksi output comparea yrittää ohjata samaa pinniä, OC1:llä on korkeampi prioriteetti ja se saa kirjoittaa pinniin. TOCn-rekisterit alustetaan resetissä arvoon FFFF. Output comparen arvon voi muuttaa odottamatta haluttua timerin arvoa kirjoittamalla rekisteriin CFORC ykkösen halutun pinnin kohdalle, jolloin tapahtuu rekisterillä TCTL1 ohjelmoitu output-toiminto. Output comparen tapahtumista tulee keskeytys, jos kyseinen keskeytyslippu on asetettu (TMSK1). Kaikilla on oma keskeytysvektori. Joka tapauksessa asetetaan lippu kertomaan tapahtumasta (TFLG1).

Pulse accumulator voi toimia kahdessa eri moodissa. Sen toimintatila riippuu PAMOD-bitistä. Kun PAMOD = 0, se laskee pulsseja input-pinnistä. Kun PAMOD = 1, se laskee kellojaksoja (taajuus E-kello/64) silloin kun input-pinnin arvo on PEDGE-bitillä määritelty. Kun PEDGE = 0, lasketaan laskevia reunoja ja kun PEDGE = 1, nousevia reunoja. Kun PEDGE = 0 ja PAMOD = 1, lasketaan kellojaksoja, kun PAI = 1 ja kun PEDGE = 0, lasketaan kellojaksoja, kun PAI = 0. Laskuri on 8-bittinen rekisteri PACNT.

AD-muunnin on 8-kanavainen ja 8-bittinen. AD-muunnin laitetaan päälle ADPU-bitillä OPTION-kontrollirekisterissä. Se ei käynnisty itsestään resetin jälkeen. RC-oskillaattorin käyttöä vaihtoehtoisena kellona AD-muuntimessa ei ole toteutettu, vaan se toimii aina E-kellon mukaan. CSEL-bitti alustetaan nollaksi ja sen muuttamisella ei simulaattorissa ole merkitystä. Muunnin tekee neljä muunnosta kerrallaan, joko neljä kertaa peräkkäin valitulta kanavalta tai yhden jokaiselta neljältä. Neljän muunnoksen sarja vie 128 E-kellojaksoa. A/D control status register (ADCTL) sisältää CCF-lipun, SCAN-lipun, MULT- lipun ja Channel select-liput. Muunnoksen jälkeen asetetaan CCF-lippu. Tähän bittiin ei voi kirjoittaa. Se alustetaan nollaksi. Joka kerta, kun ADCTL-rekisteriin kirjoitetaan, lippu nollataan ja uusi muunnos aloitetaan välittömästi. Muunnoksia voi tehdä jatkuvasti tai yhden neljän muunnoksen sarjan. Kun SCAN-lippu on 0, tehdään neljä muunnosta. Kun se on 1, tehdään jatkuvasti muunnoksia ja päivitetään tulokset muunnoksen jälkeen tulosrekistereihin. Kun MULT-lippu on 0, tehdään kaikki neljä muunnosta samalta kanavalta, joka määrätään channel select -lipuilla. Kun MULT on 1, tehdään muunnos vuorotellen neljältä kanavalta, jotka määrätään channel select -lipuilla CD ja CC. Muunnoksen jälkeen tulokset kirjoitetaan A/D-tulosrekistereihin. A/D-tulosrekisterit (ADR1-ADR4) ovat read only -rekisterejä. Ensin täytetään ADR1, sitten ADR2 jne. Jännite VL (kytketty nastaan 21) vastaa rekisterin arvoa 0 ja VH (nasta 18) arvoa FF. Siis digitaalinen arvo = floor((V-VL)/(VH-VL)*256).

Keskeytyksest tarkistetaan joka käskyn suorituksen jälkeen. IO-laitteiden aiheuttamat keskeytykset tunnistetaan vain, jos CCR-rekisterin I-bitti on 0. Keskeytysten prioriteettia voi muuttaa HPRIO-rekisterin biteillä PSEL0-PSEL3, kun CCR:n I-bitti on 1. Keskeytyksen tapahduttua kaikki CPU:n rekisterit laitetaan pinoon järjestyksessä PCL, PCH, YL, YH, XL, XH, A, B ja CCR ja haetaan PC:lle uusi arvo kyseisen keskeytyksen keskeytysvektorista. CCR:n I-bitti asetetaan ykköseksi. Sitten käsitellään keskeytys, jolla on korkein prioriteetti. CCR:n X-bittiä ei huomioida. Tämän jälkeen käsitellään muut keskeytykset järjestyksessä ennen kuin jatketaan käskyjen suoritusta.


Rekisterit, joihin manuaalin mukaan voi kirjoittaa vain 64 ensimmäisen kellojakson aikana on simulaattorissa kokonaan kirjoitussuojattu, koska niiden muuttamiseen ei ole tarvetta. RAMin ja rekisterien osoitteita muistissa ei siis voi vaihtaa, vaan ne ovat kiinteästi paikoissa

$0000 - $00ff  68hc11 internal ram
$1000 - $103F  68hc11 internal registers
$0000 - $7FFF  32k RAM (partially hidden)
$C000 - $FFFF  16k (of 32k) EPROM.

Timerin laskuri toimii vain samalla taajuudella kuin E-kello. Muita mahdollisia taajuuksia ei ole toteutettu.
COP watchdog -systeemi ei ole käytössä.
Ulkoisia keskeytyksiä ei tarvitse toteuttaa, eikä sarja- ja rinnakkaismuotoista tiedonsiirtoa ja input capturea eikä näihin liittyviä keskeytyksiä.

Testaus on suoritettu osaksi prosessorin vanhaan käyttöliittymään lisätyillä I/O-laitteiden muistiosoitteiden tulostuksilla ja mahdollisuudella muuttaa näiden muistipaikkojen arvoja, ja osaksi valmiilla simulaattorilla. Tässä on käytetty samoja testiohjelmia kuin CPU:nkin testaamisessa. I/O-laitteiden eri osia on testattu erilaisilla testitulostuksilla, jotka saa päälle Makefilestä asettamalla ko. testausliput. I/O-laitteet ovat testeissä toimineet niin kuin oli tarkoituskin.

MkLiitäntärima

Mikrokontrolleri ja auto on kytketty toisiinsa 40-nastaisella liitäntärimalla. Siinä on julkisina funktioina nastan jännitteen haku- ja päivitysfunktiot ja samat operaatiot bitteinä, jolloin looginen 1 vastaa 5.0 V ja 0 vastaa 0.0 V. Itse rimaa mallitetaan taulukolla, jossa on nastojen jännitteet.

Riman testaus on suoritettu yksinkertaisella testausohjelmalla, jota käyttäjä voi ohjata ja joka lukee ja kirjoittaa riman nastoihin halutut arvot ja tulostaa riman sisällön. Rima on toiminut kaikissa testitapauksissa niin kuin oli tarkoituskin.

FmAuto

Luokka toteuttaa auton liikutuksen ja mittaa fotodiodien etäisyyttä radasta. Rataolio on oltava olemassa luokkaa instantioidessa, koska sitä tarvitaan heti konstruktorissa.

Auton_sijainti -funktio tekee luokassa suurimman työn eli liikuttaa autoa. Funktiossa käsitellään autoon liittyviä vektoreita kahdessa eri koordinaatistossa. Auton nopeus ja asento ilmoitetaan rataan sidotussa koordinaatistossa, jossa x-akseli on oikealle ja y-akseli ylös. Tämä siksi, että uutta auton paikkaa laskettaessa voidaan nopeusvektorin x- ja y-komponentit ajalla kerrottuna suoraan summata nykyisiin koordinaatteihin. Sitävastoin autoon kohdistuvat voimavektorit sekä niiden laskentaan tarvittavat renkaiden nopeusvektorit ovat autoon sidotussa koordinaatistossa, jonka x-akseli on auton keulaa kohti ja y-akseli vasemmalle. Funktiossa lasketaan ensin etu- ja sitten takarenkaiden ohjausvoimat, jotka aiheutuvat renkaan asennon poikkeamisesta sen oman nopeusvektorin suunnasta. Seuraavaksi näihin summataan jarrujen ja moottorin voimat. Mikäli voimavektoreiden pituus ylittää voiman, joka renkaiden kautta voidaan maksimissaan lepokitkakertoimella välittää, vektoreille lasketaan uusi pituus käyttäen liikekitkakerrointa. Kitkakertoimet on määritelty tiedostossa autodata.h. Samasta paikasta voidaan myös säätää mekaniikasta aiheutuvia kitkavoimia. Jos havaitaan, että moottorivoima on suurempi kuin mitä renkaan kautta voidaan välittää, vähennetään välittyvää voimaa vielä sutimisen vuoksi. Voimaa vähennetään logaritmisesti voimien suhteessa. Näin saatujen voimien avulla lasketaan nopeuden ja kulmanopeuden muutokset. Uusien nopeuksien avulla lasketaan auton uusi paikka ja asento. Lisäksi tehdään tarkistus siitä, heilahteleeko auto paikoillaan ohjausvoimien vaikutuksesta ja asetetaan tarvittaessa nopeus nollaksi ja lopetetaan näin turha rimpuilu. Funktion lopuksi ilmoitetaan toimilaitteille, fysiikkamallissa tapahtuneen muutoksia ja palautetaan käyttöliittymälle auton uusi paikka ja asento sekä tieto onko auto teipin lähellä. Käännösoptiolla -DFYSIIKKADATATULOSTUS voidaan fysiikkamalli laittaa tulostamaan aina kutsun päättyessä kaikki keskeiset suureensa voimista auton ja renkaiden asentoon saakka. Tulostusmuoto on kryptinen.

Auton_voimat ja Akselinopeus -funktioissa vain palautetaan kysytyt arvot. Etaisyys_teipista -funktiossa lasketaan tietyn fotodiodin tai auton massakeskipisteen etäisyys rataa kuvaavan teipin keskilinjasta. Apuna käytetään Pisteen_Etaisyys_Vektorista -funktiota. Etaisyys_teipista -funktion aluksi lasketaan fotodiodin numeron perusteella mittauspisteen paikka radalla. Mittauspisteen paikaksi otetaan fotodiodin ja sitä vastapäätä olevan ledin puolivälissä oleva piste. Se lasketaan asettamalla keulaan-vektori auton keskipisteestä kohti auton nokkaa ja summaamalla tähän sivulle-vektori, joka kulkee auton keskilinjasta mittauspisteiden riviä jommallekummalle sivulle päin. Tämän jälkeen keulaan-vektorin loppupisteestä saadaan mittapisteen sijainti. Jos funktio saa parametrinaan luvun -1, se laskee anturin mittapisteen sijasta auton keskipisteen etäisyyden teipistä. Tätä käytetään määrittämään ollaanko ulkona radalta. Rata on jaettu optimonnin takia moneen pienempään osioon. Koska auto on tietyllä ajan hetkellä ainoastaan yhdessä osiossa, riittää kun tutkitaan ainoastaan tämän osion vektorit. Funktiossa käydään lävitse rata osion kahteen suuntaan linkitetty vektorilista, kutsumalla jokaiselle vektorille funktiota Pisteen_Etaisyys_Vektorista. Tämän tuloksena muuttujaan lyhin_etäisyys saadaan mittapisteen lyhin etäisyys teipin keskilinjasta. Funktiossa Pisteen_Etaisyys_Vektorista tutkitaan ensin sijaitseeko annetun vektorin suuntaisen suoran mittapistettä lähin piste kyseisellä vektorilla. Jos näin on, niin vasta sitten muodostetaan suoran yhtälö, lasketaan pisteen etäisyys suorasta ja palautetaan se. Jos piste oli vektorin ulkopuolella, palautetaan vektorin päätepisteistä se, joka on lähempänä mittapistettä.

Sekä fysiikkamallin, että toimilaiteosan testaukseen on käytetty Makefilen käännösoptiota -DKASIOHJAUS. Tällöin näppäimillä A, S, D ja W voidaan ohjailla autolle saapuvia pulssien pituuksia ja tarkkailla fysiikkamallin ja toimilaitteiden toimintaa. Prosessoriosaa ei tällöin kutsuta lainkaan vaan sen korvaa laitteet/prosu/ -hakemiston tiedostot prosu.cpp ja prosu.h. Tarvittaessa voi Makefilesta asettaa myös sopivia ylimääräisiä tulosteita näkyväksi.

Vektori

Vektoriluokassa käsitellään fysiikkamallissa sekä radan- ja näytönkäsittelyssä tarvittavia vektoreita. Luokan sisäinen esitystapa on napakoordinaattimuodossa. Vektori muodostuu tällöin suunnasta ja pituudesta sekä alkupisteen x ja y koordinaateista. Luokalle on kuitenkin määritelty funktiot, joilla sitä voidaan haluttaessa käsitellä joko suorakulmaisessa koordinaatistossa tai napakoordinaatistossa. Vektoreille on myös määritelty summaoperaattori. Kaikissa vektoria käsittelevissä operaatioissa pidetään huoli siitä, että vektorin pituus pysyy positiivisena ja radiaaneissa ilmoitettava suunta välillä miinus piistä piihin. Operaatiot ovat kaikki yksinkertaisia ja useimmat on toteutettu inline-funktioina.

TlLaitteet

TlLaitteet-luokka instantioi kaikki toimilaitteet (ja anturit). Luokka toimii myös näiden rajapintana ulkomaailmaan. Kullekin toimilaitteelle on määritelty osoitintyyppinen jäsenmuuttuja. Laitteet instantioidaan TlLaitteet-luokan konstruktorissa ja tuhotaan sen destruktorissa.

Prosessori pyöräyttää toimilaitteita kutsuessaan Keraa_tiedot -funktiota. Tällöin suoritetaan ohjausservon, moottoriservon, kulmapotentiometrin, nopeusanturin ja käynnistysnapin tilojen tutkinta. Fotodiodien toiminta suoritetaan, kun fysiikkamalli kutsuu Auto_liikahtanut -funktiota. Lisäksi luokalla on vielä seuraavat toimilaitteiden tietoja välittävät funktiot: Heijastunut_kirkkaus, Tehoprosentti, Moottorin_teho, Jarruvoima, Ohjauksen_kohdekulma ja Rengaskulma.

TlToimilaite ja TlAnturi

Luokat toimivat toimilaitteiden ja antureiden kantaluokkina. Ainakaan toistaiseksi niissä ei ole mitään toiminnallisuutta. Toimilaitteille määritellään jäsenmuuttuja inputnasta ja antureille jäsenmuuttuja outputnasta.

TlServo

TlServo periytyy luokasta TlToimilaite ja on molempien servoluokkien kantaluokka. Luokan ainoassa jäsenfunktiossa Lue_Nasta luetaan liitäntärimalta sen nykyinen signaalitaso ja tallennetaan viimeisen servopulssin pituus jäsenmuuttujaan edellisen_pulssin_kesto. Mikäli pulssit tai pulssien välit ovat liian lyhyitä tai pitkiä, tulostetaan virheilmoituksia, mutta ohjelman suoritus jatkuu kuitenkin normaalisti. Kääntäjän optiolla -DPULSSITULOSTUS voidaan asettaa funktio tulostamaan kaikkien saapuneiden pulssien pituudet.

TlMoottori

TlMoottori periytyy TlToimilaitteista. Luokan jäsenfunktiot Vaanto ja Jarruvoima tuottavat vääntömomentin ja moottorijarrutuksen arvot. Maksimi vääntömomentti laskee lineaarisesti moottorin kierrosnopeuden noustessa, jos vääntöä otetaan pyörimisen suuntaan. Jos moottoria aletaan pyörittää menosuunnan vastaisesti, voidaan saada väännön maksimi käyttöön kaikilla kierrosnopeuksilla. Jarruvoima saa nollasta poikkeavan vakioarvon tehoprosentin ollessa 0. Käännösoptio -DAKUN_VARAUS_ARVOTAAN kytkee päälle toiminnon, joka konstruktorissa arpoo akulle varausarvon väliltä 0.5 - 1.0. Moottorin palauttamat vääntöarvot on kerrottu tällä luvulla. Tiedoston tlmootto.cpp alussa on kolme moottorin ja koko simulaattorin toiminnan kannalta tärkeää vakiomäärittelyä: moottorin tuottama maksimivääntö, vakiojarruvoiman arvo sekä moottorin maksimi kierrosluku. Viimeinen tarkoittaa sellaista kierroslukua, jolla moottori ei enää tuota vääntöä ja ei siten voi kiihdyttää enää korkeammille kierroksille.

TlOhjausservo

TlOhjausservo periytyy luokasta TlServo. Luokan tärkein jäsenfunktio on Lue_Ja_Kaanna, joka kutsuu kantaluokan funktiota Lue_Nasta ja kääntää renkaita kohdekulman suuntaan. Funktiot Rengaskulma ja Renkaan_Kohdekulma palauttavat TlLaitteiden kysymät tiedot. TlLaitteet välittää vastaukset edelleen näytölle tai fysiikkamallille. Luokassa käytetään vakioita MAX_RENGASKULMA ja KAANTYMISNOPEUS, jotka on määritelty tiedostossa tldata.h.

TlMoottoriservo

TlMoottoriservo periytyy luokasta TlServo. Servon nastan lukeminen tapahtuu TlLaitteiden kutsuessa suoraan kantaluokasta perittyä Lue_Nasta -funktiota. Tehoprosentti-funktiossa määritellään moottorille menevän tehosyötön pulssisuhde. Pulssisuhde välitetään ohjelmassa tehoprosentin arvona välillä miinus yhdestä yhteen. Negatiiviset arvot tarkoittavat pakkia. Nolla-alue määrää miten lähellä edellisen pulssin keston tulee olla servon keskikohtaa, jotta palautetaan tehoprosentin arvona nolla. Lisäksi moottorin suunnanvaihtoon on ohjelmoitu säädettävä viive. Viiveen (kyllä, tämäkin muoto on suomen kielessä sallittu) pituutta voidaan säätää tiedostosta tldata.h.

TlLedikampa

TlLedikampa periytyy luokasta TlToimilaite. Luokasta tehdään yksi instanssi molempia ledikampoja kohden, ei siis jokaista lediä kohden. Luokkaan on toteutettu ledikamman jänniteen lukeminen liitäntärimalta, mutta se on kommentoitu pois, koska toistaiseksi ohjausohjelmat eivät ohjaa ledikampojen kirkkautta, vaan ne ovat jatkuvasti päällä. Nykyisellään Valoisuus-funktio palauttaa aina ykkösen, joka tarkoittaa täyttä kirkkautta (viiden voltin jännitettä).

TlNopeusanturi

TlNopeusanturi periytyy luokasta TlAnturi. Luokan ainoassa jäsenfunktiossa Kirjoita_Nasta, asetetaan liitäntärimalle joko nolla tai viisi volttia riippuen siitä, onko nopeusanturin kiekossa mittauspisteen kohdalla puola vai reikä. Tämä päätellään auton kulkemasta matkasta yksinkertaisella jakojäännösoperaatiolla. Auton kulkemaa matkaa integroidaan fysiikkamallilta kysytystä renkaiden nopeudesta aina Kirjoita_Nastaa kutsuttaessa.

TlKulmapotentiometri

TlKulmapotentiometri periytyy luokasta TlAnturi. Luokan ainoa jäsenfunktio Kirjoita_Nasta asettaa liitäntärimalle jännitteen TlLaitteiden välittämän rengaskulman perusteella. Funktiossa käytetään vakiota MAX_RENGASKULMA, joka on määritelty tiedostossa tldata.h. Kulmapotentiometri ei toistaiseksi ole autossa käytössä ja siksi luokan instantiointi ja siihen liittyvät muuttujat on kommentoitu pois luokasta TlLaitteet.

TlFotodiodi

TlFotodiodi periytyy luokasta TlAnturi. Luokasta tehdään instanssi jokaista fotodiodia kohden, ei siis diodikampaa kohden. Funktiossa Kirkkaus kysytään fysiikkamallilta kyseisen fotodiodin etäisyys teipistä. Rataoliolta saadaan teipin leveys. Näistä tiedoista funktio määrittää välille nollasta yhteen skaalatun fotodiodin näkemän kirkkauden. Kirkkaus saa ykköstä lähellä olevan arvon jos kyseinen fotodiodi on teipin päällä tai hyvin lähellä sen reunaa. Tämä etäisyys voidaan asettaa koodista NAKOETAISYYS-vakiolla. Kirkkaus-funktiota voidaan kutsua joko näytön tai Kirjoita_Nasta -funktion tarpeisiin. Kirjoita_Nasta asettaa liitäntärimalle 0 V, jos kirkkaus on 1 ja 5 V, jos kirkkaus on 0 ja lineaarisesti tältä väliltä. Nastalle menevässä arvossa on siis käänteinen signaalitasologiikka.

TlKaynnistysnappi

TlKaynnistysnappi on peritty luokasta TlAnturi. Luokan ainoassa jäsenfunktiossa Aloita kirjoitetaan liitäntäriman nastalle ensin viisi volttia ja kun simuloitavan mallin aikaa on kulunut puoli sekuntia niin nolla volttia. Tämä on ohjausohjelman odottama signaali aloittaa toiminta. Oikeassa autossa signaali siis annetaan autossa olevaa nappia painamalla.

KlPaataso

Käyttöliittymän keskeisimmät rutiinit sijaitsevat tässä luokassa. Ohjelman main-funktiossa luodaan KlPäätaso-olio, joka luo kaikki muut luokat. Luokan konstruktorissa luodaan myös ohjelman yhteinen värikartta. Värikarttana käytetään standardivärikarttaa mikäli sellainen on olemassa, muussa tapauksessa luodaan oma värikartta. Lisäämällä makefileen -DKASIOHJAUS, saa kytkettyä ohjelmasta cpu:n pois ja testattua fyysikkamallia näppäin ohjauksella. Pelkkää käyttöliittymää voi testata kääntämällä ohjelma makefilen -DTESTING_GUI option kanssa.

KlKonsoli

Luokka toteuttaa konsoli-ikkunan. Käyttäjä ohjaa konsolista ohjelman suoritusta asettamalla breakpointteja ja lokitulostus tietoja. Päätason luokasta ohjataan konsolia seuraavilla funktioilla:

Aseta_sensitiivisyys (int tila);
Määrää tilan mukaan sen mitkä napit ovat kulloinkin painettavissa.

Poista_work_proc (void);
Pysäyttää simulaation poistamalla Work Proc funktion Suorita. Work Proc on funktio, joka suoritetaan aina kun event-jono on tyhjä (no events are pending).

Kommentteja käyttäjälle voi kirjoittaa suoraan julkiseen Widgettiin kommenttirivi (parempi tapa olisi tehdä siitä yksityinen ja määritellä julkinen funktio siihen kirjoittamiseen).

KlMuisti

Luokka toteuttaa muistin näytön. Näitä luokkia linkitetään päätaso luokassa listaan, sen mukaan kuinka monta muisti ikkunaa käyttäjä haluaa näytölle. Lista on toteutettu siten että viimeistä muisti-ikkunaa ei voi sulkea. Muisti-ikkuna päivitetään funktiolla Paivita_muisti (char *); missä argumentti on osoitin muistin alkuun.

Luokka pitää muistissa scrollbarin edellisen aseman, siten on mahdollista siirtää se aina päivityksen jälkeen samaan kohtaan.

KlRata

Luokka toteuttaa radan visualisoimisen ja auton paikan tällä radalla. Auton paikka annetaan tähän ikkunaan viemällä kursori ikkunan sisään, jolloin kursori muuttuu auton näköiseksi ja sen jälkeen viemällä se haluttuun kohtaan. Auton kuvat ovat pixmappejä ja kursorit bitmappeja. Rata piirretään omaan pixmappiin heti alustuksen yhteydessä. Luokka käyttää piirtämiseen X:n multi-bufferointi laajennusta mikäli se on käytössä ja muussa tapauksessa luodaan sama efekti pixmapeillä (tällöin näyttössä huomaa kuitenkin pientä välkkymistä). Myös rata-tiedosto parsitaan tässä luokassa ja mikäli tiedostoa ei löydy käytetään sisään rakennettua rataa. Päätason luokasta ohjataan KlRata-luokkaa seuraavilla funktioilla:

Paivita (double x, double y, double asento, Boolean luistaako);
Päivittää auton paikan. Luistamistiedolla ei tehdä vielä mitään, mutta tarkoitus on tehdä rataikkunaan mustaa jälkeä silloin kun auton renkaat sutivat.
Luo_gct (void)
Luo pixmappien Graphics Contextit, jotka määräävät piirtämiseen liittyviä attribuutteja.
Aseta_sensitiivisyys (int tila);
Kun simulaatio on käynnissä, ei auton paikkaa voi vaihtaa. Tämä funktio muuttaa ikkunan mahdollisia toimintoja tilan mukaan.

Funktiolla Rata *Anna_rata (void), voi kysyä rataolion osoitetta.

KlRekisterit

Toteuttaa rekisteri-ikkunan, jossa näytetään prosessorin rekisterien arvot. Käyttäjä voi muuttaa rekisterien arvoja, jolloin kutsutaan CPU-luokan set funktioita.

KlAuto

Toteuttaa auton näyttämiseen tehdyn ikkunan. Myös tässä luokassa käytetään piirtämiseen multi-buffer laajennusta. Auto koostuu seuraavista komponenteista:
  KlAkselit *akselit;
  KlRenkaat *eturenkaat;
  KlRenkaat *takarenkaat;
  KlRenkaat *kohdekulmarenkaat;
  KlMoottori *moottori;
  KlAnturi *anturi[NMB_OF_DETECTORS];
  KlNopeus *nopeus;
  KlKitka *kitka_etu;
  KlKitka *kitka_taka;

KlAutonKomponentti

Tässä luokassa on auton eri piirrettävien osien yhteiset ominaisuudet. Luokka on abstrakti kantaluokka, eikä siitä muodosteta instansseja. Seuraavat ovat luokan suojattuja jäseniä mitkä periytyvät muille:
GC gc;
Graphics contexts on X:n määrittelemä struktuuri, jossa määritellään ominaisuudet miten grafiikka primitiivit piirretään.
Koordinaatti Kierra (Koordinaatti z, Koordinaatti z_r,
                          double sin_kulma, double cos_kulma);
Rotaatio-operaatio. Argumenttina piste (x, y), piste (x_r, y_r) jonka suhteen kierretään ja kulmasta valmiiksi lasketut sin ja cos arvot (tämä tehokkuus syistä). Paluuarvo uusi piste (x', y'). Toteutettu inline-funktiona.
Widget drawing_a;
Tähän widgettiin piirretään.

Luokka määrittelee myös puhtaan virtuaalifunktion virtual void Piirra (Drawable) = 0;, joka on toteutettava jokaisessa johdetussa luokassa!

Seuraavat luokat ovat tästä kantaluokasta johdettuja luokkia.

Koordinaatti

Toteuttaa koordinaatti-luokan. Koordinaatti on (x, y) pari.

Rata

Toteuttaa rata-luokan. Rata koostuu mittakaavasta, teipinleveydestä ja ratavektoreista. Ratavektorit on linkkitetty kaksisuuntaiseen listaan ja mittakaava ja teipinleveys ovat double-arvoisia.

Deque

Toteuttaa kahteensuuntaan linkitetyn listan kantaluokan. Tämä on ryöstetty oppaasta: Johdatus C++-ohjelmointikieleen, Peltonen Hannu, TKK.

VektoriDeque

Tiedosto sisältää toteutuksen kaksisuuntaisesta listasta jonka alkiot ovat luokan Vektori olioita. Luokka on johdettu luokasta Deque.

prosu.cpp ja prosu.h

Nämä korvaavat prosessoriosan silloin, kun simulaattori kytketään käsiohjaukseen. Makefilesta asetettavalla -DKASIOHJAUS -optiolla voidaan ohjelmasta kääntää versio, joka ei lainkaan simuloi prosessoria, vaan määrittää näppäimistöohjauksen perusteella toimilaitteille tulevien pulssien pituudet. Prosu-aliohjelmalle annentaan parametreina edellisestä kutsusta kulunut aika, ohjauspulssin pituus ja moottoripulssin pituus. Tämä kirjoittaa pulssisignaalit liitäntärimalle, josta toimilaitteet ne sitten lukevat.