ASEMBLER 6502 (cz.9)

WEKTORY NA STOS!


	Modszy i starszy bajt

   Co to jest starszy i modszy bajt, wszyscy
oczywicie dobrze wiedz, wic ja tylko tak dla
przypomnienia powiem, o co w caym tym
interesie chodzi. Commodore 64 ma procesor
omiobitowy. Za pomoc omiu tylko bitw
mona jednoznacznie (to znaczy tak, by nie
mona byo jednej komrki pomyli z inn)
zaadresowa tylko 256 komrek pamici.
Troch mato, nieprawda? Dlatego wanie
panowie konstruktorzy poszli po rozum do
gowy i wymylili, e szyna adresowa powinna
by szesnastobitowa. Od tej pory do
zaadresowania kadej komrki potrzeba a
szesnastu bitw, czyli dwch bajtw. Daje nam
to do wyboru dokadnie 65536 bajtw - czyli 64
KB, akurat tyle, ile mamy pod skorup maszyn-
ki.
   Owe bajty, ktre su do okrelenia adresu,
pewni niewtpliwie mdrzy panowie nazwali
starszym i modszym bajtem. Adres komrki
obliczamy traktujc obie komrki jako szesnas-
tocyfrow liczb zapisan w systemie
dwjkowym - bajt starszy (SB) mnoymy przez
256 i dodajemy do niego bajt modszy (MB).
Caa filozofia.
   W drug stron jest ju nieco gorzej, ale te
atwo. Bierzemy adres i dzielimy go przez 256.
Najczciej wychodzi nam jaka liczba w
przedziale od 0 do 255, a po przecinku - jaka
niepotrzebna nikomu kaszana. Kaszan t obci-
namy bez adnych skrupuw - jeszcze nikomu
nie udaa si sztuka zapisania w jednej komrce
np. 65.789463... Nasza liczba po odciciu
kaszany to gotowy ju do bezporedniego
spoycia SB. MB obliczamy za tak - od adresu
odejmujemy dwustupidziesicioszeciokrot-
no SB i po zawodach. Dla uatwienia Wam
ycia poka, jak wyglda to bdzie w BASIC-u:
 10 adres=nnnnn
 20 sb=int (adres/256)
 30 mb=adres - 256'sb
Wszystko jasne? (sprbowaoby nie by...)
   Technika modszego/starszego bajtu jest bar-
dzo szeroko stosowana w C-64. Dlatego
wanie wartaoby si z ni oswoi i zaznajomi.
Z tego prostego powodu, e - jako si rzeko -
jednym bajtem zaadresujemy najwyej pierwsze
256 bajtw (czyli stron zerow) pamici. A
porusza si tylko w 256 bajtach to troch dzi-
wny obyczaj, kiedy do dyspozycji mamy pene
64 KB.

		Wektory

   Wiadomo o tym, kto i kiedy wymyli nazw
"wektor", dawno ju zgina w pomroce dziejw.
W sumie to dobrze, bo i po co zamieca sobie
gow podobnymi dyrdymaami. Znacznie
bardziej istotne jest, co to takiego ten "wektor" i
co poytecznego mona z niego wycisn.
   Zasadniczo, wektor to adres jakiej komrki
lub procedury umieszczony ot, tak sobie w
pamici - najpierw modszy, potem starszy bajt.
Znaczenie gospodarcze wektorw jest sto-
sunkowo due - dziki nim dosownie KADY
program mona uczyni relokowalnym, po wek-
torach mona skaka, z wektorw mona
przelicza adresy komrek, ktre s nam
wanie potrzebne. Jednym z przykadw wyko-
rzystania wektorw (fuj, paskudne sowo) jest...
		
	Adresowanie porednie postindeksowane

...czyli pamitne LDA (XX), Y. XX jest tutaj
adresem komrki, w ktrej znajduje si modszy
bajt wektora. Nie trzeba (komputerowi)
dodawa, e zaraz po nim znajdzie si starszy
bajt tego wektora - to jest po prostu konieczno
wprost wynikajca z samej definicji wektora.
   Jeszcze raz: komputer bierze adres okrelony
przez wektor w komrkach XX i XX+1, dodaje
do niego zawarto rejestru Y i dopiero liczba
otrzymana po wszystkich tych przeksztaceni-
ach jest adresem komrki, z ktrej chcemy
wzi zawarto do zakumulowania w akumula-
torze.
   Skomplikowane to nieco, nieprawda? Jeli
tak, to niejasnoci wszelakie powinien rozjani
PROGRAM 1, ktry korzystajc z adresowania
poredniego postindeksowanego... nie, nie
powiem - sami sprawdcie!

Program 1

	*=10000
wektor   = $fb
	LDA #$00
	STA wektor
	LDA #$04
	STA wektor+l
	LDA #"*"
	LDY #$00
wstaw 	STA (wektor), Y
	INY	
	BNE wstaw
	INC wektor+l
	LDX wektor+i
	CPX #$08
	BNE wstaw
petla 	JMP petla

   Ju wpisane i uruchomione? Ekran peen
gwiazd? Pytacie dlaczego? To proste - wanie
uruchomilicie program, ktry najpierw wykonu-
je ptl wstawiajc do wszystkich komrek
ekranu warto $2a (42), co odpowiada kodowi
ASCII dla znaczka "*", a potem sam zaptla si
na amen w komrce $2729. To ostatnie
zaptlenie - gwoli wyjanienia - zrobiem po to
tylko, by na ekran nie powyaziy jakie
"READY.", czy "?SYNTAX ERROR", co zep-
suoby moj artystyczn koncepcj. A teraz
przeledmy szczegowo program.
   W komrkach $2710 - $2717 bierzemy
warto $00 i wstawiamy do komrki $fb, potem
bierzemy warto $04 i wstawiamy do komrki
$fc. Co nam to przypomina? Totalna wektoryza-
cja! Wemy wartoci z $fb (czyli 00) i $fc (04) i
zamiemy je miejscami, a przed tym wszystkim
postawmy symbol naszej ulubionej waluty. Co
wyszo? $0400, czyli adres pocztku ekranu.
Nastpnie do akumulatora wstawiamy warto
odpowiadajc gwiazdce, a do rejestru Y - 0.
Potem wydajemy rozkaz STA (wektor), Y. Co
robi zdyscyplinowany komputer? Wylicza sobie
warto, ktra siedzi pod adresami $fb/$fc
($0400) i dodaje do niej to, co jest w Y, czyli nic.
Do komrki o uzyskanym adresie - $0400 -
wstawia gwiazdk. Nastpnie zwiksza o 1
zawarto Y i powtarza operacj. Kiedy Y
dochodzi do 0 (przekrca licznik, jak w starym
samochodzie), zwikszamy zawarto komrki
wektor+l 0 1. Przez to wektor ten wskazywa
bdzie komrk $0500. Kiedy dojdziemy do $08
w komrce wektor+l, to znak, e dalej ju
gwiazdek wstawia nie naley - w tym obszarze
lee moe np. program w BASIC-u, ktry
moe nam by jeszcze potrzebny, a poza tym i
tak trzeba bdzie to kiedy skoczy.
   Wytumaczone. Wartaoby jeszcze doda, e
podczas uywania adresowania poredniego
postindeksowanego korzysta mona tylko z
wektorw na zerowej stronie pamici.

	
	Skakanie po wektorach

   Po wektorach mona skaka. Nie mwcie
tego nauczycielom matematyki czy fizyki, bo
jedyne, co moecie t drog osign, to widok
oczu rozszerzajcych si do rozmiarw maych
talerzykw, poza tym moe si zdarzy, e
zwolni Was wczeniej do domu "bo Krzysinek
co dzisiaj si le czuje, bredzi".
Skakanie po wektorach to idiom, znany tylko
specom od asemblera, a oznacza wykonywanie
rozkazu JMP (czyli skoku) z wykorzystaniem
jakiego wektora. Przechodzc do szczegw:
JMP ($XXXX) nie oznacza skoku do komrki
$XXXX, lecz fakt, e w inkryminowanej komrce
znajduje si wektor, ktry pokazuje, gdzie
NAPRAWD chciaby skoczy Pan i Wadca
(czyli - dla komputera - Ty). Wyprbujmy to na
przykadziku naprawd prociutkim:

Przykadzik - jako si rzeko - prociutki, wic I

Program 2

	*=10000
wektor   = $fb
	LDA #$00
	STA wektor
	LDA #$40
	STA wektor+l
	JMP (wektor)
	*=$4000
	LDA #$01
	STA $d020
	RTS

powicimy mu tylko par stw, a i tak powinno
wystarczy. Najpierw bierzemy liczb $00 i
wstawiamy j do komrki $fb, potem bierzemy
liczb $fc i odsyamy do $fc. Dziki temu wektor
$fb/$fc wskazywa bdzie adres $4000. Jeli
rzeczywicie tak jest, to skaczemy! W $4000
wstawiem wybielanie obwdki ekranu, by byo
wida, e rzeczywicie skoczylimy tam, gdzie
chcielimy, a nie - e tylko tak si nam wydaje.


	Wektory w systemie
 
   System C-64 jest do granic moliwoci uza-
leniony od wektorw. Prawie kad duperel
(sorry!) komcio robi dopiero po odwoaniu si do
jakiego wektora. Wszystko, co ma jakkolwiek
wano, idzie po wektorach - cay BASIC, prz-
erwania, obsuga dysku, obsuga magnetofonu,
RESTORE, RESET - naprawd jest tego
mnstwo.
   Wanie dziki temu C-64 ma BASIC, ktry
osobicie uwaam za jeden z najlepszych
(oczywicie o ile amigowskiego jzyka AMOS
do BASIC-a nie zaliczymy!). Cay interpreter dzi-
aa na wektorach i wcale nie odstrasza jak
Spectrum, czy Atari do robienia wasnych wersji
i przerbek jzyka. Wrcz przeciwnie, rzec
mona, e zachca. Jeden wektor gdzie indziej
i zamiast "?SYNTAX ERROR" komputer wyp-
isze "PAN SZANOWNY RACZYL OMYLI SI
W SKADNI" albo "SPADAJ GBIE" w
zalenoci od gustu i potrzeb uytkownika.


	Sw par o skokach z asekuracj

   Po wykonaniu JMP komputer nie wie, skd
skoczy i nie istnieje prosta metoda, by znale
miejsce, z ktrego skaka. Wiemy ju jednak, e
istniej skoki z asekuracj - JSR. Po JSR
mona wrci w miejsce, z ktrego wyruszal-
imy. Czyli JSR zostawia gdzie w pamici jaki
lad, po ktrym, jak po nici piknej Ariadny,
moemy powrci niczym mny Tezeusz. lad
ten jest oczywicie wektorem. Ale wektora tego
nie mona wstawi do pamici byle gdzie, bo
trudno byoby go potem znale. Nie mona te
wstawia go zawsze w jedno, okrelone
miejsce, bo co zrobimy, jeli bdziemy chcieli
skaka "pitrowo", czyli JSR po JSR? Na
szczcie w C-64 istnieje pewien obszar pami-
ci, od $0100 do $01ff, nazywany pospolicie
stosem. Zajmijmy si teraz stosem. Do JSR -
obiecuj! - powrcimy.

		Stos
to miejsce, na ktre - jak sama nazwa wskazuje
- mona zrzuca wszystko: papiery, gazy,
ksiki, czarownice - co tylko przyjdzie nam do
gowy. W komputerze jestemy nieco
ograniczeni - wstawia moemy tylko liczby, ale
za to dowolne: niech to bd adresy dwubaj-
towe, liczby, dane dla podprogramw, tymcza-
sowe wartoci czegokolwiek. Sowem co kto
chce i lubi.
   Zawarto akumulatora moemy zrzuci na
stos rozkazem PHA (PusH Accumulator on
stack - zepchnij akumulator na stos).
Wyobramy sobie, e symbolizuje to ukadanie
ksiek. Zrobilimy PHA? Zatem kadziemy na
wierzch jak ksik.
   Teraz dla odmiany chcemy zdj jak
warto ze stosu - potrzebny jest rozkaz PLA
(PuLI Accumulator from stack - cignij akumu-
lator ze stosu). Wrmy do analogii z ksikami.
Ktr ksik wemiemy najpierw? Na pewno
t, ktr pooylimy na wierzchu, czyli ostatnio.
Prba wzicia np. pierwszej pooonej ksiki
spowodowaaby zapewne zawalenie caego
stosu. W ustaleniu, ktra warto jest na stosie
ostatnia, pomaga nam SP - Stack Pointer,
wskanik stosu. Sprawdmy, jak - i czy w ogle
- stos dziaa.

	*=10000
	LDA #$01
	PHA
	LDA #$02
	PLA
	STA $0400
	RTS

    Na ekranie, jak za dawnych, dobrych czasw,
pokazaa si literka "a" odpowiadajca, jak
pamitamy, liczbie $01 wstawionej do akumula-
tora. I to pomimo tego, e potem do akumulato-
ra wstawialimy $02! Zagadk wyjaniaj
rozkazy PHA i PLA. Po woeniu do akumulato-
ra $01, jego zawarto zrzucalimy na stos. Po
wziciu $02 - cigalimy ze stosu to, co byo w
akumulatorze poprzednio, czyli $01. Ta wanie
liczba wdrowaa do $0400, co powodowao
wywietlenie "a" na ekranie.
   Nie tylko zawarto akumulatora moemy
ka na stos. Od razu dla wyjanienia dodam, e
np. rejestrw X ani Y na stos zrzuci si nie da -
tylko przez porednictwo akumulatora. Oprcz
akumulatora moemy magazynowa na stosie
stany wszystkich flag komputera -
Przeniesienia, Zera, Przepenienia etc. Suy do
tego rozkaz PHP (nie PKP!), co znaczy: PusH
Processor status register on stack, zepchnij na
stos rejestr stanu procesora.
   Rozkazem o dziaaniu odwrotnym, czyli po
ktrego wydaniu komputer ochoczo wemie ze
stosu wartoci wszystkich znacznikw, jest PLP
(PuLI Processor status register from stack -
cignij ze stosu rejestr stanu procesora). Po
wykonaniu PHP komputer zapamituje na
stosie aktualny stan znacznikw. Moe si to
nam przyda w jakim programie, np. jako
wynik oblicze (flaga Zero), ktry wykorzystamy
pniej, a tymczasem policzymy co innego, co
przecie moe le wpyn na stan naszej flagi.
Dziaa to tak:

	*=10000
	LDA #$ff
	ADC #$40
	PHP
	CLC
	PLP
	BCC zgaszony
zapalony LDA #"1"
	STA $0400
	RTS
zgaszony LDA #"0"
	STA $0400
	RTS
   
   Do $ff dodajemy $40, co, jak pamitamy, musi
zapali znacznik C (Przeniesienia). Cay rejestr
stanu (SR) zwalamy na stos. Nastpnie za
pomoc rozkazu CLC gasimy znacznik C. A
potem cigamy cay SR ze stosu. Jeli C jest
zgaszony, pokae si 0, jeli zapalony - 1.
wiadczy to bdzie o skutecznoci wydanych
przez nas rozkazw. Teraz jednak...

	Wrmy do JSR

   Obiecaem, e powiem par stw o ladzie,
jaki zostawia za sob JSR. Komputer, zanim
skoczy tam, gdzie mu kaemy, zrzuca na stos
MB i SB adresu ostatniej komrki rozkazu
skoku (ktry, jak wiemy, jest trzybajtowy). Dziki
temu po znalezieniu rozkazu RTS komputer
ciga owe wartoci ze stosu i ju wie, od
ktrego miejsca powinien dalej pracowa.
Poka to Wam na prociutkim przykadzie:

	*=10000
	JSR $4000
	*=$4000
	PLA
	TAX
	PLA
	JMP $bdcd

   Na ekranie pokae si liczba 10002. Jasna
sprawa: w 10000 siedzi $4c, czyli "JMP",
10001 - modszy bajt - $cd, a w 10002 - starszy
bajt adresu, $bd. 10002 to ostatni bajt rozkazu
JMP. Ten wanie bajt zostanie dla potomnoci
zapamitany. Od nastpnego bajtu bdzie
wykonywana dalsza cz programu. Dla
cisoci: BYABY wykonywana, gdyby nie
e liczby wskazujce ten adres leay sobie
stosie, a mymy je zdjli nie liczc si z tym,
ogupiony tym komputer moe nie znale drogi
powrotnej.
   Co jest, jak sdz, wystarczajco optymisty-
cznym akcentem, bym mg zakoczy ten
odcinek intensywnego kursu asemblera.

   Niezbyt mody, lecz cigle zdolny programator
      BARTOMIEJ KACHNIARZ


Dzisiaj poznalimy rozkazy:
PHA - przesanie zawartoci akumulatora na stos

PLA - zdjcie zawartoci akumulatora ze stosu

PHP - przesanie na stos zawartoci rejestru stanu procesora

PLP - zdjcie ze stosu zawartoci rejestru stanu procesora



SOWNICZEK

SB - starszy bajt adresu
MB - modszy bajt adresu
SR - rejestr stanu procesora

WEKTOR - adres umieszczony w pewnym
miejscu pamieci w postaci MB i SB

STOS - obszar pamici od $0100 do $01ff,
jego specyficzn cech jest fakt, e warto
wysana na stos jako ostatnia, wraca jako
pierwsza

LINPRT - procedura umieszczona w ROM
od adresu $bdcd. Jeli przed jej wywoaniem
umiecimy w akumulatorze starszy bajt, a w
rejestrze X - modszy bajt liczby, zostan one
wywietlone na ekranie w postaci liczby w
systemie dziesitnym
