Tajemnice ATARI

Piszemy DEMO


    Artykuł 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 
          Rts
    Procedura 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
          Rts
    Powyż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 File
    Program 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



Powrót na start | Powrót do spisu treści | Powrót na stronę główną

Pixel 2002