Myši a ZX Spectrum
Úvod
V následujícím textu jsem se pokusil shrnout pár drobností o oblíbeném polohovacím zařízení, které se mimo jiné používalo i u ZX Spectra. S prvními zmínkami o myši u ZX Spectra jsem se setkal poměrně brzy, snad už v 90tém roce, ale tenkrát nebylo ještě snadné sehnat rozumnou myš za rozumné peníze. Velmi často bylo možné koupit myši jen velmi nepraktické do ruky často velmi hranaté a silně neergonomické (např. třítlačítkové modely od firmy Genius, případně všelijaké stavebnice - mám jednu s pingpongovým míčkem a tlačítky realizovanými ze svěracích špendlíků s papírovými clonkami). Myši se samozřejmě poprvé začaly vyskytovat u počítačů orientovaných na grafiku, což byly všelijaké Apple Macintosh, Atari, Amiga a později i IBM PC. Koncem osumdesátých a začátkem devadesátých let, tj. v době největšího rozmachu ZX Spectra byly např. u Amigy myši standardní součástí výbavy u IBM PC je uživatelé teprve objevovali.
Není divu, že uživatelé ZX Spectra uživatelům "grafických" počítačů (tenkrát mezi ně IBM PC nepatřilo) trochu záviděli a přemýšleli jak si taky takovou myšku připojit a naučit se s ní pracovat. Bohužel to nebylo tak jednoduché. U ZX Spectra se vyskytovalo mnoho různých rozhranní, jak paralelních tak sériových, ale žádné nebylo rozšířeno globálně, žádné z rozhranní nikdy nemělo status standardu (byť nepsaného v rámci platformy). Takového standardu jako stavu dosáhly porty sériové, paralelní a USB na platformě PC (tím spíš, že jmenovaná rozhranní jsou skutečně standardizovaná, ale o to ani tak nejde, jde spíš o rozšířenost mezi uživateli).
Bylo tedy nutné použít rozhranní, když ne globálně rozšířené, tak alespoň trochu rozšířené a pokud možno snadno sehnatelné a levné, aby připojení už tak drahé myši (tenkrát stály často kolem 500Kčs i víc a platy se pohybovaly někde od 2,5 - 5000Kčs) nebylo zbytečně zatěžováno i drahým rozhranním. Jednou z možností byl sériový port. Sériové myši byly snadněji sehnatelné, levnější a byl v nich výrazně větší výběr. Ale ZX Spectrum jak známo nemělo standardně sériový port, kromě modelů ZX Spectrum 128kB, a šedivých ZX Spectrum +2, +2A, +3, které však měly naprosto nestandardní konektory, notabene nevhodně umístěné, protože byly zakryty prakticky jakýmkoliv zařízením připojeným k systémové sběrnici (např. Betadiskem). Tato jediná rozšířenější implementace sériového portu používá obvod AY-3-8912 jako IO port, takže řízení signálů jednak musel provádět software a druhak se v různých přídavných rozhranních používaly i jiné varianty čipu AY, případně jeho klony a často verze bez IO portů. Takže sériová myš existuje, ale je velmi obtížně připojitelná (má-li být zachována kompatibilita) s 48kB verzemi ZX Spectra včetně těch rozšířených na 128kB a doplněných AY, protože těm i po rozšíření chyběly převodníky z TTL <-> RS232 a napájecí zdroj dodávající napětí +12V a -12V. (Dnes dostupný např. MAX232 neexistoval.)
Další volbou byl logicky port paralelní a to nejčastěji UR-4. Zapojení myši do UR-4 je extrémně jednoduché, vlastně není potřeba provádět vůbec žádnou úpravu, pokud se spokojíte jen s jedním tlačítkem. Bohužel velmi zásadní nevýhodou je obrovské výkonové zatížení CPU, protože myš je potřeba obsluhovat zcela kompletně programově. Pro další činnosti, krom obsluhy myši zbývá nejvýše 50% výkonu CPU, obvykle spíš méně, pokud má být pohyb kurzoru opravdu plynulý. U klikacích menu to nevadí, ale je to zcela nepoužitelné v náročnějších hrách. Nicméně tato implementace se přesto v mém okolí rozšířila nejvíce. Částečně kvůli ART Studiu v češtině pro tento typ myši a Betadisk, trochu i kvůli mému Bootu a dalším drobnostem. Této myši se říkalo "Amiga Mouse" (zkráceně jen A-Mouse) podle typu použité myši, ta se vyráběla pro Amigu a Atari a neměla sériové rozhranní, ale paralelní - viz. dále.
V souvislosti s UR-4 není možné nezmínit pokus Proximy o rozšíření kompatibilnější a méně náročné varianty, tzv. "Kempston Mouse". Bohužel ji znám jen z doslechu, ale vím určitě, že byla použitelná místo Kemston Joysticku. Někdo mi říkal cosi o specielním interface, snad s jednočipovým mikroprocesorem PIC, takže její připojení zcela jednoduché nebylo. Ale extrémně jednoduché bylo využití v programech. Interface myši emuloval Kemston Joystick pomocí PWM takže bylo možné v několika málo krocích měnit i rychlost kurzoru v závislosti na rychlosti pohybu myší. Díky tomu fungovala s naprostou většinou programů používajících Kemston Joystick a to buď stejně jako joystick, nebo v lepším případě podobně jako skutečná myš. Tato verze se v mém okolí nevyskytovala vůbec, ale často jsem o ní slýchal na různých setkávacích akcích (Samcon) a možná byla v ČR podobně rozšířená jako A-Mouse.
Poslední variantou je vytvoření vlastního interface s alespoň minimální hardwareovou akcelerací, aby se o myš nemusel starat procesor. Tím spíš, když je výkon Z80 v ZX Spectru velmi nízký a každý ušetřený takt je užitečný. Nejzajímavější varianta pochází odněkud z Ruska a připojuje s k ní taky Amiga myš s TTL rozhranním. Výsledkem činnosti nepříliš složitého a vcelku levného rozhranní jsou tři čísla na třech portech. Dvě čísla udávají polohu myši v rozsahu od 0 do 255 včetně a bity ve třetím bytu určují stisknutá tlačítka. Je sice nutné provést jednoduchou softwarovou korekci pro výšku obrazovky, ale to je zanedbatelné vzhledem k ostatním variantám. A jedná se o skutečnou myš, takže pohyb kursoru zcela kopíruje pohyb myši včetně změn rychlosti pohybu. S touto variantou jsem se setkal prakticky až v době, kdy jsem se dostal poprvé k internetu a ZX Spectrum už řadu uživatelů nezajímalo (1995 - 1996).
Shrnutí nejznámějších myší
| Typ myši | rozhranní | výhody | nevýhody | ostatní |
|---|---|---|---|---|
| Kempston Mouse (Rusko) | Nutný specielní interface, schéma zde. | Skoro vůbec nezatěžuje procesor. Stačí číst 3 čísla na 3 portech a to je vše. | Obsazuje 3 porty což není málo, vrací nevhodně stav tlačítek (podle mého názoru). | Vyskytuje se u ruských počítačů Pentagon, Scorpion a zcela určitě v počítači Sprinter, emulována v X128. |
| Kempston Mouse Proxima | Specielní rozhranní od Proximy, prý dokonce s jednočipem PIC. | Není třeba specielní software, pracuje v programech, které umí pracovat s Kempston Joystickem. | Je nutné specielní relativně složité rozhranní. | Není to skutečná myš. Pohyb kurzoru není zcela dokonalý. Spíše se jedná o joystick s možností zpomalení pohybu kurzoru. |
| Amiga Mouse ( Heptau ? Nejsem si jistý.) | UR-4, nebo lehce upravený interface Kempston Joysticku. Viz. popisu 8255 a UR-4. | MHB8255 je velmi rozšířený interface na území české a slovenské republiky. Máte-li UR-4 nic jiného nepotřebujete. | Velmi hodně zatěžuje procesor, vše musí obsloužit program (zabere nejméně 1/2 přerušení). Dobře použitelné užitkových programech se spoustou ikon a tlačítek, horší ve hrách. | V ČR a SR velmi rozšířený typ myši a to především, kvůli jednoduchosti připojení. Tuto myš podporuje většina mých programů. |
| Sériová Myš (ing. Petr Simandl) | RS232, které je součástí Spectra 128 kB | Relativně málo zatěžuje procesor, nutné pouze čtení několika bytů jednou za přerušení ovšem ze sériového rozhranní. | Rozumně použitelná jen u ZX Specter 128kB, u ostatních jsou kompatibilní sériové porty jen vyjímečně. Viz. výše. | Nutno upravit konektor RS232 na cannon 9pinů, úprava myši na konektor Spectra není vhodné. Originální konektor není normálně sehnatelný. |
Amiga Mouse
V následujícím textu se budu zabývat především Amiga myší připojenou do UR-4, protože ji znám nejlépe z výše vyjmenovaných typů a protože její softwarové ovládání, resp. čtení je nejsložitější.
Předně Amiga myš není v žádném případě zaměnitelná s jinými typy, rozhodně ne sériovými. Komunikuje na úrovních TTL a v podstatě je paralelní, protože používá 4 dráty pro přenos pulzů ze čtyř čidel, další tři dráty pro přenos stavu tlačítek a dva dráty pro napájení. tj. minimálně 7, maximálně 9 vodičů, víc nemá smysl, protože se u ní stejně jako u myši sériové používá devítipinový konektor canon. Narozdíl od sériové myši, kde se napětí pulzů může pohybovat od -15V do -3V pro log. 0 a od 3V do +15V pro log. 1 (běžně to bývá +/-5V nebo +/-12V) a data se přenáší protokolem RS232 tak u Amiga myši jsou signály TTL, tj. log 0 je 0V až cca 1V a log 1 přibližně 3V až 5V (není to přesně, ale pro orientaci postačí).
Pro zajímavost se můžete podívat jak taková myš vypadá zevnitř. Všimněte si obvodu 74HC14N (Což je invertující Schmittův klopný obvod viz. datasheet), který v myši funguje prakticky jen jako tvarovač impulzů.
Stavový diagram pulzů na výstupu myši

Délka pulzů záleží na rychlosti pohybu myši. Aby se kursor myši mohl pohnout musí být dokončena celá sekvence pulzů od stavu 0, 0 do stavu 0, 0. Pořadí pulzů udává směr pohybu, resp. směr pohybu je možné zjistit z toho, který pulz přijde první. Pokud sekvence začíná jedním z pulzů a končí tímtéž, pohyb není detekován (odpovídá pohybu myši o stejnou vzdálenost tam a zpět) a kurzorem myši nebude pohnuto.
Význam pinů na konektoru myši
Pro srovnání uvádím i význam pinů Kempston Joysticku, který je známější.
| bit | pin | Kemston joystick | Amiga Myš | poznámka |
|---|---|---|---|---|
| 0 | 4 | vpravo | osa X2 (XB) | --- |
| 1 | 3 | vlevo | osa Y1 (YA) | --- |
| 2 | 2 | dolů | osa X1 (XA) | --- |
| 3 | 1 | nahoru | osa Y2 (YB) | --- |
| 4 | 6 | fire | tlačítko 1 | --- |
| 5 | 5 | --- | tlačítko 2 | nutné přidat invertor i do UR-4 |
| 6 | 9 | --- | tlačítko 3 | nutné přidat invertor i do UR-4 |
| 7 | --- | --- | --- | --- |
Myší pracujících na úplně stejném principu se běžně vyskytují dva typy lišící se pouze jiným rozmístěním vývodů na konektoru. V praxi se obvykle jedná o jedinou myš s malým přepínačem vespod a polohami označenými jako "MS AM" a "PC AT". správná poloha je "MS AM". Jedna z poloh je pro počítače Amiga a druhá pro Atari (ST, STE a pod.).
Kempston Mouse - RU
S touto myší jsem se setkal v emulátoru X128 a také jsem ji objevil na nějakých ruských www stránkách. Skládá se z rozhranní převádějícího TTL signál z myši na souřadnice (v podstatě stejně jako níže uvedený program) a standardní Amiga myši. Obrovskou výhodou této varianty jsou zcela zanedbatelné nároky na výkon CPU. Ruská Kemston Mouse je asi jako jediná bez problémů použitelná ve hrách, velmi rozumně je využitá například v předělávce WarCraft 1 na ZX Spectrum (Čornyj Varon), dokonce není problém ji používat v Basicu což s jinou plnohodnotnou myší možné není.
Jak je u ruských periferií pro ZX Spectrum zvykem adresuje se šestnáctibitově (což není tak docela přesné, jak se později ukázalo viz. popis kmouse) a to na portech uvedených v tabulce. Podle mého zkoumání je jisté, že myš pracuje nejméně se dvěma tlačítky, ale nikdy se mi nepodařilo najít program, nebo popis, kde by bylo využité tlačítko třetí (i to se časem změnilo, tlačítko se využívá a přibylo kolečko) ačkoliv tomu principielně nebrání vůbec nic, dokonce by jich mohlo být třeba i osum (právě v poslední variantě byly horní čtyři bity portu využity pro kolečko).
porty ruské Kempston mouse
| Hex | Dec | označení | poznámka |
|---|---|---|---|
| #FADF | 64223 | tlačítka | B0=pravé, B1=levé, B2=střední (0=stisknuto, 1=nestisknuto) |
| #FBDF | 64479 | souřadnice X | souřadnice v intervalu <0,255> |
| #FFDF | 65503 | souřadnice Y | souřadnice v intervalu <0,255> |
| #FEDF | 65247 | souřadnice Z | kolečko/a myši implementované Velesoftem (později opět odstraněno kvůli kompatibilitě s ruskou verzí) |
Tato myš obravdu vrací i pro Y-ovou souřadnici hodnotu od 0 do 255, je tedy potřeba provést jednoduchou korekci. Jinak funguje vše velice dobře a jak se zdá nedochází k žádným (zřejmým) kolizím zařízení. Toto ovšem raději vyzkouším u skutečného Spectra. (Opět mírná aktualizace, kolize u nejstarší varianty byly, viz. popis kmouse.)
Program zobrazující šipku ovládanou myší
Šipku zobrazovanou následujícím programem lze ovládat buď klávesami (Sinclair Joystick, OPQAM), Kempston joystickem, nebo Amiga myší. Program je napsán dost univerzálně, takže podle bitu 7 v log. 1 (což na UR-4 nenastane) detekuje přítomnost korektního interface pro Kempston joystick, nebo Amiga myš a podle současně nastavených bitů pro směry vlevo a vpravo, nebo nahoru a dolů dokáže rozlišit Amiga myš od joysticku. Případně lze obojí vypnout, kdyby to náhodou na nějaké hardwarové konfiguraci nefungovalo.
Program umožňující volat myš z Basicu (kvůli HL')
Nezapomeňte si upravit cesty ke vkládaným zdrojovým textům sipka.za a downhl.za.
;==============================================================================
; TESTOVACÍ PROGRAM PRO ŠIPKU
;==============================================================================
cpu z80undoc
org 60000
START di
push ix
exx
push hl ; HL' nutno zachovat kvůli Basicu, dělal by problémy
exx
ld a,6
out (254),a
call MOUSE
ld a,2
out (254),a
END exx
pop hl
exx
pop ix
ei
ret
EXIT ld a,1
out (254),a
jr END
XYIKON db 0,255,0,192 ; x1,x2,y1,y2 (celá obrazovka)
dw EXIT
db 255
include ../libs/sipka.za
include ../libs/downhl.za
Vlastní ovladač myši
Program byl zkoušen v emulátoru FUSE a kompilován kompilerem AS, nicméně s drobnými úpravami konstant by měl být zkompilovatelný kdekoliv. Zdrojový text je mimochodem odsazován po 10 znacích, některé řádky jsou proto trochu rozházené.
;============================================================================== ; KOMPLEXNÍ PROGRAM PRO ČTENÍ KLÁVESNICE, AMIGA MYŠI A K-MOUSE ;============================================================================== ; Stručný princip: ; ; Vezmi původní souřadnice, spočítej adresu na obrazovce (MOUSE_XY). ; Vykresli šipku na obrazovku, zároveň ulož co bylo pod ní. ; Zpracuj vstup ze zvoleného HID a spočítej nové souřadnice. ; Zapiš nové souřadnice. ; Zapiš stav tlačítek HID (proměnná MOUSE_B) ; Čekej na přerušení. ; Smaž šipku a místo ní vykresli původní obsah obrazovky. ; Opakuj celý proces dokud není stisknuto tlačítko "fire". ; Zjisti jestli a na jakou ikonu bylo kliknuto, jinak opakuj. ; Skoč na obslužnou rutinu ikony (JP). ; Význam bitů proměnné MOUSE_B: ; ; bit 0 = klávesa 1, nebo levé tlačítko myši ; bit 1 = klávesa 2, nebo pravé tlačítko myši ; bit 2 = klávesa 3, nebo prostřední tlačítko myši ; ; další tlačítka nejsou definována %00000xxx - horní bity jsou vždy 0 ; ; update (spíše jen úvaha do budoucna): ; bit 3 = kolečko myši nahoru?, resp. tlačítko 4 ; bit 4 = kolečko myši dolu, resp. tlačítko 5 ; bit 5 = tlačítko 6, resp. tlačítko pod kolečkem myši MOUSE_X equ MOUSE+2 ; poslední známé souřadnice šipky MOUSE_Y equ MOUSE+1 MOUSE_XY equ MOUSE_Y ; 16ti bitové souřadnice MOUSE_T equ MOUSE_S+1 ; typ zařízení 0=KEYS, 1=AMOUSE, 2=KMOUSE MOUSE_B equ MOUSEBUTT+1 ; stav tlačítek MOUSE_KS equ MOUSEKS ; KEYSTEP, velikost kroku při ovládání pomocí kláves MOUSE ld hl,96+128*256 ; souřadnice šipky X do L, Y do H push hl ; náhrada za neexistující instrukci ld bc,hl pop bc ; takže X je v C, Y v B ld ix,MSIPKA ; do IX adresu spritu exx ld hl,MSIPKA_B ; do HL' adresu bufferu na pozadi sipky exx ld a,b ; vezmi Y-ovou souradnici (jaký význam má v A?) call 8881 ; ze souřadnic v BC spočítej adresu ve VRAM do HL ld (MOUSEC+1),hl ; ulož tuto adresu, bude užitečná při mazání šipky ld (MOUSE2+1),a ; toto cislo budu odecitat, co znamena ???? ; vykreslení šipky - pochází z knihy Assembler a ZX Spectrum II, komentáře jsem přepsal ld b,15 ; sprite šipky je vysoký 15 pixelů (mimochodem široký je 1 byte) MOUSE1 push bc ; ulož kolik opakování - mikrořádků zbývá push hl ; dvakrát ulož adresu šipky ve VRAM, na kterou se bude kreslit push hl ld h,0 ; do H ulož 0, sem se bude rotovat sprite/maska, pokud to bude třeba ld l,(ix+0) ; do L přečti byte spritu ld d,h ; vynuluj D (to samé jako H) ld e,(ix+15) ; do E přečti byte masky inc ix ; posuň ukazatel na grafiku spritu ld a,8 ; rotovat můžu nejvýše 8x MOUSE2 sub 0 ; od počtu rotací odečtu počet rotací vlevo a získám počet rotací vpravo ld b,a ; počet rotací vpravo si uložím do B MOUSE3 add hl,hl ; HL *= 2 (náhrada rr hl) ex de,hl ; prohoď HL a DE (add de,de taky bohužel neexistuje) add hl,hl ; HL *= 2 (náhrada rr de) ex de,hl ; HL a DE prohoď zase zpátky djnz MOUSE3 ; jednobytový sprite a maska jsou uloženy v HL a DE posunuté jak je třeba ex (sp),hl ; prohoď poslední hodnotu v zásobníku (adresa šipky ve VRAM) a obsahem HL pop bc ; do BC tak ze zásobníku vyzvednu odrotovanou předlohu ld a,(hl) ; do A načtu původní obsah obrazovky exx ld (hl),a ; uložím na (HL') - adresa bufferu na původní pozadí (1. levý byte, budou dva) inc hl ; posunu ukazatel do bufferu exx ld a,d ; vezmu do a pravou část masky cpl ; invertuju ji (kdybych ji uložil už invertovanou, měl bych problém s rotací) and (hl) ; a z pozadí vymažu ty pixely, kde měla maska 0 or b ; a do vykousnutého pozadí zaoruju předlohu ld (hl),a ; a nakonec uložím do VRAM ; call RIGHTL ; spočítej adresu o byte vpravo inc hl ld a,(hl) ; celé kreslení provedu ještě jednou pro 2. byte více vpravo exx ld (hl),a inc hl exx ld a,e cpl and (hl) or c ld (hl),a pop hl ; obnov adresu levého bytu ve VRAM call DOWNHL ; spočítej adresu o pixel níž pop bc ; obnov počítadlo djnz MOUSE1 ; a opakuj, dokud nejsou vykresleny všechny mikrořádky šipky ; volba polohovacího zařízení 0=KEYS, 1=AMOUSE, 2=KMOUSE MOUSE_S ld a,0 or a jp z,MOUSEB ; A=0 ; Buttons - klávesy dec a jp z,MOUSEA ; A=1 ; Amiga mouse (myška z Amigy zapojená do UR-4) dec a jp z,MOUSEK ; A=2 ; ruská Kempston mouse vracející přímé souřadnice ; v ostatních případech čtu klávesy ;------------------------------------------------------------------------------ ; ZMĚNA SOUŘADNIC [X,Y] pomocí klávesnice ;------------------------------------------------------------------------------ MOUSEB call MOUSRKEY ; prečti porty definovaných kláves, v D bude stav testovaných kláves ld hl,(MOUSE_XY) ; do HL přečti souřadnice šipky MOUSEKS ld c,2 ; velikost kroku šipky, o kolik se šipka pohne při stisku klávesy bit 5,d ; testování 1. klávesy (UP) jr z,MOUSEB1 ; Z = klávesa nebyla stisknuta => přeskoč zpracování ld a,h ; vezmi z H Y-ovou souřadnici sub c ; odečti krok posunu ld h,a ; ulož novou Y-ovou souřadnici do H jr nc,MOUSEB1 ; nedošlo-li k podtečení, přeskoč korekci ld h,0 ; C = šipka narazila do horního okraje => proveď korekci, aby neprošla MOUSEB1 bit 6,d ; testování 2. klávesy (DOWN) jr z,MOUSEB2 ; Z = klávesa nebyla stisknuta => přeskoč zpracování ld a,h ; vezmi z H Y-ovou souřadnici add a,c ; pričti krok posunu ld h,a ; ulož novou Y-ovou souřadnici do H cp 189 ; a otestuj jestli šipka neprošla dolním okrajem jr c,MOUSEB2 ; není-li souřadnice větší než 189, přeskoč korekci ld h,190 ; C = šipka narazila do dolního okraje => proveď korekci, aby neprošla MOUSEB2 bit 3,d ; testování 3. klávesy (LEFT) jr z,MOUSEB3 ; Z = klávesa nebyla stisknuta => přeskoč zpracování ld a,l ; vezmi z L X-ovou souřadnici sub c ; odečti krok posunu ld l,a ; ulož novou X-ovou souřadnici do L jr nc,MOUSEB3 ; nedošlo-li k podtečení, přeskoč korekci ld l,0 ; C = šipka narazila do levého okraje => proveď korekci, aby neprošla MOUSEB3 bit 4,d ; testování 4. klávesy (RIGHT) jr z,MOUSEB4 ; Z = klávesa nebyla stisknuta => přeskoč zpracování ld a,l ; vezmi z L X-ovou souřadnici add a,c ; přičti krok posunu ld l,a ; ulož novou X-ovou souřadnici do L cp 252 ; a otestuj jestli šipka neprošla pravým okrajem jr c,MOUSEB4 ; není-li souřadnice větší než 252, přeskoč korekci ld l,252 ; C = šipka narazila do pravého okraje => proveď korekci, aby neprošla MOUSEB4 ld a,d ; vezmi do A stav prečtených kláves and 00000111b ; ponech jen bity, které označují tlačítka jako fire (jako tlač. myši) ld (MOUSE_B),a ; a stav tlačítek zapiš do proměnné MOUSE_B ld (MOUSE_XY),hl ; ulož nové souřadnice šipky pro příští použití jp MOUSE50 ; Rutina na čtení kláves z knihy "Assembler a ZX Spectrum 2" ; Může být společná pro klávesu a Kempston Joystick (nemá s ruskou Kempston Myší nic společného, jen jméno) MOUSRKEY ld hl,MOUSEKTAB ; vezmi adresu tabulky kláves ld de,7 ; v E je počet kláves a v D bude výsledek (1 = stisknuto) MOUSRK1 ld c,(hl) ; do BC prečti z tabulky adresu portu inc hl ld b,(hl) inc hl in a,(c) ; prečti port (BC - 16ti bitové adresování) bit 7,c ; otestuj bit 7, u kempston joysticku je tam vždy 0 (leda by byl vadný) jp z,MOUSRK2 ; přeskoč CPL jedná-li se o kempston joystick cpl ; 1 = klávesa stisknuta (normálně to je u kláves obráceně) MOUSRK2 and (hl) ; ponech jen testovaný bit (filtrace tabulkou) inc hl ; a posuň HL na začátek dalšího řádku tabulky jr z,MOUSRK3 set 7,d ; nastav bit 7 na 1 MOUSRK3 srl d ; a posuň ho dolů (tím se do D postupně uloží stav všech kláves) dec e ; sniž počítadlo portů k prečtení jr nz,MOUSRK1 ; opakuj dokud není vše přečteno ret ; Tabulka kódů kláves, kterou je možné měnit - první 2 byty jsou adresou portu, 3. byte je bitový filtr. ; Tímto způsobem je možno definovat i Kempston joystick, ale není možné ho rozumně detekovat, pokud je ; zároveň připojena amiga mouse, uživatel musí sám rozhodnout co chce používat, nejlépe stiskem klávesy. ; Kempston joystick a klávesy je samozřejmě možné libovolně kombinovat, i když to asi není praktické. MOUSEKTAB db 254, 127, 00000100b ; FIRE 1 (M) db 254, 127, 00001000b ; FIRE 2 (N) db 254, 127, 00010000b ; FIRE 3 (B) db 254, 223, 00000010b ; LEFT (O) db 254, 223, 00000001b ; RIGHT (P) db 254, 251, 00000001b ; UP (Q) db 254, 253, 00000001b ; DOWN (A) ;------------------------------------------------------------------------------ ; ZMĚNA SOUŘADNIC [X,Y] pomocí AMIGA MOUSE ;------------------------------------------------------------------------------ ; Pozor! Interface s MHB8255 je nutné inicializovat mimo tento program. MOUSEA ld bc,130*256 ; B = počet průchodů čtecí smyčkou (rozumný kompromis) ld a,(MOUSE_X) ; souřadnice se budou uvnitř smyčky měnit a je lépe budou-li operandem ld (MOUSAX+1),a ld a,(MOUSE_Y) ld (MOUSAY+1),a MOUSEA1 push bc ; uloz BC do zasobniku - zde zacina smycka ld b,c ; a do B ????? in a,(31) ; čti port ld de,MOUSEAP ; pomocná proměnná call MOUS_SM ; zjisti jakym smerem se mys pohnula MOUSAX ld a,77h ; vezmi souradnice mysi add a,(hl) jr z,MOUSAKX ; Z = preskoc zapis X-ove souradnice ld (MOUSAX+1),a MOUSAKX inc de in a,(31) ; čti port rrca ; posun o 1 bit vpravo, kvuli detekci smeru call MOUS_SM ; a ted se da pouzit stejna rutina jako pro X MOUSAY ld a,60h ; vezmi starou Y-ovou souradnici add a,(hl) ; a pricti cislo prectene z tabulky jr z,MOUSAKY ; Z = preskoc zapis a korekci Y-ove souradnice cp 192 ; otestuj jestli sipka neprosla spodnim okr. jr nz,MOUSADO ; pokud prosla (Z) ld a,191 ; proced korekci MOUSADO ld (MOUSAY+1),a ; zapis novou Y-ovou souradnici MOUSAKY pop bc ; obnov pocitadlo pruchodu djnz MOUSEA1 ; a opakuj pokud tento nebyl posledni ld a,(MOUSAX+1) ; zapis nove souradnice do promennych ld (MOUSE_X),a ld a,(MOUSAY+1) ld (MOUSE_Y),a in a,(31) ; naposledy precti port mysi rra rra rra rra and 00000111b ; ponech jen bity tlacitek ld (MOUSE_B),a jp MOUSE50 MOUS_SM and 5 ; testuje jakym smerem se amiga mys pohnula ld c,a ; na zaklade Karnaughovych map ld a,(de) rlca and 10 or c ld (de),a ld c,a ld hl,MOUSTAB add hl,bc ret MOUSTAB db 0,255,1,0 ; tabulka kódů pro výpočet pohybu AMOUSE db 1,0,0,255 db 255,0,0,1 db 0,1,255,0 MOUSEAP dw 0 ; promenna tykajici se vyhradne detekce smeru ; pohybu AMIGA MOUSE ;------------------------------------------------------------------------------ ; ZMENA SOURADNIC [X,Y] pomocí KMOUSE (Ruská verze - později i od Velesofta) ;------------------------------------------------------------------------------ ; .... OTESTOVAT V PRAXI! MOUSEK ld a,251 ; cti X-ovou souradnici z portu 64479 in a,(223) ld (MOUSE_X),a ; uloz pro pristi zavolani programu MOUSE ld a,255 in a,(223) ; cti Y-ovou souradnici z portu 65503 cpl ; u souradnice Y nam nevyhovuje hodnota nad 192 cp 191 ; takze provedu jednoduchou korekci jp c,MOUSEKK ; IF A>191 THEN A=191 ld a,191 MOUSEKK ld (MOUSE_Y),a ; a uloz pro dalsi volani programu MOUSE ld a,250 ; cti port 64223 - BUTTONS in a,(223) ; ale ziskal jsem nevhodny zpusob ulozeni stavu cpl ; takze zase provedu korekci, nejdrive neguju and 00000111b ; byte a pak z nej necham jen dolni 3 bity ld b,a ; zalohuju do B a ted prehodim bit 0 a bit 1 rla ; bit 0 v A posunu na pozici bitu 1 and 00000010b ; ponecham jen bit 1 ld c,a ; a ulozim do C ld a,b ; znovu vezmu puvodni byte rra ; posunu bit 1 v A na pozici bitu 0 and 00000001b ; ponecham jen bit 0 or c ; pridam bit 1 ulozeny v C ld c,a ; ted budu mit v C ulozene prehozene bity 0 a 1 ld a,b ; naposledy vezmu puvodni byte and 00000100b ; ponecham z nej jen bit 2 or c ; pridam k nemu bity 0 a 1 ld (MOUSE_B),a ; ulozim do pameti a je hotovo jp MOUSE50 ; Před HALT (za MOUSE50) je možno přidat automatickou detekci polohovacího zařízení a ; následnou změnu proměnné MOUSE_T. V dalším volaní pak bude takto zvolené zařízení ; normálně používáno. ; autodetect KEYBOARD - Je-li stisknuta klávesa přepne se ovladač na čtení klávesnice, užitečné ; pokud uživatel potřebuje z jakéhokoliv důvodu ovládat program klávesnicí ; ale byla zvolena myš. ; xor a ; ctu port 0*256+254 ; in a,(254) ; cpl ; and %00011111 ; ponecham dolnich 5 bitu ; jr nz,MOUSE50 ; ld a,0 ; do A cislo odpovidajici klavesnici ; ld (MOUSE_T),a ; a zapisu ho do promenne MOUSE_T ; autodetect AMIGA MOUSE - Amiga mouse se oproti Kempston joystiku liší tím, že u ní mohou běžně ; nastat log. 1 na bitech, které u joysticku znamenají protilehlé směry, ; takže je není možno zvolit bez jeho mechanického zničení. ; Bohužel detekce nemůže být 100% spolehlivá, ačkoli většinou funguje. ; in a,(31) ; čti port na němž je připojena myš ; bit a,7 ; je-li bit 7 log. 1 pravděpodobně port 31 není funkční ; jp nz,MOUSE50 ; takže zbytek rutiny přeskoč ; and %101 ; tyto bity nemohou být nikdy v log. 1 pokud ; cp %101 ; je připojen jenom Kempston Joystick ; jp nz,MOUSE50 ; Z = bity byly v log. 1 => myš je pravděpodobně připojena ; ld a,1 ; do A číslo odpovídající amiga myši ; ld (MOUSE_T),a ; a zapíšu ho do proměnné MOUSE_T ; Jak jednoduše detekovat KEMPSTON MOUSE nevím! ; Jak jednoduše detekovat KEMPSTON JOYSTICK nevím (resp. vím, ale ne v kombinaci s Amiga mouse)! MOUSE50 ei ; povolím přerušení, pokud náhodou povolené nebylo halt ; a počkám na něj (paprsek začíná kreslit obrazovku) ; případný zákaz přerušení si přidejte sami ; smazání šipky a vykreslení původního obsahu obrazovky MOUSEC ld hl,0 ; do operandu je místo 0 zapisována adresa šipky ve VRAM ld b,15 ; počet pixelů na výšku ld de,MSIPKA_B ; adresa uloženého původnho pozadí pod šipkou MOUSEC1 ld a,(de) ; vezmu byte z původního pozadí ld (hl),a ; a zapíšu ho do VRAM inc de ; posunu DE o 1 push hl ; zapamatuju HL call RIGHTL ; a spočítám adresu HL o byte vpravo (inc HL nestačí, kus šipky může zmizet) ld a,(de) ; vezmi další byte z původního pozadí ld (hl),a ; a zapíšu ho do VRAM inc de ; posunu DE o 1 pop hl ; obnovím v HL adresu levého bytu call DOWNHL ; a z ní spočítám adresu o pixel níž djnz MOUSEC1 ; opakuj tolikrát, kolik pixelů na výšku šipka má MOUSEBUTT ld a,0 ; vezmi stav stisknutí tlačítek or a ; 0 = žádné nebylo stisknuto jp z,MOUSE ; pokud nebylo tlačítko stisknuto, opakuj činnost celého programu ret ; nějaké tlačítko bylo stisknuto, vrať se, záleží na programu ; využívajícím šipku jak tlačítka zpracuje (tím může být NOIKON) ;============================================================================== ; GRAFIKA A NĚKTERÉ PROMĚNÉ ;============================================================================== MSIPKA db 00000000b ; sprite šipky db 01000000b db 01100000b db 01110000b db 01111000b db 01111100b db 01111110b db 01111000b db 01001000b db 00001000b db 00000100b db 00000100b db 00000010b db 00000010b db 00000000b MSIPKA_M db 11100000b ; maska šipky - musí následovat hned za spritem db 11110000b db 11111000b db 11111100b db 11111110b db 11111111b db 11111111b db 11111111b db 11111100b db 11111110b db 00011110b db 00001111b db 00001111b db 00000111b db 00000111b MSIPKA_B ds 30 ; sem se ukládá z VRAM to co šipka překryla ;============================================================================== ; PODPŮRNÉ RUTINY ;============================================================================== RIGHTL ld a,l ; RIGHTL zajištuje posun adresy spritu ve inc l ; VRAM o byte vpravo a jeho spravné vykreslení, xor l ; pokud je jeho levá půlka přímo u pravého bit 5,a ; okraje obrazovky. V takovém případě se ret z ; pravá půlka kreslí do ROM, takže vlastně ld h,0 ; nekreslí / BACHA NA WRITEABLE ROMky!! (nahradit 0 číslem 60, poškodí font) ret ; include downhl.za ; tato rutina by mela byt soucasti programu, který myš používá
;============================================================================== ; RUTINA, KTERÁ ZAVOLÁ ŠIPKU A VOLÁ JI TAK DLOUHO DOKUD UŽIVATEL NEKLIKNE ; NA NĚKTEROU PLATNOU IKONU (POLOHA DEFINOVANÁ V TABULCE). V TOM OKAMŽIKU ; RUTINA SKOČÍ NA ADRESU PŘÍSLUŠNÉ RUTINY, KTERÁ IKONĚ ODPOVÍDÁ. ;============================================================================== NOICON call MOUSE ; zavolej program pro obsluhu HID a kreslení šipky na obrazovku ; rutinu NOICON možno volat pomocí CALL a instrukci ; RET umístit do rutiny reagující na kliknuti na ikonu TSTXY ld de,(MOUSE_XY) ; souřadnice šipky do DE (D = X, E = Y) ld bc,6 ; do BC délku souřadnic v tabulce ikon a adresy příslušné rutiny ld ix,XYIKON-6 ; do IX adresu tabulky ikon a adres rutin mínus jednu položku TSTXY_1 add ix,bc ; pričti BC k registru IX ld a,(ix+0) ; čti X1 cp 255 ; porovnej s 255 - znamená konec tabulky jr z,NOICON ; je-li 255 (Z) nebylo kliknuto na ikonu a bude opakováno kreslení šipky ld a,(ix+0) ; jinak porovnávej dál, dokud není nalezena ikona, nebo konec tabulky cp d jr nc,TSTXY_1 ld a,(ix+1) cp d jr c,TSTXY_1 ld a,(ix+2) cp e jr nc,TSTXY_1 ld a,(ix+3) cp e jr c,TSTXY_1 ld h,(ix+5) ; bylo kliknuto na nějakou ikonu, takže ld l,(ix+4) ; přečti do HL adresu obslužné rutiny jp (hl) ; a skoč na tuto adresu ; TOTO JE JEN UKAZKA - takovato tabulka by mela byt soucasti programu ; ;XYIKON db 0,16,0,16 ; x1,x2,y1,y2 ; defw EXIT_I ; adresa vykonne rutiny ; db 255 ; konec tabulky ikon (NUTNE! Nikdy nesmí chybět!) ; ;EXIT_I ; priklad ; ret ;==============================================================================Program už je v podstatě zastaralý, stahujte z popisu KMouse
Celý ovladač myši je nutné spouštět od adresy NOICON. Rutina TEST_M je skutečně jen k testování, to není vstupní bod programu. Je nutné mít správně vyplněnou tabulku XYIKON, která obsahuje souřadnice ikon a adresu rutiny, která bude zavolána po kliknutí na ikonu. A za poslední, před tuto rutinu doporučuju přidat možnost volby ovládání, rozhodně bych si ve svém programu nedovolil jako defaultní ovladač použít jednu z myší. Když už, tak klávesy. A pokud má uživatel možnost změnit šipkou (třeba v menu) ovládání, musí existovat možnost totéž provést klávesnicí i po změně na myš.
Download
Zdroje informací: Tak různě z webu (porty a schéma připojení Kempston mouse), knížka Assembler a ZX Spectrum (prapůvodní základy pro kreslení šipky ovládané klávesami), a dost vlastních zkušeností.
Související odkazy
- HwB - popis konektoru pro připojení myši a joysticku k Amize
- HwB - popis konektoru podobné myši používané u Atari
Opravené chyby
- 28.2.2004 - celý článek přepracován, výrazně rozšířen úvod, opraveny chyby, doplněn datasheet 74HC14 a obrázek myši zevnitř.
- 11.4.2005 - opraveny přehozené bity 0 a 1 (v tabulce i diagramu), doplněny odkazy na HWBook s popisem konektorů, vše znovu pečlivě zkontrolováno podle reálného fungujícího hardwaru, upozornil Velesoft