V tem sklopu vaj bomo implementirali simulator računalnika SIC/XE. Na vajah bomo postopoma razvili osnovne funkcije, v domači nalogi pa boste dodali še kakšno. Simulator lako zasnujete tudi po svoje. Za dodatne točke ga spišite v jeziku, ki ga asistent ne zna, za čast in slavo pa v jeziku, ki ga asistent ne pozna.

Registri

Definirajte razred Machine, ki bo predstavljal osnovo simulatorja stroja SIC/XE. V njem bomo implementirali registre, pomnilnik in vhodno/izhodne naprave.

Podprite vse programsko vidne registre stroja SIC/XE (torej A, X, L, B, S, T, F) in registra PC (angl. program counter) ter SW (angl. status word). Potrebujete ustrezne atribute in metode za dostop:

int getA()
void setA(int val)
…

Za register F lahko uporabite tip double, sicer pa se zaenkrat z njim ne obremenujte (za simulacijo večine programov ga ne potrebujemo). Za register SW nas pravzaprav zanimata le bita CC (angl. condition code), ki hranita rezultat zadnje primerjave. Vseeno ga lahko implementiramo kot ostale celoštevilske registre, pri čemer vrednosti 0x0, 0x40 in 0x80 predstavljajo rezultate »manjše«, »enako« in »večje«.

Podprite še dostop do vrednosti po indeksu registra z metodama

int getReg(int reg)
void setReg(int reg, int val)

To bomo potrebovali pri implementaciji ukazov ADDR, SUBR, SHIFTL itd. Registri A, X, L, B, S, T, F so zaporedoma oštevilčeni z 0, ..., 6; registra PC in SW pa z 8 oziroma 9.

Pomnilnik

Podprite pomnilnik z naključnim dostopom. Kako velik je naslovni prostor stroja? Definirajte konstanto MAX_ADDRESS, ki predstavlja največji naslov.

Kako boste hranili pomnilniške celice? Definirajte ustrezno podatkovno strukturo in metode za dostop do pomnilnika po bajtih:

int getByte(int addr)
void setByte(int addr, int val)

Pozor! V Javi je byte predznačeno število, mi pa želimo nepredznačena števila (zato vračamo int). Kaj storiti, če addr ni znotraj naslovnega prostora?

Definirajte še metodi za dostop do pomnilnika po besedah (angl. words). Kako dolga je beseda v arhitekturi SIC/XE?

int getWord(int addr)
void setWord(int addr, int val)

★ Definirajte še metodi za dostop do pomnilnka po floatih. Kako velik je float v SIC/XE?

double getFloat(int addr)
void setFloat(int addr, double val)

Namig: v Javi znata biti koristni metodi Double.doubleToLongBits() in Double.longBitsToDouble(…).

Naprave

Podprite vhodno/izhodne naprave. Definirajte razred Device z metodami za ukaze TD, RD in WD:

boolean test()
byte read()
void write(byte value)

Razred Device predstavlja primitivno napravo, ki ne dela nič, zato naj metode naredijo le najnujnejše: test vrne true, read vrne 0, write pa ne zapiše ničesar.

Stroj SIC/XE podpira 256 naprav. Podprite jih v razredu Machine. Potrebujete tabelo naprav in metodi

Device getDevice(int num)
void setDevice(int num, Device device)

Napišite razred InputDevice, ki podpira bralno napravo. Naprava naj bere s pomočjo objekta InputStream, ki ga podamo konstruktorju. Potrebno je povoziti le metodo read. Na enak način definirajte še razred OutputDevice, pri katerem povozite le metodo write.

Razširite razred Machine, da se ob inicializaciji ustvarijo naprave s številkami 0, 1, 2, ki predstavljajo standardni vhod, standardni izhod in standardni izhod za napake.

Napišite razred FileDevice, ki je vezana na datoteko (ime podamo v konstruktorju). Branje in pisanje v to napravo torej ustreza branju in pisanju v dano datoteko. Namig: RandomAccessFile. Popravite inicializacijo Machine, da naprave s številko večjo od 2 predstavljajo te vrste naprav.

Operacijske kode

Napišite razred Opcode, namenjen podpori (de-)kodiranja operacijskih kod (angl. opcodes) ukazov. V njem definirajte konstante za vse operacije stroja SIC/XE, npr.

public static final int LDA = 0x00;
public static final int LDX = 0x04;
…

V programu tako enostavno pridete do operacijskih kod z npr. Opcode.LDA. V ta razred boste kasneje lahko dodali tudi pomožne rutine za delo z posameznimi biti operacijskih kod.

마지막 수정됨: 화요일, 9 11월 2021, 12:28 PM