energy.scene.pl
Popularny magazyn na ośmiobitowe Atari
Wybierz muzykę:
Energy 1: 1 2 3 4 5 Energy 2: 1 2 3 4 5 6 7 8 9 10 11 12 |
autor: jaskier
Wielu z Was zapewne słyszało o pewnym programie graficznym, zwanym skrótowo GED. Napisany został on w 1993 roku przez Johna Harrisa. Jest to program, który pod względem możliwości graficznych znajduje się gdzieś w pierwszej piątce wszystkich programów graficznych na Atari. Również pod względem ilości wbudowanych opcji ten program znajduje się w pierwszej piątce, tyle że od tyłu. Jednak, mimo braku nawet najbardziej elementarnych opcji, program jest szeroko używany przez grafików różnych maści. Jest to spowodowane tym, że program udostępnia chyba najwięcej (na oko jakieś 20%) możliwości graficznych Atari, spośród wszystkich innych programów graficznych.
Pomysł, aby nie tylko zmieniać kolory co linię, ale również w jej środku, a ponadto dodać pełnię możliwośći PMG, oddzielne dla każdego ghosta kolory i szerokości, priorytety i inne zabawki, jest wspaniały. Naprawdę wielkie brawa dla Johna Harrisa. Ach gdyby nie ta zapierająca dech obsługa.
Program niestety posiada również inną wadę, ujawniającą się niestety najpóźniej, bo już po narysowaniu całego obrazka. Do programu mianowicie nie dołączono procedury, którą można by umieścić we własnym programie, aby pokazać w nim własny obrazek narysowany w GED-zie. Tą niedogodnością jakiś czas temu zaciekawił mnie Dracon/USG/Taquart. Poprosił mnie mianowicie (po tym jak odmówił mu Konop i paru innych koderów) o napisanie takiej procedury, gdyż potrzebował jej do swojego slideshowu. Po przejrzeniu GED-a za pomocą wszystkich dostępnych mi debuggerów (z których każdy niestety pokazywał to samo) zabrałem się do pracy.
Oto wynik moich poszukiwań. (Pełny tekst programu znajduje się w zarchiwizowanym pliku jako GEDVIEW.ASM.)
Dane program trzyma od adresu $5330, do adresu $7f4f. Zapisywane jest to jednym ciągiem w formacie DOS-owym to znaczy z bajtami $ffff, $5330, $7f4f na początku.
Zmieniając adres danych można zmieniać tylko pierwszą cyfrę, gdyż Antic ma głupi zwyczaj dane obrazka pobierać tylko z czterech kilobajtów.
Kilka linii przed początkiem obrazka zaczyna się przerwanie. Jest ono docyklowane z dokładnością do 0.001 cykla, tak więc należy zwracać uwagę na to, że:
Mój program został przystosowany do umieszczenia na początku strony. Wszelkie zmiany tego położenia, a także wszelkie zmiany w programie mogą zmienić położenie pętli umieszczonych w przerwaniu. Pętla, której początek i koniec znajdują się na dwu różnych stronach może znaleźć się na jednej stronie, a tym samym rozkaz skoku na początek pętli (bpl) będzie działać o 1 cykl krócej. Należy również uważać na to, że display list musi znaleźć się cały w jednym kilobajcie. Ponadto zaraz za programem należy zostawić 10KB wolnego, gdyż umieszczany jest tam program przerwania generowany dopiero po uruchomieniu mojej procedury.
Oto skrócony opis programu, dla tych, którzy chcieliby poznać sposób, w jaki pokazuje się obrazki z GED-a.
Najpierw opis danych:
Osiem tablic po 200 bajtów zawiera dane zmian kolorów itp. robionych co linię: -tb2, tb3, tb4, tb5, tb6, tb7, tb8, tb9- dane ośmiu zmian kolorów w linii, kolejno: kolor 1, 2, 3, 1, 2, 3, 1, 2.
Oprócz tych zmian można dokonywać również co linię jednej ze zmian w ghostach (kolor, szerokość itp.) lub koloru tła. Wartości tych zmian zawiera tablica tb0, zaś komórki, które trzeba zmieniać tablica tb1.
-dane- szesnaście komórek:
-0,1,2,3 - kolory wpisywane do $d012-$d015
-4- szerokości playerów (po dwa bity od najstarszych wpisywane do $d008-$d00b),
-5- szerokości missilów ($d00c),
-6- priorytety ($d01b),
-7- kolor missilów (do $d019),
-8- kolor tła ($2c8 lub $d01a),
-9,10,11,12- położenia poziome graczy (komórki od $d000 do $d003),
-13- położenie poziome pierwszego missila, do pozycji następnych dodawana jest szerokość poprzedników,
-14- numer opóźnienia przerwania i tym samym miejsca zmiany kolorów. W GED-dzie ustawia się to klawiszami [,] i [.]),
-15- nieużywane.
-obr1,obr2- dane obrazka podzielone na dwie części z powodu pewnej wady Antica.
A teraz opis kilku części programu:
lda >pmg-$300 pierwsze 3 strony nie są sta $d407 używane, więc stąd ten adres. lda <end Generuje początkowe sta addr bajty umieszczane za lda >end etykietą END. Najpierw sta addr+1 na podstawie dane+14 lda dane+14 umieszczane są 4 bajty, asl @ które nic nie robią, ale asl @ dają różne opóźnienie. adc #3 Owe czwórki bajtów tax umieszczone są pod ldy #3 etykietą proc3. s1 lda proc3,x sta (addr),y dex dey bpl s1 Teraz adres jest zwiększany o 4: lda <end+4 sta addr lda >end+4 sta addr+1
i dalej będzie procedura generująca 200 razy prog. zmieniający kolory w każdej linii. (Jest za długa aby ją tu umieszczać.) Składa się ona ze zwykłego przepisania wartości z tablic, tak aby przerwanie nie marnowało czasu na długie rozkazy typu: lda tb4+175 ale zadowalało się rozkazami typu: lda #$16 (wartość $16 została wcześniej pobrana z tablicy tb4+175). Zysk: 1 cykl. Każdy fragment przerwania kończy się rozkazem inc 0, które nie ma niczego robić, ale tylko zająć 5 cykli, tak aby czas tworzenia 1 linii przez Antic był równy czasowi wykonywania tego fragmentu przerwania przez procesor. Jednakże, pamięć obrazka została podzielona na dwie części i kiedy Anticowi podaje się do żarcia tę drugą część (w dliście wygląda to jak:
dta b($4e),a(obr2)), to procesor ma o 2 pla cykle mniej czasu. clc Należy więc zmienić ten adc #1 rozkaz na lda 0, który cmp #$66 zajmuje 3 cykle. bne s4 Ten program rozpoznaje pha właściwy wiersz i dec addr+1 dokonuje drobnej zmiany ldy #$fe (bajt $a5) w już wygene- lda #$a5 rowanym fregmencie sta (addr),y programu. inc addr+1 pla s4 cmp #$c8 a tu sprawdza, czy to już bne s2 wszystkie linie. ldy <proc3-proc2 z kolei tutaj s5 lda proc2,y generowana jest sta (addr),y procedura dey wyjścia z bpl s5 przerwania. lda dane+5 Ten fragment programu ldx #0 jest o tyle ciekawy, że ldy #$ff wykorzystany jest tutaj s6 iny nic nie robiący rozkaz s7 lsr @ bit $4a. Kiedy jednak bcc s9+1 wykonamy skok w bajt lsr @ stanowiący operand $4a bcc s8 to wykona się rozkaz inx lsr @. Pozwala to znacznie inx skrócić program. Polecam inx tę sztuczkę każdemu. inx Ten fragment akurat s8 inx dokonuje ustawienia inx położeń pocisków na s9 bit $4a podstawie dane+5 oraz inx ich szerokości. Ponieważ inx to nieistotne część pha programu wyrzuciłem: (......) pla (akurat tę zapisującą cpy #3 już wartości) i zostawiłem bne s6 wyjście z pętli. Teraz rzecz najgorsza, czyli programy pracujące w przerwaniach. Na początek procedury przepisywane. (Patrz wyżej.)
-PROC1 to procedura wygenerowywana 200 razy. Była już o niej mowa wcześniej.
-PROC2 to procedura kończąca przerwanie.
-PROC3 zawiera kilka 4-bajtowych procedur służących ustawieniu (z dokładnością do 1 cyklu) miejsca zmian kolorów. Kazda 4-ka bajtów różni się czasem wykonywania.
-DL tu się zaczyna przerwanie. Zwykłe ustawianie wartości itp. Jedyny ciekawy fragment to:
ldx #11 ciekawy dlatego, że nic nie dex robi. Chodzi tutaj jedynie o bne *-1 przeczekanie trochę cykli lda (0,x) aż sprawa nie przycichnie... lda 0 tfu... co ja mówię!!! end equ * od tego miejsca wpisywane są poszczególne procedury: 4 bajty wzięte z PROC3, następnie 200*PROC1, a w końcu PROC2.
Ostatnia linia w programie wygląda tak: end
Jest to najważnieszy rozkaz w programie. Jak twierdzi pewna dobrze obeznana z tym osoba, każdy dobrze napisany program kończy się tym rozkazem, po czym można poznać, że programista skończył pracę, a nie usnął w jej trakcie.
Jak widziecie metoda pokazywania obrazków stworzonych GED-em (gadem?) jest dość prosta.
UNARC.XEX