Myši a ZX Spectrum

Historický úvod

S prvními zmínkami o myši u ZX Spectra jsem se setkal snad už v 90. roce, ale tenkrát nebylo ještě snadné sehnat pěknou myš za rozumné peníze. Velmi často bylo možné koupit myši jen velmi nepraktické do ruky, často velmi hranaté a neergonomické (např. třítlačítkové modely od firmy Genius, případně jako 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 začaly nejprve vyskytovat u vícebitových počítačů orientovaných na grafiku. Úplně prvním počítačem s kurzorem ovládaným myší byl Xerox Alto z počátku 70. let o kterém jsme tehdy ani netušili, že existuje. Později Apple Macintosh, Atari, Amiga a později i IBM PC. Koncem 80. a začátkem 90. 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 počítačů s grafickým prostředím trochu záviděli a přemýšleli, jak si taky 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 rozhraní, jak paralelních, tak sériových, ale žádné nebylo rozšířeno globálně, žádné rozhraní nikdy nemělo status standardu (byť nepsaného v rámci platformy). Jako např. sériové porty, PS/2 a později USB na platformě PC.

Bylo tedy nutné použít rozhraní, když ne globálně rozšířené, tak alespoň dostatečně 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 rozhraním.

Myš připojitelná k sériovému portu

Jednou z možností jak myš připojit 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 48k ani Didaktiky sériový port neměly. Originální ZX Spectrum 128kB, šedivé ZX Spectrum +2, a následující modely Amstradu +2A, +3 už sériový port měly. Ale Sinclair zvolil (a Amstrad převzal) u nás tehdy nesehnatelný britský konektor BT631A. U šedé +2 a následujících modelů od Amstradu navíc není nejšťastněji umístěný, je příliš blízko sběrnice a může být překrytý připojeným interface (např. Betadiskem).

Pokud by toto nebyla dost velká bariéra pro použití sériové myši, tak tento originální sériový port využívá osmibitovou bránu zvukového čipu AY-3-8912. To znamená, že řízení signálů a hlavně serializaci dat musel provádět software, to stojí výpočetní čas. Zároveň v různých přídavných rozhraních s kompatibilním zvukovým čipem se používaly i jiné varianty čipu AY, případně jeho klony a občas i verze bez IO portů. Vytvoření sériového portu by pro uživatele znamenalo zapojení tehdy komplikovaného převodníku úrovní (MAX232 nebyl dostupný), úpravu interface a jiné drobné potíže, které se málo komu chtělo řešit.

Takže sériová myš pro ZX Spectrum existuje, ale je obtížněji připojitelná, má-li být zachována kompatibilita i s 48kB verzemi ZX Spectra včetně těch rozšířených na 128kB a doplněných o AY, protože těm i po rozšíření často chyběly převodníky úrovní mezi TTL a RS232.

Dodnes (rok 2021) jsem se setkal jen s jediným programem, který s RS232 myší pracuje, je jím program Modplay od Štěpána Obdržálka, který hraje na D/A převodník Petra Simandla (též málo známý).

  • + skutečná myš
  • + standardní PC myš v 90. letech snadno sehnatelná
  • − softwarová RS232 náročná na procesorový čas i když mnohem méně než AMouse
  • − RS232 interface není tak moc rozšířený
  • − minimální softwarová podpora
  • − po roce 2020 jsou sériové myši hůř sehnatelné než PS/2
  • − moderní klony ZX Spectra často RS232 nemají

Myš připojitelná k paralelnímu portu - AMouse

Paralelní port byl v našich krajích u ZX Spectra mnohem běžnější než port sériový. Existovaly amatérské konstrukce, koupit se dala UR-4 vyráběná v Tesle a hlavně byl v Didaktiku Gama už od výroby. Později byl kompatibilní interface přítomen i v disketových jednotkách Didaktik 40 a Didaktik 80. Dal se dokoupit k Didaktiku M v podobě Interface M/P a v mnoha dalších podobách (třeba Jiiirův UPI). S připojením myši počítá i moje redukce k Didaktiku Gama 192k.

Všechna tato paralelní rozhraní, nejčastěji s čipem 8255, byla určena především k připojení tiskáren a k připojení joysticků kompatibilních se standardem Kempston joystick. Ne vždy ale byl součástí rozhraní i konektor pro joystick. Pokud však byl a pokud měl správně zapojené napájení jako to má UR-4, dal se použít i k připojení některých myší a to bez jakékoli další hardwarové úpravy. Stačilo připojit myš a spustit program. Takovou vhodnou myší byly myši určené pro Amigu případně pro Atari, má-li přepínač přehazující signály z clonek. Proto takové myši říkáme zkráceně AMouse.

Velkou nevýhodou AMouse je obrovské zatížení CPU, protože myš je potřeba obsluhovat zcela kompletně programově a tímto programem, pokud možno, číst stav signálů neustále. Pro další činnosti, krom obsluhy myši zbývá nejvýše 50% času CPU, spíš méně, pokud má být pohyb kurzoru opravdu plynulý. U klikacích menu to většinou nevadí, tam může čtení portu běžet skoro pořád, ale je to těžko použitelné v náročnějších hrách. Přesto se tato myš v mém okolí po určitou dobu rozšířila nejvíc. Čá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.

Nejsem si jistý, kdo přišel s připojením AMouse první. Možná Heptau? Vzpomínám si, že se objevila na jednom ze Samconů, kdosi tam rozdával nakopírovaný výtisk papíru A4 se zdrojovým kódem jednoduchého ovladače. Fakt je, že stejný princip už byl dříve využíván na jiných osmibitech. Např. na osmibitovém Atari lze ovládat myší (resp. trackballem - princip snímání je stejný) hru Missile Command. TTL myš se taky připojuje do joystickového portu. I na Amize se k připojení myši používá joystickový port. Takže asi bylo jen otázkou času, než někdo zkusí totéž i na ZX Spectrum.

  • + skutečná myš
  • + triviální připojení, stačí správně zapojený joystick interface
  • + standardní Amiga myš (TTL myš), kdysi snadno dostupné
  • + existují redukce z PS/2 na Amiga myš, lze používat i optické myši
  • + existují dokonce i optické čipy s kompatibilními výstupy
  • − zpracování velmi náročné na procesorový čas
  • − softwarová podpora není velká, ale taky ne zcela zanedbatelná

Joysticková Kempston Mouse od Proximy

V souvislosti s UR-4 musím zmínit pokus Proximy o rozšíření kompatibilnější a méně náročné varianty, tzv. "Kempston Mouse" Ing. Holmana - neplést se skutečnou Kempston Mouse od firmy Kempston.

Bohužel tuto myš znám jen "z doslechu", neměl jsem příležitost ji vyzkoušet, ale vím (a viz odkazovaný článek), že byla použitelná místo Kempston joysticku tak, že pomocí PWM simulovala délku sepnutí příslušných směrů joysticku a tím se dala hrubě měnit rychlost pohybu kurzoru po obrazovce.

Bylo potřeba, kromě samotného rozhraní joysticku, ještě rozhraní s jednočipovým mikroprocesorem PIC, takže její připojení zcela jednoduché nebylo. O to jednodušší bylo využití v programech. Teoreticky fungovala s naprostou většinou programů používajících Kempston joystick a to buď stejně jako joystick, nebo v lepším případě skoro jako skutečná myš. Viz článek o této myši přímo od autora (bohužel už jen na Archive.org).

  • + teoreticky funkční s každým programem, který pracuje s Kempston joystickem
  • − není skutečná myš, spíš hybrid mezi joystickem a myší
  • − softwarová podpora diskutabilní

Skutečná Kempston Mouse zvaná KMouse

Jednou z možností je i vytvoření vlastního interface s nějakou hardwerovou akcelerací, aby se o dekódování pohybu myši nemusel starat procesor. Každý ušetřený takt je užitečný. Nejzajímavější varianta pochází od firmy Kempston, od stejné firmy jako známé a velmi používané zapojení joysticku na port 31.

K původnímu Kempston Mouse interface se připojuje taky myš s TTL rozhraním, jako jsou Amiga/Atari myši. Interface dekóduje směr pohybu v osách X/Y a podle toho inkrementuje, nebo dekrementuje osmibitové čítače. Hodnotu z čítačů lze kdykoli přečíst na dvou portech. Na třetím portu se čte stav tlačítek. To nestojí o mnoho víc procesorového času, než čtení joysticku, nebo klávesnice. Takový myší interface je z pohledu softwaru tak nenáročný, jak je jen technicky možné.

Kempston myš (zkráceně KMouse) je na ZX Spectrum jediný interface, který dovoluje myš používat i v akčních hrách. Proto se stal velmi oblíbeným mimo jiné v Rusku, postupem času s klesající cenou hardwaru potřebného k postavení interface se KMouse stala defakto standardem. Je podporována v mnoha emulátorech a jsou jí vybaveny i některé nové klony ZX Spectra.

Jednodušší a starší varianty interface pracovaly s TTL myší a mohly být zapojené např. takto. Modernější varianty pracují s PS/2 myší, příp. mohou pracovat i s USB myší (staré USB myši uměly i PS/2 protokol). Ve Velesoftově KMouse Turbo se o konverzi stará MCU PIC16F84A podobně jako v mnoha PS/2 - Amiga myš konvertorech.

Originální Kempston Mouse podporuje pouze dvě tlačítka. Poslední Velesoftova varianta, kterou považuji za nejlepší, podporuje tlačítka tři a dokonce i scrollovací kolečko je-li připojena kompatibilní PS/2 myš. V emulátorech ale podpora kolečka a často i třetího tlačítka chybí. Software by s tím měl počítat.

Výsledkem činnosti KMouse interface jsou tedy tři čísla na třech portech. Dvě čísla udávají polohu myši v rozsahu od 0 do 255, třetí port slouží ke čtení tlačítek, případně kolečka, umí-li to interface. Vrácené souřadnice lze buď přímo použít a zkonvertovat na souřadnice na obrazovce (z 255 na max 191 v ose y). Nebo lze spočítat rozdíl od minulé hodnoty a o tolik posunout kurzor.

  • + skutečná myš
  • + velmi nenáročná na software, použitelná i v akčních hrách
  • + velmi rozšířená a dobře podporovaná mnoha programy
  • + často emulovaná v emulátorech
  • + existuje několik KMouse interface i k reálným počítačům
  • + možnost používat optické PS/2 myši s kolečkem
  • + pokud nový klon ZX Spectra podporuje myš, bývá to právě KMouse
  • − vyžaduje komplikovanější interface
  • − obsazuje hned tři 16 bitové porty

Detailní popis Velesoftovy konstrukce KMouse Turbo a Velesoftů článek o originální Kempston myši.

Můj článek věnovaný převážně KMouse.

AMX Mouse

A nakonec nelze opominout AMX Mouse. S touto myší jsem se osobně také nikdy nesetkal. V 90. letech jsme o ní věděli jen díky programu Artist, kde byla na výběr (podporována prý byla i v konkurenčním Art Studiu), jako jedna z možností ovládání. I tato myš vyžaduje speciální interface, málo obvyklý, použitelný jen pro tuto myš, který ještě ke všemu pracuje na stejných portech jako 8255 a tedy není společně s ním použitelný.

Podle popisu je tak trochu vylepšenou AMouse. Změny na clonkách zpracovává procesor Z80, ale nemusí stav myši hlídat v cyklu, protože interface vyvolává přerušení když změna nastane. V konečném důsledku to může být podobně náročné jako AMouse, pokud uživatel myší pohybuje, nebo možná nenáročné, když je myš v klidu, nebo je s ní pohybováno jen pomalu. Nejsem si jistý, nezkoušel jsem.

V dnešní době (rok 2021), kdy KMouse podporuje většina emulátorů a leckterý nový hardware vč. ZX Spectrum Next už bych AMX Mouse považoval jen za zajímavou technickou kuriozitu.

Zajímavé detaily o AMX myši lze najít i u Velesofta.

Další myši pro ZX Spectrum zmiňuje Jarek (GEOS mouse a sériovou myš na skutečném UARTu s čipem 8250/8251). Myš lze určitě připojit i přes SIF, zkoušel jsem to, jen se to kvůli malé rozšířenosti SIFu nevyužívá.

Amiga Mouse zvaná AMouse

Amiga myš (přepínatelná Atari myš), zkráceně AMouse není zaměnitelná se sériovou i když její konektor vypadá stejně. U počítačů ZX Spectrum, ale i Amiga a Atari se připojuje do joystickového portu a komunikuje s nimi na úrovních TTL logiky.

Počítači myš předává přímo stav clonek přes tvarovač se Schmittovými klopnými obvody, např. 74HC14. Tvarovač s hysterezí v myši je důležitý, protože fototranzistory mohou být zastíněné jen částečně a jejich zastínění se může měnit velmi pomalu. Přímo připojený výstup z fototranzistoru na TTL vstup by při pomalém průchodu zakázanou oblastí (přibližně mezi napětím 1V až 2.5V) mohl vést k zákmitům na výstupu hradla a to by vedlo k chybnému určení rychlosti a směru pohybu myši počítačem.

Připojit TTL myš do RS232 je špatný nápad, RS232 pracuje s napětím až ±15V a to by mohlo TTL logiku poškodit. Pokud si nejste jistí, jakou myš máte, podívejte se dovnitř, podívejte se jaký čip je uvnitř myši a kolika vodiči je připojená k počítači. RS232 myši v sobě určitě nebudou mít pouze Schmittovy klopné obvody a budou připojeny méně vodiči, nejčastěji jen čtyřmi.

Typické připojení AMouse k ZX Spectru pomocí joystickového interface.

foto foto

Na pravém snímku je optická Amiga myš, která vznikla úpravou původně PS/2 myši, krátká zmínka je i v tomto srovnání. Úprava byla možná jen díky optickému snímači, který kromě PS/2 umí poskytovat i kvadraturní signály, stejné jako výstupy z kuličkové Amiga myši. Jiiirovo rozhraní UPI je s UR-4 plně kompatibilní a opět jde jen o paralelní port s konektorem pro Kempston joystick.

AMouse používá 4 vodiče pro přenos pulzů ze čtyř čidel, dva signály ze dvou fototranzistorů pro každou osu. Další jeden až tři vodiče používá pro přenos stavu tlačítek a dva vodiče pro napájení GND a +5V. Celkem myš potřebuje pro připojení 7 až 9 vodičů. Víc nemá smysl, protože se u ní, stejně jako u joysticku (Kempston, Amiga ...) používá devítipinový konektor DSUB (Canon).

foto foto

Velikost mé staré červené kuličkové Amiga myši je docela běžná, nijak nevybočuje ani ve srovnání se "současnými", resp. vyráběnými o cca 10 až 20 let později. Na pravém obrázku je vidět obvod 74HC14N tvořící veškerou logiku myši. Konstrukce je tedy narozdíl od RS232 a pozdějších myší extrémně jednoduchá. Přesto bývaly i tyto myši velmi drahé a tehdy možná ještě o pár korun dražší kvůli barvě. Opravdu, i mnoho let potom bylo u PC běžné, že skoro všechny komponenty byly v barvě "slonovinová kost", tj. trochu zažloutle béžové plasty a výjimečně jiné (nejčastěji bílé, hnědé, černé).

Konstrukce Amiga myši

Na prvním obrázku je kromě jednoduché elektroniky jasně vidět i konektor s pouze osmi vodiči. Zapojené je totiž pouze levé a pravé tlačítko. Na připojení prostředního tlačítka už vodič nezbyl i kdyby to interface umožňoval.

foto foto foto

Všimněte si přepínače na spodní straně myši, ale nenechte se zmást písmeny MS/PC, to se této myši netýká, plast je společný i pro RS232 variantu. Smysl mají písmena AM a AT, která značí počítače Amiga a Atari. K oběma se používala TTL myš, ale u Atari byly oproti Amize jinak zpřeházené signály z clonek. Pro ZX Spectrum je správná poloha přepínače AM

Konstrukce mechaniky je opět velmi jednoduchá, dva válečky s clonkami a přítlačné kolečko s pružinkou. Válečky i kolečko bylo občas nutné očistit, protože se na ně přes kuličku lepí prach z podložky. Ten vytvoří nejprve tenkou vrstvu, později tlustší a hrbolatější až se nakonec začnou válečky, nebo kulička zadrhávat, častý problém všech kuličkových myší.

foto

Na snímku je vidět i trochu odřené místo, kde se kulička válečků dotýká, to je běžný důsledek používání.

A ještě příklad jiné varianty myši. Rozlišení má velmi podobné, viz srovnání myší zde, opět je vybavena přepínačem. Měly ho skoro všechny myši, snad jen s výjimkou těch původních, co se dodávaly přímo k počítačům Amiga a Atari. Stejný druh myší lze použít i s počítači Sam Coupe (viz originál SAMCo interface) a od roku 2020 i s PMD 85.

amiga/atari mouse amiga/atari mouse foto amiga/atari mouse

Integrovaný obvod MC14584BC uvnitř bílé myši je opět šestice invertorů se Schmittovými klopnými obvody na vstupu. Zapojením se od červené myši téměř neliší.

Zapojení konektoru AMouse

Pro srovnání jsem přidal i zapojení Kempston joysticku. Tlačítko 2 se u joysticku využívá výjimečně, pokud ano, tak by vždy měla existovat i alternativní klávesa, která dělá totéž. Dvě tlačítka bývají na joysticku často, ale málokterý joystick je má zapojená samostatně.

bitvývodKempston joystickAmiga Myš
04vpravoosa X2 (XB)
13vlevoosa Y1 (YA)
22dolůosa X1 (XA)
31nahoruosa Y2 (YB)
46tlačítko 1tlačítko 1 (levé)
59tlačítko 2 (výjimečně)tlačítko 2 (pravé)
65 tlačítko 3 (prostřední)
7 nezapojenonezapojeno
 7+5V+5V
 8GNDGND

V případě UR-4 je pro 2. a 3. tlačítko nutné doplnit invertory po vzoru ostatních signálů joysticku (jako směry a fire). V případě jiných interface možná ne, Jiiirův UPI i moje redukce k Didaktiku Gama 192k mají zapojená všechna 3 tlačítka.

Nepřipojený bit 7 znamená, že interface na tomto bitu vždy vrací 0. Podle toho lze při čtení hodnoty z portu 31 softwarově odhadnout přítomnost Kempston joysticku, nebo kompatibilního rozhraní. Resp. když se na bitu 7 vyskytne 1, můžeme s velkou pravděpodobností říct, že Kempston joystick interface není k počítači připojený a čtení joysticku, nebo myši vypnout.

foto

Na snímku konektoru je černou čárkou označený vývod číslo 1. Následující nákres ukazuje číslování všech vývodů kabelového konektoru.

nakres

Stavový diagram pulzů na výstupu myši a jejich zpracování

Jak jsem psal výše, AMouse vrací tvarovaný signál z fototranzistorů, ty jsou zakrývány clonkami tak, aby při jednom směru pohybu přicházel pulz z jednoho tranzistoru dříve než z druhého. Ideálně přesně o 90° při konstantní rychlosti pohybu, ale v praxi to přesné není, protože fototranzistor může být vůči štěrbině v clonce mírně posunutý, nebo nakloněný. Do určité míry to nevadí. Počítač detekuje změny stavů, ne trvání jednotlivých pulzů.

stavovy diagram výstupu z Amiga myši

K zobrazení stavů clonek připojené myši můžete použít můj program portscope. Signály zobrazené na skutečném osciloskopu ukazují následující snímky obrazovky. Pořadí kanálů je shodné s pořadím bitů, žlutý kanál 1 je bit 0 atd...

foto foto foto

Doba trvání pulzů záleží na rychlosti pohybu myši. Z kombinace pulzů, jak jdou po sobě, lze určit směr pohybu myši. Každá změna stavu na dvojici signálů v jedné ose znamená jeden krok pohybu kurzoru odpovídajícím směrem. Všimněte si, že se nikdy nemění oba signály jedné osy, v podstatě to je nejjednodušší forma Grayova kódu používaná u nejrůznějších rotačních enkodérů.

Nejkratší pulzy s optickou myší, která má rozlišení 400cpi, jsem zaznamenal dlouhé zhruba okolo 250μs, resp. okolo 500μs celý jeden cyklus všech čtyř stavů. To znamená, že by počítač měl snímat port rychlostí alespoň dvojnásobnou (s frekvencí přibližně 4kHz), aby spolehlivě nedocházelo ke ztrátě informace při rychlých pohybech. Rychlejší snímání neuškodí.

Dekódování směru pohybu je docela jednoduché. Například když se stav bitů z kombinace 00 změní na 01 můžeme jednoznačně určit, že došlo k posunu myši o jeden krok jedním směrem, když se ale změní z 00 na 10, tak došlo k pohybu směrem opačným. Ovladač myši k dekódování používá dekódovací tabulku pro každou z možných kombinací předchozího a nového stavu. Vezme dva bity předchozího stavu (např. na pozici bitů 0 a 2), přidá je pomocí OR k dvěma bitům nového stavu (např. na pozici bitů 1 a 3), tím vznikne 4 bitové číslo 0 až 15, číslo přičte k adrese tabulky a z ní přečte hodnotu 0, +1, nebo -1 (to jsou ty 255), kterou může rovnou přičíst k aktuálním souřadnicím kurzoru. Totéž provede pro druhou osu a to celé provádí většinu času z 1/50s, pak překreslí kurzor na novou pozici. To celé opakuje dokud uživatel na nějakém místě obrazovky nestiskne tlačítko myši.

Díky tomu může kurzor na obrazovce počítače přesně kopírovat pohyb myši a ten pohyb je pro uživatele přirozený.

Kempston Mouse

TODO: přesunout tuto část textu do článku o KMouse a tento článek nechat výhradně pro AMouse.

Kempston Mouse interface vytvořila v roce 1986 stejná firma, jako interface pro připojení joysticků na port 31 jehož vylepšenou variantou je i UR-4. Jako polohovací zařízení se k interface připojuje zas TTL myš podobná té k Amize (zpřeházené vývody, viz schéma překreslené Velesoftem), ale navíc je v interface logika, která signály z clonek převádí na byte, jehož hodnota se mění v rozsahu <0, 255> podle směru a rychlosti pohybu myši. Logika interface prakticky dělá totéž, co by jinak musel provádět procesor. Uživateli pak stačí přečíst ze dvou portů hodnoty pro osy X a Y jednou za čas, třeba jednou za 1/50s. Nároky na čas procesoru jsou tak minimální.

S touto myší jsem se poprvé setkal v emulátoru X128, později jsem ji objevil na ruských webových stránkách. V Rusku byla zjevně oblíbená pro svou použitelnost i ve hrách, např. v předělávce WarCraft 1 pro ZX Spectrum "Black Raven" (rusky Чёрный Ворон) a mnoha dalších, dokonce není problém ji používat v Basicu, což ani s A-Mouse, ani s RS232 myší přímo možné není.

Kempston Mouse používá šestnáctibitové adresy portů (detailněji v tomto článku) a to na portech uvedených v tabulce. Původní interface pracoval se dvěma tlačítky, ruské verze i se třemi, v některých případech bylo levé a pravé tlačítko přehozené. Velesoftův interface podporuje tři tlačítka s možností levé a pravé přehodit, navíc na horních 4 bitech vrací hodnotu v rozsahu <0, 15> měnící se podle pohybu kolečkem myši. Princip čtení kolečka je stejný jako princip čtení polohy myši.

porty Kempston mouse

HexDecoznačenípoznámka
#FADF64223tlačítkaB0=pravé, B1=levé, B2=střední (0=stisknuto, 1=nestisknuto)
#FBDF64479souřadnice Xsouřadnice v intervalu <0, 255>
#FFDF65503souřadnice Ysouřadnice v intervalu <0, 255>
#FEDF65247souřadnice Zkolečko myši implementované Velesoftem (později, přesunuto na port tlačítek kvůli kompatibilitě, verze 2008 zde vrací obsah portu #7FFD, na orig. ZXS 128k nečitelný)

Kempston Mouse vrací hodnotu od 0 do 255 i pro Y-ovou souřadnici, je tedy potřeba provést jednoduchou korekci na výšku obrazovky 192px. Hodnoty je možné chápat jako absolutní souřadnici, což je triviální, ale v některých ohledech problematické, nebo porovnáním s minulou hodnotou získat posun určitým směrem a ten pak použít.

Program zobrazující šipku ovládanou myší

K využití myši je dobré mít i program, který to vše usnadní. Postupem času vzniklo několik verzí různých ovladačů. Program tady uvedený je založený na původním ovladači, který jsem kdysi dávno získal vytištěný na papíru. Postupem času byl různě přizpůsobován. Pro potřeby článku jsem ho zjednodušil na minimum, upravil tak, aby byl dobře čitelný a důkladně okomentoval v angličtině, protože to je dnešní standard. Snažil jsem se, aby komentáře byly stručné a věcně správné. Doufám, že se mi to i podařilo.

Ovladač pracuje výhradně s klávesnicí a AMouse, přičemž AMouse lze nastavením MOUSE_HID na nulu vypnout a šipku ovládat pouze klávesnicí. Ovladač neobsahuje zpracování horkých kláves, emulaci kolečka, neřeší čtení josticku a případnou kolizi s myší. To proto, aby v něm nebylo nic navíc, co by mohlo komplikovat pochopení práce s AMouse a komplikovat přenesení částí kódu do jiných programů. Existuje komplikovanější ovladač s podporou KMouse, který to vše umí.

Program se skládá ze dvou základních částí. Části, která čte porty, mění souřadnice myšího kurzoru a vykresluje šipku na obrazovku a z části, která je v podstatě nejjednodušším možným programem, který ovladač využívá. Ta část smaže obrazovku, vykreslí ikonu (jeden červený čtverec), nadefinuje ovládací klávesy a souřadnice ikon a potom zavolá myší ovladač s šipkou. Ovladač běží tak dlouho, dokud uživatel neklikne na ikonu a pak provede v tabulce nadefinovanou akci, v případě této ukázky EXIT, tj. vrátí se to BASICu.

Zde je možné zobrazit ukázkový program se zvýrazněním syntaxe. Zde je původní, méně přehledná a špatně komentovaná verze z doby, než jsem ji nahradil tou současnou.

;==============================================================================
; simplified AMouse + keyboard only driver
;==============================================================================
; simplest possible demo with one icon (red square) for exit

		cpu	z80undoc
		org	32768

START		push	iy			; some registers are needed for Sinclair BASIC
		exx
		push	hl
		exx

		ld	a,56			; PAPER 7, INK 7
		call	CLS			; clear screen
		ld	a,2*8			; red PAPER, black ink
		ld	(22528),a		; make red square 16x16px in top left corner
		ld	(22528+1),a		; = simplest icon "exit"
		ld	(22528+32),a
		ld	(22528+33),a
		ld	a,6			; BORDER 6
		out	(254),a
		
		
		ld	a,1			; enable AMouse
		ld	(MOUSE_HID),a

		ld	hl,ICONS		; set address of icon table
		ld	(MOUSE_ICONS),hl	; should contain at leas one icon

		ld	hl,KEYTAB		; set address of table, where are defined control keys
		ld	(MOUSE_KEYTAB),hl

		jp	CALLMOUSE		; call mouse driver

EXIT		exx				; return to Sinclair BASIC
		pop	hl
		exx
		pop	iy
		ret

;--------------------------------------------------------------------------------------------------

ICONS		db	0,16,0,16		; x1,x2,y1,y2 - area where icon is
		dw	EXIT			; address where to jump if clicked on icon
		db	255			; end of table

; Every item in these tables is composed from 5 bytes. First two are port address.
; For example 254+256*127 = 32766 which is io port for keys B, N, M, symbol shift and space
; Third byte is mask. Last two bytes is address determinig what code to call if key will be
; pressed.

KEYTAB		db	254, 223, 00000010b	; LEFT			(O)
		dw	MOUSE_KLEFT		; where call if key pressed
		db	254, 223, 00000001b	; RIGHT			(P)
		dw	MOUSE_KRIGHT
		db	254, 251, 00000001b	; UP			(Q)
		dw	MOUSE_KUP
		db	254, 253, 00000001b	; DOWN			(A)
		dw	MOUSE_KDOWN
		db	254, 127, 00000100b	; FIRE			(M)
		dw	MOUSE_KFIRE1
		db	255			; end of table

; This table can be defined for Kempson joystick too, but it doesn't make sense if
; AMouse is connected to the same port. Disable AMouse, redefine table and it will work.
;
; In table could be more keys with same function. For example OPQAM and Sinclair joystick 67890.
;==================================================================================================

MOUSE_CHEIGHT	equ	13			; height of pointer - all pointers have same height

;--------------------------------------------------------------------------------------------------
; start of main loop

MOUSE		ld	hl,128+96*256		; cursor coordinates X in L, Y in H
		ld	a,h			; copy cordinates
		ld	c,l			; X -> C, Y -> A
		call	8880			; from coordinates compute address in VRAM in HL
		ld	(MOUSE_DRAW+1),hl	; set pattern for drawing
		ld	(MOUSE_CLEAR+1),hl	; set pattern for erasing
		ld	(MOUSE_DRAW_2+1),a	; set, how many rotations subtract from 8
		call	MOUSE_DRAW		; draw cursor on screen

;------------------------------------------------------------------------------
; change coordinates of mouse cursor by keyboard

MOUSE_KEYBOARD	ld	ix,MOUSE_DUMMY_TAB	; get address of table with defined keys
		ld	hl,(MOUSE_XY)		; get cursor coordinates in HL
		xor	a
		ld	(MOUSE_RKEYS_JR+1),a	; modify address in relative jump to MOUSE_RKEYS
		ld	d,a			; set D = 0, default a state of buttons = nothing pressed (yet)
		ld	e,a			; set E = 0, it has no use in this driver
		call	MOUSE_READKEYS		; process whole key table
		ld	(MOUSE_XY),hl		; store new coordinates
		ld	a,d
		ld	(MOUSE_BUTTONS),a	; store new buttons status

; keyboard processed - continue with real mouse if enabled
;
; MOUSE_HID
; 0 = only keyboard
; 1 = keyboard + AMouse

MOUSE_HIDLD	ld	a,0			; is AMouse enabled?
		or	a
		jp	nz,MOUSE_AMOUSE		; NZ = jump to AMouse driver

MOUSE_COMMON	ei				; enable interrupt (just for any case)
		halt				; and wait for interrupt (1/50s when picture is starting on TV screen)
		call	MOUSE_CLEAR		; remove old cursor from screen

MOUSE_FB_STATE	ld	a,0			; get buttons status (FIRE BUTTONS, or HOTKEYS)
		or	a			; 0 = check for zero (nothing pressed)
		ret	nz			; NZ = something was pressed -> return

		jr	MOUSE			; repeat whole loop

;--------------------------------------------------------------------------------------------------
; these subroutines are called by table of control keys

MOUSE_KFIRE1	set	0,d			; fire 1 was pressed - set bit 0
		ret

MOUSE_KLEFT	ld	a,l			; get X coordinate in A
		sub	c			; subtract step size
		ld	l,a			; store new X coordinate back
		ret	nc			; NC = no correction is needed
		ld	l,0			; left border was crossed, correct it
		ret

MOUSE_KRIGHT	ld	a,l			; get X coordinate in A
		add	a,c			; add step size
		ld	l,a			; store new X coordinate back
		ret	nc			; NC = no correction is needed
		ld	l,254			; right border was crossed, correct it
		ret

MOUSE_KUP	ld	a,h			; get Y coordinate in A
		sub	c			; subtract step size
		ld	h,a			; store new Y coordinate back
		ret	nc			; NC = korekce není potřeba
		ld	h,0			; top border was crossed, correct it
		ret

MOUSE_KDOWN	ld	a,h			; get Y coordinate in A
		add	a,c			; add step size
		ld	h,a			; store new Y coordinate back
		cp	190			; check if bottom border was crossed
		ret	c			; C = no correction is needed
		ld	h,190			; bottom border was crossed, correct it
		ret

;--------------------------------------------------------------------------------------------------
; MOUSE_READKEYS - universal code for processing table of ports and masks for keys or joystick
; need address of table in register IX
; doesn't affect registers HL & DE (HL contains coordinates, DE state of buttons and scroll wheel)

MOUSE_READKEYS	ld	a,(ix+0)
		cp	255			; 255 = end of table?
		ret	z			; Z = end of table reached = return
		ld	c,a			; read 16 bit address in register BC, will be port address
		ld	b,(ix+1)
		in	a,(c)			; read 16 bit io port
		bit	7,c			; try detect if port was keyboard or Kempston joystick
						; for Kempston joystick should be bit 7 always 0
						; for keyboard should be bit 7 alwais 1
		jr	z,MOUSE_RKEYS_JOY	; Z = probably joystick
		cpl				; invert bits, for keyboard is pressed key = 0
MOUSE_RKEYS_JOY	and	(ix+2)			; now should be pressed key or joystick direction = 1, apply mask
		jr	z,MOUSE_RKEYS_NXT	; Z = tested key not pressed
		ld	c,(ix+3)		; address of code for tested key in BC
		ld	b,(ix+4)

; this relative jump is switch for differen behavior for regular keys (directions, fire...) and hotkeys

MOUSE_RKEYS_JR	jr	MOUSE_RKEYS		; relative address will be modified do MOUSE_RKEYS, or to MOUSE_RHKEYS

; regular keys for moving cursor etc.

MOUSE_RKEYS	ld	(MOUSE_RKEYS_3+1),bc	; modify address in instruction CALL
MOUSE_KSLD	ld	c,2			; step size for cursor movement
MOUSE_RKEYS_3	call	MOUSE_RET		; call subroutine for pressed key
MOUSE_RKEYS_NXT	ld	bc,5			; 5 bytes per item in table
		add	ix,bc			; compute address of next item in table
		jr	MOUSE_READKEYS		; repeat

MOUSE_RET	ret

;------------------------------------------------------------------------------
; change coordinates by AMouse
;
; will change these coordinates
; will change status of buttons on address MOUSE_BUTTONS if pressed

MOUSE_AMOUSE	ld	bc,130*256		; B = how many times read port every 1/50s (compromise), set C = 0
		ld	a,(MOUSE_X)		; copy coordinates in operands inside cycle
		ld	(MOUSE_AM_X+1),a
		ld	a,(MOUSE_Y)
		ld	(MOUSE_AM_Y+1),a
MOUSE_AM_LOOP	push	bc			; 11T	store BC - here starts main loop for AMouse
		ld	b,c			; 4T	copy zero from C to B (zero will be returned every pass through loop from stack)
		in	a,(31)			; 11T	read AMouse (Kjoy) port
		ld	de,MOUSE_AM_STAT	; 10T	pointer to old status of mouse signals for X
		call	MOUSE_AM_DIR		; 17T	check which direction mouse moved
MOUSE_AM_X	ld	a,0			; 7T	get X coordinate in A
		add	a,(hl)			; 7T	add value 0, +1 or -1 from table
 		jr	z,MOUSAKX		; 12/7T	Z = left border reached or right border crossed, don't store new coordinate
		ld	(MOUSE_AM_X+1),a	; 13T	write new X coordinate

MOUSAKX		inc	de			; 6T	increment pointer to old status of mouse signals to Y
		in	a,(31)			; 11T	read AMouse (Kjoy) port
		rrca				; 4T	rotate 1 bit right, to be able use same subroutine as for X
		call	MOUSE_AM_DIR		; 17T	check which direction mouse moved
MOUSE_AM_Y	ld	a,0			; 7T	get Y coordinate in A
		add	a,(hl)			; 7T	add value 0, +1 or -1 from table
		jr	z,MOUSAKY		; 12/7T	Z = top border was reached, don't store new coordinate
		cp	190			; 7T	check if bottom border was crossed
		jr	c,MOUSADO		; 12/7T	C = mouse cursor is still above bottom border
		ld	a,190			; 7T	make correction
MOUSADO		ld	(MOUSE_AM_Y+1),a	; 13T	write new Y coordinate
MOUSAKY		pop	bc			; 10T	restore BC
		djnz	MOUSE_AM_LOOP		; 13/8T	repeat B times

; total 11+4+11+10+17+75+7+7+7+13+6+11+4+17+75+7+7+7+7+12+13+10+13 = 351T most typical run (cca 10kHz)

		ld	a,(MOUSE_AM_X+1)	; copy new coordinates from AMouse part to main "variable"
		ld	(MOUSE_X),a
		ld	a,(MOUSE_AM_Y+1)
		ld	(MOUSE_Y),a
		in	a,(31)			; last time read AMouse port
		rra				; move bits 4,5,6 for buttons to position of bits 0,1,2
		rra
		rra
		rra
		and	00000001b		; leave only bit significant for button (can be up to three)
		ld	b,a			; copy to register B
		ld	a,(MOUSE_BUTTONS)	; read status of "fire" keys
		or	b			; OR it with mouse buttons,
		ld	(MOUSE_BUTTONS),a	; now can be used both at a same time
		jp	MOUSE_COMMON

; this subroutine will combine old and new status of mouse signals and will return pointer in HL to value 0,+1,-1

MOUSE_AM_DIR	and	00000101b		; 7T	leave only bits for mouse signals
		ld	c,a			; 4T	store it in C
		ld	a,(de)			; 7T	read old state of mouse signals
		rlca				; 4T	rotate left
		and	00001010b		; 7T	and leave only these bits
		or	c			; 4T	combine with new state of mouse signals - now ve have number 0..15 
		ld	(de),a			; 7T	store result for future use
		ld	c,a			; 4T	copy it in C, B is already zero
		ld	hl,MOUSE_AM_TAB		; 10T	get pointer in "directions" table
		add	hl,bc			; 11T	add number 0..15 assembled from "new and old mouse signals"
		ret				; 10T

; total 7+4+7+4+7+4+7+4+10+11+10 = 75T

MOUSE_AM_TAB	db	0,255,1,0		; table of values 0, +1, -1 for every possible
		db	1,0,0,255		; combination of old and new mouse signals
		db	255,0,0,1
		db	0,1,255,0

MOUSE_AM_STAT	db	0			; old status of mouse signals for axis X
		db	0			; old status of mouse signals for axis Y

;--------------------------------------------------------------------------------------------------
; cursor drawing - code heavily inspired by book "Assembler and ZX Spectrum II" from Proxima
;--------------------------------------------------------------------------------------------------
; MOUSE_DRAW a MOUSE_CLEAR subroutines can be called any time without need set registers.
; MOUSE_DRAW will draw cursor on screen at same position as it was last time when was driver running.
; Buffer will be updated, so MOUSE_CLEAR can be called after that.

MOUSE_DRAW	ld	hl,19472		; pointer to the screen where mouse cursor should be
MOUSE_CURLD	ld	ix,MOUSE_SPR_ARROW	; sprite address in IX (can be changed for another sprite)
		exx
		ld	hl,MOUSE_BACKGRBUF	; buffer address in second HL, in buffer will be copied screen content
		exx
		ld	b,MOUSE_CHEIGHT		; sprite height
MOUSE_DRAW_1	push	bc			; store height in stack
		push	hl			; store screen pointer twice on stack
		push	hl
		ld	h,0			; 0 in H, here will be rotated sprite/mask if needed
		ld	l,(ix+0)		; read sprite in L
		ld	d,h			; 0 in D
		ld	e,(ix+MOUSE_CHEIGHT)	; read mask in E
		inc	ix			; move pointer IX to next byte of graphics
		ld	a,8			; 8 in A (8 bits/rotations per byte)
MOUSE_DRAW_2	sub	0			; subtract number of rotations to the right
		ld	b,a			; number of rotation to the left in B
MOUSE_DRAW_3	add	hl,hl			; HL *= 2 (rl HL)
		sla	e			; DE *= 2 (rl DE)
		rl	d
		djnz	MOUSE_DRAW_3		; repeat until B = 0 (up to 7 times)
		ex	(sp),hl			; swap address of cursor on screen from stack to HL
		pop	bc			; get rotated graphics of cursor into BC (was in HL originally)
		ld	a,(hl)			; read original content of screen
		exx				; second set of registers
		ld	(hl),a			; store original content of screen in buffer
		inc	hl			; next byte in buffer
		exx				; primary set of registers
		ld	a,d			; get left part of mask
 		cpl				; invert it
		and	(hl)			; remove pixels from background where mask had 0
		or	b			; add graphics of mouse cursor
		ld	(hl),a			; store it back in screen
		inc	l
		ld	a,l
		and	00011111b		; was right border crossed?
		jr	z,MOUSE_DRAW_4		; Z = yes
		ld	a,(hl)			; whole proccess repeat again for second byte
		exx
		ld	(hl),a
		inc	hl
		exx
		ld	a,e
 		cpl
		and	(hl)			; remove pixels from background where mask had 0
		or	c			; add graphics of mouse cursor
		ld	(hl),a
MOUSE_DRAW_5	pop	hl			; restore address of left byte in screen from stack
		call	DOWNHL			; compute address one pixel down
		pop	bc			; restore counter
		djnz	MOUSE_DRAW_1		; repeat for whole height of mouse cursor
		ret

MOUSE_DRAW_4	exx
		inc	hl			; only increment pointer to the buffer
		exx
		jr	MOUSE_DRAW_5

;--------------------------------------------------------------------------------------------------
; clear cursor and replace it with original content of screen before mouse cursor was drawn
;--------------------------------------------------------------------------------------------------

MOUSE_CLEAR	ld	hl,16384		; pointer to the screen where is placed mouse cursor
		ld	b,MOUSE_CHEIGHT		; height of mouse cursor in pixelx
		ld	de,MOUSE_BACKGRBUF	; address of buffer with original content
MOUSE_CLEAR_1	ld	a,(de)			; get byte from buffer
		ld	(hl),a			; write it in screen
		inc	de			; move DE to next byte in buffer
		push	hl			; store HL
		inc	l
		ld	a,l
		and	00011111b		; was right border crossed?
		jr	z,MOUSE_CLEAR_2		; Z = yes, jump over processing second byte
		ld	a,(de)			; get byte from buffer
		ld	(hl),a			; write it in screen
MOUSE_CLEAR_2	inc	de			; move DE to next byte in buffer
		pop	hl			; restore HL to address of left byte
		call	DOWNHL			; compute address one pixel down
		djnz	MOUSE_CLEAR_1		; repeat for whole height of mouse cursor
		ret

;==================================================================================================
; graphics of some very basic cursors
;==================================================================================================

MOUSE_SPR_ARROW	db	00000000b		; classic arrow cursor
		db	01000000b
		db	01100000b
		db	01110000b
		db	01111000b
		db	01111100b
		db	01111110b
		db	01111000b
		db	01001000b
		db	00001000b
		db	00000100b
		db	00000100b
		db	00000000b

		db	11100000b		; mask
		db	11110000b
		db	11111000b
		db	11111100b
		db	11111110b
		db	11111111b
		db	11111111b
		db	11111111b
		db	11111100b
		db	11111110b
		db	00011110b
		db	00011110b
		db	00001110b

MOUSE_BACKGRBUF	ds	MOUSE_CHEIGHT*2		; buffer for part of screen where cursor was drawn

;==================================================================================================
; wait until any key is pressed include mouse buttons if selected
; PAUSE 0 because command in Sinclair BASIC with similar behaviour

PAUSE0		call	MOUSE_TESTFIRE
		jr	z,PAUSE0		; Z = no key or button was pressed, repeat
		ret

; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; wait while any key is pressed include mouse buttons if selected

PAUSENK		call	MOUSE_TESTFIRE
		jr	nz,PAUSENK		; NZ = some key or button is pressed, repeat
		ret

; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; common part for keys/buttons testing - returns Z if nothing pressed

MOUSE_TESTFIRE	xor	a			; set port upper byte of address to zero
		in	a,(254)			; read all keyboard ports at once
		cpl				; invert bits
		and	11111b			; leave only bits significant for keys
		ret	nz			; NZ = a key was pressed, return, otherwise we will check mouse buttons
		ld	a,(MOUSE_HID)		; is mouse control enabled?
		or	a			; check for zero
		ret	z			; Z = only keyboard is enabled, but fire is not pressed, return
		jr	MOUSE_TSTBUTAM		; NZ = AMouse enabled, jump to test AMouse buttons

MOUSE_TSTBUTAM	in	a,(31)			; AMouse left button, or Kempston Joystick fire button
		and	00010000b		; only bit for buttons (can be up to three buttons)
		ret

;==================================================================================================
; CALLMOUSE is the main entry point for program using this driver
;==================================================================================================
; See example how to use it.
; Basically call this code and it will jump to address defined in table for clicked icon or pressed hotkey.

CALLMOUSE	call	MOUSE			; call main loop, it will draw mouse cursor
						; until fire button will be pressed

MOUSE_TSTXY	ld	de,(MOUSE_XY)		; read coordinates where user clicked in DE (D = X, E = Y)
		ld	bc,6			; size of item in BC (4 bytes coordinates, 2 bytes address)
MOUSE_TSTXY_0	ld	ix,MOUSE_DUMMY_TAB	; table address in IX
		jr	MOUSE_TSTXY_FRS		; jump over first add

MOUSE_TSTXY_NXT	add	ix,bc			; add size of intem BC and pointer to table IX
MOUSE_TSTXY_FRS	ld	a,(ix+0)		; read coordinate X1
		cp	255			; is it end of table (255)?
		jr	z,CALLMOUSE		; Z = end of table, user did not clicked on icon, but somewhere else
		cp	e			; compare coordinates of cursor with coordinates from table
		jr	nc,MOUSE_TSTXY_NXT	; NC = cursor is outside icon
		ld	a,(ix+1)
		cp	e
		jr	c,MOUSE_TSTXY_NXT	; C = cursor is outside icon
		ld	a,(ix+2)
		cp	d
		jr	nc,MOUSE_TSTXY_NXT	; NC = cursor is outside icon
		ld	a,(ix+3)
		cp	d
		jr	c,MOUSE_TSTXY_NXT	; C = cursor is outside icon

		ld	h,(ix+5)		; get address for this icon in HL 
		ld	l,(ix+4)
		jp	(hl)			; and jump on that address

;==================================================================================================
; important addresses for this driver
;==================================================================================================
; compiler needs these values here, at end of code

MOUSE_BUTTONS	equ	MOUSE_FB_STATE+1	; button status (of not zero, button or key was pressed)
MOUSE_X		equ	MOUSE+1			; last known coordinates
MOUSE_Y		equ	MOUSE+2
MOUSE_XY	equ	MOUSE+1
MOUSE_HID	equ	MOUSE_HIDLD+1		; 0 = keyboard only, 1 = AMouse enabled
MOUSE_KEYSTEP	equ	MOUSE_KSLD+1		; KEYSTEP, step size for cursor movement by keyboard
MOUSE_ICONS	equ	MOUSE_TSTXY_0+2		; address where set pointer to icon table
MOUSE_KEYTAB	equ	MOUSE_KEYBOARD+2	; address where set pointer to table of control keys

MOUSE_DUMMY_TAB	equ	15360			; it points in ROM, where should be 255 = end of table
						; MOUSE_DUMMY_TAB should be always replaced by real address

;==================================================================================================
; compute address on screen one pixel down under current address
; This is usualy part of program which is using this driver

DOWNHL		inc	h
		ld	a,h
		and	7
		ret	nz
		ld	a,l
		add	a,32
		ld	l,a
		ld	a,h
		jr	c,DOWNHL2
		sub	8
		ld	h,a
DOWNHL2		cp	88
		ret	c
		ld	h,0			; if bottom margin was reached draw sprite in read only ROM
		ret

;--------------------------------------------------------------------------------------------------
; clear screen - short and slow
		
CLS		ld	(CLS_2+1),a
		ld	hl,16384
        	ld	de,16385
		ld	bc,6144
		ld	(hl),0
		ldir				; fill pixels with zeroes
		ld	bc,767
CLS_2		ld	a,56			; colors - 0*128 + 0*64 + 8*7 + 0 = FLASH 0, BRIGHT 0, PAPER 7, INK 0
		ld	(hl),a
		ldir				; fill color attributes
		ret

;==================================================================================================
; Chips 8255 (clones of Intel 8255) are often used for paralell interface compatible with
; Kempston joystick. Normally after reset it have all 3 ports set as input, but sometimes it
; need to be set again. You can do it by this code.

SET8255INPUT	ld	a,155			; all ports as input (default state after reset)
		out	(127),a
		ret

; Standard decimal addresses are
;
; 31 - io port
; 63 - io port
; 95 - io port
; 127 - control port
;
;==================================================================================================

Program by mělo být možné zkompilovat většinou kompilerů pro PC. Já jsem ho kompiloval pomocí kompileru AS a testoval na reálném ZX Spectrum +2 s AMouse k čemuž mi opět pomohl program sercp.

Kompletnější ovladač s podporou KMouse a dalších vychytávek je ke stažení v článku o KMouse. V reálném použití taky nebývá dobrý nápad nějaký ovladač použít bez možnosti konfigurace uživatelem. Přítomnost AMouse se nedá spolehlivě rozpoznat, pouze s nějakou mírou nejistoty odhadnout. Na přítomnost AMouse lze usuzovat z bitu 7, který je roven 0 a z toho, že směry joysticku vlevo a vpravo, nebo nahoru a dolu, mohou být sepnuté současně, což s joystickem nejde. Ale pořád to neznamená, že je na portu přítomna myš. Bit 7 může být 0 protože je k počítači připojen úplně jiný interface a protilehlé směry mohou být aktivní současně protože místo joysticku uživatel připojil tlačítka, nebo taky úplně z jiného důvodu. Proto by každý program měl mít volbu ovládání, kde si uživatel sám zvolí, co chce používat.

Download

Související odkazy

Historie změn článku

  • 2004-02-28 - celý článek přepracován, výrazně rozšířen úvod, opraveny chyby, doplněn datasheet 74HC14 a obrázek myši zevnitř.
  • 2005-04-11 - opraveny přehozené bity 0 a 1 (v tabulce i diagramu), upozornil Velesoft
  • 2005-04-11 - doplněny odkazy na HWBook s popisem konektorů, vše znovu pečlivě zkontrolováno podle reálného fungujícího hardwaru
  • 2015-12-23 - revidováno, promazán balast a nesmysly z textu, doplněny obrázky, opraven pinout (poštouchl nalezenou chybou z00m).
  • 2021-06-12 - opět revidováno, přepsán historický úvod, opraven a doplněn text o AMouse

[ Zpět na hlavní stránku ]

Tento web je převážně o ZX Spectru, kompatibilních počítačích a jiném zajímavém hardwaru. Naleznete-li chybu, nebo byste rádi cokoliv co s tímto souvisí, můžete mi napsat email. Stručně o mém webu zde.