Instrukce se čtyřmi bity na operační kód umožňují již celkem velkou sadu až 16 instrukcí. Nyní, když jsme prošli návrhy s 8 a menším počtem instrukcí, musí nám těchto 16 zdá hodně. A to také je. Při umístňování instrukcí do tabulky můžeme usnadnit programátorovi život tak, že se podíváma na běžně psyný kód pro procesor s menším počtem instrukcí. Pokusíme se vyhledat často opakované vzory a těm přidělit vlastní operační kód. Takto jsem do tabulky umístnil instrukce LD
, SUB
, OR
a XOR
.
S tím jak se tabulka plnila jsem se rozhodl instrukce v ní přeskupit. Myšlenka přeskupení instrukcí je rozmístnit je tak, aby bylo možno realizovat jejich dekódování jednodušeji, s menším počtem hradel. První myšlenka byla oddělit od sebe instrukce které z paměti pouze čtou, od instrukcí které do paměti i zapisují. Takto jsem se rozhodl umístnit do prvních 8 pozic, první a do dalších 4 druhé. Je-li tedy první bit operačního kódu 0
může obvod přípravy operandu zahájit čtení operandu z paměti nezávisle na dekódování ostatních bitů operačního kódu. Vzniklo tedy rozdělení:
0... | operand=mem[a] |
1 | …; →mem[a] |
Toto jsem dále upravil po zakreslení instrukcí skoků.
0... | operand=mem[a] # load |
10 | …; →mem[a] #store, load modify store |
11 | … →PC #skoky |
Do tabulky jsem také umístnil instrukce pro zmenšení a zvětšení hodnoty v paměti (INC a, DEC a). A poté ještě i instrukce s nepřímým adresováním (LDD a, STD a). Na závěr jsem se rozhodl doplnit skoky instrukcí určenou pro programování cyklů (DJNZ)
Zůstaly mi volné dvě místa v tabulce s operačními kódy 0111
a 1111
. Do těch jsem umístnil mikdokódovanou instrukci ve stylu instrukce OPR a poslední pozici nechal volnou pro případnou další mikrokódovanou instrukci nebo pro rozšíření procesoru.
Výsledná tabulka vypadá následovně.
Tabulka 30.1. Ukázka návrhu instrukční sady
kód | zápis | popis operace |
---|---|---|
0000 | LD a | AC=mem[a]; {ZN} |
0001 | LDD a | AC=mem[mem[a]]; {ZN} |
0010 | ADD a | AC=AC+mem[a]; {CZN} |
0011 | SUB a | AC=AC-mem[a]; {CZN} |
0100 | AND a | AC=AC∧mem[a]; {ZN} |
0101 | OR a | AC=AC∨mem[a]; {ZN} |
0110 | XOR a | AC=AC⊕mem[a]; {ZN} |
0111 | OPR x | μCode CLA, CLC, CPA, CPC, ROT(Arit/Logic), ROT(Left, Right), INCA, … |
1000 | ST a | mem[a]=AC |
1001 | STD a | mem[mem[a]]=AC |
1010 | INC a | mem[a]=mem[a]+1; {CZ} |
1011 | DEC a | mem[a]=mem[a]-1; {CZ} |
1100 | JSR a | save PC; a→PC |
1101 | JMP a | a→PC |
1110 | DJNZ a | AC=AC-1; if AC!=0 then a→PC |
1111 | volné pro další rozšíření |
V nevyužitých polích mohou být mikrokódované instrukce. Ve skutečnosti taková instrukce musí být alespoň jedna. Tato pak specifikuje operace nad střadačem AC a příznakem C, (CLA, CLC, CPA, CPC). Další operace jsou rotace a posuvy (ROL,ROR,ASL,ASR). Poté doplňkové instrukce jako například zastavení procesoru, specální instrukce jako například prohození (swap) dolní a horní poloviny střadač, atd.
Uvedený příklad instrukcí je jen orientační. Instrukční sada není založena na důkladné analýze kódu a je to jen "střelba od boku". Už teď mě napadají drobná vylepšení.
Úprava LDD a STD instrukcí pro práci se zásobníkem. Tyto instrukce bych přejmenoval a předefinoval takto:
LDS | mem[a]=mem[a]+1; AC=mem[mem[a]] # POP | |
STS | mem[mem[a]]=AC; mem[a]=mem[a]-1; # PUSH |