Urcte ste uz vsetci videli nejake to demo, v ktorom vsetko na
obrazovke velmi kmitalo, scrollovalo a pohybovalo sa po vseliakych
hranatych i oblych drahach a zdalo sa, ako keby to uz proste ani
nebol ZX Spektrum s jeho Z80 ale daky super vykonny pocitac s nejakym
aspon 32 bitovym procesorom. A ti z vas, ktori vedia aspon trosku
programovat v strojaku, ste (aspon v kutiku duse) tiez zatuzili nieco
take, alebo dokonca este lepsie, naprogramovat. Cielom tohto serialu
je ukazat vam nejake priklady rutiniek, ktore vyuzivaju procesor Z80
"naplno" a ktore sa zvyknu pouzivat v rychlych grafickych efektoch v
demach (a ktore tiez tvoria zaklad mojich dem). V tomto seriali budu
aj rozne moje finty, ktore som doteraz este nikde inde nezverejnil.
Tento serial som pisal hlavne pre ludi, ktori uz maju urcite skusenosti
s programovanim v strojovom kode a pripadne si uz vedia aj sami nieco
naprogramovat. Preto nebudem uvedene rutinky vysvetlovat uplne do detailov
(ako som to robil v seriali "Strojovy kod pre pokrocilych"), miesto toho
sa budem zameriavat na hlavnu myslienku a niektore najzaujimavejsie
aspekty uvedenych rutiniek. Z tohto pohladu by sa tento serial tiez
dal nazdat "Strojovy kod pre profesionalov".
Najvecsim postrachom, nocnou morou z Elm street zacinajuceho programatora
je samotna videoramka ZX Spektra, lepsie povedane jej sialene usporiadanie
(tzv. prekladana videoramka), ktore na prvy pohlad nema logiku. Verte ci
nie, aj mna to kedysi strasilo po nociach (aj ja som raz zacinal:))
Prvy bodovy riadok sa sice zacina slusne na zaciatku - na adrese #4000,
avsak dalsi riadok sa uz nenachadza tam kde by sme ho logicky mohli
ocakavat - zaciatok + dlzka prveho riadku (#4020), ale na adrese uplne
inej. Urcite si este z dob kazetovych magnetofonov pametate, ako
zaujimavo sa nahraval obrazok. Schvalne skuste spustit toto:
CLS: FOR a=16384 TO 23295: POKE a,126: NEXT a
Preco autori ZX Spektra vobec vymysleli takuto sialenu organizaciu
videoramky ? Preco sa takto zlomyselne zachovali k poctivym
programatorom ? Pozorne si vsimnite jednotlive adresy v pixelovej casti
videoramky a ake adresy im zodpovedaju v atributovej casti. Hned na
prvy pohlad sa ukaze zaujimava zakonitost: Nizsie bajty adries vsetkych
osmych bajtov v pixelovej oblasti a nizsi bajt adresy im
zodpovedajuceho atributu su rovnake ! (Rada pre tych, ktori robia v
desiatkovej sustave: skuste si tie adresy pozriet v sestnastkovej
sustave - bude vam hned vsetko jasne aj bez vypoctu.) Preco je to tak ?
Operacna pamet v nasom ZX Spektre je realizovana tzv. dynamickymi
ramkami. Tieto ramky maju okrem inych jednu specialnu vlastnost:
Ked chceme z takejto ramky precitat udaj, musime do nej po zbernici
najprv poslat nizsi bajt adresy, potom musime poslat vyssi bajt
adresy (alebo najprv vyssi a potom nizsi - pre nas to nie je teraz
podstatne) a potom nakoniec mozeme precitat udaj. Bajty adresy si ramka
v sebe pameta, preto ak chceme citat iny udaj, ktory ma povedzme nizsi
bajt adresy zhodny s predchadzajucim udajom, staci do ramky poslat
len vyssi bajt adresy. A presne tento princip vyuziva ULA v ZX
Spektre. Aby sa usetril cas a procesor bol pri pristupe do
videoramky co najmenej zdrzovany zobrazovanim, je videoramka
organizovana tak, aby ULA mohla nacitat bajt z pixelovej oblasti
a jeho atribut co najrychlejsie.
No dobre, dajme tomu, ze uz vieme preco je to tak, ale co s tym
budeme robit ? Jedna moznost by tu bola: Existuje rutinka v ROMke
ZX Spektra, ktora nam zo suradnic X,Y priamo vypocita adresu daneho
pixela vo videoramke. Tato rutinka sa nachadza na adrese #22B0,
pricom na vstupe ocakava X suradnicu v registri C, Y suradnicu v A,
a na vystupe vrati v HL adresu bajtu v pixelovej oblasti kde sa
nachadza dana pozicia X,Y. Ak by sme pouzili tuto rutinku, vobec
by sme sa uz nemuseli starat o umiestnenie bodovych riadkov v
prekladanej videoramke. Toto riesenie by sme mohli pouzit v
pripadne, ak by sa tento serial volal len "Graficke rutinky". Lenze
nas serial sa vola "Rychle graficke rutinky" a kedze rutinka na #22B0
bude pre niektore nase poziadavky pomerne pomala, skusme najst ine
riesenie.
Ponukam vam jednu specialnu rutinku, ktora sice nerobi presne to co
#22B0, ale zato nam tiez ciastocne umozni vyriesit problem prekladanej
videoramky. Rutinku som nazval "dole" - hned uvidite preco. Na
vstupe ocakava v HL adresu nejakeho bajtu z pixelovej oblasti
videoramky a na vystupe vrati v HL adresu bajtu v pixelovej oblasti,
ktory lezi hned pod tym prvym bajtom. Rutinka v podstate realizuje
posun "o jeden bod dole".
dole | inc | h |
ld | a,h | |
and | #07 | |
ret | nz | |
ld | a,#20 | |
add | a,l | |
ld | l,a | |
ret | c | |
ld | a,#f8 | |
add | a,h | |
ld | h,a | |
ret |
V dalsich castiach serialu uvidite, ze aj ked sa to mozno na prvy pohlad nezda, tato rutinka ma naozaj velmi siroke (mozno aj dlhe a bystrozrake:)) pouzitie. Napriklad nechyba v ziadnom mojom deme v ktorom sa robi nieco s pixelovou grafikou. Nabuduce si ukazeme, co to znamena "predpocitana tabulka".
Vas Busy.