Ad Počítač má prázdnou paměť, černou obrazovku, a CPU stojí na adrese 0×0000.
:
V dôsledku čoho stojí? Zdroj taktu predpokladám beží, očakávateľné by bolo, že sa bude snažiť dekódovať a vykonávať inštrukcie, zodpovedajúce hodnotám v neinicializovanej RAM (neviem či v tomto prípade 0x00, 0xFF, prípadne nedefinovaný obsah), väčšina CPU v takomto prípde fungovala ako nejaký druh čítača, cyklicky prechádzajúceho adresový priestor. Alebo je defaultne v nejakom statickom režime, s explicitným krokovaním externým signálom?
V dôsledku čoho stojí?
CPU má vstupní signál Run, kterým se spouští běh programu. Tento signál je nastavován z CDI (řídicí a ladicí rozhraní), ovládaného přes sériový port z debuggeru běžícího na hostitelském počítači. Normální postup je takový, že se příkazem debuggeru load nahraje do paměti program a následně se spustí příkazem execute, který prostřednictvím CDI nastaví signál Run CPU.
Toto je taka vyssia nerdska :)
Tak 13 rokov dozadu som podobnu "koninu" spravil tiez. Mali sme hotovy a battle-tested hardware postaveny na 8-bite, ktory neslo rozsirit o dalsiu FLASH ani RAM ale software nam zacal z procesora statocne vytekat.
Problem bol tak trocha v tom, ze vtedajsie prekladace C-cka nerobili uplne uzasnu robotu a binarky boli velke.
Na HW sme ale mali (kto ho vie preco) prilepenu sialene velku FRAM. Ta ma sice obmedzeny pocet zapisov, ale to cislo je tak velke, ze pre vsetky prakticke ucely sa da povazovat za neznicitelnu.
A mna nenapadlo nic lepsie, nez ten povodny problem poriesit tak, ze som si vytvoril architekturu 8-bitoveho pocitaca, vytvoril na nu virtualnu masinu a napisal pre to assembler a prekladac C-cka.
Kedze od zaciatku bolo planovane, ze ta architektura bude bezat ako virtualizovana, s hradlami ani s VHDL sme sa nehrali. VHDL dokonca ani neovladam a nemam zaujem sa ho ucit, to s radostou prenecham inym.
Ciel bol tiez jasny: co najjednoduchsi beh C-ckoveho kodu. Takze instrukcna sada sa prakticky doslova nasila na mieru prekladacu C.
Zobrali sme zoznam toho, co vie C, vydestilovali z toho operacie na urovni "hardware-u" a z toho vytvorili instrukcnu sadu. Po par iteraciach, zlucovani, preriedovani a rozsirovani z toho vypadlo 21 instrukcii.
Pre tie sa nasledne spravil encoding do 16-bitoveho fixed-width formatu.
Vznikla z toho virtualka, ktora bola implementovana v jednej 130 riadkovej C-ckovej funkcii a mala zopar callbackov.
Aký mal byť kľúčový benefit (oproti prekladu dotyčných C zdrojákov priamo do strojového kódu underlying architektúry natívnym prekladačom), aby to odôvodňovalo investíciu do vývoja takejto proprietárnej vrstvy abstrakcie spolu s custom prekladačom – a hlavne utrasenie toho celého do stavu vhodného na produkčné nasadenie? Len čisto vyššia hustota "bajtkódu" oproti natívnemu kódu? Performance penalizácia v dôsledku takto riešenej interpretácie neprekážala? Pôsobí to každopádne ako hodne veľký bizár a spálené človekohodiny museli byť netriviálne.
A čo sa týka FPGA a VHDL, to nie je úplne nutné, custom CPU sa dá spáchať aj z bežných TTL alebo CMOS obvodov, e.g.:
https://www.homebrewcpu.com/
https://www.ttlcpu.com/articles/4-bit-ttl-scratchbuilt-computer
Z dnesneho pohladu to bola hovadina.
Z vtedajsieho pohladu asi tomuto napadu dala zelenu kombinacia battle-tested existujuceho HW, moznost pouzit (vtedy oproti 32-bitom vyznamne lacnejsie) 8-bity a nepotreba navrhovat od 0 novy HW a moznost tymto riesenim ulavit aj tam, kde uz HW nasadeny bol, ale kvoli jeho limitom sme osekavali, alebo neimplementovali dalsie vlastnosti.
Bol som ale o 15 rokov mladsi a sprostejsi, tak som sa do toho pustil.
Jedna trivialna optimalizacia, ktora sa dala spravit a cele by to vyznamne zrychlila a zlacnila bolo proste nevymyslat novu architekturu, ale urobit emulator toho isteho jadra, ktore sme mali v CPU a vyuzit cely tech stack. Co je podla vsetkeho to, na co sa pytate.
Paradoxne, nikto na toto predtym nemyslel.
Prekvapivo to ale netrvalo sialene dlho. Iste, mnozstvo clovekohodin bolo netrivialne, ale cisto z pohladu bang for buck je napriklad taky priemerny automotive bizar o rad vacsi.