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
|