Piszemy DEMOArtykuł dotyczy procedur obsługi płynących napisów w pierwszej części naszego dema. Poniżej zamieszczone są trzy procedury, które należy skompilować na dysk i zachować, oraz dodatkowe dwie procedury pomocnicze. Procedura "HSCROLL.ASM" realizuje przesuw poziomy dwu najmniejszych płynących napisów. Oto jej tekst źródłowy: Procedure Equ $9DA5 List_mem Equ %00000110 List_err Equ %00000101 Code_mem Equ %00010000 Code_dsk Equ %00100000 DList Equ $9800 HHScrol Equ $0089 Text Equ $7000 Opt List_err+Code_dsk Org Procedure Jmp InitScrl IntProc Dec HHScrol Lda HHScrol Cmp #$0B Bne L2 Lda #$0F Sta HHScrol Inc DList+$28 Inc DList+$78 Bne L1 Inc DList+$29 Inc DList+$79 L1 Lda DList+$28 Cmp #$E0 Bne L2 Lda DList+$29 Cmp #$71 Bne L2 Lda <Text Sta DList+$28 Sta DList+$78 Lda >Text Sta DList+$29 Sta DList+$79 L2 Rts InitScrl Lda #$0F Sta HHScrol RtsProcedura odwołuje się do zamieszczanych w poprzednich artykułach procedur: "DLI.ASM", "DLIV.ASM" oraz korzysta z tekstu umieszczonego w pamięci od adresu $7000. Uruchomienie procedury powoduje wykonanie jedynie jej fragmentu od etykiety InitScrl - ustawienie zmiennej HHScrol. Dla przypomnienia podajemy, że zmienna ta przechowuje wartość rejestru Hscrol dla płynących napisów i jest przepisywana do Hscrol'a podczas przerwania Display List. Właściwy przesuw napisu wykonuje dopiero główna część procedury (od etykiety IntProc), która jest wywoływana co 1/50 sekundy przez przerwanie Timer'a 2. W każdym obiegu tego przerwania zmniejszana jest wartość HHScrol, co powoduje delikatne przesuwanie napisów. W przypadku gdy HHScrol osiągnie wartość $OB, oba napisy trzeba przesunąć zgrubnie poprzez zwiększenie adresów pamięci ekranu w Display List i ustawienie HHScroll'a na początkową wartość. Gdy tekst się skończy, należy puścić go od początku. Druga procedura to "VSCROLL.ASM". Obsługuje ona dwa pionowe napisy w grafice PMG. Procedure Equ $9D49 List_mem Equ %00000110 List_err Equ %00000101 Code_mem Equ %00010000 Code_dsk Equ %00100000 Pomoc Equ $0080 Start_pl Equ $9000 Text Equ $6E00 VText Equ $0084 Znak Equ $9A92 Opt List_err+Code_dsk Org Procedure Jmp Init_Scrl IntProc Lda Licznik Bne L3 Ldy #$00 Lda (VText),y Inc VText Bne L1 Inc VText+$01 Ldx VText+$01 Cpx #$70 Bne L1 Ldx >Text Stx VText+$01 L1 Jsr Znak Ldy #$00 Ldx #$00 L2 Lda (Pomoc),y Sta Start_pl+$04A2,x Sta Start_pl+$04A3,x Iny Inx Inx Cpy #$08 Bne L2 L3 Ldx #$00 L4 Lda Start_pl+$0432,x Sta Start_pl+$0431,x Sta Start_pl+$0631,x Inx Cpx #$80 Bne L4 Inc Licznik Lda Licznik Cmp #$10 Bne L5 Lda #$00 Sta Licznik L5 Rts Init_Scrl Ldx <Text Ldy >Text Stx VText Sty VText+$01 Rts Licznik Dta B($00)Podobnie jak poprzednia, ta procedura korzysta z tekstu, tym razem umieszczonego od adresu $6E00. Obszar grafiki PMG wskazywany jest przez etykietę Start_pl. Wykorzystywane są również dwubajtowe zmienne umieszczone na stronie zerowej: Pomoc (zmienna pomocnicza) oraz VText (wskazująca na kolejną literę tekstu). Jak poprzednio, wywołanie procedury inicjuje tylko odpowiednie zmienne (VText). Część główna procedury rozpoczyna się od etykiety IntProc. Na początku sprawdzana jest wartość Licznika (zmienna, która przyjmuje wartości od $OO do $00. Jeśli Licznik jest różny od zera, to wystarczy tylko przepisać dane w obszarze pamięci PMG o jeden bajt w górę, co spowoduje przesunięcie tekstu. Gdy Licznik równy jest zero, oznacza to, że napis został przesunięty o całą literę i trzeba pobrać kolejny znak z tekstu (wskazuje na nią zmienna VText) i wywołać procedurę Znak ze znakiem w akumulatorze. Procedura ta zwraca w zmiennej Pomoc adres znaku w zestawie znaków: Procedure Equ $9A92 List_mem Equ %00000110 List_err Equ %00000101 Code_mem Equ %00010000 Code_dsk Equ %00100000 Zestaw Equ $E000 Pomoc Equ $0080 Opt List_err+Code_dsk Org Procedure Pha And #$60 Lsr @ Lsr @ Lsr @ Lsr @ Lsr @ Clc Adc >Zestaw Sta Pomoc+$01 Pla And #$1F Asl @ Asl @ Asl @ Sta Pomoc RtsPowyższa procedura korzysta ze standardowego zestawu znaków Atari, umieszczonego od adresu $E000. Proponujemy skompilowanie wersji tej procedury ze zmienionym adresem zestawu znaków na $8C00, gdyż w przyszłości w tym miejscu pamięci będzie się znajdował zestaw znaków ze zdefiniowanymi przez nas polskimi literami. Wróćmy do opisu procedury "VSCROLL.ASM". Po odnalezieniu adresu znaku w zestawie należy przepisać wygląd znaku w pamięć PMG. Ostatnia procedura przesuwu napisu w pierwszej części dema to "BSCROLL.ASM". Procedura ta tworzy płynący napis o szerokości i wysokości ośmiu znaków trybu $02 Antic'a: Procedure Equ $9DE6 List_mem Equ %00000110 List_err Equ %00000101 Code_mem Equ %00010000 Code_dsk Equ %00100000 BHScrol Equ $0088 BText Equ $0086 Dlist Equ $9800 Pomoc Equ $0080 Pomoc2 Equ $0082 Scrol2 Equ $6600 Text Equ $7200 Znak Equ $9A92 Opt List_err+Code_dsk Org Procedure Jmp Init_Scrl IntProc Lda BHScrol Eor #$02 Sta BHScrol Cmp #$0F Bne L8 Ldx #$15 L1 Inc Dlist+$7D,x Dex Dex Dex Bpl L1 Lda Dlist+$7D Cmp #$08 Bne L8 Ldx #$15 Ldy #$07 L2 Lda Tab,y Sta Dlist+$7D,x Dex Dex Dex Dey Bpl L2 Ldx <Scrol2 Ldy >Scrol2 Stx Pomoc2 Sty Pomoc2+$01 Ldy #$00 Lda (BText),y Jsr Znak Ldy #$00 L3 Tya Pha Lda (Pomoc),y Pha Ldx #$2F L4 Ldy #$08 Lda (Pomoc2),y Ldy #$00 Sta (Pomoc2),y Inc Pomoc2 Bne L5 Inc Pomoc2+$01 L5 Dex Bpl L4 Pla Ldx #$00 L6 Ldy #$00 Asl @ Bcc L7 Ldy #$03 L7 Pha Tya Ldy #$00 Sta (Pomoc2),y Inc Pomoc2 Pla Inx Cpx #$08 Bne L6 Pla Tay Iny Cpy #$08 Bne L8 Inc BText Bne L8 Inc BText+$01 Lda BText+$01 Cmp #$74 Bne L8 Lda >Text Sta BText+$01 L8 Rts Init_Scrl Ldx <Text Ldy >Text Stx BText Sty BText+$01 Lda #$0F Sta BHScrol Rts Tab Dta B($00),B($38),B($70) Dta B($A8),B($E0),B($18) Dta B($50),B($88)"BSCROLL.ASM" wykorzystuje zmienną BHScroll, przechowującą wartość HScrol'a tego napisu (podobnie jak w procedurze HHScroll) oraz znane procedury Dlist i Źnak Dwubajtowa zmienna BText wskazuje na kolejny znak tekstu, którego początek wskazuje stała Text ($7200). Stała Scrol2 określa adres początku pamięci ekranu dla pierwszej linii płynącego napisu. Po uruchomieniu procedury inicjowane są wartości zmiennych BText i BHScrol. W każdym obiegu przerwania wykonuje się główna cześć procedury (od etykiety IntProc). Na początku modyfikujemy wartość BHScrol'a, co powoduje delikatny przesuw tekstu. Gdy BHScrol osiągnie wartość $Of, robiony jest zgrabny przesuw kolejnych linii ekranu (pętla L1). Gdy przesunięcie zgrubne zostanie wykonane osiem razy, to najpierw przywracane są początkowe wartości adresów kolejnych linii pamięci ekranu (pętla L2) na podstawie tabeli Tab zażerającej młodsze bajty tych adresów. Potem zmienna Pomoc2 przyjmuje wartość stałej Scrol2 i pobierany jest następny znak z tekstu. Rozpoczyna się główna pętla (etykieta L3). Instrukcje w niej zawarte wykonywane są osiem razy. W trakcie każdego obiegu tej pętli modyfikowana jest kolejna linia ekranu. Pobierany jest każdy bajt wyglądu znaku i odkładany na stos. Potem w wewnętrznej pętli L4 przesuwane są kolejne bajty pamięci ekranu o osiem w lewo, co daje przesunięcie części dużej litery o jeden znak. W następnej pętli wewnętrzej (etykieta L6) bajt pobrany ze stosu rozkładany jest na bity i w ten sposób tworzony jest wygląd części kolejnego dużego znaku. Jeśli bit znaku jest ustawiony, to w pamięć ekranu wpisywana jest wartość $03, w przeciwnym wypadku - zero. Każda część dużego znaku zawiera się w jednej linii ekranu, czyli operacja przesunięcia i tworzenia nowego znaku jest wykonywana odrębnie dla każdej linii. Gdy tekst się skończy, to zmienna BText przyjmuje początkową wartość. Na zakończenie tego artykułu prezentujemy program, który pozwala oglądnąć efekty dotychczasowej pracy. Program należy nagrać na dysk i skompilować. Aby uruchomić całość, należy załadować zbiory: DLI.OBJ, DLIV.OBJ, PLAYER.OBJ, ZNAK.OBJ, BSCROLL.OBJ, HSCROLL.OBJ, VSCROLL.OBJ, RUN1.0BJ i zbiór z tekstem z poprzedniego artykułu utworzony przy pomocy Zgrywusa. "Mini-Demo" uruchamia się zleceniem RUN 600. Procedure Equ $0600 List_mem Equ %00000110 List_err Equ %00000101 Code_mem Equ %00010000 Code_dsk Equ %00100000 Cdtma2 Equ $0228 Cdtmv2 Equ $021A BScroll Equ $9DE6 Dli Equ $9800 Dliv Equ $9897 HScroll Equ $9DA5 Player Equ $9B5B VScroll Equ $9D49 Opt List_err+Code_dsk Org Procedure Jsr Dli Jsr Dliv Jsr Player Jsr BScroll Jsr HScroll Jsr VScroll Ldx <Timer_2 Ldy >Timer_2 Stx Cdtma2 Sty Cdtma2+$01 Koniec Lda #$01 Sta Cdtmv2 Rts Timer_2 Lda Licznik Eor #$01 Sta Licznik Bne L1 Jsr Player+$03 L1 Jsr HScroll+$03 Jsr VScroll+$03 Jsr BScroll+$03 Jmp Koniec Licznik Dta B($00) End of FileProgram inicjuje wszystkie procedury oraz przerwanie Timer'a 2, w którym wywoływane są kolejno procedury płynących napisów, i - co drugi obieg przerwania - procedurę "PLAYER.ASM". Tomasz Bielak
Rafał Bielecki |