Programowanie stacji LDW Super 2000 i CA-2001
From Atariki
Wersja z dnia 18:48, 7 lut 2006 Sc0rpi0 (Dyskusja | wkład) (Complete) ← Previous diff |
Aktualna wersja Trub (Dyskusja | wkład) (aktualny link) |
||
Linia 1: | Linia 1: | ||
+ | Do stacji [[Indus GT]], [[LDW Super 2000]] i [[CA-2001]] można przesyłać własne podprogramy i zlecać ich wykonanie. | ||
- | Używając komendy SIO "X" można przesyłać/wykonywać małe fragmenty własnych programów, pamiętając oczywiście, że w stacjach dysków LDW 2000 znajduje się procesor z rodziny Z80, więc wszelkie programy muszą być zapisane w kodzie maszynowym tego właśnie procesora. Można przy tym skorzystać z wbudowanych w ROM funkcji. Nie ma oczywiście gwarancji niezmienności tej tabeli funkcji, ale jest duże tego prawdopodobieństwo. | + | == Od strony Atari == |
+ | Do programowania stacji służy komenda [[SIO]] o kodzie $58 ("X"). Ma ona dwie postaci, pierwsza służy do przesłania programu, druga do uruchomienia go wraz z ewentualnym odebraniem wyników. | ||
- | Aby użyć danej funkcji nalezy jej numer załadować do rejestru C procesora, a następnie wywołać procedurę spod adresu $0004 (call). Rejestry, z których korzysta się przy wywołaniu/powrocie z funkcji znajdują się w nawiasach, z wyjątkiem funkcji 0C, która używa | + | === Przesyłanie programu === |
- | flagi przeniesienia (carry) procesora (CF). | + | W pierwszym przypadku parametry [[DCB]] ustawia się tak, jak do każdego nadawania danych przez SIO: |
- | Poniżej lista funkcji (numery funkcji zapisane szesnastkowo): | + | * DDEVIC - wartość $31 |
+ | * DUNIT - numer stacji | ||
+ | * DCMND - kod $58 ("X") | ||
+ | * DSTATS - wartość $80 (zapis) | ||
+ | * DBUFA - adres, gdzie znajduje się kod do wysłania | ||
+ | * DTIMLO - timeout jak do zapisu sektora (8) | ||
+ | * DBYT - liczba bajtów do wysłania (zawsze <= 256) | ||
+ | * DAUX1 - to samo, co w młodszym bajcie DBYT | ||
+ | * DAUX2 - wartość $01 (download) | ||
- | 00 - zwraca wersje ROMu (DE)<BR> | + | Wywołanie [[Tablica skoków#JSIOINT|JSIOINT]] ($E459) z takimi parametrami spowoduje wysłanie programu do stacji. W tej chwili na jej konsolce powinna zapalić się lampka BUSY. |
- | 01 - powrót głowicy<BR> | + | |
- | 02 - ustawienie głowicy nad konkretną półścieżką (D)<BR> | + | |
- | 03 - odczyt sektora (E) ze scieżki (D)<BR> | + | |
- | 04 - zapis sektora (E) na scieżce (D)<BR> | + | |
- | 05 - odbiór bajtu (transmisja szeregowa) (C)<BR> | + | |
- | 06 - wysłanie bajtu (A)<BR> | + | |
- | 07 - odbiór rekordu o długości (B) pod adres (DE)<BR> | + | |
- | 08 - wysłanie rekordu o długości (B) spod adresu (DE)<BR> | + | |
- | 09 - konwersja pojedynczej cyfry wyswietlacza (A) do (A)<BR> | + | |
- | 0A - konwersja dwucyfrowa decymalna (A) do (DE)<BR> | + | |
- | 0B - konwersja dwucyfrowa heksadecymalna (A) do (DE)<BR> | + | |
- | 0C - włączenie (CF=1) lub wyłączenie (CF=0) silnika<BR> | + | |
- | 0D - aktualizacja statusu przełączników i zmiany dysku.<BR> | + | |
- | 0E - zwraca adres bieżącego bufora (BC)<BR> | + | |
- | 0F - zwraca adres flagi typu kontrolera (IX)<BR> | + | |
- | 10 - wytworzenie dźwięku na linii audio<BR> | + | |
- | 11 - aktualizacja wyświetlacza<BR> | + | |
- | 12 - zwraca adresy rejestrów (odczyt/zapis) kontrolera (BC i DE)<BR> | + | |
- | 13 - ustawienie gęstości zapisu w zależności od trybu<BR> | + | |
- | 14 - zwraca adresy statusu i bieżącej półścieżki (DE i IX)<BR> | + | |
- | [[Kategoria:Peryferia_8-bit]] | + | === Wykonywanie programu === |
+ | Uruchomienie przesłanego kodu uzyskujemy tą samą komendą "X", tylko z nieco innymi parametrami. | ||
+ | |||
+ | * DSTATS powinien zawierać wartość $80, gdy uruchomiony kod oczekuje nadesłania z komputera dodatkowych danych; $40, gdy ma przesłać z powrotem do komputera jakieś wyniki; $C0, gdy zachodzi jedno i drugie, albo $00, gdy nic nie jest przesyłane. | ||
+ | * DBUFA to adres bufora na dane wynikowe, | ||
+ | * do DBYT trzeba wpisać ich spodziewaną ilość (w bajtach); | ||
+ | * wartość timeout (DTIMLO) też jest zależna od tego, co robi przesłany program i ile czasu mu to zajmuje - na ogół jednak timeout "8" (10,24 sek.) powinien wystarczyć dla większości zadań. | ||
+ | * DAUX1 - wartość $00 | ||
+ | * DAUX2 - wartość $00 (execute) | ||
+ | |||
+ | Wywołanie JSIOINT spowoduje uruchomienie przez stację przesłanego kodu. Po zakończeniu procedury lampka BUSY na konsolce stacji powinna zgasnąć. | ||
+ | |||
+ | Ważny szczegół jest taki, że pomiędzy przesłaniem programu a jego wykonaniem nie można wysyłać do stacji żadnych innych rozkazów - gdy się to zrobi, stacja "zapomni" o kodzie załadowanym przez użytkownika i nie będzie można dokonać uruchomienia. | ||
+ | |||
+ | == Od strony stacji == | ||
+ | Program dla stacji musi być napisany w asemblerze Z80, gdyż taki właśnie procesor, taktowany zegarem 4 MHz, się tam znajduje. Komenda "X" ładuje kod do pamięci stacji pod adres $7F00. Ponieważ stacja typowo ma tylko 2k pamięci RAM zlokalizowanej w obszarze $7800-$7FFF, a pod wyższymi adresami zawartość całej pamięci od początku powtarza się, zatem przesyłany jednorazowo blok nie może mieć więcej niż 256 bajtów, gdyż bufor programu zajmuje ostatnią stronę pamięci RAM. | ||
+ | |||
+ | Ważne: procedura przesłana rozkazem "X" odpowiada za poprawne zakończenie transmisji SIO, tj. zwłaszcza za zadbanie, by komputer dostał końcowe potwierdzenie wykonania ("C") lub sygnał błędu ("E"). Jeśli w chwili opuszczania procedury (rozkazem RET) bit CF rejestru znaczników Z80 jest ustawiony, stanowi to sygnał dla stacji, że ma sama zakończyć transmisję przesyłając do komputera kod potwierdzenia umieszczony w rejestrze A (patrz przykład nr 1). W przeciwnym wypadku, gdy CF=0, jest to sygnał, że program użytkownika zatroszczył się o dopełnienie protokołu i żadne dalsze działania nie są potrzebne (patrz przykład 2). | ||
+ | |||
+ | === Tabela funkcji ROM-u === | ||
+ | |||
+ | Programy mogą skorzystać z wbudowanych w [[ROM]] funkcji. Nie ma oczywiście gwarancji niezmienności tej tabeli funkcji, ale jest duże tego prawdopodobieństwo. | ||
+ | |||
+ | Aby użyć danej funkcji należy jej numer załadować do rejestru C procesora, a następnie wywołać (rozkazem CALL) procedurę spod adresu $0004. Rejestry, z których korzysta się przy wywołaniu/powrocie z funkcji znajdują się w nawiasach, z wyjątkiem funkcji 0C, która używa flagi przeniesienia (carry) procesora (CF). | ||
+ | |||
+ | * $00 - zwraca numer wersji ROM-u (DE) | ||
+ | * $01 - powrót głowicy | ||
+ | * $02 - ustawienie głowicy nad konkretną ścieżką (D); numer ścieżki musi być pomnożony przez dwa | ||
+ | * $03 - odczyt sektora (E) ze ścieżki (D) | ||
+ | * $04 - zapis sektora (E) na ścieżce (D) | ||
+ | * $05 - odbiór bajtu z SIO (C) | ||
+ | * $06 - wysłanie bajtu na SIO (A) | ||
+ | * $07 - odbiór z SIO rekordu o długości (B) pod adres (DE); długość $00 oznacza 256 bajtów | ||
+ | * $08 - wysłanie na SIO rekordu o długości (B) spod adresu (DE) z zadanym potwierdzeniem (A); długość $00 to 256 bajtów | ||
+ | * $09 - konwersja cyfry do formatu odpowiedniego dla wyświetlacza (A do A) | ||
+ | * $0A - konwersja dwucyfrowa decymalna (A do DE) | ||
+ | * $0B - konwersja dwucyfrowa heksadecymalna (A do DE) | ||
+ | * $0C - włączenie (CF=1) lub wyłączenie (CF=0) silnika | ||
+ | * $0D - aktualizacja statusu przełączników i zmiany dysku | ||
+ | * $0E - zwraca adres bieżącego bufora (BC) | ||
+ | * $0F - zwraca adres flagi typu kontrolera (IX) | ||
+ | * $10 - wytworzenie dźwięku na linii audio | ||
+ | * $11 - aktualizacja wyświetlacza | ||
+ | * $12 - zwraca adresy rejestrów (odczyt/zapis) kontrolera (BC i DE) | ||
+ | * $13 - ustawienie gęstości zapisu w zależności od trybu | ||
+ | * $14 - zwraca adresy statusu i bieżącej ścieżki (DE i IX); numer ścieżki musi być pomnożony przez dwa | ||
+ | |||
+ | === Porty I/O === | ||
+ | |||
+ | * IN $0,$1 - sygnał audio | ||
+ | * IN $2,$3 - włączenie śledzenia impulsu indeksowego | ||
+ | * IN $4,$5 - inwertowanie linii TxD gniazda SIO | ||
+ | * IN $6,$7 - inwertowanie linii RxD gniazda SIO | ||
+ | * IN $8,$9 - włączanie/wyłączanie sygnału DDEN dla FDC | ||
+ | * IN $A,$B - włączenie/wyłączenie silnika | ||
+ | * IN $C,$D - wygenerowanie impulsu indeksowego | ||
+ | * IN $E,$F - wyłączenie/włączenie [[RAM Charger]]a w obszarze $0000-$7FFF. | ||
+ | |||
+ | === Mapka pamięci === | ||
+ | |||
+ | <table border = 1 cellpadding = 5> | ||
+ | <tr><td><b>Adres</b></td><td><b>Opis</b></td></tr> | ||
+ | <tr><td>$0000-$0FFF</td><td>ROM z oprogramowaniem wewnętrznym stacji (4 kB).</td></tr> | ||
+ | <tr><td>$1000-$1FFF</td><td> | ||
+ | <p>2 porty ośmiobitowe tylko do odczytu. $1000 i $1001 działają tak samo, z tym, że odczyt tego pierwszego zeruje zatrzaski.</p> | ||
+ | * bit 7: przycisk PROTECT | ||
+ | * bit 6: przycisk ERROR | ||
+ | * bit 5: przycisk ID | ||
+ | * bit 4: przycisk TRACK | ||
+ | * bit 3: nieużywany | ||
+ | * bit 2: stan przełącznika gęstości (sprawdzane tylko przy włączeniu zasilania) | ||
+ | * bit 1: wybór numeru napędu, stan przełącznika nr 2 | ||
+ | * bit 0: wybór numeru napędu, stan przełącznika nr 1 | ||
+ | </td></tr> | ||
+ | <tr><td>$2000-$2FFF</td> | ||
+ | <td><p>1 port ośmiobitowy:</p> | ||
+ | * bit 7: INTRQ (kontroler FDD) | ||
+ | * bit 6: DRQ (kontroler FDD) | ||
+ | * bit 5: COMMAND (SIO) | ||
+ | * bit 4: READY (SIO) | ||
+ | * bit 3: DATA IN (SIO) | ||
+ | * bit 2: DATA OUT (SIO) | ||
+ | * bit 1: CLOCK IN (SIO) | ||
+ | * bit 0: CLOCK OUT (SIO) | ||
+ | </td></tr> | ||
+ | <tr><td>$3000-$3FFF</td><td> | ||
+ | <p>1 port ośmiobitowy tylko do zapisu: sterowanie silnikiem krokowym napędu. Używane są tylko bity 0-3.</p> | ||
+ | </td></tr> | ||
+ | <tr><td>$4000-$4FFF</td><td><p> | ||
+ | 1 port ośmiobitowy: prawa cyfra wyświetlacza. Skasowanie danego bitu powoduje zaświecenie się odpowiedniego segmentu wyświetlacza:</p> | ||
+ | * bit 0 - szczytowy segment | ||
+ | * bit 1 - prawy, góry segment | ||
+ | * bit 2 - prawy, dolny segment | ||
+ | * bit 3 - najniższy segment | ||
+ | * bit 4 - lewy, dolny segment | ||
+ | * bit 5 - lewy, górny segment | ||
+ | * bit 6 - środkowy segment | ||
+ | * bit 7 - lampka BUSY | ||
+ | </td></tr> | ||
+ | <tr><td>$5000-$5FFF</td><td><p>1 port ośmiobitowy: lewa cyfra wyświetlacza. Działa analogicznie do prawej, z tym, że bit 7 to ENPRE (enable precompensation) dla FDD.</p></td></tr> | ||
+ | <tr><td>$6000-$6FFF</td><td><p>Kontroler FDD:</p> | ||
+ | * $6000 - COMMAND/STATUS | ||
+ | * $6001 - TRACK | ||
+ | * $6002 - SECTOR | ||
+ | * $6003 - DATA | ||
+ | </td></tr> | ||
+ | <tr><td>$7000-$77FF</td><td><p>Powtórka adresów $7800-$7FFF</p></td></tr> | ||
+ | <tr><td>$7800-$7FFF</td><td> | ||
+ | <p>Pamięć RAM (2 kB):</p> | ||
+ | * $7824-$7941 - bufor I/O (286 bajtów) | ||
+ | * $7942-$7A7F - pamięć wewnętrzna (318 bajtów) | ||
+ | * $7A80-$7B7F - stos Z80 (256 bajtów) | ||
+ | * $7B80-$7EFF - pamięć wewnętrzna (896 bajtów); tu m.in. rezyduje [[Synchromesh]] | ||
+ | * $7F00-$7FFF - bufor programu użytkownika (256 bajtów) | ||
+ | </td></tr> | ||
+ | </table> | ||
+ | |||
+ | Do bufora programu stacja wczytuje też pierwszy sektor włożonej dyskietki, gdy zostaną naciśnięte jednocześnie klawisze "DRIVE" i "ERROR", a potem próbuje go uruchomić. Służy to przede wszystkim do bootowania systemu [[CP/M]] - oczywiście tylko w stacjach z pamięcią RAM rozszerzoną do 64k. | ||
+ | |||
+ | === Przykłady === | ||
+ | |||
+ | ==== Przykład nr 1: brzęknięcie dzwonkiem stacji ==== | ||
+ | Program wywołuje "sygnał ostrzegawczy" na linii audio, ten sam, którym stacja się posługuje dla zasygnalizowania np. błędów odczytu. Nie towarzyszy temu transmisja danych do komputera (DSTATS=$00), a o wysłanie potwierdzenia wykonania rozkazu "X" martwi się stacja. | ||
+ | |||
+ | LD C,$10 ;0e 10 numer funkcji: "bell" | ||
+ | CALL $0004 ;cd 04 00 wykonać | ||
+ | LD A,$43 ;3e 43 kod potwierdzenia: "C" (Complete) | ||
+ | SCF ;37 CF=1 - potwierdzenie z A wyśle ROM stacji | ||
+ | RET ;c9 powrot | ||
+ | |||
+ | ==== Przykład nr 2: odczytanie numeru wersji ROM ==== | ||
+ | Program przesyła do komputera dwa bajty stanowiące numer wersji ROM-u stacji zapisany w postaci dziesiętnej. Najpierw przesyłany jest numer rewizji, następnie numer wersji - a więc odpowiedź w rodzaju $20,$01 trzeba rozumieć jako wersję "1.20". Procedura wysyła też końcowe potwierdzenie wykonania rozkazu "X". Kod pochodzi z programu [[Synchromesh]] dla [[CA-2001]]. | ||
+ | |||
+ | LD C,$00 ;0e 00 numer funkcji: "version" | ||
+ | CALL $0004 ;cd 04 00 wykonać | ||
+ | LD ($7F17),DE ;ed 53 17 7F zapisz DE pod adres $7F17 w pamięci stacji | ||
+ | LD DE,$7F17 ;17 17 7F adres danych do przesłania umieść w DE | ||
+ | LD B,$02 ;06 02 ilość danych wynikowych (dwa bajty) | ||
+ | LD C,$08 ;0e 08 numer funkcji: "send record" | ||
+ | LD A,$43 ;3e 43 kod potwierdzenia: "C" (Complete) | ||
+ | CALL $0004 ;cd 04 00 wykonać | ||
+ | OR A ;b7 CF=0 - transmisja zakończona | ||
+ | RET ;c9 powrót | ||
+ | |||
+ | == Zobacz też == | ||
+ | * [https://atariwiki.org/wiki/Wiki.jsp?page=Indus%20GT%20Firmware%20ROM%20Source Indus GT Firmware ROM source] | ||
+ | |||
+ | [[Kategoria:Peryferia_8-bit|LDW 2000 Super, Funkcje ROM]] | ||
+ | [[Kategoria:Programowanie Atari 8-bit|LDW 2000 Super, Funkcje ROM]] | ||
+ | [[Kategoria:Niezbędnik kodera]] |
Aktualna wersja
Do stacji Indus GT, LDW Super 2000 i CA-2001 można przesyłać własne podprogramy i zlecać ich wykonanie.
Spis treści |
Od strony Atari
Do programowania stacji służy komenda SIO o kodzie $58 ("X"). Ma ona dwie postaci, pierwsza służy do przesłania programu, druga do uruchomienia go wraz z ewentualnym odebraniem wyników.
Przesyłanie programu
W pierwszym przypadku parametry DCB ustawia się tak, jak do każdego nadawania danych przez SIO:
- DDEVIC - wartość $31
- DUNIT - numer stacji
- DCMND - kod $58 ("X")
- DSTATS - wartość $80 (zapis)
- DBUFA - adres, gdzie znajduje się kod do wysłania
- DTIMLO - timeout jak do zapisu sektora (8)
- DBYT - liczba bajtów do wysłania (zawsze <= 256)
- DAUX1 - to samo, co w młodszym bajcie DBYT
- DAUX2 - wartość $01 (download)
Wywołanie JSIOINT ($E459) z takimi parametrami spowoduje wysłanie programu do stacji. W tej chwili na jej konsolce powinna zapalić się lampka BUSY.
Wykonywanie programu
Uruchomienie przesłanego kodu uzyskujemy tą samą komendą "X", tylko z nieco innymi parametrami.
- DSTATS powinien zawierać wartość $80, gdy uruchomiony kod oczekuje nadesłania z komputera dodatkowych danych; $40, gdy ma przesłać z powrotem do komputera jakieś wyniki; $C0, gdy zachodzi jedno i drugie, albo $00, gdy nic nie jest przesyłane.
- DBUFA to adres bufora na dane wynikowe,
- do DBYT trzeba wpisać ich spodziewaną ilość (w bajtach);
- wartość timeout (DTIMLO) też jest zależna od tego, co robi przesłany program i ile czasu mu to zajmuje - na ogół jednak timeout "8" (10,24 sek.) powinien wystarczyć dla większości zadań.
- DAUX1 - wartość $00
- DAUX2 - wartość $00 (execute)
Wywołanie JSIOINT spowoduje uruchomienie przez stację przesłanego kodu. Po zakończeniu procedury lampka BUSY na konsolce stacji powinna zgasnąć.
Ważny szczegół jest taki, że pomiędzy przesłaniem programu a jego wykonaniem nie można wysyłać do stacji żadnych innych rozkazów - gdy się to zrobi, stacja "zapomni" o kodzie załadowanym przez użytkownika i nie będzie można dokonać uruchomienia.
Od strony stacji
Program dla stacji musi być napisany w asemblerze Z80, gdyż taki właśnie procesor, taktowany zegarem 4 MHz, się tam znajduje. Komenda "X" ładuje kod do pamięci stacji pod adres $7F00. Ponieważ stacja typowo ma tylko 2k pamięci RAM zlokalizowanej w obszarze $7800-$7FFF, a pod wyższymi adresami zawartość całej pamięci od początku powtarza się, zatem przesyłany jednorazowo blok nie może mieć więcej niż 256 bajtów, gdyż bufor programu zajmuje ostatnią stronę pamięci RAM.
Ważne: procedura przesłana rozkazem "X" odpowiada za poprawne zakończenie transmisji SIO, tj. zwłaszcza za zadbanie, by komputer dostał końcowe potwierdzenie wykonania ("C") lub sygnał błędu ("E"). Jeśli w chwili opuszczania procedury (rozkazem RET) bit CF rejestru znaczników Z80 jest ustawiony, stanowi to sygnał dla stacji, że ma sama zakończyć transmisję przesyłając do komputera kod potwierdzenia umieszczony w rejestrze A (patrz przykład nr 1). W przeciwnym wypadku, gdy CF=0, jest to sygnał, że program użytkownika zatroszczył się o dopełnienie protokołu i żadne dalsze działania nie są potrzebne (patrz przykład 2).
Tabela funkcji ROM-u
Programy mogą skorzystać z wbudowanych w ROM funkcji. Nie ma oczywiście gwarancji niezmienności tej tabeli funkcji, ale jest duże tego prawdopodobieństwo.
Aby użyć danej funkcji należy jej numer załadować do rejestru C procesora, a następnie wywołać (rozkazem CALL) procedurę spod adresu $0004. Rejestry, z których korzysta się przy wywołaniu/powrocie z funkcji znajdują się w nawiasach, z wyjątkiem funkcji 0C, która używa flagi przeniesienia (carry) procesora (CF).
- $00 - zwraca numer wersji ROM-u (DE)
- $01 - powrót głowicy
- $02 - ustawienie głowicy nad konkretną ścieżką (D); numer ścieżki musi być pomnożony przez dwa
- $03 - odczyt sektora (E) ze ścieżki (D)
- $04 - zapis sektora (E) na ścieżce (D)
- $05 - odbiór bajtu z SIO (C)
- $06 - wysłanie bajtu na SIO (A)
- $07 - odbiór z SIO rekordu o długości (B) pod adres (DE); długość $00 oznacza 256 bajtów
- $08 - wysłanie na SIO rekordu o długości (B) spod adresu (DE) z zadanym potwierdzeniem (A); długość $00 to 256 bajtów
- $09 - konwersja cyfry do formatu odpowiedniego dla wyświetlacza (A do A)
- $0A - konwersja dwucyfrowa decymalna (A do DE)
- $0B - konwersja dwucyfrowa heksadecymalna (A do DE)
- $0C - włączenie (CF=1) lub wyłączenie (CF=0) silnika
- $0D - aktualizacja statusu przełączników i zmiany dysku
- $0E - zwraca adres bieżącego bufora (BC)
- $0F - zwraca adres flagi typu kontrolera (IX)
- $10 - wytworzenie dźwięku na linii audio
- $11 - aktualizacja wyświetlacza
- $12 - zwraca adresy rejestrów (odczyt/zapis) kontrolera (BC i DE)
- $13 - ustawienie gęstości zapisu w zależności od trybu
- $14 - zwraca adresy statusu i bieżącej ścieżki (DE i IX); numer ścieżki musi być pomnożony przez dwa
Porty I/O
- IN $0,$1 - sygnał audio
- IN $2,$3 - włączenie śledzenia impulsu indeksowego
- IN $4,$5 - inwertowanie linii TxD gniazda SIO
- IN $6,$7 - inwertowanie linii RxD gniazda SIO
- IN $8,$9 - włączanie/wyłączanie sygnału DDEN dla FDC
- IN $A,$B - włączenie/wyłączenie silnika
- IN $C,$D - wygenerowanie impulsu indeksowego
- IN $E,$F - wyłączenie/włączenie RAM Chargera w obszarze $0000-$7FFF.
Mapka pamięci
Adres | Opis |
$0000-$0FFF | ROM z oprogramowaniem wewnętrznym stacji (4 kB). |
$1000-$1FFF |
2 porty ośmiobitowe tylko do odczytu. $1000 i $1001 działają tak samo, z tym, że odczyt tego pierwszego zeruje zatrzaski.
|
$2000-$2FFF | 1 port ośmiobitowy:
|
$3000-$3FFF |
1 port ośmiobitowy tylko do zapisu: sterowanie silnikiem krokowym napędu. Używane są tylko bity 0-3. |
$4000-$4FFF | 1 port ośmiobitowy: prawa cyfra wyświetlacza. Skasowanie danego bitu powoduje zaświecenie się odpowiedniego segmentu wyświetlacza:
|
$5000-$5FFF | 1 port ośmiobitowy: lewa cyfra wyświetlacza. Działa analogicznie do prawej, z tym, że bit 7 to ENPRE (enable precompensation) dla FDD. |
$6000-$6FFF | Kontroler FDD:
|
$7000-$77FF | Powtórka adresów $7800-$7FFF |
$7800-$7FFF |
Pamięć RAM (2 kB):
|
Do bufora programu stacja wczytuje też pierwszy sektor włożonej dyskietki, gdy zostaną naciśnięte jednocześnie klawisze "DRIVE" i "ERROR", a potem próbuje go uruchomić. Służy to przede wszystkim do bootowania systemu CP/M - oczywiście tylko w stacjach z pamięcią RAM rozszerzoną do 64k.
Przykłady
Przykład nr 1: brzęknięcie dzwonkiem stacji
Program wywołuje "sygnał ostrzegawczy" na linii audio, ten sam, którym stacja się posługuje dla zasygnalizowania np. błędów odczytu. Nie towarzyszy temu transmisja danych do komputera (DSTATS=$00), a o wysłanie potwierdzenia wykonania rozkazu "X" martwi się stacja.
LD C,$10 ;0e 10 numer funkcji: "bell" CALL $0004 ;cd 04 00 wykonać LD A,$43 ;3e 43 kod potwierdzenia: "C" (Complete) SCF ;37 CF=1 - potwierdzenie z A wyśle ROM stacji RET ;c9 powrot
Przykład nr 2: odczytanie numeru wersji ROM
Program przesyła do komputera dwa bajty stanowiące numer wersji ROM-u stacji zapisany w postaci dziesiętnej. Najpierw przesyłany jest numer rewizji, następnie numer wersji - a więc odpowiedź w rodzaju $20,$01 trzeba rozumieć jako wersję "1.20". Procedura wysyła też końcowe potwierdzenie wykonania rozkazu "X". Kod pochodzi z programu Synchromesh dla CA-2001.
LD C,$00 ;0e 00 numer funkcji: "version" CALL $0004 ;cd 04 00 wykonać LD ($7F17),DE ;ed 53 17 7F zapisz DE pod adres $7F17 w pamięci stacji LD DE,$7F17 ;17 17 7F adres danych do przesłania umieść w DE LD B,$02 ;06 02 ilość danych wynikowych (dwa bajty) LD C,$08 ;0e 08 numer funkcji: "send record" LD A,$43 ;3e 43 kod potwierdzenia: "C" (Complete) CALL $0004 ;cd 04 00 wykonać OR A ;b7 CF=0 - transmisja zakończona RET ;c9 powrót