Super clanek!
Jen mi to neda a musim podotknout ze 6502 neni vylepsena verze 6800 ale spis downgrade. 6800 mel 2 akumulatory, 16bitovy index registr a stack pointer a nemel tudiz omezeny stack na adresy 0×100..0×1FF jako 6502. Ale jinak byla 6502 super — jednoduchost a elegance.
Jen ten stack pointer kdyby nechali 16tibitovej a misto toho ze ji dali instrukce ASL a LSL (s ruznymi op-cody, ktere vsak delaji totez) mohli ji dat instrukci ASR. Mela jen LSR. Az mi skoro prijde ze to popletli ;) Taky BCD aritmetiku si mohli odpustit, to je vec prakticky k nicemu, ale tenkrat to byla takova moda, Z80 ji ma taky a koneckoncu to prezilo az do dnesnich AMDcek a Intelu. V 6502ce bohuzel bylo BCD reseny dost nestastne a totiz flagem. Takze instrukce ADD scitala bud binarne nebo BCD podle stavu toho flagu. Dusledkem bylo ze po vstupu do preruseni si ho clovek spravne mel vynulovat a pred RTS nastavit zpet na puvodni hodnotu, protoze hlavni program mohl mit BCD nastaveno v kteremzto pripade by nefungovala spravne aritmetika v prerusovaci rutine.
PS: Sice tvrdim ze BCD je k nicemu, ale vim ze ATARI BASIC mel pomoci BCD reprezentovany floatovy cisla. Melo to i vyhody napriklad kdyz jste napsali FOR i=0 to 1 step 0.1 tak se cyklus provedl presne 11* a nemuseli jste si lamat hlavu s tim jak dopadne zaokrouhleni. Ale to je asi tak jedina vyhoda, jinak to bylo silene pomaly a zabiralo zbytecne moc mista v pameti (float mel 6 bytu). Vzpominam ze jsem tenkrat napsal FP-aritmetiku (+,–,*, deleni uz ne to me to akorat prestalo bavit) binarne ve 4bytech a vysledkem bylo uzasne zrychleni ;)
Však taky 6502 žádné LSL neměla, měla dvojici ASL – LSR. Řekl bych, že to vycházelo z logiky toho, k jakým účelům se hlavně posuny používaly – posun vpravo hlavně k posunu horního nibblu do spodního, tzn. logický posun, posun vlevo hlavně k násobení dvěma, takže aritmetický posun (kvůli znaménku). Neřekl bych, že to popletli, jen vycházeli z praxe a tak to má IMHO být (tedy alespoň v případech, kdy nehodláte uvést technologickou novinku své doby). 8bitové indexy a SP představovalo celkem velkou úsporu a zjednodušení logiky procesoru – a o to šlo, snížit cenu co nejvíce. Vzhledem k malému počtu registrů a bohatému sortimentu adresových režimů (v tomto případě nepřímé indexace přes nultou stránku pomocí Y) to nepředstavovalo žádné zásadní omezení. Např. Z80 šla opačnou cestou – přidala 16bitové „indexovací“ registry IX, IY, ale kdo je kdy opravdu použil k indexaci, když práce s nimi trvala 19 cyklů (oproti 7 při použití BC/DE/HL)? Udělat indexovací registry zdaleka nejpomalejší ze všech – tomu zase já říkám skutečný konstruktérský přehmat.
Tez jsem to hledal, a tetelil se na dalsi 65×x chybku, ale opravdu ne. Umelo to jen shiftovat „logicky“ doleva/doprava,coz byl zrejme puvodni zamer tvurcu.
I ty dalsi chyby jsou takove chyby-nechyby, viz carry ze spodniho bytu pri fetchi argumentu jumpu, nebo wordu ze zeropage. Carry je v navrhu potvora, jeho propagace brzdi aritmetiku, a dost mozna si tak pomohli z prekerniho casovani (ze stejneho duvodu je v Atari vsude LSFR namisto „poctivych“ counteru).
No ted jsem to teda taky hledal a vypada to ze jsem leta zil v bludu. Mozna to byl jenom redundantni mnemonic-code v assembleru ATMAS-II. Jen si tak matne pamatuju ze jsem se nad tim tenkrat pozastavoval, proc ty samy veci rikaji ruzne (i kdyz vlastne maji pravdu aritmeticky posuv vpravo je totez co logicky (ve 2kovym komplementu)).
Jinak ASR dost citelne chybi, kdyz clovek dela znamenkovou aritmetiku. Jeste ze mu aspon dali ADC abych nemusel C-flag vytahovat ze status wordu rucne.
BTW: nejak nerozumim te poznamce s propagaci carry v navrhu. Pri programovani mi nikdy neprislo ze je s nim potiz. To spis to mohlo umet shiftovat o vic bitu, jenze barrel shifter zabira pomerne velkou plochu chipu, takze by nebylo moudry ho tam davat.
Tak uz vim s cim jsem si to spletl: instrukce ASL a LSL mela motorola 68000 ---- procesor se spoustou zbytecnych instrukci.
ASL ma operacni kod 1110ccc1ssm00rrr
LSL ma operacni kod 1110ccc1ssm01rrr
takze opravdu jsou to 2 ruzne instrukce ktere delaji totez. Navrhari k tomu podle me dosli tak ze zobecnili intrukce posuvu doleva a doprava na instrukci posuvu (smer se ridi tim bitem mezi ccc a ssm, 1 znamena doleva 0 doprava) a tim jim vysla tataz operace 2*. Skoda ze to s tou ortogonalizaci nedotahli do konce, misto neceho takoveho by bylo mnohem uzitecnejsi mit instrukci, ktera umi posuv podle znamenkoveho cisla (coz se lisi od jejich reseni v okamziku kdy pocet bitu o ktery se bude posouvat je specifikovan registrem).
Ta uspora je asi 80 tranzistoru (jak tak koukam do schematu). Celkove jich je tam neco kolem 4k az 5k, takze to uz tam fakt mohli dat. Jinak zasadni omezeni to predstavuje, pokud chcete rekurzi hlubsi nez 128 zanoreni (a spis min kdyz mate povoleny preruseni), musite si stack delat sotwarove. S pouzitim 8bitovych index-registru je to fakt lahudka (muzete sice si v zero-page zridit 2bytovy pointer a ten pak pouzivat jako neprimou adresu, ale to zase trva tech 6 taktu nebo tak nejak — jen ho pouzit, pak ho jeste musite decrementovat).
Me osobne se osvedcilo, kdyz jsem potreboval indexovat vic nez 256 bytu nekde v kratkem cyklu udelat ten kod sebemodifikujci, a cist *(pevnaadresa+X) kdyz X preteklo tak se inkrementovala pevna adresa ktera byla soucasti instrukce. Ovsem je to uz takovy hackovani a na implementaci stacku se to beztak moc nehodi.
Jinak Z80 nemela 2fazovy hodiny jako 6502, takze se zdalo ze jakoby bezi na 2* vetsi frekvenci a vsechno trva 2* vic taktu.
jj, to je pravda, pro hlubsi rekurzi muze byt zasobnik v prvni strance maly. Ale porad lepsi nez 8 nebo 16urovnovy zasobnik z 8048 ne? :-)
Tim ze je SP pouze osmibitovy se usetrilo par taktu pri pl/ph/jsr/rts operacich, protoze se vsechno do ALU prenaselo jen jednou a na adresovou sbernici se natvrdo posilal horni bajt 0×01. Spis je mozna skoda, ze neexistovalo adresovani typu SP+offset, to se muselo resit pres index registry a podprogramy to zbytecne natahovalo.
S tim sebemodifikujicim se kodem mas pravdu, presne takove smycky jsem videl v realnych profi programech pro 6502.
btw: to me pripomina: prvni verze AutoLispu (zalozene na XLispu) povolovaly pouze 8 urovni zanoreni, coz je na jazyk zalozeny na rekurzi (spise nez na smyckach) docela vysmech.
S tim autolispem je to pravda? To si vazne nedokazu predstavit jak se v tom mohlo neco udelat. Mozna ze kdyby to bylo po tail-recursion-elimination tak treba trochu jo, ale bez toho bych takrka nemohl pracovat se seznamem delsim nez 8.
Jinak SP + offset asi nedali protoze zkratka stack byl tak malej ze cokoliv pres nej predavat stejne nemelo moc vyznam.
Pravda to je, zasobnik rozsirili tusim az mezi AutoCADem devitkou a desitkou (ale je to strasne davno, mozna to bylo 10->11) a moc se s tim skutecne delat nedalo, jen jednoduche skripty (a stejne jeste dlouhou dobu tam bylo omezeni tusim na 1000 polozek). Pravda je, ze AutoLisp mel i smycky + nejake zakladni „iteracni“ funkce typu apply a map, takze se to dalo v nekterych pripadech obejit.
No praveze to zasobnik procesoru nepouzivalo, to by nebylo omezeny na osm urovni ale treba na 32768 (u i386 v realnem rezimu). To omezeni bylo umele, stejne jako omezeni na 1000 zanoreni v pozdejsich verzich AutoLispu. Autodesk si asi neuvedomil silu toho jazyka (resp. spis spojeni Lispu s CADem), tak ho zbytecne orezal.
Abych jen doplnil, k cemu se napriklad AutoLisp dal pouzit. Vstupem byl vykres, v jehoz jedne hladine byly umisteny 2D body (namerene v terenu), u nichz byl textovy box se zapsanou vyskou – tento vykres byl vyexportovan primo z „laseroveho“ geodetickeho pristroje.
Nasledne AutoLispovsky program sahl do databaze tohoto vykresu, provedl parovani bodu s textove zapsanymi vyskami a potom pomoci dost nabuseneho algoritmu vytvoril vrstevnice (pomoci polycar). Bylo tam docela dost rekurzivniho volani, takze na starsich AutoCADech docela problem.
Ty dva mikroprocesory se daji dost tezko komplexne porovnavat kdyz si vezmes, ze se 6800 prodavala za 179 dolaru zatimco zhruba srovnatelna 6502 pouze za 25 dolaru – to je takovy rozdil, ze nebyl problem postavit cely pocitac zalozeny na 6502 za cenu samostatne 6800 nebo 8080 (viz Atarka, komouse, Apple atd.).
Takze Chuck Peddle musel setrit kde se dalo a vsechny interni sbernice tudiz udelal pouze osmibitove. Je to pekne videt napriklad pri adresovani pres dve pametove stranky, adresovani 16bitovou adresou atd., coz jsou instrukce trvajici dele – vypocet adresy musel v ALU probihat 2×.
6502 sice nema 2 akumulatory, ale zase 2 index registry a v podstate se da rict, ze prvnich 256 bajtu pameti se dalo vyuzit jako 256 osmibitovych registru (k nulte strance se pristupuje opravdu rychle a kratkymi instrukcemi), popr. 128 adresovych registru, takze zas tak velke omezeni to nebylo :-)
Tak takovýhle souboj by byl naopak hodně vyrovnaný. Záleželo by na konkrétních operacích – někde by byl lepší 6502, někde Z80. Ale tvrdit, že 6502 na 2 MHz nemá na Z80 na 4 MHz „ani náhodou“, tak to je podle mě vážně naprostý nesmysl. Např. nevím o žádné operaci 6502, která by zabrala 23 taktů, jako je tomu na Z80.
Je pravda, že bez konkrétních úloh (scroll, násobení 2 float čísel, vyreslení úsečky, apod.) se to z hlavy dá říct těžko. Někdy si to budu muset vyzkoušet. Jinak 23 taktů je extrém, pro 6502 by při poloviční frekvenci odpovídalo něco jako 12 taktů, což žádná instrukce nemá. Nicméně – logické je IX a IY registry používat pouze, když se to vyplatí. Takže zřídka :-)
No ASR se skutecne musela naprogramovat dvemi instrukcemi (nebo tremi?), ale zase se zde (a nejenom zde) mohlo vyuzit „implicitniho CMP“ – 6502 pri mnoha ALU operacich nastavovala flagy, zatimco u intel-like procesoru se muselo casteji pouzivat CMP, aby se nastavil Z, S, C apod. V tomto pripade to je tak fifty-fifty, nekdy je vhodnejsi pristup 6502 nekdy zase intelacky.
Aby to nevypadalo ze tu pomlouvam 6502. To ne! Je to muj druhy nejoblibenejsi CPU (1. je ARM, ten starej s 26tibitovym adresovanim, ale i ARM7 a ARM9 jsou jeste pekny).
Jen mi prijde ze mohli odpoustit tech nejmin 50 tranzistoru co jsem napocital ze pouzili pro BCD a misto nich dat slusnej stack pointer.