C64 – CAKE 6
U ovoj „CAKE 6“ lekciji učimo kako da kontrolišemo VIC-II raster i dobijemo precizne preseke boja na pozadini i okviru ekrana. Kroz jasne asembler primere ($D012, $D011) pokazujemo stabilne efekte i trikove koje koriste igre i intro scene.
Dobrodošli u nove cake. Danas radimo sa najmoćnijem registrom VIC II grafičkog čipa, moćnim rasterom. Možemo slobodno reći da je zahvaljujući ovom registru omogućeno mnogo vizuelnih efekata koje srećemo u igrama i introima.
Ovaj registar se nalazi na memorijskoj adresi $D012 i isti kontroliše mlaz iscrtavanja linije piksela od 0 do 255 linije kojom se pokrivaju raster linije cele ekranske pozadine ali ne i celog okvira ekrana. Zato 8 bit raster registra koji se nalazi na memorijskoj lokaciji $D011 (njegov 7 bit 0–7) pokriva kontrolu mlaza iscrtavanja piksela obuhvatajući time ceo okvir ekrana.
U svakom trenutku zahvaljujući ovom registru možemo proveravati i kontrolisati mlaz iscrtavanja, tako da jednostavnim upoređivanjem trenute pozicije možemo promeniti boje okvira i pozadine gde dobijamo efekat presečenog ekrana, dupliciramo sprajtove u presečenim delovima (ako ste videli da u nekom introu izgleda da ima više od osam sprajtova to se postiže na ovaj način), izvršimo promenu dela ekrana tako da jedan deo bude u tekstualnom a drugi u grafičkom delu i još mnogo toga.
Primeri iz prakse
1) Deljenje boje ekrana na dva dela
*= $1000
sei ; setujemo I-bit čime onemogućavamo prekide. Ovo je potrebno zbog
; stabilnosti preseka inače linije preseka trepere
opet ; mesto skoka beskonačne petlje
lda $d012 ; učitavamo u akumulator vrednost raster registra i samim tim saznajemo gde
; se trenutno mlaz iscrtavanja nalazi
cmp #139 ; upoređujemo da li je mlaz dostigao vrednost 139. Ova vrednost daje stabilni
; presek dok neke druge vrednosti mogu izazvati blago talasanje preseka bez
; obzira na uključenu zabranu prekida
bpl dalje ; ukoliko je vrednost veća od uporedne prelazimo na boju pozadine druge
; polovine ekrana
lda #0 ; stavljamo u akumulator vrednost nula koja će nam biti crna boja pozadine
sta $d021 ; smeštamo vrednost iz akumulatora u registar boje pozadine ekrana
jmp opet ; vraćamo se na mesto skoka beskonačne petlje
dalje ; mesto skoka ako je mlaz prešao na drugu polovinu ekrana
lda #1 ; stavljamo u akumulator vrednost nula koja će nam biti bela boja pozadine
sta $d021 ; smeštamo vrednost iz akumulatora u registar boje pozadine ekrana
jmp opet ; vraćamo se na mesto skoka beskonačne petljeStartovanjem ovog programa pozadina ekrana će se podeliti na dve boje — gornji deo preseka biće crn, a donji beo. To je sve postignuto zahvaljujući raster registru čijom proverom trenutne linije ispisivanja možemo promeniti boju pozadine u pravom trenutku i time dobiti efekat presečenog ekrana.
2) Deljenje okvira na dve boje
*= $1000
sei ; setujemo I-bit čime onemogućavamo prekide. Ovo je potrebno zbog
; stabilnosti preseka inače linije preseka trepere
opet ; mesto skoka beskonačne petlje
lda $d012 ; učitavamo u akumulator vrednost raster registra i samim tim saznajemo gde
; se trenutno mlaz iscrtavanja nalazi
cmp #120 ; upoređujemo da li je mlaz dostigao vrednost 120. Ova vrednost daje stabilni
; presek okvira
bpl dalje ; ukoliko je vrednost veća od uporedne prelazimo na boju okvira druge
; polovine ekrana
lda #2 ; stavljamo u akumulator vrednost 2 koja će nam biti crvena boja okvira
sta $d020 ; smeštamo vrednost iz akumulatora u registar boje pozadine okvira
jmp opet ; vraćamo se na mesto skoka beskonačne petlje
dalje ; mesto skoka ako je mlaz prešao na drugu polovinu okvira
lda #7 ; stavljamo u akumulator vrednost nula koja će nam biti žuta boja okvira
sta $d020 ; smeštamo vrednost iz akumulatora u registar boje pozadine okvira
jmp opet ; vraćamo se na mesto skoka beskonačne petljeStartovanjem ovog primera dobijamo okvir ekrana u dve boje — crvenu i žutu — ali sa tri preseka. Zašto? Raster koji očitava mlaz ima najveću vrednost 255, dok okvir izlazi iz ovog opsega. Kada se to desi raster počinje ponovo od nule, pa se boja okvira vraća na prvobitnu i dobijamo: crvena do pola ekrana, zatim žuta do kraja opsega registra, pa ponovo crvena.
Da bi se ovo izbeglo, treba uključiti pri proveri 8. bit raster registra koji se nalazi na memorijskoj lokaciji $D011 — proverom njegovog 7. bita (0–7).
3) Savršeni presek okvira na dve boje
*= $1000
sei ; setujemo I-bit čime onemogućavamo prekide. Ovo je potrebno zbog
; stabilnosti preseka inače linije preseka trepere
opet ; mesto skoka beskonačne petlje
lda $d012 ; učitavamo u akumulator vrednost raster registra i samim tim saznajemo gde
; se trenutno mlaz iscrtavanja nalazi
cmp #140 ; upoređujemo da li je mlaz dostigao vrednost 140. Ova vrednost daje stabilni
; presek kod savršenog preseka okvira
bpl dalje ; ukoliko je vrednost veća od uporedne prelazimo na boju okvira druge
; polovine ekrana
lda $d011 ; učitavamo u akumulator vrednost registra $D011 gde se nalazi osmi bit
; raster registra
and #$80 ; dajemo filter za njegov 7 bit (8 bit raster registra) da bi se samo on uzeo za
; poređenje
cmp #$80 ; upoređujemo da li je ovaj bit setovan
beq dalje ; ukoliko jeste skačemo na donji deo ekrana i nastavljamo boju okvira od 256
; linije
lda #2 ; stavljamo u akumulator vrednost 2 koja će nam biti crvena boja okvira
sta $d020 ; smeštamo vrednost iz akumulatora u registar boje pozadine okvira
jmp opet ; vraćamo se na mesto skoka beskonačne petlje
dalje ; mesto skoka ako je mlaz prešao na drugu polovinu okvira
lda #7 ; stavljamo u akumulator vrednost nula koja će nam biti žuta boja okvira
sta $d020 ; smeštamo vrednost iz akumulatora u registar boje pozadine okvira
jmp opet ; vraćamo se na mesto skoka beskonačne petljeStartovanjem ovog programa dobijamo savršeni presek okvira ekrana sa jasnom podelom na gornji deo crveno i donji deo žuto. Vrednost poređenja od 140 je praktično idealna.
Na kraju ostaje nam program za analizu:
*= $1000
sei
lda #<opet
sta $0314
lda #>opet
sta $0315
cli
rts
lda #0
sta 2
opet
inc 2
lda $02
cmp #145
bpl dalje
lda #155
sta $d011
jmp $ea31
dalje
lda #59
sta $d011
jmp $ea31Mala pomoć: ima veze sa intervalima i promeni grafičke rezolucije ekrana.
❓ Pitanja i odgovori (FAQ)
Šta je uopšte raster na Commodore 64?
Raster je „mlaz iscrtavanja“ – tačka koja ide liniju po liniju od vrha do dna ekrana i crta piksele. Na C64 možemo da „uhvatimo“ trenutnu raster liniju i u tom trenutku promenimo boju, režim ekrana ili sprajtove, čime dobijamo razne vizuelne efekte (preseci ekrana, više sekcija, dodatni sprajtovi itd.).
Čemu služi registar na adresi $D012, a čemu $D011?
$D012 je osnovni raster registar – u njemu se nalazi vrednost od nula do dvesta pedeset pet i govori nam na kojoj raster liniji se trenutno nalazi mlaz iscrtavanja.
$D011 između ostalog sadrži i osmi (najviši) bit rastera, pa zajedno sa $D012 omogućava praćenje linija iznad dvesta pedeset pet, tj. kompletnog okvira ekrana.
Zašto u svim primerima na početku stoji SEI i pominje se „stabilnost preseka“?
SEI zabranjuje maskabilne prekide. Ako prekidi rade dok pokušavamo da pogodimo tačan trenutak raster linije, program „kasni“ i presek okvira ili pozadine počinje da treperi, talasa ili „šeta“ za nekoliko linija. Zbog toga se za stabilan raster efekat obično prvo radi SEI, a kasnije po potrebi CLI kada završimo.
U drugom primeru okvir je u dve boje, ali se vide tri preseka. Zašto?
Raster registar $D012 ide od nula do dvesta pedeset pet. Okvir (border) vizuelno „izlazi“ iz tog opsega. Kada raster „pređe“ granicu, vrednost ponovo kreće od nule, pa se boja vrati na početnu i dobijamo efekat: jedna boja – druga boja – pa opet prva. Zato se u trećem primeru uključuje i osmi bit iz $D011, da bi se dobila savršena podela na gornji i donji deo.
Šta konkretno radi instrukcija AND #$80 u trećem primeru?
AND #$80 ostavlja samo sedmi bit akumulatora (bit sa vrednošću sto dvadeset osam) i briše ostale. Pošto je u $D011 taj bit rezervisan za osmi bit raster registra, mi na taj način izdvajamo baš informaciju da li se raster nalazi u „donjoj zoni“ (iznad dvesta pedeset pet). Ako je rezultat #$80, znamo da je taj bit postavljen.
Kako da pokrenem ove programe na pravom C64 ili emulatoru?
Pošto je kod smešten na adresu $1000 (decimalno 4096), procedura je tipično:
- Učitaš program u memoriju (npr. preko monitora, assemblera ili kao .PRG fajl).
- U BASIC-u ukucaš
SYS 4096i pritisneš RETURN.
Time se program startuje od adrese $1000.
Da li ovi raster trikovi rade isto na PAL i NTSC C64 računarima?
Princip je isti, ali se broj raster linija i frekvencija razlikuju između PAL i NTSC sistema. To znači da vrednosti za poređenje (npr. CMP #140) možda neće davati isti vizuelni presek na NTSC kao na PAL mašini. Za potpuno „pixel-perfect“ efekte treba posebno prilagoditi vrednosti za svaku verziju.
Gde se ovi trikovi koriste u praksi – samo za menjanje boje okvira?
Ne. Deljenje boje okvira i pozadine je samo najjednostavniji primer. Raster se u praksi koristi za efekat presečenog ekrana (više „zona“ sa različitim podešavanjima), „multiplikaciju“ sprajtova da izgleda kao da ih ima više od osam, kombinovanje tekstualnog i grafičkog moda na istom ekranu, scroll efekte, status trake, HUD-ove u igrama i demoe.
Šta radi onaj poslednji „program za analizu“ sa vektorom prekida $0314/$0315?
Taj program preusmerava rutinu za raster prekid na etiketu opet. Svakim prekidom uvećava lokaciju 2 (INC 2), upoređuje je sa određenom vrednošću i menja $D011. To je svojevrsni „eksperiment“ za razumevanje kako promena grafičkog moda i raster intervala utiče na presek ekrana. Cilj je da čitaoca podstakne da sam „prokljuvi“ šta se dešava i zašto.
Da li je bezbedno eksperimentisati sa ovim registrima ili mogu da „pokvarim“ C64?
Potpuno je bezbedno za sam računar. U najgorem slučaju „srušićeš“ ekran, dobiti konfuznu sliku ili se sistem zaglavi pa će biti potreban reset. VIC-II i ostali čipovi su pravljeni da trpe ovakve softverske eksperimente – baš na njima su nastale sve one demo scene koje volimo.
To je sve za danas. Veliki pozdrav!

