Jak se objevují strojové instrukce

Radek Štěrba

Zdeněk Burian mě požádal, abych napsal něco málo o objevitelské činnosti, kterou jsme prováděli s R.Petruželou na jedné ze schůzek Atariklubu.

Jakožto jeden ze skupiny vývojářů emulátoru Atari800 pro "vyšší" počítače jsem řešil problém s neoficiálními instrukcemi procesoru 6502.

Co to vlastně je?

Jak známo, na 8-bitů lze udělat 256 kombinací, a tedy zákonitě existuje celkem 256 strojových instrukcí. V různých příručkách o assembleru 6502 však najdete popisy jen těch oficiálních. O těch ostatních se tak nějak moc nemluví, protože nejsou "čisté". Provádějí většinou více různorodých akcí najednou a nalézt pro ně využití je mnohdy obtížné.

Vezměme například instrukci LAX.

Ta naplní současně akumulátor i X-registr příslušnou hodnotou. Lze ji tedy bez problémů nahradit dvěma klasickými instrukcemi LDA a TAX.

LAX adresa 
= 
LDA adresa
TAX

Existují ale i mnohem komplikovanější. Takovým hezkým příkladem opravdu složité instrukce je OAL.

Ta provede ORA akumulátoru a hodnoty $EE, pak AND s pamětí a nakonec TAX. Je to tedy velmi zajímavá složenina:

OAL hodnota 
=
ORA #$EE
AND hodnota
TAX

Soupis všech neoficiálních instrukcí se v literatuře většinou neobjevuje. Začátečníky by to zbytečně mátlo a při klasickém programování tyto instrukce nepotřebujete. Jakmile se však stanete zkušeným "assembleristou" a dostanete se k tvorbě něčeho náročného, kde by výpočetní síla Atárka nemusela stačit, mohou být elegantním řešením.

Softwareové emulátory Atari pro PC (atd.) dříve většinou neměly tyto instrukce zabudovány, a to způsobovalo nefunkčnost programů, které je používaly. Mezi jinými se jednalo např. i o mého Naturixe, ve kterém jsou obsaženy hned dvě takové (LAX a AXS).

Tak jsem se rozhodl to napravit.

Soupis neoficiálních instrukcí doma mám, tak jsem jednu po druhé doprogramovával do emulátoru (je napsán v jazyce C). Přitom jsem ale narazil na problém - čtyři instrukční kódy nebyly nikde popsány. Co teď? Nastupuje pravá badatelská činnost.

Jak se zjišťují neznámé instrukce?

Představte si, že znáte jen kód instrukce a chcete zjistit co dělá. Zamyslel jsem se nad tím a stanovil následující strategii:

    zjistit délku instrukce zjistit adresní mód dle vstupů a výstupů zjistit činnost

1. Délka instrukce

To je celkem jednoduché. Napíšete si následující prográmek:

ZACATEK
  .BYTE kód
  BRK        ;1.
  BRK        ;2.
  BRK        ;3.
  BRK        ;4.

Pak skočíte na ZACATEK a podle toho, kde došlo k přerušení instrukcí BRK, odvodíte délku instrukce. V paměti je:
kód,0,0,0,0
Některé z nul budou pochopeny jako parametry instrukce. Pokud se tedy program přeruší např. na třetím BRK, je jasné, že má 2 bytový parametr.

2. Adresní mód

Pokud instrukce nemá parametr, může jít jen o módy:

Pokud má instrukce 1 bytový parametr:

Pokud má 2 bytový parametr:

K tomu poslouží program:

ZACATEK
  LDA #5
  STA $0000
  LDA #6
  STA $0002
  LDA #7
  STA $0003
  CLS
  CLD
  CLI
  CLV
  LDA #1
  LDX #2
  LDY #3
  .BYTE kód
  .BYTE 0   ;1 byte parametr
  BRK

respektive bez parametru nebo

  .WORD 0   ;2 byte parametr

Opakovaně spouštíme program a vždy po proběhnutí sledujeme výsledný obsah registrů, příznakového registru, ukazatele zásobníku, případně obsah adresy 0000, 0002 a 0003. Při nejasnostech obměňujeme počáteční hodnoty A, X, Y a počáteční obsah adres 0000, 0002 a 0003 nebo příznakového registru. Logickou dedukcí musíme dříve či později objevit, které hodnoty se mění a v závislosti na jakých, a tím pádem adresní mód. Zda se nám to podaří záleží čistě na zkušnostech a důvtipu.

3. Činnost instrukce

V druhém bodu jsme přesně zjistili adresní mód. Víme tedy, které registry či adresy jsou vstupní a které výstupní. Provádíme opakované spouštění programu (jako v bodě dva) a vstupní hodnoty postupně zvyšujeme po jedné od 0 alespoň do 15. Sledujeme výstupní hodnoty a všechno si zakreslujeme na papír do tabulky. Hodnoty si poznačujeme v HEX i v BIN soustavě.

Potom se dlouze zadíváme na papír a snažíme se objevit nějaké souvislosti vstupů s výstupy. Uvažujeme o součtech, odpočtech, logických funkcích (AND, OR, EOR) atd. Úspěch je podmíněn opět jen zkušenostmi, důvtipem a trochou štěstí.

Nám se to podařilo.
Rozluštili jsme čtyři nikde nepopsané instrukce, z nichž jedna je přímo nádherná. Nazvali jsme ji AXA a posuďte sami, co všechno najednou udělá:

AXA adresa,Y
=
LDA adresa,Y
AND #$FD
TAX
a ještě nastaví ukazatel zásobníku na hodnotu obsahu akumulátoru - 4.

Díky tomu jsem pak mohl i tyto čtyři instrukce doprogramovat do emulátoru, čímž se stal jako první na celém světě emulátorem s PLNOU INSTRUKČNÍ SADOU !