CLAUDIA Lite

primitivní 4-bitový procesor/počítač sestavený z obvodů TTL 74xx



Instrukční soubor Claudia Lite

Přestože třeba 4-bitový mikroprocesor Intel 4004 měl instrukce 8-bitové (operační kód se přenášel nadvakrát) a není to technicky žádný problém, zvolil jsem pro svůj procesor Claudia Lite instrukční soubor pouze 4-bitový. Pochopitelně především z důvodu jednoduchosti stavby a také kvůli omezenému adresovému rozsahu paměti programu. Kdyby každá instrukce zabírala v paměti 2 nibble, tak by se do té RAM 7489 opravdu moc instrukcí nevešlo. Tím je dáno, že počet instrukcí může být maximálně 16. Jenže to je pouze teoretická hodnota. Jak bylo uvedeno v popisu sequenceru, nebylo možné zde z důvodu jednoduchosti zapojení a využití maličké řídící PROM 74188 všech 16 instrukčních kódů použít. Nakonec se mi podařilo do té 74188 těch instrukcí nacpat 13, což považuji za malý zázrak (vysvětlení na konci stránky), neboť původní PIP-2 jich měl jen 6! Pravda, instrukci HLT jsem zrušil bez náhrady, ale i tak je to úspěch. Pojďme se na ty instrukce podívat.


Seznam a popis instrukcí Claudia Lite

V následující tabulce jsou všechny instrukce procesoru Claudia Lite. Níže následuje popis každé jednotlivé instrukce, její operační kód, přehled povinných parametrů a také rozklad instrukce na mikroinstrukce z řídící ROM procesoru. Jak bylo uvedeno v popisu sequenceru, je možné každou instrukci rozložit na maximálně 4 mikroinstrukční kroky. A díky fíglu s vnucenou NOP instrukcí se většina instrukcí dá popsat jen dvěma mikrokroky s tím, že zbylé dva se realizují vnucenou instrukcí NOP. Vyjímkou je samotná NOP, dále instrukce skoků (JMP, JC a JZ) a instrukce SEF a CLF. Vzhledem k tomu, že nejnižší bit čítače mikroinstrukcí v sequenceru je na začátku každéno instrukčního cyklu automaticky vynulován, musí každý mikroinstrukční cyklus začínat na sudé adrese mikroinstrukční PROM (A0=0). Drtivá většina instrukcí tedy vystačí se zápisem dvou mikrokroků. Má-li instrukce jen jeden, resp. tři mikrokroky, v paměti ROM jsou jim stejně vyhrazeny 2 resp. 4 pozice a ta poslední je prostě nevyužitá. Zdá se to jako plýtvání místem, ale jinak to nešlo a úspora místa pomocí vnucení instrukce NOP je daleko větší. Význam mikroinstrukcí byl popsán na předešlé stránce.


NOPMOV BALDALDB
ADD ABXOR ABIN AOUT A
JMPJCJZCLF
SEF   


NOP - No Operation. Žádná operace. Nezdá se to, ale je to jedna z nejdůležitějších instrukcí mikroprocesorů:-) Proto i v tak omezeném instrukčním souboru, jaký Claudia Lite bezpochyby má, má instrukce NOP své místo. Instrukce pouze inkrementuje programový čítač a vyzvedne z paměti další instrukci pro zpracovnání. Rozklad NOP na mikroinstrukce je následující:

/PLONK + /INCA
/MEMRD + LIR2 + /LIR

Operační kód: 00h (adresa v řídící ROM je 00h)
Parametry: žádné


MOV BA - Move data from A to B. Zkopírování dat z A registru do B registru. Následně se skočí na mikroinstrukční cyklus NOP, který inkrementuje programový čítač a vyzvedne z paměti další instrukci pro zpracování. Zápis BA odpovídá zavedenému standardu Intel, kdy se u instrukcí přesunu dat nejprve uvádí cíl (B) a pak zdroj (A). Rozklad MOV BA na mikroinstrukce je následující:

/ARD + LB + /NOP + /LIR
(NOP)

Operační kód: 01h (adresa v řídící ROM je 02h)
Parametry: žádné


LDA - Load Directly A-register. Přímé nahrání konstanty do registru A. Instrukce převezme data bezprostředně následující za operačním kódem instrukce a vloží je do A registru. Instrukce ovlivňuje i stav příznaku Z. Ten se nastaví na HIGH, je-li do registru A zapisována nula. Jsou-li zapisovaná data nenulová, Z se vynuluje. Následně se skočí na mikroinstrukční cyklus NOP, který inkrementuje programový čítač a vyzvedne z paměti další instrukci pro zpracování. Rozklad LDA na mikroinstrukce je následující:

/PLONK + /INCA
/MEMRD + LA + /NOP + /LIR
(NOP)

Operační kód: 02h xxxx (adresa v řídící ROM je 04h)
Parametry: data (1x nibble)


LDB - Load Directly B-register. Přímé nahrání konstanty do registru B. Instrukce převezme data bezprostředně následující za operačním kódem instrukce a vloží je do B registru. Následně se skočí na mikroinstrukční cyklus NOP, který inkrementuje programový čítač a vyzvedne z paměti další instrukci pro zpracování. Rozklad LDB na mikroinstrukce je následující:

/PLONK + /INCA
/MEMRD + LB + /NOP + /LIR
(NOP)

Operační kód: 03h xxxx (adresa v řídící ROM je 06h)
Parametry: data (1x nibble)


ADDC AB - Add data from A+B with Carry. Provede součet dat z registrů A a B a příznaku C a výsledek vloží do registru A. Instrukce ovlivňuje příznaky C a Z. Před jejím použitím je možné příslušně upravit hodnotu příznaku C instrukcemi SEF či CLF. Následně se skočí na mikroinstrukční cyklus NOP, který inkrementuje programový čítač a vyzvedne z paměti další instrukci pro zpracování. Rozklad ADDC AB na mikroinstrukce je následující:

/ADDRD + LA + /NOP + /LIR
(NOP)

Operační kód: 04h (adresa v řídící ROM je 08h)
Parametry: žádné


XOR AB - Data from A XOR B. Provede logický XOR dat z registrů A a B a výsledek vloží do registru A. Instrukce ovlivňuje příznak Z. Ten se nastaví na HIGH, je-li do registru A zapisována nula. Jsou-li zapisovaná data nenulová, Z se vynuluje. Následně se skočí na mikroinstrukční cyklus NOP, který inkrementuje programový čítač a vyzvedne z paměti další instrukci pro zpracování. Rozklad XOR AB na mikroinstrukce je následující:

/XORRD + LA + /NOP + /LIR
(NOP)

Operační kód: 05h (adresa v řídící ROM je 0Ah)
Parametry: žádné


IN A - Input data to A. Nahrání dat ze vstupního portu se spínači do A registru. Instrukce přečte stav spínačů na vstupním portu a data vloží do A registru. Instrukce ovlivňuje i stav příznaku Z. Ten se nastaví na HIGH, je-li do registru A zapisována nula. Jsou-li zapisovaná data nenulová, Z se vynuluje. Následně se skočí na mikroinstrukční cyklus NOP, který inkrementuje programový čítač a vyzvedne z paměti další instrukci pro zpracování. Rozklad IN A na mikroinstrukce je následující:

/INA + LA + /NOP + /LIR
(NOP)

Operační kód: 06h (adresa v řídící ROM je 0Ch)
Parametry: žádné


OUT A - Output data from A. Zkopírování dat z A registru do výstupního portu OUT. Následně se skočí na mikroinstrukční cyklus NOP, který inkrementuje programový čítač a vyzvedne z paměti další instrukci pro zpracování. Rozklad OUT A na mikroinstrukce je následující:

/ARD + LOUT + /NOP + /LIR
(NOP)

Operační kód: 07h (adresa v řídící ROM je 0Eh)
Parametry: žádné


JMP - Jump. Nepodmíněný skok. Instrukce provede skok na zadanou adresu v programové paměti. Bezprostředně za operačním kódem instrukce se musí nacházet cílová adresa skoku. Následně je vyzvednuta z nové adresy v paměti další instrukce pro zpracovnání. Rozklad JMP na mikroinstrukce je následující:

/PLONK + /INCA
/MEMRD + /JP
/MEMRD + LIR2 + /LIR

Operační kód: 08h xxxx (adresa v řídící ROM je 10h)
Parametry: cílová adresa skoku (1x nibble)


JC - Jump if C. Podmíněný skok podle příznaku C (carry). Instrukce provede skok na zadanou adresu v programové paměti za předpokladu, že příznak C je nastaven (HIGH). Není-li příznak C nastaven (LOW) provede se pouze (2x) inkrementace programového čítače a pokračujeme další instrukcí následující za JC. Bezprostředně za operačním kódem instrukce se musí nacházet cílová adresa skoku. Následně je vyzvednuta z nové adresy v paměti další instrukce pro zpracovnání. Rozklad JC na mikroinstrukce je následující:

/PLONK + /INCA
/MEMRD + /JC
/MEMRD + LIR2 + /LIR

Operační kód: 0Ah xxxx (adresa v řídící ROM je 14h)
Parametry: cílová adresa skoku (1x nibble)


JZ - Jump if Z. Podmíněný skok podle příznaku Z (zero). Instrukce provede skok na zadanou adresu v programové paměti za předpokladu, že příznak Z je nastaven (HIGH). Není-li příznak Z nastaven (LOW) provede se pouze (2x) inkrementace programového čítače a pokračujeme další instrukcí následující za JZ. Bezprostředně za operačním kódem instrukce se musí nacházet cílová adresa skoku. Následně je vyzvednuta z nové adresy v paměti další instrukce pro zpracovnání. Rozklad JZ na mikroinstrukce je následující:

/PLONK + /INCA
/MEMRD + /JZ
/MEMRD + LIR2 + /LIR

Operační kód: 0Ch xxxx (adresa v řídící ROM je 18h)
Parametry: cílová adresa skoku (1x nibble)


CLF - Clear Flags. Nulování příznaků. Instrukce nastaví příznaky C a Z na LOW. Současně s nulováním se inkrementuje programový čítač a v následujícím kroku se vyzvedne z paměti další instrukce pro zpracování. Rozklad CLF na mikroinstrukce je následující:

/CLF + /INCA
/MEMRD + LIR2 + /LIR

Operační kód: 0Eh (adresa v řídící ROM je 1Ch)
Parametry: žádné


SEF - Set Flags. Nastavení příznaků. Instrukce nastaví příznaky C a Z na HIGH. Současně s nastavením se inkrementuje programový čítač a v následujícím kroku se vyzvedne z paměti další instrukce pro zpracování. Rozklad SEF na mikroinstrukce je následující:

/SEF + /INCA
/MEMRD + LIR2 + /LIR

Operační kód: 0Fh (adresa v řídící ROM je 1Eh)
Parametry: žádné



Poznámka: pokud by někomu moc chyběla instrukce HLT z původního PIPa-2, nemusí zoufat. Lze ji v programu nahradit skokem na sebe sama (JMP $). Procesor sice běží, ale ve skutečnosti stojí na jedné adrese. Můžeme to využít jako testovací breakpoint a pokud ho budeme chtít odstranit, stačí jej nahradit dvěma instrukcemi NOP. Ale myslím, že režim krokování (STEP) je výhodnější, než HLT. Pro praktickou práci s Claudií Lite je vhodné mít po ruce instrukční soubor v přehledné tabulce. Třeba takovéto:


Instruction set summary



Proč 13x4=32 a né 52?

A nyní slíbené vysvětlení, proč považuji nacpání 13 mikroinstrukčních sekvencí do 32 pozic paměti 74188 za malý zázrak. Původní PIP-2 měl 6 instrukcí a využíval jen polovinu (16 pozic) z 74188. Mých 13 instrukcí ve 32 pozicích tedy nevypadá bůhvíjak zázračně. Jenže... Instrukce HLT u PIPa-2 vyžaduje jen 1 mikrokrok, kterým se vše zablokuje. Zbývá 5 instrukcí na 15 pozic PROM. To jsou v průměru 3 mikrokroky na instrukci. A to je žůžo labůžo. Většině instrukcí 3 mikrokroky stačí. Jiné potřebují jen 2 a jiné zase 4. Tím se to tak nějak vše vykompenzuje a v pohodě se to vleze do celkových 15 mikrokroků. Klíčové je, že seguencer může skákat na sudou i lichou adresu PROM.

Pokud chci použít 32 pozic z PROM, musím původní 4-bitový operační kód instrukce nějak "nastavit" o jeden bit na 5 bitů. Nejjednodušší je nastavit jej "nulou" vždy, když dochází k přepisu operačního kódu z pomocného IR* do hlavního IR (který zároveň obsahuje čítač mikroinstrukcí). Tím ale můžu skákat jen na sudé adresy v PROM a tedy 3-krokovým instrukcím musím vždy vyhradit 4 mikrokroky! A protože 13x4=52 pozic, tak nacpat to do 32 pozic prostě zázrak je:-) Je ale fakt, že některé instrukce vystačí jen se 2 mikrokroky, takže to není úplně 52, ale je to rozhodně víc, než 32. Kapišto? :-)

Řešení hádanky je jednoduché. Většina instrukcí má poslední 2 mikrokroky shodné s instrukcí NOP. Je tedy zbytečné tyto 2 (pořád stejné) mikrokroky do PROM zapisovat několikrát. Stačí jednou. Pak se provede pouze odlišná část pro každou instrukci (na to 2 mikrokroky stačí vždy, ale většinou jen jeden) a instrukční cyklus se dokončí automatickým skokem na sekvenci instrukce NOP. Ale to se pořád opakuju. Já to s tou výukovostí asi přeháním...:-)


A nyní se již můžeme podívat, jak sestavit jednoduché výukové prográmky.


Mikroinstrukce

Programy


RET



Odladěno na MS IE 8.0 a Firefoxu při rozlišení min. 1024 x 768 pixelů
www.NOSTALCOMP.cz    2010  -  2019