HRA

Aquanaut
Herní styl H. Scrolling
Multiplayer Bez multiplayeru
Rok vydání 1988
Programátor (Unknown)
Grafik (Unknown)

INTRO

Ilegální instrukce C64

Po letech jsme se s Sadem vyheverovali a stvořili malý společný produkt - příspěvek do soutěže, kde produkty měly nevázaně prezentovat použití ilegálních instrukcí na C64. Na tuto problematiku jsem párkrát nahlédl a tak se rozhodl napsat o tom i pár řádků. Ta je celkem detailně zpracována a dostupná na internetu (v angličtině), např. na stránkách německé demoskupiny The Dreams, nebo na studnici kódování C64 Codebase. Ovšem pro ty zástupy českých C64 koderů snad ani žádný článek v češtině nikdy nevyšel, proto jsem přišel se svojí troškou na haldu. Nemám ambice toto téma obsáhle zpracovat, nýbrž jen popsat několik technik, kde je použití těchto instrukcí možné. Nejedná se o efekty, které jsou bez ilegálních instrukcí nedostupné, ale využití je například v 1.kilových intrech, kde se v paměti vyskytuje napnelismus (ušetří se pár Bytů), nebo u precizních raster efektů (a podobně časově kritických rutin), kde tak lze ušetřit nějaký cyklus.

Na začátek připomenu dvojici instrukcí, které nepatří mezi ilegální, ale opomíjené regulérní. Bez problémů je možný tento zápis:

LDX $2000,Y

Stejně tak i tento:

LDY $2000,X

Není nutné tedy psát něco takového:

LDA $2000,Y
TAX

Bohužel, takováto instrukce již neexistuje, ani mezi ilegálními:

STX $2000,Y

Mezi nejpoužitelnější ilegální instrukce se řadí ALR, která udělá AND a poté LSR. Zde je příklad použití, jak to může vypadat bez a se zmíněnou instrukcí:

	LDA $2000
	AND #%11111000
	LSR
	LSR
	LSR
	LDA $2000
	ALR #%11111000
	LSR
	LSR

Velmi podobná instrukce ARR dělá AND a ROR. Obdobného ražení (kombinace logické funkce a bitového posunu) je několik dalších instrukcí, například jedna z těch použitelnějších je ASO, která dělá ASL a ORA.

Šikovná instrukce je také LAX, která dělá to stejné, jako LDA a TAX (tedy naplní A a X stejnou hodnotou - najednou). Pokud tato instrukce přistupuje do paměti, např. takto, je její používání bez problémů:

LAX $2000

Dokonce jí lze indexovat pomocí Y. Ale pokud má přímo naplnit registry procesoru A a X, jedná se o nestabilní instrukci. Tento zápis je možný, ale s nepředvídatelným výsledkem:

LAX #$05

Instrukcí, ke které je možné také najít využití, je i SBX. Provede AND mezi A a X a poté od X odečte zadanou hodnotu. Pokud potřebujeme od X odečíst nějakou hodnotu, můžeme to zapsat dvěma způsoby:

	TXA
	SEC
	SBC #$18
	TAX
	LDA #$FF
	SBX #$18

Nebo pokud prostě potřebujeme udělat s hodnotou v X logický AND, můžeme napsat toto:

LDA #%00000111
SBX #$00

SBX lze vhodně kombinovat s LAX, např.:

	LDA $2000
	SEC
	SBC #$18
	TAX
	LAX $2000
	SBX #$18

Instrukce DCP dělá DEC a po něm CMP. Využít se dá tam, kde potřebujeme snižovat hodnotu a kontrolovat, zda doběhla do konkrétní hodnoty (jiné než 0):

  - DEC $2000
    LDA $2000
    CMP #$18
    BNE -
    LDA #$18
 -  DCP $2000
    BNE -

Instrukce ISC dělá INC a s jeho výsledkem SBC. To je možné využít tam, kde potřebujeme od nějaké hodnoty jednomu číslu přičítat jedničku a druhému jí odečítat. V tomto příkladu pojede jeden sprite doleva a druhý stejně rychle doprava:

     -  LDA #$50
        SEC
        ISC $D002
        STA $D000
        JMP -

Jako poslední použitelnou zmíním instrukci SAX. Ta zapíše do paměti hodnotu AND mezi A a X. Údajně dělá to, že na sběrnici v jeden moment zapíše A i X a pouze bity s hodnotou 1 v obou registrech mají i ve výsledku hodnotu 1. Zápis je možný např. takto:

SAX $2000

Použitelná je například pro nějaké jednoduché textury, kdy se v registru A uchovává podklad a přes X se dělá maskování. Bohužel není možné použít u této instrukce dvě nejběžnější indexování - přímé, ani nepřímé Y přes nulovou stránku. Tento potencionálně velmi zajímavý zápis není možný:

SAX $2000,Y

Možný je pouze s jednobytovou adresou (v zeropage), existuje také verze s nepřímým indexováním X:

    SAX $20,Y
    SAX ($FF,X)

Na C64 existuje několik ilegálních instrukcí, které jsou popisovány jako nestabilní. Např. instrukce XAA, která kdyby pořádně fungovala, by do A uložila výsledek AND mezi X, A a zadanou hodnotou:

XAA #$50

Při pátrání, co je vlastně míněno jako nestabilní instrukce, jsem narazil na tuto stránku, kde je XAA podrobena zkoumání, včetně testu na různých verzích procesoru (nejen C64).

S výslednou hodnotou této instrukce se ještě nakonec provede AND s číslem, které je na té stránce pojmenováno jako "magic". Toto magické číslo se liší dle verze procesoru a navíc na některých procesorech není pokaždé stejné. Takže zhruba toto je možné si představit pod pojmem "nestabilní instrukce".

LHS

Nový příspěvek k článku

podpis :
První znak podpisu musí být vykřičník, jinak se příspěvek neodešle (ochrana proti spamu)

06.06.2016 - Ray

Moje oblibena je $fc, xskip 2 bajtyx (resp. neco ala lda/bit ale neulozit vysledek). Zatim se mi nestalo, ze by nekde nefungovala, narozdil od jinych, ktery nebehaji vsude. Typuju, z podobnosti s bit ($2c), ze to bude prave bit bez vysledku. Nekdy se to hodi :)

04.06.2016 - LHS

Ten obrázek je z filmu Karate Cop (neviděl jsem ho).

03.06.2016 - F6

Instrukce JAM je opravdu delikátní. Jinak co znamená vyheverovat? Nějaké kladenské nářečí? A z čeho je ten obrázek v článku?

Advert

Hardcode and datamining by PCH of UNREAL, Hardware guru by RAY of UNREAL, Bugs report by SILLICON of UNREAL
UNREAL 2014-2021 Czech republic