PISZEMY DEMOProgram 1Program Equ $8800 List_mem Equ %00000110 List_err Equ %00000101 Code_mem Equ %00010000 Code_dsk Equ %00100000 Colpf2 Equ $D018 Dliv Equ $0200 Dlptrs Equ $0230 Rtclok Equ $12 Nmien Equ $D40E Wsync Equ $D40A Pom Equ $F0 Opt List_err+Code_mem Org Program Jmp Init Przerw Pha Txa Pha Tya Pha Ldx #$D0 Ldy Rtclok+$02 L1 Sty Colpf2 Sty Wsync Iny Dex Bne L1 Pla Tay Pla Tax Pla Rti Init Lda Dlptrs Sta Pom Lda Dlptrs+1 Sta Pom+1 Lda Dliv Pha Lda Dliv+1 Pha Ldy #$00 Lda (Pom),y Ora #$80 Sta (Pom),y LdxZarówno w tym jak i w kolejnych programach korzystamy ze znanej procedury Klawisz oczekującej na wciśnięcie dowolnego klawisza, oraz z dotąd nie znanej procedury Init. Pierwsza część procedury Init ustawia wektor przerwania Display List oraz inicjuje go. Po powrocie z procedury Klawisz przywracana jest wartość wektora Dliv i na tym procedura się kończy. A co się dzieje w procedurze przerwania (etykieta Przerw)? Po odłożeniu wszystkich rejestrów na stos wykonywana jest jedna pętla, która realizuje efekt tęczy. Rejestr X służy jako licznik pętli, natomiast rejestr Y zachowuje wartość koloru linii. Dzięki temu, że jest on zwiększany w każdym przebiegu pętli, kolory układają się w tęczę. Pozostaje jeszcze do wyjaśnienia rola rejestru Rtclok. Rejestr Rtclok ($12) jest to 3-bajtowy zegar czasu rzeczywistego. W momencie włączenia komputera (lub "zimnego startu") jest on zerowany. Następnie w każdym obiegu przerwania systemowego VBLK jest on zwiększany o jeden. Jak już wiemy przerwanie VBLK wykonywane jest 50 razy na sekundę, czyli z taką samą prędkością, jak przerwanie Display List. Dzięki temu najmłodszy bajt zegara ($14) zwiększa się po wykonaniu procedury przerwania. Wracając do naszego przykładu: kolor pierwszej linii pobierany jest z Rtclok'a. Program 2Program Equ $8800 List_mem Equ %00000110 List_err Equ %00000101 Code_mem Equ %00010000 Code_dsk Equ %00100000 Colpfl Equ $D017 Colpf2 Equ $D018 Dliv Equ $0200 Dlptrs Equ $0230 Nmien Equ $D40E Wsync Equ $D40A Pom Equ $F0 Opt List_err+Code_mem Org Program Ldy #$00 Ldx #$07 L1 Tya Asl @ Sta Kolory,y Txa Asl @ Sta Kolory+$08,y Iny Dex Bpl L1 Ldy #$01 L2 Tya Pha Ldx #$00 Asl @ Asl @ Asl @ Asl @ Tay L3 Lda Kolory,x Sta Kolory,y Inx Iny Cpx #$10 Bne L3 Pla Tay Iny Cpy #$0C Bne L2 Jmp Init Przerw Pha Txa Pha Tya Pha Ldx #$00 L4 Lda Kolory,x Sta Colpf2 Eor #$FF Sta Colpfl Sta Wsync Inc Kolory,x Inx Cpx #$C0 Bne L4 Pla Tay Pla Tax Pla Rti Kolory Dta B ($00) End of filePrzed wywołaniem procedury Init tworzona jest tablica kolorów. Realizują to dwie pętle. Pierwsza z nich tworzy szesnastobajtową tablicę o następujących wartościach: $00, $02, $04, $06, $08, $0A, $0C, $0E, $0E, $0C, $0A, $08, $06, $04, $02, $00. Pętla druga powiela tę tablicę $0C razy. Procedura przerwania Display List to znów jedna pętla, w której pobierane są kolejne wartości z tablicy kolorów i wpisywane do dwóch rejestrów kolorów: do znanego nam już z poprzednich programów Colpf2 i (po wykonaniu operacji logicznej) do Colpf1 określającego w trybie Antic'a 2 kolor tekstu. Również w tej samej pętli poszczególne elementy tablicy zwiększane są o jeden. Program 3Program Equ $8800 List_mem Equ %00000110 List_err Equ %00000101 Code_mem Equ %00010000 Code_dsk Equ %00100000 Colbak Equ $D01A Colbks Equ $2C8 Dliv Equ $200 Dlptrs Equ $230 Nmien Equ $D40E Wsync Equ $D40A Pom Equ $F0 Opt List_err+Code_mem Org Program Ldx #$00 Stx Poz_y Stx Licznik Jmp Init Przerw Pha Tya Pha Txa Pha Ldy Poz_y Lda Pozycje,y Tax Inc Poz_y Cpy #$1E Bne L2 Ldy Licznik Clc Lda Kolory,y Adc #$10 Sta Kolory,y Ldy #$00 Inc Licznik Lda Licznik Cmp #$0E Bne L1 Sty Licznik L1 Sty Poz_y L2 Sta Wsync Sta Wsync Dex Bpl L2 Ldy #$00 L3 Lda Kolory,y Sta Colbak Sta Wsync Sta Wsync Sta Wsync Iny Cpy #$0E Bne L3 Lda Colbks Sta Colbak Pla Tax Pla Tay Pla Rti Poz_y Dta B($00) Licznik Dta B($00) Kolory Equ * Dta B($D2),B($D4),B($D6) Dta B($D8),B($DA),B($DC) Dta B($DE),B($DE),B($DC) Dta B($DA),B($D8),B($D6) Dta B($D4),B($D2) Pozycje Equ * Dta B($20),B($21),B($21) Dta B($22),B($22),B($23) Dta B($24),B($26),B($28) Dta B($2A),B($2C),B($2F) Dta B($32),B($35),B($38) Dta B($3C),B($38),B($35) Dta B($32),B($2F),B($2C) Dta B($2A),B($28),B($26) Dta B($24),B($23),B($22) Dta B($22),B($21),B($21) Dta B($20) End of fileW programie korzystamy z dwóch tablic. Pierwsza z nich to tablica kolorów modyfikowana w trakcie wykonywania programu, natomiast druga to tablica pozycji "rury". Do poprawnego działania konieczne są jeszcze dwa rejestry: Pos_y wskazujący na element w tablicy pozycji i Licznik wskazujący na element tablicy kolorów. Przed uruchomieniem przerwania obydwa te rejestry otrzymują wartość $00. W samej procedurze przerwania wybierana jest wartość z tablicy pozycji wskazywana przez Poz_y i zapisywana w rejestrze X procesora. Jeśli tablica pozycji już się skończyła, to konieczne jest wyzerowanie Poz_y oraz zmodyfikowanie tablicy kolorów: element tablicy kolorów wskazywany przez Licznik zwiększany jest o $10 a następnie Licznik zwiększany jest o $01. W przypadku, gdy osiągnie wartość $0E (co oznacza, że tablica kolorów się skończyła) należy go też wyzerować. Od etykiety L2 zaczyna się część programu tworząca "rurę". Przypomnijmy, że w rejestrze X znajduje się wartość pobrana z tablicy Pozycje. W pętli zmniejszana jest wartość rejestru X i zarazem "opuszczane" są po dwie linie ekranu podczas każdego obiegu pętli, co powoduje, że "rura" skacze. W kolejnej pętli wyświetlana jest sama "rura" na ramce ekranu. Wartości kolorów odkładane są w rejestrze Colbak. Przed zakończeniem procedury przerwania do rejestru Colbak wpisywana jest wartość jego ciena - Colbaks (niestety byliśmy zmuszeni zmienić nazwę etykiety Colbaks na Colbks ze względu na to, że dla QA Colbak i Colbaks to to samo). Program 4Program Equ $8800 List_mem Equ %00000110 List_err Equ %00000101 Code_mem Equ %00010000 Code_dsk Equ %00100000 Colpf2 Equ $D018 Dliv Equ $0200 Dlptrs Equ $0230 Nmien Equ $D40E Wsync Equ $D40A Pom Equ $F0 Opt List_err+Code_mem Org Program Ldx #$00 Stx Licznik Stx Licznik+$01 Txa L1 Sta Kolory,x Inx Bne L1 Ldy #$00 Ldx #$0F L2 Tya Eor #$30 Sta Kolory+$20,y Txa Eor #$30 Sta Kolory+$30,y Iny Dex Bpl L2 Jmp Init Przerw Pha Txa Pha Tya Pha Ldx #$00 Stx Licznik L3 Clc Lda Licznik+$01 Adc Licznik Tax Ldy #$07 L4 Lda Kolory,x Sta Wsync Sta Colpf2 Inx Dey Bpl L4 Inc Licznik Ldx Licznik Cpx #$1A Bne L3 Inc Licznik+$01 Ldx Licznik+$01 Cpx #$48 Bne L5 Ldx #$00 Stx Licznik+$01 L5 Pla Tay Pla Tax Pla Rti Licznik Dla B($00),B($00) Kolory Dla B($00) End of filePodobnie jak poprzednik, program korzysta z dwóch komórek pamięci (etykieta Licznik) i tablicy kolorów. Tablica kolorów kreowana jest przed uruchomieniem przerwania. Miejsce w pamięci przeznaczone na tablicę jest zerowane w pierwszej pętli, a wraz z nim zerowane są liczniki. W kolejnej pętli od $20 elementu tablicy wpisywane są wartości od $30 do $3F a od elementu $30 w odwrotnej kolejności. Dane nie są wpisywane na początek tablicy po to, aby efekt rozpoczął się na dole ekranu. Na początku procedury Display List zerowany jest licznik zliczający w całej procedurze ilość małych "rur". Licznik+$01 wskazuje na element tablicy kolorów. W pętli L4 tworzona jest jedna mała "rura", następnie zwiększany jest Licznik. Wartość $1A w Liczniku oznacza utworzenie wszystkich $1A "rur". Dzięki dodawaniu na początku pętli L3 ułożenie kolorów w każdej z małych "rur" jest inne. Po zmianie kolorów Licznik+$01 zwiększany jest o jeden. W przypadku, gdy osiągnie koniec tablicy ($48) jest zerowany. W następnym artykule zakończymy zmagania z Antic'em definiując własne zestawy znaków. Rafał Bielecki
Tomasz Bielak |