C64 ASEMBLER (C64 ASSEMBLY) – LEKCIJA 7

Dobrodošli u lekciju 7 male škole programiranja u asembleru na Commodore 64.

Napomene, saveti i objašnjenja

Za poslednju lekciju smo pripremili jednu prostu video igru u asembleru na kojoj ćemo objasniti većinu naučenih asemblerskih naredbi, važne adrese i sl. Takođe ćemo uporediti dužine i brzine izvršavanja asemblerskog sa sličnim bejzik programom.

Možda će vam se na prvi pogled činiti da program ima veliki broj programskih linija u odnosu na bejzik programe iste namene ali imajte u vidu da prilikom kompajliranja mašinski kod zauzima dosta manju memoriju, a što se tiče brzine izvršavanja one su više stotina, pa i hiljade puta veće od ekvivalentnih bejzik programa (zavisno od vrste programa).

Veoma važno objašnjenje/savet za snimanje programa

Kada završimo sa unošenjem našeg asemblerskog programa (koji smo dali u današnjem primeru) i isti kompajliramo i startujemo da bi smo videli da li radi sve kako treba, ovo je način kako da radnu/izvršnu verziju direktno snimimo na disketu sa startovanjem preko programske linije u bejziku.

Prilikom kompajliranja našeg asemblerskog programa sa komandom turbo asemblera ←3 zapišimo vrednost njegove krajnje adrese / last adress (do koje memorijske lokacije se prostire).

U današnjem primeru krajnja adresa je heksadecimalna memorijska lokacija $13ee (možda kod vas ne bude tačno ova adresa pogotovu ako izvršite neke promene ili prilikom unosa teksta ispisa u programu, unesete višak ili manjak razmaka između karaktera ili znaka navoda, dodate ili oduzmete tekst i sl. što sve utiče na vrednost krajnje adrese za nekoliko bajta gore ili dole). Isto tako možemo za krajnju adresu uzeti bilo koju veću adresu (ako tako radimo onda je najbolje uzeti nekoliko bajta više od stvarne).

Preračunajmo niži bajt $ee u decimalnu vrednost gde dobijamo iznos 238, a onda i viši bajt $13 gde dobijamo iznos 19.

Ukoliko smo i dalje u turbo asembleru dajemo ←1 i prelazimo u bejzik. Kada smo u bejziku kucamo naredbu za restartovanje sistema SYS 64738.

Zatim treba otkucati bejzik programsku liniju 10 SYS adresa_početka_našeg_programa u decimalnom obliku, a u našem slučaju:

10 SYS 4096

Unesimo sada naredbu POKE 45,238 (niži bajt kraja našeg mašinskog programa), a onda POKE 46,19 (viši bajt kraja našeg mašinskog programa). Time smo sistemu rekli da želimo da prilikom snimanja memorije obuhvati memorijske adrese od početka bejzik programa $0801/2049 (u našem slučaju jedine bejzik programske linije) do kraja našeg mašinskog programa u našem slučaju $13ee/5102 (u stvari u memorijskim adresama 43 i 44 nalaze se niži i viši bajt početka bejzik programa ($0801/2049), dok memorijska adresa 45 i 46 sadrže niži i viši bajt kraja bezik programa čijom promenom njihove vrednosti na adresu kraja našeg mašinskog programa smo naterali sistem da misli da je sve ovo bejzik program).

Sada nam ostaje još da snimimo naš program na pravu ili virtualnu disketu sa sledećom naredbom:

SAVE „ime programa“,8,1 (npr.SAVE „FORMULA“,8,1)

Snimiće se memorija počev od adrese početka bejzik programske linije ($801) do kraja našeg mašinskog programa ($13ee), a kada sledeći put damo naredbu za učitavanje LOAD „FORMULA“,8,1 učitaće se bejzik programska linija koja služi za startovanje, kao i ceo naš mašinski program (naravno bez izvornog koda i turbo asemblera).

Kada se program učita ostaje nam da damo naredbu RUN i isti će se startovati (ako koristimo emulator sa direktnim pristupom na željeni program isti će se učitati i odmah startovati).

Na ovaj način možemo snimiti bilo koji mašinski program koji radimo sa startovanjem istog preko bejzik programske linije.

Važnost početne adrese smeštanja kompajliranog mašinskog programa

Mogli smo prilikom rada sa asemblerom umesto početne adrese $1000/4096 da damo i nižu adresu prevođenja i smeštanja (koja ne sme da se preklopi sa memorijskim zauzećem bejzik programa) npr.$0810/2064 čime bi smo uštedeli dosta memorije (oko 2 kilobajta) što je veoma važno kada radimo sa velikim mašinskim programima (inače bi ova memorija ostala neiskorišćena) i naravno time štedimo memoriju diskete na kojoj snimamo. Pošto je naš primer samo kratak program koji ćemo raditi na emulatoru ova ušteda nam nije bitna.

Takođe ako želimo da radimo mešanu verziju programa (jedan deo u bejziku a drugi u mašincu) preporuka je da se prvo uradi bejzik deo, vidi koliko memorije zauzima, a onda odradi mašinski deo koji će se prevesti/smestiti što je bliže moguće memorijskoj adresi kraja bejzik programa (naravno treba voditi računa ukoliko bude potrebno da se učine ispravke ili dodavanje dodatnih naredbi u bejzik programu da ne bi došlo do preklapanja programa). Kraj bejzik programa utvrđujemo kucanjem naredbe PRINT PEEK(45)+PEEK(46)*256

Uporedni pregled kompajliranog i izvornog koda asemblerskog programa

Da bi smo videli kako izgleda izvorni kod preveden na mašinski u turbo asembleru dajemo ←4 (prikaz prevođenja) gde će se pojaviti pitanje „print-file:“, a zatim kucamo „*“ (prikaz na ekranu) i pretisnimo return/enter. Kada ovo uradimo mašinski kod (u obliku adrese, koda naredbe i kodova parametra ukoliko ih naredba poseduje) prikazaće se sa leve strane ekrana u heksadecimalnom obliku, a izvorni kod će se prikazati sa desne strane ekrana i sve će se izlistati od početka do kraja programa. Listanje možemo usporiti pritiskom na control taster (tab kod emulatora).

Primer asemblerskog programiranja

A sada o samoj igri. Potrebno je svojom formulom prevesti 9 puta do kraja ekrana na dole (kada se formula pojavljuje na vrhu ekrana). Smetala su dva kvadrata koji se brzo kreću od leve do desne strane ekrana i ako se sudarite sa njime igri je kraj. Ukoliko odradite 9 kruga pobeđujete. Komadne za upravljanje biće „A“-levo,“D“-desno,“W“-gore,“S“-dole. Takođe postoji i primitivni zvučni efekat kao i ispis bodova na ekranu.

Učitajmo turbo asembler i startujemo ga sa SYS 36864. Imajte u vidu da se u turbo asembleru sve piše malim slovima ali u ovom primeru su data velika radi lakšeg snalaženja. Kucamo sledeći kod:

*= $1000

Počinjemo kompajliranje i smeštaj našeg mašinskog programa od adrese $1000 (4096) – početna adresa programa

ISPISI = $FFD2

Dajemo labeli „ispisi“ vrednost od $ffd2 koja memorijska adresa sadrži sistemski podprogram za izvršavanje petascii koda koji se nalazi u akumulatoru, potpuni ekvivalent bejzik naredbe PRINT CHR$(A) koja i koristi ovaj podprogram. Ovu labelu dajemo samo radi primera. Sve ostale bitne adrese ispisivaćemo direktno u programu

POCETAK

Mesto skoka na početak programa. Imajte u vidu da turbo asembler (kao i drugi asembleri) svako mesto skoka, podprograma, memorijske lokacije opisa bajtova ili teksta preračunava u memorijske adrese prilikom prevođenja koje će se kasnije zavisno od situacije koristiti u naredbama uslovnih i bezuslovnih skokova kao i u naredbama čitanja i smeštanja podataka.

LDA #147

Unosimo decimalnu vrednost 147 u akumulator. Ova vrednost je petascii kod karaktera za brisanje ekrana. Želimo da pokažemo da možemo unositi po želji decimalnu, heksadecimalnu ($) ili binarnu (%) vrednost u turbo asembleru i tako ćemo raditi nadalje u programu koristeći sve brojne sisteme.

JSR ISPISI

Odlazimo na sistemski podprogram koji se nalazi na memorijskoj adresi $ffd2 datoj u labeli „ispisi“ koji, kao što smo rekli, izvršava petascii kod koji se nalazi u akumulatoru, u našem slučaju ekvivalent bejzik naredbe PRINT CHR$(147) / briše ekran i postavlja kurzor na početak. Ovo smo uradili da bi smo vam pokazali da u svakom trenutku možemo iskoristiti mašinske podprograme koji postoje u sistemu računara (koji se koriste prilikom rada standardnog bejzik programa i samog sistema)

LDX #0

Učitavamo nulu u registar X koji će nam poslužiti kao brojač

JSR POCETEKRAN

Odlazak na podprogram koji nam ispisuje uputstvo na početnom ekranu i čeka da se pretisne neki taster da bi igra krenula

LDA #$93

Ponovo u akumulator unosimo petascii kod ovog puta kao heksadecimalni broj $93 (147) za brisanje ekrana

JSR ISPISI

Ponovo odlazimo na sistemski podprogram da bi smo izvršili petascii kod dat u akumulatoru

LDA #8

Unosimo u akumulator vrednost 8 koja će nam biti narandžasta boja okvira i pozadine

STA $D020

Smeštamo vrednost akumulatora u memorijsku lokaciju za boju okvira

STA $D021

Smeštamo vrednost akumulatora u memorijsku lokaciju za boju pozadine

LDX #0

Praznimo registar X. Uvek kada u akumulator ili registar unesemo vrednost nula kažemo da ga „praznimo“, „čistimo“ ili „brišemo“.

LDA #0

Čistimo akumulator.

STA $d010

Stavljamo vrednost iz akumulatora u registar koji sadrži deveti bit X kordinata sprajtova samim tim ga resetujući (ovo je potrebno kada odigramo prvu igru i želimo da odigramo novu da bi smo sprajtove vratili na početni položaj)

LDA #48

Unosimo vrednost 48 u akumulator. Ova vrednost je petascii/ekranski kod za karakter „0“ koji će nam biti brojač bodova.

STA BOD

Stavljamo vrednost iz akumulatora u BOD. Šta ovo znači? Na kraju programa smo dali naziv ove nazovimo programske promenljive (mesto čitanja i smeštanja). Pored naziva BOD u programu smo stavili komandu turbo asemblera .byte koja nam na toj memorijskoj adresi stvara bajt željene početne vrednosti koji možemo po potrebi čitati ili menjati. Nama će služiti za smeštaj vrednosti bodova u petascii kodu

JSR PRIPZVUK

Skačemo na podprogram za pripremu i reprodukciju zvuka

JSR POZADINA

Skačemo na podprogram za pripremu pozadine

JSR POZSKROL

Skačemo na podprogram za skrolovanje neprijateljskih kvadrata/smetala

LDA #0

Brišemo akumulator. Akumulator će nam kao i obično služiti za čitanje memorijskih lokacija kao i za smeštanje vrednosti na istima. Takođe će nam služiti za smeštaj ekranskog ili petascii koda u željenu memorijsku adresu i sve ostalo što nam je bitno kod manipulacije memorije (akumulator je najbitniji registar koji može neke stvari koje drugi registri ne mogu kao npr.smeštanje vrednosti na stek, prebacivanje vrednosti između registra, preindeksiranje i postindeksiranje šesnaestobitnih adresa, itd.)

TAX

Prenosimo vrednost nula iz akumulatora u registar X i na taj način ga čistimo. Ovaj registar će nam najviše koristiti kao brojač. Takođe će nam koristiti za proveru vrednosti na željenim memorijskim lokacijama. Ovde kao primer koristimo naredbu za premeštanje. Naravno mogli smo da koristimo i naredbu za učitavanje vrednosti LDX #0 za istu stvar. Obratite pažnju da smo ovim uštedeli jedan bajt jer naredba za učitavanje vuče dva bajta memorije dok naredba za premeštanje samo jedan

TAY

Premeštamo vrednost nula iz akumulatora u registar Y što znači da i njega brišemo. Koristiće nam kao drugi brojač i za potrebna ispitivanja vrednosti memorije

OPET

Mesto skoka koje će nam služiti prilikom formiranja prvog sprajta

LDA SPRAJT1,X

Čitamo vrednost sa memorijske lokacije „sprajt1“ u akumulator uvećanu za brojač registra X. U programu postoji sekcija „sprajt1“ koja se prilikom prevođenja automatski pretvara u memorijsku adresu gde je opis našeg prvog multikolor sprajta datog pomoću turbo asemblerske komande .byte (ukupno 63 bajta / 3×21)

STA 832,X

Stavljamo vrednost akumulatora počev od memorijske lokacije 832 (13 blok memorije za smeštaj sprajta 64×13) uvećano za vrednost registra X i na ovaj način prebacujemo opis prvog sprajta u blok memorije za čuvanje sprajta bajt po bajt (sve informacije o radu sa sprajtovima imate u lekciji 5 standardnog bejzika)

INX

Uvećavamo vrednost registra X za jedan koji uvećava adresu smeštanja i broji bajtove sprajta

CPX #63

Proveravamo da li je registar X dostigao vrednost od 63 koliko bajta je potrebno za opis sprajta

BNE OPET

Ukoliko nije idemo na mesto skoka/početak petlje za unos prvog sprajta dok se svaki bajt ne prebaci/kopira u memoriju koja služi za čuvanje i prikazivanje istog

LDX #0

Praznimo registar X i spremamo za unos opisa drugog sprajta

OPET2

Mesto skoka koje će nam služiti prilikom prenosa opisa drugog sprajta

LDA SPRAJT2,X

Čitamo vrednost sa memorijske lokacije „sprajt2“ u akumulator uvećanu za brojač registra X. U programu takođe postoji sekcija „sprajt2“ gde je opis našeg drugog multikolor sprajta datog pomoću turbo asemblerske komande .byte (ukupno 63 bajta / 3×21). Opis za drugi će nam poslužiti i za treći sprajt

STA 896,X

Stavljamo vrednost akumulatora počev od memorijske lokacije 896 (14 blok memorije za smeštaj sprajta 64×14) uvećano za vrednost registra X i na ovaj način prebacujemo opis drugog (koji će služiti i za treći sprajt) u blok memorije za čuvanje i prikaz istog

INX

Uvećavamo vrednost registra X za jedan koji uvećava adresu smeštanja i broji bajtove opisa sprajta

CPX #63

Proveravamo da li je registar X dostigao vrednost od 63 koliko bajta je potrebno za opis ovog sprajta

BNE OPET2

Ukoliko nije idemo na mesto skoka za drugi sprajt dok se svaki bajt ne prebaci u memoriju koja služi za čuvanje i prikaz ovog sprajta

LDA #$0D

Sada dolazimo do uključenja i početnog smeštaja sprajtova na ekranu. Unosimo vrednost $0d (13) u akumulator. Ova vrednost će objasniti sistemu u kom bloku je smešten opis prvog sprajta

STA $07F8

Smeštamo vrednost iz akumulatora u memorijsku adresu $07f8 (2040) koja daje sistemu informaciju u kom bloku je smešten opis prvog sprajta (blok 13)

LDA #$01

Unosimo vrednost 1 u akumulator. Ova vrednost će nam uključiti prvi sprajt. Ne moramo ovo raditi sada možemo na kraju uključiti sva tri sprajta ali dajemo za primer uključenja sprajt po sprajt

STA $D015

Smeštamo vrednost akumulatora u memorijsku adresu $d015 (53269) koja će nam uključiti visokorezolucijsku opciju za prvi sprajt (bit po sprajtu)

STA $D01C

Smeštamo vrednost akumulatora u memorijsku adresu $d01c (53276) koja će nam uključiti multikolor opciju za prvi sprajt (bit po sprajtu)

LDA #$71

Unosimo vrednost $71 (113) u akumulator

STA $D000

Smeštamo vrednost akumulatora u memorijsku adresu $d000 (53248) koja nam predstavlja X kordinatu za prvi sprajt

STA $D001

Smeštamo istu vrednost akumulatora u memorijsku adresu $d001 (53249) koja nam predstavlja Y kordinatu za prvi sprajt

LDA #$01

Unosimo vrednost 1 u akumulator

STA $D025

Stavljamo vrednost akumulatora (1-bela boja) u memorijsku adresu $d025 (53285) koja predstavlja prvu zajedničku multikolor boju kombinacije tačaka (01) svih sprajtova

LDA #$02

Unosimo vrednost 2 u akumulator

STA $D026

Stavljamo vrednost akumulatora (2-crvena boja) u memorijsku adresu $d026 (53286) koja predstavlja drugu zajedničku multikolor boju kombinacije tačaka (11) svih sprajtova

LDA #$03

Unosimo vrednost 3 u akumulator

STA $D027

Stavljamo vrednost akumulatora (3-svetlo plava boja) u memorijsku adresu $d027 (53287) koja predstavlja posebnu boju za prvi sprajt kombinacije tačaka multikolor sprajta (10-jedina boja kombinacije tačaka različita kod svakog sprajta). Ova adresa se takođe koristi za boju prvog sprajta visoke rezolucije

LDA #$0E

Unosimo vrednost $0e (14) u akumulator.

STA $07F9

Smeštamo vrednost iz akumulatora u memorijsku adresu $07f9 (2041) koja daje sistemu informaciju u kom bloku je smešten opis drugog sprajta (blok 14)

LDA #$03

Unosimo vrednost 3 u akumulator. Ova vrednost će nam uključiti prvi (koji je već uključen i ostaće uključen) i drugi sprajt.

STA $D015

Smeštamo vrednost akumulatora u memorijsku adresu $d015 (53269) koja će nam uključiti visokorezolucijsku opciju za prvi i drugi sprajt (bit po sprajtu)

STA $D01C

Smeštamo vrednost akumulatora u memorijsku adresu $d01c (53276) koja će nam uključiti multikolor opciju za prvi i drugi sprajt (bit po sprajtu)

LDA #$A0

Unosimo vrednost $a0 (160) u akumulator

STA $D002

Smeštamo vrednost akumulatora u memorijsku adresu $d002 (53250) koja nam predstavlja X kordinatu za drugi sprajt

LDA #$90

Unosimo vrednost $90 (144) u akumulator

STA $D003

Smeštamo vrednost akumulatora u memorijsku adresu $d003 (53251) koja nam predstavlja Y kordinatu za drugi sprajt

LDA #$05

Unosimo vrednost 5 u akumulator

STA $D028

Stavljamo vrednost akumulatora (5-zelena) u memorijsku adresu $d028 (53288) koja predstavlja posebnu boju za drugi sprajt kombinacije tačaka multikolor sprajta (10-jedina boja kombinacije tačaka različita kod svakog sprajta). Ova adresa se takođe koristi za boju drugog sprajta visoke rezolucije

LDA #$0E

Unosimo vrednost $0e (14) u akumulator. Ova vrednost će objasniti u kom bloku je smešten opis trećeg sprajta (biće isti opis kao i kod drugog)

STA $07FA

Smeštamo vrednost iz akumulatora u memorijsku adresu $07fa (2042) koja daje sistemu informaciju u kom bloku je smešten opis trećeg sprajta (blok 14)

LDA #$07

Unosimo vrednost 7 u akumulator. Ova vrednost će nam uključiti prvi i drugi (koji su već uključeni i ostaće uključeni) i treći sprajt.

STA $D015

Smeštamo vrednost akumulatora u memorijsku adresu $d015 (53269) koja će nam uključiti visokorezolucijsku opciju za prvi, drugi i treći sprajt (bit po sprajtu)

STA $D01C

Smeštamo vrednost akumulatora u memorijsku adresu $d01c (53276) koja će nam uključiti multikolor opciju za prvi,drugi i treći sprajt (bit po sprajtu)

LDA #$05

Unosimo vrednost 5 u akumulator

STA $D004

Smeštamo vrednost akumulatora u memorijsku adresu $d004 (53252) koja nam predstavlja X kordinatu za treći sprajt

LDA #$E0

Unosimo vrednost $e0 (224) u akumulator

STA $D005

Smeštamo vrednost akumulatora u memorijsku adresu $d005 (53253) koja nam predstavlja Y kordinatu za treći sprajt

LDA #$07

Unosimo vrednost 7 u akumulator

STA $D029

Stavljamo vrednost akumulatora (7-žuta) u memorijsku adresu $d029 (53289) koja predstavlja posebnu boju za treći sprajt kombinacije tačaka multikolor sprajta (10-jedina boja kombinacije tačaka različita kod svakog sprajta). Ova adresa se takođe koristi za boju trećeg sprajta visoke rezolucije

UPRAVLJANJE

Glavno mesto skoka od koga krećemo sa upravljanjem našeg sprajta (formule) i na koje ćemo se stalno vraćati u toku u programa

LDA $D01E

Učitavamo vrednost iz memorijske adrese registra detekcije sudara sprajtova. Ovde još ne radimo ispitivanje da li je došlo do sudara između njih. Problem je što detekcija sudara ima grešku (bag) i na ovaj način kada očitamo ovu adresu pre detekcije praznimo/resetujemo njenu vrednost (ne pomaže direktno unošenje vrednosti 0 u istoj / služi samo za čitanje). Ako ovo ne uradimo često će se po pokretanju nove igre odmah registrovati sudar sprajtova iako do istog nije došlo i igra će se odmah završiti porazom

JSR POZSKROL

Idemo na podprogram za skrolovanje neprijateljskih kvadrata

JSR USPORI

Idemo na podprogram za usporavanje brzine izvršenja mašinskog programa. Ovo je neophodno jer zbog velike brzine mašinskog izvršavanja dobili bismo samo mrlje prilikom kretanja sprajtova koje nebismo mogli da kontrolišemo (čak ni da vidimo u većini njihovih kretanja)

JSR ZVUK

Odlazimo na podprogram za emitiranje zvuka motora

JSR ISPIS

Idemo na podprogram za ispis broja bodova i za proveru da li je došlo do 9 prelaza formule preko ekrana čime bi smo uspešno završili igru

JSR SUDAR

Idemo na podprogram za detekciju sudara između sprajtova

LDX 197

Učitavamo u registar X vrednost sa memorijske lokacije 197 koja služi za očitavanje tastature.

CPX #10

Upoređujemo da li je vrednost X registra 10 koji broj predstavlja pretisnuti taster „A“

BEQ SMANJIX

Ukoliko jeste skačemo na mesto skoka za umanjenje X kordinate prvog sprajta/formule (kretanje ulevo)

CPX #18

Upoređujemo da li je vrednost X registra 18 koji broj predstavlja pretisnuti taster „D“

BEQ UVECAJX

Ukoliko jeste skačemo na mesto skoka za uvećanje X kordinate prvog sprajta (kretanje udesno)

CPX #9

Upoređujemo da li je vrednost X registra 9 koji broj predstavlja pretisnuti taster „W“

BEQ SMANJIY

Ukoliko jeste skačemo na mesto skoka za umanjenje Y kordinate prvog sprajta (kretanje na gore)

CPX #13

Upoređujemo da li je vrednost X registra 13 koji broj predstavlja pretisnuti taster „S“

BEQ UVECAJY

Ukoliko jeste skačemo na mesto skoka za uvećanje Y kordinate prvog sprajta (kretanje na dole)

JSR POZSKROL

Idemo ponovo na podprogram za skrolovanje neprijateljskih kvadrata (iz razloga ubrzavanja skrolovanja neprijateljskih kvadrata u odnosu na brzinu kretanje formule)

JMP UPRAVLJANJE

Skačemo natrag na mesto skoka početka upravljanja čime pravimo beskonačnu petlju dok se neki od uslova pobede ili poraza ne ispune

SMANJIX

Mesto skoka za smanjenje X kordinate prvog sprajta

DEC $D000

Umanjujemo za jedan X kordinatu prvog sprajta

LDA $D010

Učitavamo u registar X vrednost iz registra $d010 u kome se nalazi deveti bit X kordinate sprajta

AND #%0000001

Radimo logičku operaciju nad stanjem vrednosti u akumulatoru u kojoj ćemo potvrditi da li je setovan nulti bit (9 bit prvog sprajta). Kada damo naredbu AND (logičko množenje I) gde su svi bitovi osim nultog nula vrednost akumualtora će biti jedan samo ako je nulti bit već setovan

CMP #1

Proveravamo vrednost u akumulatoru. Ukoliko je 1 deveti bit je setovan važi opseg X kordinate prvog sprajta od 256 do 511 (vidljivo je do 343)

BEQ PROVERIX

Ukoliko je akumulator jednak 1 to znači da je 9 bit setovan tako da idemo na mesto skoka koje proverava kordinatu X i ukoliko je ona nula isključuje 9 bit sprajta

LDX $D000

Učitavamo u registar X vrednost iz registra $d000 kordinate X prvog sprajta

CPX #14

Proveravamo da li je vrednost u registru X jednaka 14.

BEQ STANIX

Ukoliko je vrednost X jednaka 14 idemo na mesto skoka koje će blokirati dalje kretanje formule prema levoj strani ekrana

JMP UPRAVLJANJE

Vraćamo se na glavno mesto skoka

PROVERIX

Mesto skoka za proveru da li je kordinata horizontale X jednaka 0

LDX $D000

Učitavamo u registar X vrednost memorijske lokacije $d000/53248 koja sadrži X kordinatu prvog sprajta

CPX #0

Ispitujemo da li je vrednost u registru 0 što znači da se vraćamo u zonu kontrole X kordinate prvog sprajta (0-255) pa iz tog razloga treba da isključimo 9-bit ovog sprajta (+256)

BEQ RESETUJX

Ukoliko jeste odlazimo na mesto skoka gde ćemo resetovati 9-bit prvog sprajta

JMP UPRAVLJANJE

Vraćamo se na glavno mesto skoka

RESETUJX

Mesto skoka gde će se resetovati deveti bit X kordinate prvog sprajta

LDA $D010

Učitavamo u akumulator stanje memorijske lokacije $d010 gde se nalaze 9-bit za sve sprajtove (bit po sprajtu 0-7)

AND #%11111110

Radimo logičku operaciju nad stanjem vrednosti u akumulatoru u kojoj ćemo resetovati nulti bit (9 bit prvog sprajta). Kada damo naredbu AND (logičko množenje I) gde su svi bitovi osim prvog jedinice neće biti promene stanja kod ostalih sprajtova (0*1=0 i 1*1=1) dok će se bit prvog sprajta resetovati (1*0=0)

STA $D010

Smeštamo vrednost akumulatora u memorijsku lokaciju $d010 (9-bit svih sprajtova/bit po sprajtu 0-7) i time brišemo/resetujemo 9-bit prvog sprajta

LDA #255

Unosimo vrednost 255/$ff u akumulator pošto smo poništili 9-bit prvog sprajta koji teži 256/$100 i na taj način imamo glatki prelaz pomeranje sprajta ulevo iz zone gde je bio setovan 9-bit (256+255) u normalnu zonu koju kontroliše X kordinata prvog sprajta (0-255)

STA $D000

Smeštamo vrednost akumulatora u memorijsku lokaciju X kordinate prvog sprajta

JMP UPRAVLJANJE

Vraćamo se na glavno mesto skoka

STANIX

Mesto skoka koje će blokirati dalje kretanje formule u levo

LDA #15

Unosimo u akumulator vrednost 15

STA $D000

Smeštamo vrednost iz akumulatora u memorijsku lokaciju X kordinate prvog sprajta i na taj način ne dozovoljavamo dalje pomeranje prvog sprajta (formule) ulevo inače bi se isti izgubio na levoj strani ekrana

JMP UPRAVLJANJE

Vraćamo se na glavno mesto skoka

UVECAJX

Mesto skoka uvećanja X kordinate prvog sprajta

INC $D000

Uvećavamo vrednost memorijske lokacije kordinate X prvog sprajta za jedan

BEQ SETUJX

Ukoliko smo putem uvećanja X kordinate prvog sprajta stigli do nule (0-255-0 ciklični tok uvećanja vrednost bajta) odlazimo na mesto skoka gde setujemo 9-bit prvog sprajta tako da isti može nastaviti putanju od 256 tačke.

LDA $D010

Učitavamo u akumulator vrednost memorijske lokacije stanja 9-bita svih sprajtova

AND #%00000001

Radimo logičku operaciju nad stanjem vrednosti u akumulatoru u kojoj ćemo potvrditi da li je setovan nulti bit (9 bit prvog sprajta). Kada damo naredbu AND (logičko množenje I) gde su svi bitovi osim nultog nula vrednost akumualtora će biti jedan samo ako je nulti bit već setovan

CMP #1

Proveravamo da li akumulator sadži vrednost 1 što znači da je 9-bit prvog sprajta setovan

BEQ PROVERI

Ukoliko je vrednost akumulatora jednaka jedinici skačemo na mesto skoka za proveru da li je sprajt blizu izlaska iz vidljivog okvira sa desne strane ekrana

JMP UPRAVLJANJE

Vraćamo se na glavno mesto skoka

SETUJX

Mesto skoka gde setujemo 9-bit X kordinate prvog sprajta

LDA $D010

Učitavamo u akumulator vrednost memorijske lokacije stanja 9-bita svih sprajtova

ORA #%00000001

Radimo logičku operaciju nad stanjem vrednosti u akumulatoru u kojoj ćemo setovati nulti bit (9 bit prvog sprajta). Kada damo naredbu ORA (logičko sabitanje ILI) gde je samo nulti bit jedinica a ostali nula neće biti promene kod ostalih sprajtova (0+0=0, 0+1=1) dok će bit nultog sprajta biti setovan (1+0=1)

STA $D010

Smeštamo vrednost akumulatora u memorijsku lokaciju $d010 (9-bit svih sprajtova/bit po sprajtu 0-7) i time setujemo 9-bit prvog sprajta

JMP UPRAVLJANJE

Vraćamo se na glavno mesto skoka

PROVERI

Mesto skoka provere da li je X kordinata prvog sprajta zajedno sa 9-bitom dostigla desnu ivicu ekrana

LDX $D000

Učitavamo u registar X vrednost memorijske lokacije X kordinate prvog sprajta (nemojte mešati registar X sa X kordinatom sprajta)

CPX #71

Proveravamo da li je u registar X vrednost 71 što znači da zajedno sa 9-bitom dostižemo vidljivu ivicu sprajta na desnoj strani ekrana

BEQ STANIX2

Ukoliko je vrednost u registru X jednaka 71 skačemo na mesto skoka gde će se zaustaviti dalje kretanje sprajta formule udesno

JMP UPRAVLJANJE

Vraćamo se na glavno mesto skoka

STANIX2

Mesto skoka koje zaustavlja dalje kretanja sprajta formule udesno

LDA #70

Unosima u akumulator vrednost 70

STA $D000

Stavljamo vrednost iz akumulatora u memorijsku lokaciju X kordinate prvog sprajta i na taj način sprečavamo njegovo kretanje nadalje udesno i samim tim njegovog nestanka sa desne strane ekrana

JMP UPRAVLJANJE

Vraćamo se na glavno mesto skoka

SMANJIY

Mesto skoka za smanjivanje vrednosti Y kordinate prvog sprajta

DEC $D001

Umanjujemo za jedan vrednost u memorijskoj lokaciji Y kordinate prvog sprajta

JMP UPRAVLJANJE

Vraćamo se na glavno mesto skoka

UVECAJY

Mesto skoka za uvečanje vrednosti Y kordinate prvog sprajta

INC $D001

Uvećavamo za jedan vrednost u memorijskoj lokaciji Y kordinate prvog sprajta (ukoliko pređe vrednost 255 vratiće sa na početak ekrana iz razloga cikličnog uvećanja vrednosti 0-255-0)

LDA $D001

Unosimo u akumualtor vrednost memorijske lokacije Y kordinate prvod sprajta

CMP #$FF

Ispitujemo da li je vrednost u akumulator $ff/255 što znači da je prvi sprajt izašao iz vidljivog polja ekrana na dole

BEQ UVECAJBOD

Ukoliko je vrednost u akumulatoru $ff/255 uvećavamo vrednost boda za 1

JMP UPRAVLJANJE

Vraćamo se na glavno mesto skoka

UVECAJBOD

Mesto skoka za uvećanje broja bodova (koliko je puta sprajt formule izašao iz ekrana na dole)

INC BOD

Uvećavamo memorijslku lokaciju koja sadrži jedan bajt počev od petascii koda za 0 (48) za jedan

JMP UPRAVLJANJE

Vraćamo se na glavno mesto skoka

USPORI

Mesto skoka za usporenje izvršenja mašinskog programa. Ovaj deo programa je veoma bitan jer inače je kretanje sprajtova izuzetno brzo da je neupotrebljivo za igru. Ako želite da vidite koliko brzo stavite ovde naredbu RTS koja će odmah vratiti tok programa u glavni program bez usporenja

NOP

Naredba koja nema funkciju osim da povećava tok programa za jedan. Ovde je koristimo jer dobijamo delić usporenja

NOP

Još jedna naredbe bez funkcije osim veoma malog usporenja mašinskog programa. Bez obzira na ovo pošto su ove dve NOP naredbe date u ciklusu imaju neki uticaj na smanjenje brzine izvršavanja programa

INY

Ovde imamo uvećanje registra Y (u ovom slučaju programskog brojača) za jedan

BNE USPORI

Skok na početak mesta skoka usporavanja sve dok registar Y ne odbroji 255 ciklusa što pravi ono pravo usporavanje programa

RTS

Povratak na glavni program

SPRAJT1

Opis izgleda prvog sprajta

.BYTE 0,0,0

.BYTE 0,0,0

.BYTE 63,0,252

.BYTE 63,170,252

.BYTE 63,170,252

.BYTE 63,150,252

.BYTE 63,150,252

.BYTE 63,150,252

.BYTE 63,150,252

.BYTE 0,150,0

.BYTE 0,150,0

.BYTE 0,150,0

.BYTE 0,150,0

.BYTE 63,150,252

.BYTE 63,190,252

.BYTE 63,190,252

.BYTE 63,190,252

.BYTE 63,170,252

.BYTE 63,40,252

.BYTE 63,0,252

.BYTE 0,0,0

Ovde imamo 63 bajta koji čine opis/definiciju izgleda prvog sprajta (formule) koju vodi igrač

SPRAJT2

Opis izgleda drugog sprajta (koji opis će poslužiti i za treći sprajt)

.BYTE 255,255,255

.BYTE 255,255,255

.BYTE 250,170,175

.BYTE 250,106,175

.BYTE 250,85,175

.BYTE 250,85,175

.BYTE 250,85,175

.BYTE 250,85,175

.BYTE 250,65,175

.BYTE 250,65,175

.BYTE 250,65,175

.BYTE 250,65,175

.BYTE 250,65,175

.BYTE 250,85,175

.BYTE 250,85,175

.BYTE 250,85,175

.BYTE 250,85,175

.BYTE 250,170,175

.BYTE 250,170,175

.BYTE 255,255,255

.BYTE 255,255,255

Imamo ponovo 63 bajta koji čine opis/definiciju izgleda drugog sprajta (šarenog kvadrata/smetala) koji opis će poslužiti i za treći sprajt

POZSKROL

Podprogram za povećanje horizontalne X kordinate drugog sprajta kvadrata/smetala

JSR POZSKROL2

Poziv podprograma za kretanje trećeg sprajta kvadrata/smetala

INC $D002

Uvećavamo memorijsku lokaciju X kordinate drugog sprajta/kvadrata za jedan

BEQ UVECAJ41

Ukoliko je vrednost ove memorijske lokacije 0 (ciklično uvećanje 0-255-0) skačemo na setovanje 9 bita drugog sprajta

LDA $D010

Učitavamo u akumulator vrednost memorijske lokacije stanja 9-bita svih sprajtova

AND #%00000010

Radimo logičku operaciju nad stanjem vrednosti u akumulatoru u kojoj ćemo potvrditi da li je setovan prvi bit (9 bit drugog sprajta). Kada damo naredbu AND (logičko množenje I) gde su svi bitovi osim prvog nula vrednost akumulatora će biti dva samo ako je prvi bit već setovan

CMP #2

Proveravamo da li akumulator sadži vrednost 2 što znači da je 9-bit drugog sprajta setovan

BEQ PROVERI41

Ukoliko je vrednost akumulatora jednaka dvojci skačemo na mesto skoka za proveru da li je drugi sprajt blizu izlaska iz vidljivog okvira sa desne strane ekrana

RTS

Povratak iz podprograma

UVECAJ41

Podprogram za setovanje 9-bita drugog sprajta

LDA $D010

Učitavamo u akumulator vrednost memorijske lokacije stanja 9-bita svih sprajtova

ORA #%00000010

Radimo logičku operaciju nad stanjem vrednosti u akumulatoru u kojoj ćemo setovati prvi bit (9 bit drugog sprajta). Kada damo naredbu ORA (logičko sabitanje ILI) gde je samo prvi bit jedinica a ostali nula neće biti promene kod ostalih sprajtova (0+0=0, 0+1=1) dok će bit drugog sprajta biti setovan (1+0=1)

STA $D010

Smeštamo vrednost akumulatora u memorijsku lokaciju $d010 (9-bit svih sprajtova/bit po sprajtu 0-7) i time setujemo 9-bit drugog sprajta

RTS

Povratak iz podprograma

PROVERI41

Podprogram provere da li je X kordinata drugog sprajta zajedno sa 9-bitom dostigla desnu ivicu ekrana

LDA $D002

Učitavamo u akumulator vrednost memorijske lokacije X kordinate drugog sprajta

CMP #70

Proveravamo da li je u akumulator vrednost 70 što znači da zajedno sa 9-bitom dostižemo vidljivu ivicu drugog sprajta na desnoj strani ekrana

BEQ VRATI41

Ukoliko je vrednost u akumulatoru jednaka 70 skačemo na mesto skoka gde će se drugi sprajt vratiti na početak ekrana poništavanjem 9-bita i stavljanjem nule u njegovu X kordinatu

RTS

Povratak iz podprograma

VRATI41

Podprogram gde će se resetovati 9-bit drugog sprajta i resetovati njegova X kordinata

LDA $D010

Učitavamo u akumulator vrednost memorijske lokacije stanja 9-bita svih sprajtova

AND #%11111101

Radimo logičku operaciju nad stanjem vrednosti u akumulatoru u kojoj ćemo resetovati prvi bit (9-bit drugog sprajta) ne dirajući stanja drugih sprajtova

STA $D010

Smeštamo vrednost akumulatora u memorijsku lokaciju $d010 (9-bit svih sprajtova/bit po sprajtu 0-7) i samim tim resetujemo 9-bit drugog sprajta

LDA #0

Brišemo vrednost akumulatora

STA $D002

Smeštamo stanje akumulatora u memorijsku lokaciju X kordinate drugog sprajta i samim tim isti vraćamo na početak ekrana

RTS

Povratak iz podprograma

POZSKROL2

Podprogram za povećanje horizontalne X kordinate trećeg sprajta kvadrata/smetala

INC $D004

Uvećavamo memorijsku lokaciju X kordinate trećeg sprajta/kvadrata za jedan

BEQ UVECAJ51

Ukoliko je vrednost ove memorijske lokacije 0 (ciklično uvećanje 0-255-0) skačemo na setovanje 9 bita trećeg sprajta

LDA $D010

Učitavamo u akumulator vrednost memorijske lokacije stanja 9-bita svih sprajtova

AND #%00000100

Radimo logičku operaciju nad stanjem vrednosti u akumulatoru u kojoj ćemo potvrditi da li je setovan drugi bit (9 bit trećeg sprajta). Kada damo naredbu AND (logičko množenje I) gde su svi bitovi osim drugog nula vrednost akumulatora će biti 4 samo ako je drugi bit već setovan

CMP #4

Proveravamo da li akumulator sadži vrednost 4 što znači da je 9-bit trećeg sprajta setovan

BEQ PROVERI51

Ukoliko je vrednost akumulatora jednaka 4 skačemo na mesto skoka za proveru da li je treći sprajt blizu izlaska iz vidljivog okvira sa desne strane ekrana

RTS

Povratak iz podprograma

UVECAJ51

Podprogram za setovanje 9-bita trećeg sprajta

LDA $D010

Učitavamo u akumulator vrednost memorijske lokacije stanja 9-bita svih sprajtova

ORA #%00000100

Radimo logičku operaciju nad stanjem vrednosti u akumulatoru u kojoj ćemo setovati drugi bit (9 bit trećeg sprajta). Kada damo naredbu ORA (logičko sabitanje ILI) gde je samo drugi bit jedinica a ostali nula neće biti promene kod ostalih sprajtova (0+0=0, 0+1=1) dok će bit trećeg sprajta biti setovan (1+0=1)

STA $D010

Smeštamo vrednost akumulatora u memorijsku lokaciju $d010 (9-bit svih sprajtova/bit po sprajtu 0-7) i time setujemo 9-bit trećeg sprajta

RTS

Povratak iz podprograma

PROVERI51

Podprogram provere da li je X kordinata trećeg sprajta zajedno sa 9-bitom dostigla desnu ivicu ekrana

LDA $D004

Učitavamo u akumulator vrednost memorijske lokacije X kordinate trećeg sprajta

CMP #70

Proveravamo da li je u akumulator vrednost 70 što znači da zajedno sa 9-bitom dostižemo vidljivu ivicu trećeg sprajta na desnoj strani ekrana

BEQ VRATI51

Ukoliko je vrednost u akumulatoru jednaka 70 skačemo na podprogram gde će se treći sprajt vratiti na početak ekrana poništavanjem 9-bita i stavljanjem nule u njegovu X kordinatu

RTS

Povratak iz podprograma

VRATI51

Podprogram gde će se resetovati 9-bit trećeg sprajta i resetovati njegova X kordinata

LDA $D010

Učitavamo u akumulator vrednost memorijske lokacije stanja 9-bita svih sprajtova

AND #%11111011

Radimo logičku operaciju nad stanjem vrednosti u akumulatoru u kojoj ćemo resetovati drugi bit (9-bit trećeg sprajta) ne dirajući stanja drugih sprajtova

STA $D010

Smeštamo vrednost akumulatora u memorijsku lokaciju $d010 (9-bit svih sprajtova/bit po sprajtu 0-7) i samim tim resetujemo 9-bit trećeg sprajta

LDA #0

Brišemo vrednost akumulatora

STA $D004

Smeštamo stanje akumulatora u memorijsku lokaciju X kordinate trećeg sprajta i samim tim isti vraćamo na početak ekrana

RTS

Povratak iz podprograma

ISPIS

Podprogram gde će se ispisati tekst i stanje bodova i takođe proveriti da li je formula prošla 9 puta donju ivicu ekrana u kom slučaju će se proglasiti pobeda

LDA #“B“-64

Dajemo slovo „b“ pod navodnicima koje turbo asembler preračunava u vrednost petascii koda (66) koju umanjujemo za 64 da bi se dobila ekranska vrednost ovog slova (2) koju unosimo u akumulator. Isto tako smo mogli odmah dati broj dva ali da ne bismo pamtili ili pretraživali za svaki ekranski kod slova koje želimo da koristimo ovo je najbolji način

STA $0410

Smeštamo vrednost akumulatora direktno u ekransku memoriju. Iz ovog razloga smo morali u akumulatoru pretvoriti vrednost petascii koda u ekransku kodnu vrednost karaktera

LDA #“O“-64

Dajemo slovo „o“ pod navodnicima koje turbo asembler preračunava u vrednost petascii koda koji umanjujemo za 64 da bi se dobila ekranska vrednost slova koju unosimo u akumulator

STA $0411

Smeštamo vrednost akumulatora direktno u ekransku memoriju uvećanu za jedan u odnosu na prethodni ispis

LDA #“D“-64

Dajemo slovo „d“ pod navodnicima koje turbo asembler preračunava u vrednost petascii koda koji umanjujemo za 64 da bi se dobila ekranska vrednost slova koju unosimo u akumulator

STA $0412

Smeštamo vrednost akumulatora direktno u ekransku memoriju uvećanu za jedan u odnosu na prethodni ispis

LDA BOD

Učitavamo vrednost iz memorijske adrese BOD koja se nalazi na kraju programa i sadrži jedan bajt dat turbo asemblerskom naredbom .byte (početna vrednost je 48 što odgovara karakteru 0 bilo u petascii ili u ekranskom kodu pa ne treba umanjiti njegovu vrednosti)

STA $0414

Smeštamo vrednost akumulatora direktno u ekransku memoriju uvećanu za dva u odnosu na prethodni ispis i time pravimo razmak između teksta i ispisa vrednosti boda

CMP #57

Proveravamo da li BOD sadrži vrednost 57 što znači da smo imali 9 prelaza

BEQ KRAJPOBEDA

Ukoliko je vrednost BOD-a došla do ekranskog/petascii koda 57 (broja 9) znači da smo uspeli i idemo na deo programa gde se ispisuje da smo pobedili

RTS

Povratak iz podprograma

KRAJPOBEDA

Podprogram koji proglašava pobedu

LDA #147

Unosimo u akumulator vrednost 147 (petascii kod za brisanje ekrana)

JSR ISPISI

Pozivamo podprogram za izvršavanje petascii koda datog u akumulatoru

LDA #“P“-64

Dajemo slovo „p“ pod navodnicima koje turbo asembler preračunava u vrednost petascii koda koji umanjujemo za 64 da bi se dobila ekranska vrednost slova koju unosimo u akumulator

STA $0400

Smeštamo ekranski kod karaktera iz akumulatora u ekransku memoriju (prvi red,prva kolona)

LDA #“O“-64

Dajemo slovo „o“ pod navodnicima koje turbo asembler preračunava u vrednost petascii koda koji umanjujemo za 64 da bi se dobila ekranska vrednost slova koju unosimo u akumulator

STA $0401

Smeštamo ekranski kod karaktera iz akumulatora u ekransku memoriju (prvi red,druga kolona)

LDA #“B“-64

Dajemo slovo „b“ pod navodnicima koje turbo asembler preračunava u vrednost petascii koda koji umanjujemo za 64 da bi se dobila ekranska vrednost slova koju unosimo u akumulator

STA $0402

Smeštamo ekranski kod karaktera iz akumulatora u ekransku memoriju (prvi red,treća kolona)

LDA #“E“-64

Dajemo slovo „e“ pod navodnicima koje turbo asembler takođe preračunava u vrednost petascii koda koji umanjujemo za 64 da bi se dobila ekranska vrednost slova koju unosimo u akumulator

STA $0403

Smeštamo ekranski kod karaktera iz akumulatora u ekransku memoriju (prvi red,četvrta kolona)

LDA #“D“-64

Dajemo slovo „d“ pod navodnicima koje turbo asembler preračunava u vrednost petascii koda koji umanjujemo za 64 da bi se dobila ekranska vrednost slova koju unosimo u akumulator

STA $0404

Smeštamo ekranski kod karaktera iz akumulatora u ekransku memoriju (prvi red,peta kolona)

LDA #“A“-64

Dajemo slovo „a“ pod navodnicima koje turbo asembler preračunava u vrednost petascii koda koji umanjujemo za 64 da bi se dobila ekranska vrednost slova koju unosimo u akumulator

STA $0405

Smeštamo ekranski kod karaktera iz akumulatora u ekransku memoriju (prvi red,šesta kolona)

LDA #0

Brišemo vrednost akumulatora

STA $D015

Unosimo vrednost akumulatora u memorijsku lokaciju $d015 (53269) i time isključujemo sve sprajtove

STA $D400

Unosimo nulu u memorijsku lokaciju $d400 (54272) i time gasimo zvuk

STA $D401

Unosimo nulu u memorijsku lokaciju $d401 (54273) i time gasimo zvuk

STA $D404

Unosimo nulu u memorijsku lokaciju $d404 (54276) i time gasimo zvuk

RTS

Povratak iz podprograma koji se pošto nam je ovo kraj programa vraća u glavni program i beskonačno ponavlja ispis pobede i isključenje sprajtova i zvuka. Mogli smo ovde dati naredbu za bezuslovni skok JMP na neko mesto u samom programu (time bi program stalno vrteli tu petlju) ili naredbu BRK gde bi izašli iz programa (obaška što bismo trebali dodatno da restartujemo neka stanja)

SUDAR

Podprogram za detekciju sudara između sprajtova

LDA $D01E

Učitavamo vrednost iz registra sudara sprajtova u akumulator. Ukoliko se neki sprajt sudari sa drugim setovaće se za svaki od njih njegov bit vrednosti (po sprajtu 0-7). Pošto imamo tri sprajta, ukoliko nema sudara vrednost će biti nula, a ako ima biće minimum 3 (naravno zavisno od toga koji su se sprajtovi sudarili i koliko njih biće i veće vrednosti)

CMP #0

Proveravamo da li je vrednost akumulatora nula što znači da nije bilo sudara između sprajtova

BNE IZGUBIO

Ako vrednost nije nula znači da je bilo sudara i skačemo na kraj programa gde se objavljuje poraz (pošto nije moguće proveriti da li se desio sudar sprajt-sprajt između smetala šta ne utiče na ishod igre, dajemo ih na različitu visinu gde ne može doći do njihovog sudara)

RTS

Povratak iz podprograma

IZGUBIO

Podprogram/mesto skoka za objavu poraza

LDA #147

Unosimo u akumulator vrednost 147 (petascii kod za brisanje ekrana)

JSR ISPISI

Pozivamo podprogram za izvršavanje petascii koda datog u akumulatoru

LDA #“I“-64

Dajemo slovo „i“ pod navodnicima koje turbo asembler preračunava u vrednost petascii koda koji umanjujemo za 64 da bi se dobila ekranska vrednost slova koju unosimo u akumulator

STA $0400

Smeštamo ekranski kod karaktera iz akumulatora u ekransku memoriju (prvi red,prva kolona)

LDA #“Z“-64

Dajemo slovo „z“ pod navodnicima koje turbo asembler preračunava u vrednost petascii koda koji umanjujemo za 64 da bi se dobila ekranska vrednost slova koju unosimo u akumulator

STA $0401

Smeštamo ekranski kod karaktera iz akumulatora u ekransku memoriju (prvi red,druga kolona)

LDA #“G“-64

Dajemo slovo „g“ pod navodnicima koje turbo asembler preračunava u vrednost petascii koda koji umanjujemo za 64 da bi se dobila ekranska vrednost slova koju unosimo u akumulator

STA $0402

Smeštamo ekranski kod karaktera iz akumulatora u ekransku memoriju (prvi red,treća kolona)

LDA #“U“-64

Dajemo slovo „u“ pod navodnicima koje turbo asembler takođe preračunava u vrednost petascii koda koji umanjujemo za 64 da bi se dobila ekranska vrednost slova koju unosimo u akumulator

STA $0403

Smeštamo ekranski kod karaktera iz akumulatora u ekransku memoriju (prvi red,četvrta kolona)

LDA #“B“-64

Dajemo slovo „b“ pod navodnicima koje turbo asembler preračunava u vrednost petascii koda koji umanjujemo za 64 da bi se dobila ekranska vrednost slova koju unosimo u akumulator

STA $0404

Smeštamo ekranski kod karaktera iz akumulatora u ekransku memoriju (prvi red,peta kolona)

LDA #“I“-64

Dajemo slovo „i“ pod navodnicima koje turbo asembler preračunava u vrednost petascii koda koji umanjujemo za 64 da bi se dobila ekranska vrednost slova koju unosimo u akumulator

STA $0405

Smeštamo ekranski kod karaktera iz akumulatora u ekransku memoriju (prvi red,šesta kolona)

LDA #“O“-64

Dajemo slovo „o“ pod navodnicima koje turbo asembler preračunava u vrednost petascii koda koji umanjujemo za 64 da bi se dobila ekranska vrednost slova koju unosimo u akumulator

STA $0406

Smeštamo ekranski kod karaktera iz akumulatora u ekransku memoriju (prvi red,sedma kolona)

LDA #0

Brišemo vrednost akumulatora

STA $D015

Unosimo vrednost akumulatora u memorijsku lokaciju $d015 (53269) i time isključujemo sve sprajtove

STA $D400

Unosimo nulu u memorijsku lokaciju $d400 (54272) i time gasimo zvuk

STA $D401

Unosimo nulu u memorijsku lokaciju $d401 (54273) i time gasimo zvuk

STA $D404

Unosimo nulu u memorijsku lokaciju $d404 (54276) i time gasimo zvuk

RTS

Povratak iz podprograma koji se pošto nam je ovo kraj programa vraća u glavni program i beskonačno ponavlja ispis poraza i isključenje sprajtova i zvuka

POCETEKRAN

Podprogram za ispis teksta uputstva na početnom ekranu i čekanje pritiska bilo kog tastera

LDA #147

Unosimo vrednost 147 (petascii kod za brisanje ekrana) u akumulator

JSR ISPISI

Pozivamo sistemski podprogram za izvršavanje petascii koda koji je dat u akumulatoru

LDX #0

Praznimo registar X. Služiće nam kao brojač ispisa teksta početnog ekrana

POCET1

Mesto skoka početne petlje ispisa teksta na početnom ekranu

LDA TEKST,X

Učitavamo u akumulator podatak iz memorijske lokacije TEKST uvećan za vrednost registra X. Memorijska lokacija TEKST se dobija prilikom prevođenja programa, a služi za čuvanje teksta koji će se ispisati na početnom ekranu

JSR ISPISI

Pozivamo sistemski podprogram za ispis petascii koda datog u akumulatoru. Ovaj put je u pitanju karakter teksta koji se učitava iz memorije

INX

Uvećavamo registar X za jedan i na taj način pomeramo se za jedan bajt kroz tekst koji ispisujemo

CPX #200

Proveravamo da li je X registar dostigao vrednost 200 što znači da smo ispisali 200 karaktera teksta

BNE POCET1

Ako vrednost nije jednaka 200 skačemo na početak petlje za ispis teksta

CEKAJ

Mesto skoka čekanja pritiska tastera

LDA 197

Učitavamo u akumulator vrednost memorijske lokacije 197 koja služi za očitavanje tastature

CMP #64

Proveravamo da li je vrednost 64 koja se dobija kada nije pretisnut nijedan taster

BEQ CEKAJ

Ukoliko nije pretisnut nijedan taster skačemo natrag i ne pokrećemo igru

RTS

Ukoliko je pretisnut bilo koji taster vraćamo se u glavni program gde počinje igra

TEKST

Mesto čuvanja teksta za ispis na početnom ekranu

.TEXT „{CLR}{3 DOWN} UPRAVLJAJ SVOJOM“

Prvi red teksta. Dajemo turbo asemblersku naredbu za čuvanje teksta .text. Tekst se stavlja između navodnika i može sadržati običan tekst kao i petascii kodove karaktera sa specijalnom namenom. U našem slučaju dajemo tekst za brisanje ekrana (višak od ranije ali nam neće smetati), skakanje tri reda dole i ispis poruke. Ukoliko želimo možemo direktno dati petascii/ekranski kod nekog karaktera čime u istom redu stavljamo {} i odmah upisujemo vrednost istog. U pitanju su vitičaste zagrade (na engleskom keyboardu preko emulatora: shift + i shift -). Isto tako u njih možemo upisati vrednosti za izvršavanje nekih posebnih petascii kodova (kao što je npr. {clr}, a što je lakše od pamćenja brojnih vrednosti koje se razlikuju za petascii i ekranski kod / mala i velika slova)

.TEXT „{DOWN} FORMULOM I IZBEGNI“

Drugi red teksta koji pokazuje da koristeći specijalne petascii kodove kroz tekst možemo pomerati mesto ispisa i učiniti ga da bude pregledan

.TEXT „{DOWN} PROTIVNIKE“

Treći red teksta

.TEXT „{DOWN} A-LEVO D-DESNO“

Četvrti red teksta

.TEXT „{DOWN} W-GORE S-DOLE“

Peti red teksta

.TEXT „{DOWN} PRETISNI TASTER“

Šesti red teksta

.TEXT „{DOWN} I KRENI“

Sedmi red teksta

POZADINA

Podprogram za iscrtavanje pozadine puta kojim će se kretati formula

LDX #0

Praznimo registar X koji će nam služiti kao brojač za bojenje pozadine

POZADINA1

Mesto skoka za ciklus bojenja pozadine

LDA #3

Unosimo vrednost 3 u akumulator

STA 55351,X

Smeštamo vrednost akumulatora u boju pozadine računajući od zadate memorijske adrese uvećano za vrednost X registra

STA 55391,X

Smeštamo vrednost akumulatora u boju pozadine računajući od zadate memorijske adrese uvećano za vrednost X registra

INX

Uvećavamo vrednost registra X za jedan

CPX #22

Proveravamo da li je X dostigao vrednost 22

BNE POZADINA1

Ako nije idemo na početak petlje za bojenje pozadine

RTS

Povratak iz podprograma

PRIPZVUK

Podprogram za pripremu zvuka

LDA #15

Unosimo vrednost 15 u akumulator

STA $D418

Smeštamo vrednost akumulatora u memorijsku lokaciju $d418 (54296) koja služi za regulaciju jačine zvuka

LDA #0

Brišemo akumulator

STA $D405

Smeštamo vrednost akumulatora u memorijsku lokaciju $d405 (54277)

STA $D406

Smeštamo vrednost akumulatora u memorijsku lokaciju $d406 (54278)

STA $D404

Smeštamo vrednost akumulatora u memorijsku lokaciju $d404 (54276)

STA $D401

Smeštamo vrednost akumulatora u memorijsku lokaciju $d401 (54273)

STA $D400

Smeštamo vrednost akumulatora u memorijsku lokaciju $d400 (54272)

RTS

Povratak iz podprograma

ZVUK

Podprogram za proizvodnju zvuka

LDA #12

Unosimo vrednost 12 u akumulator

STA $D400

Smeštamo vrednost akumulatora u memorijsku lokaciju $d400 (54272) koja služi za niži bajt frekvencije prvog glasa

LDA #16

Unosimo vrednost 16 u akumulator

STA $D401

Smeštamo vrednost akumulatora u memorijsku lokaciju $d401 (54273) koja služi za viši bajt frekvencije prvog glasa

LDA #33

Unosimo vrednost 33 u akumulator

STA $D404

Smeštamo vrednost akumulatora u memorijsku lokaciju $d404 (54276) koja služi za kontrolu oblika zvuka prvog glasa

RTS

Povratak iz podprograma

BOD

Mesto čuvanja broja bodova

.BYTE 48

Opis bajta za smeštanje vrednosti bodova čija je početna vrednost 48 (petascii/ekranski kod za vrednost nula)

Prateći objašnjenja za svaku programsku liniju mogli smo videti jedan malo veći asemblerski program sa svim zanimljivim radnjama koje koristi, a sada ostaje da ga prevedemo, pokrenemo i testiramo.

Snažno vam preporučujemo iz ličnog iskustva da uvek snimite na disketu ili virtualnu disketu uneti izvorni asemblerski program, pre prevođenja i aktiviranja programa. Ovo iz razloga što prilikom unošenja koda može doći do greške, a i turbo asembler zna nekad da pobrljavi i da program zabode. Ukoliko je sve u redu sa kompajliranjem i startovanjem programa idite ←5, a zatim „S“ za snimanje izvornog koda na disketu. Kasnije za ponovno učitavanje istog dovoljno je ići ←5 pa „L“. Program u turbo asembleru se snima sa ekstenzijom .s (koju ne morate ukucavati prilikom učitavanja)

Do sada smo za testiranje koristili tastaturu. Za programiranje igrica bi bilo zgodno da možemo koristiti džojstik ili danas joypad (što turbo asembler i mašinski programi i te kako mogu). U našem programu nismo želeli to da uradimo zbog dužine i dodatnog objašnjavanja ali nije veliki problem. Na C64 postoje dve memorijske lokacije očitanja položaja džojstika i dugmeta za pucanje i to $dc00/56320 za port 1 i $dc01/56321 za port 2.

Moguća stanja položaja palice za igru i njenog dugmeta za pucanje očitane kao brojne vrednosti su sledeće:

Palica u portu 1 ($DC00/56320) Palica u portu 2 ($DC01/56321)

GORE 254 127

DOLE 253 126

LEVO 251 125

DESNO 247 123

PUCANJE 239 119

Obratite pažnju da ukoliko držimo palicu ukoso ili u više pravaca biće dobijena kombinacija ovih vrednosti i takvo očitanje se kao takvo može koristiti za manipulaciju programom (npr: u levo i dole = 249 za port 1)

Sada još da damo uporedne dužine programa i brzine izvršavanja:

Veličine programa:

1) Trke – bejzik program $078E/1934 bajta

2) Formula – mašinski program $03EE/1006 bajta

Razlika u korist mašinskog programa $03A0/ 928 bajta

Brzina izvršavanja programa:

Provera na 50 for/next petlji sa po 10000 ciklusa i po 10

obrada u svakom ciklusu što daje oko 5 miliona obrada

1) Trke – bejzik program 14,5 sek

2) Formula – mašinski program (znači obuhvaćeno usporenje, iščitavanje

tastera sa detekcijom sudara i ispitivanjem granica

ekrana 0,0085 sek

Razlika u korist mašinskog programa 1705 puta brže

Ova poređanja jasno stavljaju do znanja zašto su programeri gotovo isključivo programirali u asembleru na C64 (svi bitni komercijalni programi su pisani u njemu) što je važilo i za druge osmobitne računare koji su korišćeni u to vreme.

Sa današnjom lekcijom završili smo malu školu asemblera za C64. Nadam ste da ste uživali u proučavanju mogućnosti asemblerskih/mašinskih programa. Na vama je da ukoliko želite nastavite dalje. Bez obzira što smo upoznali sve asemblerske naredbe i kako ih koristiti u programima postoje još mnogo stvari koje možete naučiti o programiranju u njemu (korišćenje memorijskih lokacija i sistemskih podprograma, razne cake koje mogu smanjiti iskorišćenost memorije i još dodatno ubrzati izvršavanje koda (optimizacija), izvođenje veoma zanimljivih efekata prilikom prikaza grafike i reprodukcije zvuka i mnogo drugih mogućnosti).

Puno pozdrava i želimo vam sve najbolje u daljem životu, učenju i radu.

Ostavite komentar

Vaša adresa e-pošte neće biti objavljena. Neophodna polja su označena *

Scroll to Top