Tajemnice ATARI

PROGRAMOWANIE PROCESORA 6502
W KOMPUTERACH ATARI XL/XE

Poczta 6502

   Dostaję dużo listów. Serdecznie za nie dziękuję. Szczególnie cenne są rzeczowe uwagi dotyczące cyklu "Programowanie...", konkretne pytania i postulaty. Brane są one pod uwagę przy przygotowywaniu kolejnych odcinków kursu. Zdarzają się też przedziwne listy, na które doprawdy trudno odpowiedzieć. Jeden z czytelników uskarża się, że język wykładu jest zbyt trudny, słownictwo niezrozumiałe, a przykłady nie dają się uruchomić. Ten list roi się od błędów ortograficznych, gramatycznych i stylistycznych. Wszystkim tym, którzy uważają moją rubrykę za zbyt trudną, radzę bez złośliwości: porzućcie ten temat. Może za jakiś czas, gdy poznacie lepiej swój komputer, nabierzecie wprawy w programowaniu w Basicu i Pascalu, język asemblera wyda się Wam przystępniejszy. W żadnym jednak wypadku zabawa z komputerem nie powinna hamować postępów w nauce. Szkoła jest najważniejsza!

    Życie programisty asemblerowego obfituje w klęski o niepowodzenia, stresy, załamania nerwowe oraz wszelkie inne plagi. Rozmiar wiedzy niezbędnej do wchłonięcia jest ogromny. Szeregu problemów charakterystycznych dla języka maszynowego i asemblera nie spotyka się w innych językach programowania. Jeden z czytelników pyta: "Jaka instrukcja lub instrukcje asemblera odpowiadają rozkazowi basicowemu GRAPHICS 0?". Oczywiście nie ma gotowej recepty. Sposób postępowania będzie zależał od kontekstu, czyli tego, co działo się dotąd w komputerze oraz tego, co zamierzamy zrobić dalej. Najprostszą znaną mi metodą byłby skok
       JMP GR0
do systemowej procedury, która wykonuje wspomnianą instrukcję Basica. Niestety, należałoby ją poprzedzić deklaracją GR0 EQU .... ale nie znam stosownego adresu. W tej sytuacji stosuję więc trik, który polega na otwarciu kanału dla urządzenia "E:". System sam wykona akcję "GRAPHICS 0".
READ   EQU 4
WRITE  EQU 8
OPEN   EQU 3
EOL    EQU $9B

IOCB   EQU $340
IO_COM EQU IOCB+2
IO_ADR EQU IOCB+4
IO_MOD EQU IOCB+10
CHN1   EQU $10
CIOV   EQU $E456

       ORG $480
GR0    LDX #CHN1
       LDA #OPEN
       STA IO_COM,X
       LDA E
       STA IO_ADR+1,X
       LDA #READ+WRITE
       STA IO_MOD,X
       JSR CIOV
   W tym momencie na ekranie jest już tryb 0. Oczywiście nie można tak po prostu pozostawić aktywnego kanału. Ponieważ nie będzie więcej używany, należy go zamknąć.
CLOSE  EQU 12

       LDA #CLOSE
       STA IO_COM,X
       JSR CIOV
GROMożna to zrobić bez obawy, że CLOSE "zabierze" tryb z ekranu. Ta sztuczka została zastosowana między innymi w programie Panther. Powyższy program może służyć do przywrócenia standardowego ekranu z poziomu DOS-u. Wiele DOS-ów nie regeneruje ekranu po zmianie trybu np. na 8 w BASIC-u lub w jakimś programie, o ile program sam tego nie zrobi. Należy dopisać zakończenie
DOSVEC EQU $OA
RUNAD  EQU $2EO

       JMP (DOSVEC)

E      DTA C'E:',B(EOL)

       ORG RUNAD
       DTA A(GR0)
     
       END 
   Taki program, wygenerowany po dołączeniu z przodu
DOS    EQU %100000
ERR    EQU %000101
       OPT ERR+DOS
i zasemblowaniu na dysk (kasetę) pod nazwą CLS.COM nadaje się do uruchomienia z poziomu dowolnego systemu DOS.

    Czasem jednak zdarza się, że sekretny zamysł zmusi nas do tworzenia trybu 0 na własną rękę. Do tego niezbędna jest wiedza o budowie programu ANTIC-a (Display List). Myślę, że wszyscy (czytelnicy cyklu "Piszemy Demo") Już ją posiadamy. Umieszczenie DL w programie pozwala ulokować obszar ekranu praktycznie w dowolnym miejscu pamięci. Spróbujmy napisać taki "program" bez programu, który objawi się naszym oczom podczas wczytywania:
DOS    EQU %100000
ERR    EQU %000101
       OPT ERR+DOS
   Pierwszą czynnością będzie skierowanie ANTIC-u na nasz, nie istniejący jeszcze, program DL. W tym celu wstawiamy adres DL do słowa DLPTR. Zamiast zbędnych LDA i STA definiujemy po prostu dwubajtowy blok danych, a resztę zrobi za nas DOS lub COS:
DLPTR  EQU $230
DL_ORG EQU $9C20
       
       ORG DLPTR
       DTA A(DL)
    Analogicznie należy zdefiniować dane DL:
       ORG DL_ORG
DL     DTA B($70),DTA B($70),DTA B($70)
       DTA B($42),A(SCR)
       DTA B($02),DTA B($02),DTA B($02)
       DTA B($02),DTA B($02)
       DTA B($02),DTA B($02)
       DTA B($02),DTA B($02)
       DTA B($02),DTA B($02)
       DTA B($02),DTA B($02)
       DTA B($02),DTA B($02)
       DTA B($02),DTA B($02)
       DTA B($02),DTA B($02)
       DTA B($02),DTA B($02)
       DTA B($02),DTA B($02)
       DTA B($41),A(DL)
   Zwróć uwagę, że nasza DL ma się znaleźć pod adresem $9C20, czyli tam, gdzie się zwykle mieści podczas pracy z BASIC-em. Jeżeli uruchomimy nasz program przy nieobecnym BASIC-u, to DL (i podążający za nią ekran) znajdzie się w nietypowym w tych warunkach miejscu. Po zakończeniu programu cała ta struktura pozostanie oczywiście widoczna w telewizorze, podczas gdy inne adresy, jak SAVMSC ($58) wskazują całkiem co innego. To powoduje nieco zamieszania, gdyż komunikaty systemu będą się "pokazywać" w niewidocznym dla nas miejscu. Jedynym rozsądnym zakończeniem tarapatów będzie użycie przycisku RESET. Można, rzecz jasna, ustalić DL_ORG na $BC20, tak jak w systemie bez BASIC-u, ale wówczas program uruchomiony przy BASIC-u zachowa się jeszcze gorzej: pokaże "sieczkę", gdyż obszar ten znajdzie się w obrębie ROM-u. Jest to ważna, choć nie jedyna wada prezentowanego programu.
SCR    DTA D'****** EKRAN TESTOWY'
       DTA D' WIERSZ #01 ********'
       DTA D'****** EKRAN TESTOWY'
       DTA D' WIERSZ #02 ********'
       DTA D'****** EKRAN TESTOWY'
       DTA D' WIERSZ #24 ********'
z brakującymi 21 wierszami w miejscu kropek. Oczywiście, zamiast przepisywać bezmyślnie "EKRAN TESTOWY" możesz pofolgować swojej wyobraźni i wypełnić ekran według własnego uznania, na przykład obrazkiem ze znaczków semigraficznych. W przykładzie każdy 40-znakowy wiersz został podzielony na dwie części po 20 znaków z powodu ograniczonej szerokości szpalty w TA. Jednak we własnym programie można. a nawet należy wpisywać każdy wiersz ekranu w jednej linijce. Pseudorozkaz DTA typu D służy do definiowania danych przeznaczonych do wyświetlania na ekranie w formie znaków. Kody tych znaków, generowane przez QA różnią się od kodów ASCII (uzyskiwanych przez DTA typu C), tak jak wymaga tego ANTIC. Trzeba o tym pamiętać, gdy sami umieszczamy dane w pamięci ekranu. Przy korzystaniu z CIO napisy podaje się w ASCII, gdyż system sam dokonuje konwersji.

    Tu dostrzegamy drugą poważną wadę tego sposobu wyświetlania. Program musi zawierać dane całego ekranu i DL, czyli bez mała 1K bajtów, choć czasem spora część ekranu świeci pustką lub powtarza ten sam wzór.

    Niestety, choć program jest już niemal gotowy, okazuje się, że niektóre DOS-y próbują ZAWSZE wykonać wczytany program, nawet gdy nie podamy adresu uruchomienia. Oto więc adres:
RUNAD  EQU $2EO
DUMMY  EQU $E450
    
       ORG RUNAD 
       DTA A(DUMMY)
   Jest to systemowa procedura inicjalizacji sterownika dysku, znana z literatury jako DISKIV (co można humorystycznie odczytać jako DISK4 albo DISKI5). Jest bardzo krótka, niewiele robi (czytaj: psuje), nie stwierdziłem jej szkodliwego działania w żadnych warunkach. Wykorzystuję ją zazwyczaj jako równoważnik rozkazu RTS, którym jest zakończona, gdy nie mam pod ręką żadnego innego RTS-a.

    Pozostaje problem RESET-u, który trzeba wykonać dla przywrócenia właściwych parametrów ekranu. Pozostawienie tego zapominalskiemu użytkownikowi byłoby nieroztropne. Z drugiej strony trzeba zostawić trochę czasu na zapoznanie się z obrazem. 10 sekund powinno wystarczyć:
CDTMV2 EQU $21A 
CDTMA2 EQU $228 
T      EQU 500 (10 * 50)

       ORG CDTMV2
       DTA A(T)
   Wpisanie wartości do licznika CDTMV2 inicjuje odliczanie czasu. Ponieważ jednostką jest tu 1/50 sekundy, więc na sekundę trzeba ich 50. Po odliczeniu do zera system wykona skok do adresu podanego w CDTMA2. Trzeba tam wpisać (szybko, zanim upłynie te 10 sekund!)
WARMST EQU $E474
     
       ORG CDTMA2 
       DTA A(WARMST)

       END
   Proszę zauważyć, że w całym programie nie padł ani jeden rozkaz maszynowy! Pokazana metoda nie nadaje się do krótkich programów uruchamianych DOS-em. Doskonała jest natomiast do czołówek gier, w trybie graficznym.

Janusz B. Wiśniewski



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

Pixel 2002