Trochę trwało, zanim Dariusz "DarkDK" Kubasz doprowadził do szczęśliwego finału swój flagowy projekt - podpięcia pecetowej myszki do Atari. Interfejs, który swoją ostateczną formę oraz nazwę DarkMouse otrzymał wczoraj, zaczął na serio budować w 2006 roku. Niniejszy tekst powstał na podstawie dokumentacji autorstwa DarkDK.
1. DarkMouse
Interfejs umożliwia podłączenie myszki standardu PS/2 do 8-bitowego Atari. Zbudowany jest w oparciu o mikrokontroler PIC16F628 i kilka elementów dyskretnych. Został zaprojektowany jako zewnętrzny, bez potrzeby dokonywania przeróbek w samym Atari. Z tego powodu procedury obsługujące transmisję pomiędzy Atari a PIC są w moim odczuciu dosyć wolne, lecz zdecydowanie szybsze i wygodniejsze w użyciu niż procedury obsługujące myszy od Atari ST i Amigi. Pierwotnie interfejs miał wykorzystywać dwa porty joysticków w celu uproszczenia i przyśpieszenia transmisji. Ostatecznie interfejs wykorzystuje tylko jeden port (dowolny, według uznania programisty). Nic nie stoi na przeszkodzie aby podłączyć dwa interfejsy i dwie myszki PS/2 do Atari.
tak wygląda pierwszy egzemplarz DarkMouse
2. Co w pakiecie?
Obecna edycja interfejsu, schematu i oprogramowania oznakowana jest liczbą 0.5. Paczka podesłana przez Darka zawiera dokumentację i schemat podłączenia myszy PC do małego Atari:
pcmouse2atari_ver05.hex - plik do zaprogramowania PIC16F628
pcmouse2atari.asm - źródła procedur w formacie MADS
pcmouse2atari_schemat.png - schemat interfejsu
pcmouse2atari.doc - dokumentacja w formacie MS Word
lepix-src-0.2.0_pcmouse - katalog ze źródłami i plikem xex programu graficznego LePix 0.2.0, w wersji obsługującego myszkę PC
readme.txt - plik tekstowy ze spisem plików
3. Obsługa interfejsu
Interfejs uruchamia się w trybie PCMOUSE. Aby przejść do trybu emulacji joysticka należy przycisnąć klawisz w interfejsie i wcisnąć lewy przycisk myszy, po czym zwolnić przycisk w interfejsie. Aby powrócić do trybu PCMOUSE należy zrobić jeszcze raz to samo. Aby zmienić rozdzielczość (szybkość działania myszki) należy przycisnąć klawisz w interfejsie, kółkiem wybrać rozdzielczość i zwolnić klawisz.
4. Zasada działania interfejsu
Ogólny schemat działania:
krok 1: inicjacja interfejsu
krok 2: rozpoznanie urządzenia PS/2 - wykonuje się dopóki nie nastąpi poprawne rozpoznanie urządzenia
krok 3: odczyt raportu (stany liczników, przycisków, itd.) urządzenia PS/2
krok 4: obliczenia związane z implementacją wewnętrznych liczników
krok 5: oczekiwanie na rozkaz pochodzący od Atari
krok 6: wykonanie rozkazu
krok 7: skok do kroku 3
Nie wszystkie rozkazy działają według powyższego schematu. Szczegóły podane są poniżej, przy opisach konkretnych rozkazów. Gotowość do realizacji rozkazów sygnalizowana jest odpowiednim ustawieniem bitów w PORTA Atari.
komplet: Atari, interfejs i myszka PC
5. Rozkazy interfejsu
Rozkazy dla interfejsu można podzielić na cztery grupy:
A. Rozkazy odczytu zaimplementowanych liczników
B. Rozkazy obsługujące przesyłanie danych w trybie RAW
C. Rozkazy ustawiające rozdzielczość liczników urządzeń wskazujących PS/2
D. Pozostałe rozkazy (odczyt wersji firmware, identyfikacja interfejsu, testujące transmisję między interfejsem a Atari)
Numeracja odczytywanych bajtów zaczyna się od 0 (zera).
A. Rozkazy odczytu zaimplementowanych liczników
Schemat działania rozkazów posiadających w nazwie człon "_nwoc_":
krok 3: odczyt raportu (stany liczników, przycisków, itd.) urządzenia PS/2
krok 4: obliczenia związane z implementacją wewnętrznych liczników
krok 5: oczekiwanie na rozkaz pochodzący od Atari
krok 6: wykonanie rozkazu
krok 7: skok do kroku 3
Schemat działania rozkazów posiadających w nazwie człon "_woc_":
krok 3: odczyt raportu (stany liczników, przycisków, itd.) urządzenia PS/2
krok 4: sprawdzenie, czy wystąpiły zmiany od ostatniego raportu. Jeżeli nie, to skok do kroku 3
krok 5: obliczenia związane z implementacją wewnętrznych liczników
krok 6: oczekiwanie na rozkaz pochodzący od Atari
krok 7: wykonanie rozkazu
krok 8: skok do kroku 3
W nazwach rozkazów człony "_1B", "_2B", "_3B", "_4B", "_6B" oznaczają ilość odbieranych bajtów (1, 2, 3, 4 albo 6 ). Wartości względne liczone są od ostatniego odczytanego raportu. ; cmd_count_228_nwoc_2B, 0x20 ; cmd_count_228_woc_2B, 0x22
Odczyt liczników pozycji (wartości bezwzględne): Bajt 0: pozycja X, zakres: 0 do 228 Bajt 1: pozycja Y, zakres: 0 do 228 ; cmd_count_8bit_nwoc_2B, 0x24 ; cmd_count_8bit_woc_2B, 0x26
Odczyt 8-bitowych liczników pozycji (wartości względne): Bajt 0: pozycja X, zakres: -128 do 127 w kodzie U2 Bajt 1: pozycja Y, zakres: -128 do 127 w kodzie U2 ; cmd_count_8bit_nwoc_3B 0x28 ; cmd_count_8bit_woc_3B 0x2A
Odczyt 8-bitowych liczników pozycji oraz scroll’i (wartości względne): Bajt 0: pozycja X, zakres: -128 do 127 w kodzie U2 Bajt 1: pozycja Y, zakres: -128 do 127 w kodzie U2 Bajt 2: pozycja kółek (scroll), zakres: -8 do 7 w kodzie U2 (UWAGA! Jeżeli myszka posiada dwa kółka to: kółko wertykalne powoduje zmiany licznika o wartość 1, kółko horyzontalne powoduje zmianę licznika o 2. Nie jest możliwe jednocześnie odczytanie liczników obydwóch kółek. Jeżeli w tym samym czasie zmieniły się liczniki dwóch kółek to myszka wysyła dwa osobne raporty) ; cmd_count_9bit_nwoc_4B 0x2C ; cmd_count_9bit_woc_4B 0x2E
Odczyt 9-bitowych liczników pozycji, stanów przycisków oraz scrolli (wartości względne): Bajt 0: i bit 6 (znak) w 3 bajcie - pozycja X, zakres: -256 do 255 w kodzie U2 Bajt 1: i bit 7 (znak) w 3 bajcie - pozycja Y, zakres: -256 do 255 w kodzie U2 Bajt 2: pozycja kółek (scroll), zakres: -8 do 7 w kodzie U2 (UWAGA! Patrz opis rozkazu cmd_count_8bit_woc_3B) Bajt 3: stany przycisków ( 1 - wciśnięty): Bit 0: przycisk lewy Bit 1: przycisk prawy Bit 2: przycisk środkowy Bit 3: przycisk czwarty Bit 4: przycisk piąty Bit 5: nieużywany Bit 6: 9 bit pozycji X Bit 7: 9 bit pozycji Y
B. Rozkazy obsługujące przesyłanie danych w trybie RAW
Rozkazy te mają umożliwić obsługę myszek, tabletów niezgodnych ze standardem Microsoft Intellimouse. W tej wersji firmware (0.5) nie jest możliwa obsługa innego standardu niż Microsoft Intellimouse. Urządzenia PS/2 po resecie (włączeniu zasilania) identyfikowane są jako mysz o identyfikatorze id = 0x00. Właściwość ta jest cechą wszystkich urządzeń wskazujących, działających w oparciu o protokół PS/2. Do zadań systemu operacyjnego (np. "Windows") należy przesłanie sekwencji rozkazów przełączających urządzenie w odpowiedni tryb. Firmware interfejsu również generuje odpowiednią sekwencję rozkazów w celu wykrycia rodzaju urządzenia. W pamięci są zapisane sekwencje dla urządzeń o id=0x03 lub 0x04. ; cmd_get_raw_nwoc_3B 0x42
Odczyt raportu RAW 3 bajty. Znaczenie poszczególnych bajtów zależy od urządzenia PS/2 ; cmd_get_raw_nwoc_4B 0x44
Odczyt raportu RAW 4 bajty. ; cmd_get_raw_nwoc_6B 0x48
Odczyt raportu RAW 6 bajtów.
Schemat działania rozkazów odczytujących identyfikator, status urządzenia, ustawiające rozdzielczość i testujących:
krok 3: odczyt raportu (stany liczników, przycisków, itd.) urządzenia PS/2
krok 4: obliczenia związane z implementacją wewnętrznych liczników
krok 5: oczekiwanie na rozkaz pochodzący od Atari
krok 6: wykonanie rozkazu
krok 7: skok do kroku 5
; cmd_get_id_device_1B 0x80
Odczyt id urządzenia PS/2. Bajt 0: id urządzenia: 0x00 – zwykła mysz dwu (lub trzy?) przyciskowa 0x03 – mysz trzy przyciskowa plus kółko/a 0x04 – mysz pięcio przyciskowa plus kółko/a ; cmd_get_raw_lenght_1B 0x40
Odczyt długości raportu urządzenia PS/2 Bajt 0: długość raportu RAW w bajtach Odczytana wartość bajtu wskazuje jaki rozkaz należy użyć do odczytu raportu RAW: 3 - cmd_get_raw_nwoc_3B, 4 - cmd_get_raw_nwoc_4B, 6 - cmd_get_raw_nwoc_6B. ; cmd_get_status_request_3B 0x82
Odczyt statusu urządzenia PS/2. Bajt 0: Bit 0: przycisk prawy, 1 - wciśnięty Bit 1: przycisk środkowy, 1 - wciśnięty Bit 2: przycisk lewy, 1 - wciśnięty Bit 3: zawsze 0 Bit 4: Scaling, 1 – skalowanie 2:1, 0 – skalowanie 1:1 Bit 5: Enable, 1 – nadawanie raportów włączone, 0 - nadawanie raportów wyłączone Bit 6: Mode, 1 – Remote mode, 0 – Stream mode. Opisywane firmware obsługuje tylko remote mode. Bit 7: zawsze 0.
Bajt 1: rozdzielczość Odczytana wartość wskazuje rozdzielczość w jakiej pracuje urządzenie wskazujące: 0x00 – 1 impuls/mm 0x01 – 2 impulsy/mm 0x02 – 4 impulsy/mm 0x03 – 8 impulsów/mm
Bajt 2: ilość raportów na sekundę. W tej wersji firmware nie ma znaczenia. Odczytana wartość może wynosić 10, 20, 40, 60, 80, 100 i 200 raportów na sekundę.
DarkMouse działa!
C. Rozkazy ustawiające rozdzielczość pracy urządzeń PS/2
; cmd_set_resolution1_1B 0x60
Ustawienie rozdzielczości urządzenia PS/2 – 1 impuls/mm: Bajt 0: Wartość ACK - $FA – nie znaczący, ale trzeba odebrać. ; cmd_set_resolution2_1B 0x62
Ustawienie rozdzielczości urządzenia PS/2 – 2 impulsy/mm: Bajt 0: Wartość ACK - $FA – nie znaczący ; cmd_set_resolution4_1B 0x64
Ustawienie rozdzielczości urządzenia PS/2 – 4 impulsy/mm – wartość domyślna (po resecie): Bajt 0: Wartość ACK - $FA – nie znaczący ; cmd_set_resolution8_1B 0x66
Ustawienie rozdzielczości urządzenia PS/2 – 8 impulsów/mm: Bajt 0: Wartość ACK - $FA – nie znaczący
D. Pozostałe rozkazy (odczyt wersji firmware, testujące)
; cmd_firmware_version_1B 0x84
Odczyt wersji firmware: Bajt 0: Oznaczenie wersji firmware w kodzie BCD – obecna wartość to 0x05 (wersja 0.5) ; cmd_test_00_55_AA_3B 0x86
Rozkaz testujący transmisję pomiędzy PIC’iem a Atari. Może być wykorzystany do identyfikacji interfejsu. Bajt 0: 0x00 Bajt 1: 0x55 Bajt 2: 0xAA ; cmd_switch_test_6B 0x00 ; cmd_test_6B dowolny kod oprócz 0x00
Rozkazy testujące transmisję pomiędzy PIC a Atari. Rozkaz "cmd_switch_test_6B" powoduje potraktowanie następnego rozkazu jako "cmd_test_6B". Po wykonaniu "cmd_test_6B" następny rozkaz jest wykonywany zgodnie z jego opisem. Aby przetestować poprawność transmisji należy na przemian generować obydwa rozkazy, na przykład 0x00, 0x02, 0x00, 0x04, 0x00, 0x06, itd. Bajty 0-3: po wykonaniu "cmd_test_6B" wartość każdego bajtu zwiększana jest o 1, "cmd_switch_test_6B" nie zmienia wartości bajtów Bajt 4: suma kontrolna liczona jako suma bajtów 0-3 bez uwzględnienia przeniesień Bajt 5: kod rozkazu wykonywanego przez PIC powiększony o 1 Podczas wykonywania rozkazów testujących rejestry TRIG0 lub TRIG1 w Atari nie wskazują stanu lewego przycisku urządzenia PS/2.
6. Odczyt stanu przycisków
Interfejs DarkMouse umożliwia również odczyt stanów trzech przycisków myszy bezpośrednio z rejestrów sprzętowych Atari:
lewy przycisk - TRIGx
prawy przycisk – PADDLx
środkowy przycisk – PADDLx
Ze względu na sposób działania interfejsu nie jest możliwe odczytanie stanu lewego przycisku z rejestru TRIGx podczas przesyłu danych z interfejsu. Ponadto, aby poprawnie działał odczyt stanów przycisków, musi zachodzić komunikacja między interfejsem a Atari. W źródłach procedur komunikacyjnych zostało opisane w którym miejscu najlepiej zrealizować odczyt stanów przycisków.
7. Procedury obsługujące urządzenia PS2
Źródła znajdują się w pliku pcmouse2atari.asm w formacie MADS. Zawierają dwie główne procedury. Pierwsza – "init", odpowiedzialna za przygotowanie PORTA do transmisji. Druga – "exe_cmd_mouse" odpowiedzialna za przebieg transmisji. Można ją wywołać w przerwaniu VBL lub w głównej pętli programu. W źródłach programu "Lepix" występuje pod nazwą update.
Procedura "exe_cmd_mouse" obsługuje interfejs podłączony do dowolnego portu joysticków. Do wolnego portu można podłączyć joystick, a jego obsługa programowa nie zmienia się. Po małej modyfikacji możliwa jest obsługa dwóch interfejsów (np. dwie myszki) na raz. Procedura "exe_cmd_mouse" jest napisana tak, aby przerwania nie miały wpływu na wynik jej działania. Jedynym ograniczeniem jest maksymalny czas w jakim musi zakończyć działanie procedura komunikacji z interfejsem. Czas ten wynosi około 15 ms. Czas jest liczony od wysłania komendy do odbioru ostatniego bajtu danych. Przekroczenie tego czasu powoduje reset interfejsu. init
wej: nie ma wyj: ustawiony port A do transmisji Inicjuje port A do transmisji, wywołać raz na początku programu. Wywołanie: jsr MOUSE.init exe_cmd_mouse
wej: cmd - kod komendy cmd_c - długość odczytywego raportu (w bajtach) wyj: A=0 - nie wykonano, A=1 wykonano, w buffer znajdują się odczytane bajty procedura wykonująca komendy PIC (UWAGA! Komendy muszą być postaci xxx0xxx0 tzn 0 i 4 bit równe zero). Wywołanie można umieścić w przerwaniu VBL lub w głównej pętli programu: mva #kod_komendy MOUSE.cmd mva #ilość_odbieranych_bajtów MOUSE.cmd_c jsr MOUSE.exe_cmd_mouse
8. DarkMouse działa z LePixem
Rewelacyjny program graficzny Lepix autorstwa Marcin "Eru" Żurawskiego został wyposażony przez Darka w procedury obsługi DarkMouse, dzięki czemu praca nad grafiką stanie się jeszcze łatwiejsza. Po zeszłorocznych zmianach w programie dokonanych przez Eru oraz dzięki współpracy z myszką pecetową, LePix może stać się czarnym koniem wśród programów graficznych - jako jedyny pozwala rysować w szerokiej palecie trybów z interlacem (właściwie brakuje tylko RIP-a i trybów hi-res):
TIP (rozdzielczość 160x100 i 256 kolorów, mieszanka trzech trybów - GR.9, GR.10 i GR.11)
CIN (rozdzielczość 160x200 i 64 kolory, mieszanka dwóch trybów - GR. 15 i GR.11)
HIP (rozdzielczość 160x200 i 31 odcieni - w Lepix da się edytować 16, mieszanka dwóch trybów - GR.9 i GR.10)
INP (rozdzielczość 160x200 i 7 kolorów, mieszanka dwóch ekranów w trybie GR.15)
Lepix i tryb TIP
Ponieważ ostatnio ukazał się TipConv autorstwa Adriana "Epi" Matogi, mamy już prawie komplet dobrych narzędzi do sprawnego konwertowania i rysowania obrazków z interlacem. Oczywiście czekamy na kolejne programy, które będą rozpoznawały nie tylko myszkę od Atari ST czy Amigi, ale również pecetowską. Ciekawe, kto pierwszy napisze grę z obsługą DarkMouse?
O, kurcze pieczone. To mi się podoba! Mam nadzieję, że wykorzystanie myszki nie będzie trudne od strony programowej. Na razie i tak z tego nic nie kumam, ale mam nadzieję, że to kwestia czasu ;) Brawo!
pajero @2008-06-30 00:04:39
To teraz wiem, o jakim zakończonym projekcie wspominałeś. Świetna rzecz!
tebe @2008-06-30 01:51:27
no ładne cacko :) a jak wygląda sprawa obciążenia CPU?
darkdk @2008-06-30 09:29:34
Napewno mniejsze niż przy obsłudze myszek amigi czy st. Procedurę transmisji można wywołać w przerwaniu VBL lub w głównej pętli programu (tak jest w lepixie). Można wywoływać 50 razy na sekundę lub tyle na ile pozwala myszka. Można ograniczyć się np. do 40 albo 20 wywołań na sekundę. Interfejs sygnalizuje kiedy można odebrać dane. Czyli jeżeli nie ruszamy myszki to wykonywanych jest tylko klika rozkazów testujących. Jeżeli ruszyliśmy myszką to zaczyna się transmisja.