AMD am9511A

matematický koprocesor pro osmibity



Bylo nebylo. V dobách na přelomu 80. a 90. let kdy jedna banda sviní "předávala" moc jiné bandě, tak v těchto dobách vtrhly k nám masivně počítače typu PíSí. Sice se tu stále ještě potloukalo pár zoufalců, kteří snili o tom, jak konečně seženou a ke svému beznadějně zastaralému ZX Spectru připojí třeba AYčko, či z bývalého Západu konečně legálně dovezou 8272 na FDD řadič, ale většina počítačových pošuků té doby již snila o něčem jiném. Ze spaní cumlali roh polštáře a vykřikovali jediné slovo: "koprák! koprák!". Řeč je o matematickém koprocesoru 80x87, jehož prázdná patice na motherboardu, působila jak červený hadr na býka. I já jsem cumlal a i já jsem slintal před výlohou obchodu (ano, tehdy se ještě počítače prodávaly v obchodech:-)) a upřeně pozoroval krabičku s nápisem Intel 80287 Math Coprocessor. Bohužel cenovka u té krabičky obsahovala cifru, jež nebyla daleko od cifry za celý můj tehdejší PC AT286, na který se skládala celá rodina... Sice jsem nakonec tu 80287 sehnal, ale to bylo až celkem nedávno, v rámci nostalgické vlny. Takže svůj vysněný koprák nakonec sice mám, ale už dávno nemám žádnou patici, do které bych jej zasunul. A PC AT pro mě tedy retro dlouho nebude...

Od dob cumlání polštářů uběhlo čtvrt století a mě začal v hlavě strašit opět další koprák. Již nikoliv z řady 80x87, protože ten se od dob Pentií přestěhoval přímo do hlavního procesoru a má ho tak dnes každý, ale koprák jiný, ještě starší, o kterém jsem donedávna neměl tušení. Jedná se o čipy AMD am9511, resp 9512, které dokonce licenčně vyráběl i samotný velký INTEL jako 8231 a 8232. Zkrátka 8-bitové kopráky z konce 70. let! A to se muší zkusiti!



AMD am9511A



Vysněný kopráček ke mě doputoval z Číny a měl na sobě letopočet Léta Páně 1979, ovšem první kousky se na trhu objevily již o rok dříve, v roce 1978. Vzpomínáte na celočíselnou aritmetiku ZX80 z roku 1980? Tohle umí 32-bitové operace v pevné i plovoucí řádové čárce... A má to jen 24 pinů. Datum vzniku ale nezapře už díky tomu, že kromě obligátních +5V vyžaduje ještě +12V. Ihned jsem začal přemýšlet nad způsobem testování. Pochopitelně se úlohy hostitelského počítače měl zhostit 8051, resp. mé DUINo52. Otázkou bylo s čím budu porovnávat výsledky z kopráku. To totiž znamená dělat stejné výpočty i v 8051 a to je vyšší dívčí. Nakonec jsem usoudil, že pro začátek bude stačit 16-bitová celočíselná aritmetika, kterou 9511 taky umí a která se na 8051 dá "levou zadní". Pak se může přidat 32-bit fixed point a koneckonců nějaké ty x51 knihovny na 32-bit floating point bych taky vyštrachal... Ale nepředbíhejme:-)

Co tedy am9511 vlastně umí? Jak jsem naznačil výše, umí počítat:-) Umí provádět základní celočíselné operace (sčítání, odčítání, násobení dělení) v pevné řádové čárce se 16 a 32-bitovými čísly. V obou případech je nejvyšší bit znaménkový. Umí měnit znaménko a umožňuje konvertovat čísla v plovoucí řádové čárce na 16, resp. 32 bitový integer. Dále umí provádět operace se stackem, což bude vysvětleno dále.

Ovšem pravou sílu ukazuje v oblasti pohyblivé řádové čárky, kde umí zpracovávat 32-bitová čísla. Kromě obligátních základních operací je možné umocňovat, odmocňovat a provádět základní goniometrické funkce (sínus, kosínus, deskriptíva, kdo je tu inženýr ať s námi zpívá:-)), logaritmy, atd. Samozřejmostí jsou i převody 16/32 bitových integerů na floating point.

Am9511 nemá žádné speciální registry pro operandy a výsledek. Všechny operace se provádějí nad zásobníkem čítajícím 16 bajtů. A je jen na vás, jak se na ten stack díváte. Pokud operujete s 16-bitovými čísly, musíte si stack představovat jako 8 úrovní po 16 bitech. V případě 32-bitových čísel jsou to 4 úrovně po 32 bitech. Ale fyzicky je to prostě pořád 16 úrovní po 8 bitech:-) Přímý přístup (při C/D = 0) máte jen k vrcholu zásobníku TOS (top of stack). V případě zápisu nové hodnoty ji zapisujete právě na TOS, přičemž původní TOS se přesouvá dolů na NOS (next of stack) a tak dále. Poslední hodnota je ztracena. V případě čtení přečtete vždy TOS, který se po čtení přesune na konec stacku a celý zásobník odrotuje vzhůru. Na TOS se tak dostane NOS:-) Operandy tedy postupně zapisujete po bajtech, vždy od nejnižšího po nejvyšší bajt. Nejvyšší bajt druhého operandu je tedy na pozici TOS. Při čtení je to opačně. Máte-li vloženy operandy, můžete zadat kód požadované operace (při C/D = 1). Výsledek operace je vždy zapsán na vrchol zásobníku (nejvyšší byte výsledku na TOS), přičemž zásobník odrotuje a jeden z původních operandů je zpravidla ztracen. Zde záleží na typu operace a je nutné to konzultovat s manuálem či datasheetem. Je potřeba si na to trochu zvykat, ale není to nic, co by se nedalo zvládnout.

Na rozdíl od koprocesorů 80x87, které sedí "vedle" hlavního procesoru, čtou stejné instrukce z paměti a ty které jsou určeny pro ně rovnou zpracovávají (vím, je to hodně zjednodušený popis), je am9511 klasický podružný koprocesor. Dostává příkazy od hlavního procesoru a jemu předává výsledky. Spojení s hlavním CPU je na první pohled jednoduchá klasika. Signály /RD, /WR, /CS, C/D, CLK, PAUSE (u Intelu READY), nějaké ty signály vhodné k přerušení... to zná přece každý a každý je umí propojit s tím svým milovaným mikroprocesůrkem. Jenže vono prd. Jak velký to byl omyl jsem poznal záhy.

Původní ideou bylo, že am9511 připojím k 8051 jako externí paměť a budu jej obsluhovat instrukcí MOVX s automaticky generovanými signály /RD a /WR. Jako zdroj hodin jsem použil výstup ALE z 8051, což je jediný použitelný výstup impulsů synchronních s vnitřními hodinami CPU. Je na něm kmitočet 1/6 kmitočtu vstupních hodin (krystalu) 8051. Ostatní signály jsem již obsluhoval softwarově přímým přístupem na bity portů. Jenže ono to moc nefungovalo. Nejprve jsem zjistil, že po resetu obvodu musím zařadit jedno plonkové čtení stacku, než se dostanu k TOS. Dále se ukázalo, že po provedeném příkazu čtu na nejvyšším byte TOS vždy kód příkazu, namísto nejvyššího byte výsledku (nižší byty byly OK). A za třetí mi to nechtělo násobit. Ostatní operace byly OK, ale násobení nefungovalo. To jsem již upustil od vyblikávání čísel na 8 LEDkách (i když světýlka já rád:-)) a napsal si rutiny pro zobrazení stacku na sériovém terminálu (Hyperterminálu z Windows) Jediné, co se zdálo být v pořádku, byl zápis dat do stacku.

Ihned jsem pojal podezření na časování. Něco mi říkalo, že s tím ALE jsem na něco zapoměl. A taky, že jo. Pulsy na ALE jsou pořád (pokud není SW zakázán, což defaultně není) s vyjímkou druhého instrukčního cyklu při čtení instrukcí MOVX. Tedy v době, kdy tam ty hodiny člověk nejvíc potřebuje.... OK, to vyřešíme, říkám si a signál /RD kopráku jsem připojil na /PSEN 8051 s tím, že číst budu pomocí MOVC a ALE poběží pořád. Fungovalo to. Jenže pořád stejně blbě... Po dlouhém experimentování jsem se nakonec pokorně vrátil ke studiu (což je vzdycky to nejlepší, co člověk může udělat) a kromě datasheetu (toho od Intelu, v tom od AMD je prd) jsem si pořádně prostudoval i oba User Manuály od AMD. A bylo to jasný! Am9511 je na to časování fakt hóóódně háklivej a třeba takový čtení mu trvá fakt dlouho. Ukázalo se, že potřebuju dynamicky prodlužovat trvání signálu /RD (a ideálně i /WR) podle odezvy READY (PAUSE) z kopráku. Automaticky generovaný signály z 8051 jsou prostě příliš krátké (zejména tedy ten /RD). Jenže 8051 nemá vstup READY či WAIT, aby mohl dle potřeby vkládat čekací stavy do instrukčních cyklů. Nezbylo, než tedy komunikaci řídit zcela softwarově a na MOVX/MOVC a automatické generování signálů se vyprdnout. Pochopitelně za cenu zpomalení komunikace obou obvodů, což ale pro testovací účely nevadilo. Ještě malá poznámka k "bezáčkovému" provedení 9511. U tohoto obvodu je nutné, aby každé operaci čtení/zápis předcházela sestupná hrana na /CS! To já pochopitelně původně neměl (/CS byl trvale aktivní), ale naštěstí jsem měl verzi 9511A, která toto nevyžaduje. Nicméně poslední verze testovacího SW i toto zohledňuje a měla by tak fungovat i s 9511 bez A.


    Software pro 8051 a 9511



Nakonec jsem se úplně vykašlal i na automatickou kontrolu výsledků a souběžné výpočty v 8051. Naprogramoval jsem si jakousi "kalkulačku", které provádí toto: Nejprve naplní stack 9511 předem danými hodnotami a zobrazí jej na terminálu. Pak čeká na zadání kódu operace (pouze čísla a velká písmena!), tu ihned provede a vypíše modifikovaný obsah stacku. Následně je možné zadat další kód operace. Kód FFh zajistí, že se stack naplní opět původními novými daty daty. Ověření správnosti výsledku si udělám sám v hlavě, případně pomocí skutečné hexakalkulačky (třeba té z Windows). První verze byla pro 16-bitové integer operace a konečně vše fungovalo, jak má. Ovšem pořád kromě toho násobení (instrukce 6Eh, result = lower 16 bit), kde jsem dostával chybné výsledky. U instrukce 76h (result = upper 16 bit) a všech ostatních instrukcí pro 16-bitové operace bylo vše OK.

Nakonec jsem to nechal být a pustil se do verze pro počítání s 32-bitovými čísly. Změnil jsem způsob výpisu stacku a také jeho plnění. Jinak zůstalo vše při starém. A při starém bohužel zůstalo i nefunkční násobení. Opět stejná písnička. Násobení 2Ch (lower 32 bits) nefunguje. Výsledkem jsou vždy samé FFh a nastavený příznak přetečení. Upper 32 bits (36h) šlape stejně jako všechny ostatní operace, tedy správně. Na následujících obrázcích je průběh testu am9511A s mým DUINem52:


Test am9511A
Test am9511A s 8051
Test am9511A
Test am9511A s 8051


Na závěr jsem se pustil i do počítání s plovoucí řádovou čárkou. Abych se nemusel trápit s operandy, zadával jsem je jako INT32 a interní funkcí 1Ch je převáděl na Floating Point. Když jsem potřeboval nějaké další číslo, použil jsem 1Ah, což vloží Pi na pozici TOS. Byla-li potřeba jednička, zařídil to podíl dvou Pi, nulu jsem zase získal rozdílem dvou Pi, atd. Tímto způsobem jsem otestoval snad všechny FP operace. Výsledek, jsem pak vždy převedl na INT32 (instrukce 1Eh) a porovnal s výsledkem na klasické vědecké kalkulačce. Kupodivu zde fungovalo i to násobení, což je vidět na screenshotech níže.


Test am9511A
Počáteční naplnění stacku 9511
Test am9511A
Prohození TOS a NOS



Test am9511A
Konverze TOS z INT32 na FP32
Test am9511A
Vložení Pi na TOS



Test am9511A
Vynásobení TOS a NOS
Test am9511A
Konverze TOS z FP32 na INT32


Nejprve je stack naplněn přednastavenými hodnotami (zde TOS = 7Fh, NOS = FFh, ale zkoušel jsem i plně 32- bitová čísla). Následně jsou prohozeny (instrukcí 39h) hodnoty TOS a NOS. Na TOS je tedy číslo 0FFh, které je posléze převedeno (instr. 1Ch) na Floating point (FP32). Pak je na TOS vloženo číslo Pi (instr. 1Ah). Původní TOS je přesunut na NOS. Poté jsou obě čísla vynásobena (instr. 12h) a výsledek převeden (instr. 1Eh) na INT32. Výsledek je správně: 255 x Pi = 0321h, račte si to ověřit třeba na vědecké kalkulajdě ve Windejsi:-)

Testování připravenosti kopráku na zadání dalších příkazů provádím v programu dvojím způsobem. Jednak čtením BUSY flagu ze STATUS registru 9511 a druhak testováním výstupu READY. To je pochopitelně zbytečné a postačoval by jen jeden způsob (ideálně to čtení statusu). Já střídavě testoval obojí a nakonec jsem tam obojí i ponechal...

Co se toho násobení integerů týká, tak fakt nevím. Prostě jsem na to nepřišel a nakonec se tím i přestal trápit. Netroufám si ukázat na AMD, že měli chybu v návrhu, ale zatím mě jiné vysvětlení nenapadá. Mám ty kopráky totiž dva. A oba se chovají naprosto stejně. Měl jsem zpočátku podezření na velký počet cyklů potřebných k násobení, ale u FP operací jsou počty řádově větší a funguje to dobře. Tím to není. Fakt nevím...

Přestože testy nakonec dopadly relativně dobře, kopráček am9511 mě hodně potrápil. Je to pochopitelně moje vlastní chyba. Díky zkušenostem s celou řadou jiných obvodů z té doby, jsem prostě předpokládal... A to byla ta chyba. Předpokládat se nemá. Je potřeba si to všechno hezky znova a pečlivě nastudovat. Zkratky neexistují. Ještě, že jsem nakonec upustil od připojení am9511 ke svému milovanému PMI-80. To, co vypadá jako brnkačka, se totiž mohlo proměnit v noční můru pokusů a omylů. Až v jednom manuálu jsem se totiž dočetl, že při spojení s 8080 je nutný systémový řadič 8238 namísto klasického 8228! Je mi jasné, že řada uživatelů 8080 o něm teď slyší poprvé. Já ho sice mám a testoval jsem ho v PMI, ale použít ho v tomto případě by mě fakt nenapadlo... V manuálu k 9511 je i způsob připojení k dalším populárním CPU (8085, Z80, 6800) a zejména to připojení k 8085 je opravdu chuťovka. Jsou potřeba další 2 obvody (7474 a 7402) na vnucování čekacích stavů procesoru!

Přesto jsem se nevzdal myšlenky na testování am9511 v PMI-80. Na systémovém konektoru K1 jsou všechny potřebné signály dostupné. Adresový dekodér také není třeba, protože by se využil některý z dostupných /CS2-/CS6. Akorát by to chtělo přidat ještě sériáček (8251), aby se dalo zobrazovat v rozumné formě na terminálu a též loadovat testovací program do PMI. Vše by se luxusně vešlo na Unikartu, kterých mám dost. Ale přeci jen je to nějaká ta práce, že? Ovšem věc nejdůležitější už teď vím: musí se použít 8238 namísto 8228. Ještě, že nějaký mám...



Literatura:

[1] Datasheet AMD am9511A
[2] Datasheet INTEL 8231A
[3] Am9511_Algorithm_Details (PDF)
[4] Am9511A-9512FP_Processor_Manual (PDF)



RET



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