Osien koodaus tehdään ennalta sovitun tyylin mukaisesti.
Toteutettavia asioita ovat keskeytykset ja I/O-laitteet, joista pitää toteuttaa output compare, pulssilaskuri, timer ja AD-muunnin. I/O-laitteet toteutetaan omana luokkanaan. Keskeytyksiin liityvät käskyt wai, swi ja rti puuttuvat. Stop-käskyssä pitää ottaa huomioon stop disabled-bitti, mitä ei valmiissa koodissa ole tehty. Keskeytykset tarkistetaan jokaisen käskyn suorituksen jälkeen.
Output comparen ja pulssilaskurin pitäisi toimia koko ajan.
Toteutus tehdään kuitenkin siten, että laitteiden tilat päivitetään
vain käskyjen suorituksen välillä, jolloin
virhe on pahimmillaan 41 kellojaksoa = n. 5 us (FDIV, IDIV). Tästä
ei aiheudu kovin suurta virhettä, koska ohjauspulssien ja nopeusanturin
pulssien pituudet ova millisekunteja.
Toinen vaihtoehto olisi päivittää laitteiden tilat joka kellojaksolla, jolloin ne toimivat tarkasti, mutta tämä hidastaisi simulaattorin toimintaa.
Suojattujen kontrollirekisterien muuttamista ei tarvitse toteuttaa, vaan rekisterien ja muistin osoitteet ovat kiinteitä.
Simulaattori toimii normal expanded -moodissa ja suorittaa yhden käskyn kerrallaan.
Valmiista C-koodista tehdään pienillä muutoksilla oma luokkansa, jossa on toteutettu CPU:n toiminta. Kuluneet kellojaksot, rekisterien arvot ja tilaliput ovat prosessorin tilaa kuvaavassa tietueessa. Julkisina funktioina toteutetaan seuraavan käskyn suoritus, rekisterien arvon muuttaminen ja prosessorin tilan kysely.
// CPU.h
typedef unsigned char byte; // tavu 8 bittiä
typedef long word; // sana 16 bittiä
typedef struct m6811_s {
long t; /* time in cycles */
word d, x, y; /* normal regs */
word sp; /* stack pointer */
word pc; /* program counter */
unsigned int overflow:1; /* overflow bit (V) */
unsigned int negative:1; /* negative bit (N) */
unsigned int zero:1; /* zero bit */
unsigned int carry:1; /* carry bit (C) */
unsigned int idisable:1; /* disable interrupts (I) */
unsigned int half_carry:1; /* half carry (H) */
unsigned int x_interrupt:1; /* x interrupt (X) */
unsigned int stop_disable:1; /* stop disable (S) */
} m6811;
class CPU
{
public:
// Konstruktori
CPU();
// Staattinen osoitefunktio, jolta luokan palvelujen käyttäjät voivat
kysyä viimeksi luodun instanssin
// osoitetta. Jos viimeisen luonnin
jälkeen jokin luokan instanssi on tuhottu, palautetaan NULL.
static CPU *Osoite ();
// Funktiot rekisterien arvojen muuttamista varten
void Aseta_a(byte arvo);
void Aseta_b(byte arvo);
void Aseta_d(word arvo);
void Aseta_x(word arvo);
void Aseta_y(word arvo);
void Aseta_sp(word arvo);
void Aseta_pc(word arvo);
// Seuraavan käskyn suoritus
// Palauttaa, onnistuiko käskyn suoritus.
// TRUE = onnistui
// FALSE = epäonnistui (luettiin tuntematon käsky)
// Argumenttina palautetaan tähän asti kuluneet kellojaksot.
bool Suorita_kasky(int *aika);
// Palauttaa sisäisten rekisterien arvot
m6811 Rekisterit();
// Destruktori
~CPU();
}; // CPU
Testaus suoritetaan Tampereelta saatavilla valmiilla ohjausohjelmilla ja mahdollisesti itse tehtävillä erittäin yksinkertaisilla assembler-pätkillä. Testauksessa voi käyttää simulaattorin alkuperäistä käyttöliittymää, jossa näkyvät rekisterien ja muistin sisältö ja seuraavaksi suoritettava käsky.
// IO-laitteet.h
class IO-laitteet
{
public:
// Konstruktori
IO-laitteet();
// Staattinen osoitefunktio, jolta luokan palvelujen käyttäjät voivat
kysyä viimeksi luodun instanssin
// osoitetta. Jos viimeisen luonnin
jälkeen jokin luokan instanssi on tuhottu, palautetaan NULL.
static IO-laitteet *Osoite();
// Ladataan suoritettava tiedosto EEPROMiin.
// Palauttaa, onnistuiko tiedoston avaaminen.
// TRUE = onnistui
// FALSE = ei onnistunut
bool Lataa_koodi(char *tiedostonnimi);
// Funktiot muistin lukemista ja kirjoittamista varten.
// Molemmista on 8 ja 16-bittiset versiot.
void Kirjoita8(word osoite, byte arvo);
void Kirjoita16(word osoite, word arvo);
byte Lue8(word osoite);
word Lue16(word osoite);
// IO-laitteiden päivitysfunktiot.
void Keskeytykset();
void Output_compare();
void AD_muunnin();
// Destruktori
~IO-laitteet();
}; // IO-laitteet
Testaus voidaan suorittaa tekemällä testausohjelma, jota käyttäjä voi ohjata ja joka lukee ja kirjoittaa muistiin halutut arvot haluttuihin osoitteisiin ja kutsuu tämän jälkeen IO-laitteiden päivitysfunktioita.
Mahdollinen kohinan mallitus tehdään liitäntärimaan.
Riman testaus voidaan suorittaa tekemällä testausohjelma, jota käyttäjä voi ohjata ja joka lukee ja kirjoittaa riman nastoihin halutut arvot ja tulostaa riman sisällön.
// liitantarima.h
// Riman kautta kulkevat tiedot mikrokontrollerin ja auton välillä
// Rimassa on 64 nastaa
class Liitantarima
{
public:
// Konstruktori
Liitantarima();
// Staattinen osoitefunktio, jolta luokan palvelujen käyttäjät voivat
kysyä viimeksi luodun instanssin
//osoitetta. Jos viimeisen luonnin
jälkeen jokin luokan instanssi on tuhottu, palautetaan NULL.
static Liitantarima *Osoite ();
// Haetaan tietoa rimasta. Argumenttina annetaan nastan numero (1-64).
// Palauttaa jännitteen voltteina.
double Hae(int nasta);
// Sama bittina, 0 V = 0, 5 V = 1
bool Hae_bitti(int nasta);
// Päivitetään liitäntäriman sisältöä. Argumenttina annetaan nastan
// numero (1-64) ja sen jännite.
void Paivita(int nasta, double jannite);
// Sama bittina, 0 V = 0, 5 V = 1
void Paivita_bitti(int nasta, bool bitti);
// Destruktori
~Liitantarima();
}; // Liitantarima