Programowanie 6502Errare humanum estW poprzednim odcinku proponowałem Państwu testowanie "buta" kasetowego przez wykonanie zimnego startu z klawiszami SELECT I START. Oczywiście miałem na myśli klawisze START I OPTION. Za pomyłkę przepraszam. Po prostu jest tych klawiszy tak wiele, że trudno się w tym wszystkim połapać. I jeszcze sprostowanie do sprostowania z TA 6/91: znów pominąłem grupę rozkazów, które modyfikują znacznik C. Są to: CMP, CPX, CPY czyli rozkazy porównania zawartości odpowiednio rejestrów A, X, Y z argumentem w pamięci. Miała baba koguta......wsadziła go do boota! Użytkowników ATARI z pamięcią taśmową można poznać z daleka po charakterystycznym skrzywieniu sylwetki. Lewa ręka jest nieco dłuższa, wyciągnięta w kierunku wyłącznika zasilania, palce prawej układają się w rodzaj widełek, które nieomylnie trafiają w klawisze OPTION i START. A przecież jest to postawa unikalna w świecie komputerów. Maszyny PC włącza się rano, a wyłącza wieczorem, są także komputery, które nie usypiają nigdy... Ożywia je system operacyjny, którego zadaniem jest uruchamianie kolejnych programów, zgodnie z żądaniami użytkowników. ATARI XL/XE jest w pełni przystosowany do takiego stylu pracy, lecz niestety, brak jest ogólnie uznanego standardu, któremu wierni byliby programiści. Tymczasem zasada jest prosta. Istnieje tylko jeden "boot": jest nim dyskowy lub kasetowy system operacyjny. Każdy inny program powinien się uruchamiać pod kontrolą tego systemu (z zasady DOS oferuje więcej możliwości, niż komputer sam z siebie) i po zakończeniu działania do niego powrócić. Niedopuszczalny jest brak w programie opcji wyjścia (zmuszanie użytkownika do wyłączania zasilania stanowi jawny zamach na jego czas i portfel, bo zwiększa ryzyko awarii). KanałyNie te na Marsie i nie w Wenecji, lecz tu, w pamięci naszego ATARI, kanały wejścia/wyjścia są niezwykle ważne dla działania komputera, a na dodatek wcale ich nie ma. Mianem kanału określa się bowiem coś ulotnego: metodę realizacji połączenia pomiędzy uniwersalną procedurą wejścia/wyjścia, zwaną CIO, a sterownikiem konkretnego urządzenia. Dzięki tej metodzie możliwe jest jednakowe traktowanie wszystkich urządzeń zewnętrznych, niezależnie od ich fizycznych właściwości. Prostym przykładem użycia kanału będzie wysłanie tą drogą napisu "Hej, to ja!". Zobaczmy to na żywym programie:
OPT %10101
ORG $480
OPEN EQU 3 Przez tak otwarty kanał można teraz przesyłać dane, co też niezwłocznie uczynimy:
PISZ EQU 11
CLOSE EQU 12 Dopiszmy do naszego programu jeszcze przykładowy tekst:
EOLN EQU 155 Pozostaje jeszcze tylko nazwa urządzenia, czy raczej ściślej: nazwa pliku wraz z określeniem urządzenia. Tu mamy szeroki wybór: Jeżeli napiszemy
NAME DTA C'E:'
NAME DTA C'P:'
NAME DTA C'D:DOWOL.TXT'
END
JSR CIOV NakładkiW tym miejscu, aby poszerzyć sobie horyzonty, zajrzyjmy do artykułu "Jak powstają DOS-y", który zawiera nieco więcej informacji na ten temat, po czym być moje ogarnie nas chęć wykonania rezydentnego sterownika jakiegoś nowego urządzenia, np. "B:", co można uznać za skrót słowa "border", które oznacza ramkę ekranu. Nic łatwiejszego:
OPT %100101
RANDOM EQU $D20A
INIT JSR 0
LDX #'B'
LDA NEWML
CLOSE LDA #0
NEWML DTA A(ENDBH)
BHTAB DTA A(OPEN-1)
ENDBH EQU *
SETINI LDX #1 Bo oto uwaga! Prezent pod choinkę! Następujący program potrafi przemieszczać w pamięci dowolne programy, z góry w dół, na granicę MEMLO, pod warunkiem zachowania kilku prostych zasad (większość z nich zasygnalizowano w tym przykładzie): Relokator następuje tuż po segmencie danych i musi mieć zdefiniowane dwie etykiety: STAR__ określa początek programu do przesuwania (znajdzie się on pod adresem zawartym w MEMLO), USER__ wskazuje na procedurę, która będzie wykonana PRZED rozpoczęciem przemieszczania programu. Wszystkie etykiety użyte w relokatorze kończą się dwoma znakami podkreślenia dla uniknięcia konfliktów z nazwami w przesuwanym programie. |
STAR__ EQU START USER__ EQU SETINI *------------------* * * * Relocator 1.0 * * * * by JBW * * * * may'88 * * * *------------------* *--- page 0 -------- BYTE__ EQU $CE DATF__ EQU $CF DIST__ EQU $D0 (2) SRCE__ EQU $D2 (2) DEST__ EQU $D4 (2) ADDR__ EQU $D6 (2) *--- system -------- RUNA__ EQU $2E0 (2) MELO__ EQU $2E7 (2) *--- move ---------- MOVE__ EQU * JSR USER * disable RUN comm LDA #$60 (RTS) STA MOVE__ * clear data flag LDA #0 STA DATF__ * destination LDA MELO__ STA DEST__ LDA MELO__+1 STA DEST__+1 * code source, distance SEC LDA <STAR__ STA SRCE__ SBC DEST__ STA DIST__ LDA >STAR STA SRCE__+1 SBC DEST__+1 STA DIST__+1 *** move process *** LDY #0 BEQ MOVL__ (JMP) SEDA__ SEC ROR DATF__ MOVL__ EQU * LDA SRCE__ CMP <MOVE LDA SRCE__+1 SBC >MOVE__ BCC DCHK__ * done ! JMP (MELO__) * data flag check DCHK__ BIT DATF__ BVS MOV1__ BMI TPE3__ INST__ EQU * LDA (SRCE__),Y STA BYTE__ STA (DEST__),Y JSR INCA__ TAX BEQ SEDA__ * instr type check CMP #$20 JSR BEQ TPE3__ CMP #$40 RTI BEQ MOVL__ CMP #$60 RTS BEQ MOVL__ AND #$0D CMP #$08 x8,xA BEQ MOVL__ BCC MOV1__ TXA AND #$lF CMP #$09 BEQ MOV1__ * 3-byte instruction TPE3__ EQU * LDA (SRCE__),Y INY CMP <STAR__ LDA (SRCE__),Y DEY SBC >STAR__ BCC MOV2__ LDA (SRCE__),Y INY CMP <MOVE__ LDA (SRCE__),Y DEY SBC >MOVE__ BCS MOV2__ * alter abs adresses LDA DIST__ LDX DIST__+1 BCC MOVA__ * move w/o changes MOV2__ BIT DATF__ BMI SEDA__ LDA #0 TAX * move 2b address MOVA__ EQU * STA ADDR__ STX ADDR__+1 SEC LDA (SRCE__),Y SBC ADDR__ STA (DEST__),Y JSR INCA__ LDA (SRCE__),Y SBC ADDR__+1 JMP SD__ * move 1b data MOV1__ EQU * LDA (SRCE__),Y SD__ STA (DEST__),Y JSR INCA__ JMP MOVL__ *inc SRCE,DEST - INCA__ INC SRCE__ BNE *+4 INC SRCE__+1 INC DEST__ BNE *+4 INC DEST__+1 RTS *---- start ------- ORG RUNA__ DTA A(MOVE__) END |
Podczas asemblacji powstanie plik typu COM, który można uruchomić spod DOS-u lub COS-u. Zaprezentowane tu urządzenie "B:" jest pomocne przy testach własnych programów I/O. Pozwala zapisywać dane, mrugając do
taktu ramką obrazu i odczytywać losowe pliki nie zawierające zer (oczywiście dane odczytywane nie mają żadnego związku z zapisywanymi). Janusz B. Wiśniewski
|