Retró rovat X: HIDcsekk

Lehet, hogy ez a billentyűzetes téma másnak már a könyökén jön ki, nekem még mindig akad hozzá időnként lelkesedésem. A közelmúltban szintén volt egy olyan napom, amikor másra nem voltam képes, csak egy szokásos régi vasas takarításra, néha van ilyen is. Magának a billentyűzetnek a takarítását lehet, hogy túllihegtem, most a mozgó részek még kaptak egy kevés szilikonos zsírt is. Arról viszont nem vagyok meggyőződve, hogy egyáltalán kenőzsír-e, amit használtam. De a jelek biztatóak, a darab olyan, mint a vaj!

Egyrészt pont olyan sárga, :) másrészt úgy működik, mint egy vatta-új darab. Körülbelül... Na de! Most nem a mechanika lesz a fő téma, hanem a hozzá tartozó vezérlőelektronika, aztán beesik egy meglepően furcsa tapasztalat is.

A feladat alapban az, hogy van egy rakás kontakt, amit le kellene kérdezni szoftverrel. Ezt anno hogyan oldották meg? Vizsgálati alanynak jöjjön egy nagy öreg, a CBM PET. Ez ugyan jó néhány fajta gépet takar, (egyik típusom sincs, ) de a billentyűzet-kezelést az összes ugyanúgy oldja meg. A kérdéses áramkör:

A CPU egy MOS 6502, ez nincs a képen. Az ezen futó program egy 6520 PIA csip segítségével kialakított porton keresztül kezeli a billentyűzetet. Egy-egy sornak a kiválasztásáért egy 74LS145 típusú dekóder (demultiplexer) csip felel, ennek van 4 bemenete, aminek a kombinációival kiválasztható egy kimenet, az lesz alacsony szintű. A bemenetek kombinációinak a száma 16, kimenet viszont csak 10 van, így van 6 nem használható érték, de ennek itt nincs jelentősége. Az első billentyűzetes mesében volt szó a „fantom billentyű paráról”; amikor „pont úgy”, több gomb van egyidejűleg nyomva, akkor a kiválasztott sorhoz képest egy másik sor is aktív állapotba kerül. Ez itt azért lényeges, mert ekkor a dekóder csipnek két kimenete rövidre záródik, de itt ezzel nincs semmi probléma, mivel az 'LS145 kimenetei nyitott kollektoros felépítésűek, logikai magas szintet nem tudnak hajtani. Mondhatni tökéletes választás erre a feladatra. A PET billentyűmátrixa így 10 sor × 8 oszlop, a dekóder ezt a 10 sort hajtja. A sorkiválasztás a PIA PA3..0 vonalaival történik, az oszlopokat ugyanezen csip PB7..0 vonalain lehet visszaolvasni. Hogy nem kapcsolt állapotban a bemenetek magasak legyenek, egy adag (ebben 10KΩ-os) ellenállás az oszlopokat magasra húzza. Itt ez nincs elspórolva (később lesz ez máshogyan is megoldva), cserébe maga a PET van néhány helyen „érdekesen” megcsinálva... Például az I/O címeket kiosztó logika meglehetősen hiányosra van véve. :-D A PIA csipeknek 3 (!) engedélyező bemenete van, mindegyiknek aktívnak kell lennie ahhoz, hogy a tok ki is legyen választva. Ha a kapcsolási rajzot jól bogoztam ki, akkor itt, a KB-t kezelő PIA az $E810..$E81F tartományban látszik. A gépben van egy másik PIA is $E820..$E82F-en, illetve egy 6522 VIA is, ez $E840..$E84F-en van. A két PIA közül az egyiket az A4 magas szintje engedélyezi egy $Exxx illetve egy $x8xx címtartományt kapuzó jellel együtt. A másik PIA az A5 + $Exxx + $x8xx jelekre aktív. Na de mi van akkor, ha az A4 és az A5 is magas? Tehát $E830..$E83F tartományban? Olvasáskor sanszosan mindkét PIA egyszerre hajt az adatbuszra... Mi lehet erre a megoldás? Tudom, ne olvasd azt a címtartományt! :-D Ez egy olyan hardvernél még el is megy, amire csak a gyár ír programot, de egy általános számítógépben ilyet elkövetni..? Azért néha elcsodálkozok ezeken a megoldásokon... :) (...attól függetlenül, hogy ez valószínűleg nem akkora trauma, mint aminek látszik.)

Mivel a PET-nek nincs dedikált Joystick bemenete, ezért annak a kezeléséről itt nincs mit mondani. A következő CBM gépnél, a VIC-20-nál már akad érdekesség ezen a környéken is, de először maradjunk a billenők kezelésénél, áramkörrészlet:

Ez az áramkör annyira fura, hogy meg kellett nézzem a saját példányom, hogy tényleg így van-e. (Igen, így van.) A gépben a perifériák kezelését két darab 6522 VIA-val oldották meg. Ránézésre a tokok kiválasztását itt is az A4/A5 vonal végzi, gyanúsan itt is összehajt az adatbuszon a két eszköz, ha rossz helyről olvas az ember. Node! A billentyűzetmátrix itt csak 8×8-as, és nincs külön „sorhajtó” csip, azt is a VIA végzi közvetlenül. Illetve az oszlopokat felhúzó ellenállások is mintha hiányoznának... A VIA mindkét portjának kb. összes vonalát szabadon lehet konfigurálni ki / bemenetnek egyaránt. Emiatt a kapcsolásból nem derül ki, hogy mi a hajtás / mi a bemenet, erre a gépben futó szoftver lehet csak a válasz. A billentyűzetért felelős VIA-t a $9120..$912F tartományban lehet elérni. Az inicializációs rutin $FDF9-en kezdődik, részlet:

. FE1A  A2 FF     LDX #$FF
. FE1C  8E 22 91  STX $9122
. FE1F  A2 00     LDX #$00
. FE21  8E 23 91  STX $9123

A rutin a DDRB-t állítja kimenetre, az a PB7..0 vonalakat jelenti, a DDRA-t meg bemenetre, ami a PA7..0. Ugyan van itt egy csavar, a név szerinti „sorok” a bemenet, az „oszlopok” meg a kimenet, de ez most részletkérdés, ezek a nevek önkényesen lettek adva. Mint ahogy a port kiosztása is lehet, hogy a véletlen műve; részlet a VIA dokumentációjából:

A PAx lábak hajtásánál a felső FET tulajdonképpen egy félvezetőből létrehozott felhúzó ellenállás, ami mindig aktív. Ezek a lábak kimenetként magasat csak ezzel az ellenállással tudnak előállítani, amit ebben az esetben büntetlenül le is lehet húzni, és ezt bemenetként vissza is lehet ilyenkor olvasni. Viszont a felhúzás bemeneti állapotban is aktív, és igen, ezek helyettesítik a külső felhúzó ellenállásokat a billentyűzet oszlopain. De azért itt is van fejvakarós rész... :) A mátrix hajtását a PBx lábak végzik, viszont azok „megerősített” módon tudnak magas szintet hajtani, tehát ha a „több-gombos” nyomogatás van, akkor ezek szépen rövidre zárhatják a kimeneteket. Vajon miért nem fordított lett a portkiosztás? A beépített felhúzó ellenállás ott van a PBx vonalakon is, (annak a „furcsa” alkatrésznek a jobb oldala ugyanaz a FET, mint a másik porton, ) a PAx vonalak meg ideálisak lennének a vonalhajtásra, mivel nem okoz semmi galibát két vonal rövidre zárása. Valószínűleg a PBx-en sem, de cserébe legalább jól melegszik tőle a tok. :) A „furcsaság”, amit fent említettem viszont az, hogy a „nagy áramú” PB7 vonal, ami kimenetnek van konfigurálva, erre van rákötve a Joy-port egyik irányvonala! Az hagyján, hogy ha húzzák a Joyt a megfelelő irányba, akkor blokkolja a billentyűzet (egyik sorának az) olvasását... De! A „nagy áramú” PB portra van kötve, annál meg az adatregisztert olvasva mindig a beállított érték jön vissza kimenet esetén, nem a láb aktuális állapota, mint a PA-nál! Szóval ha Joyt akar kezelni a szoftveríró, akkor kapcsoljon bemenetre, ha meg billentyűzetet, akkor kimenetre. Hogy ebben így mi a jó... :) Sőt: a PB-t lehetne „okosan” is kezelni, hogy kifelé nyitott kollektoros működést szimuláljon: alapból az adatregiszterébe $00-t kell állítani, majd csak azt a vonalat kell kimenetre kapcsolni, amelyiket hajtani akarja, a többi meg bemenet. Tulajdonképpen ugyanúgy egy regisztert kellene írogatni, mint az adatregiszternél, máris nem történne az összehajtásnál / Joy-húzásnál „zárlat”. Vajon így van-e? Hát, nem, $EB1E-n kezdődik a billentyűvizsgálat:

. EB1E  A9 00     LDA #$00
. EB20  8D 8D 02  STA $028D
. EB23  A0 40     LDY #$40
. EB25  84 CB     STY $CB
. EB27  8D 20 91  STA $9120
. EB2A  AE 21 91  LDX $9121
. EB2D  E0 FF     CPX #$FF
. EB2F  F0 5E     BEQ $EB8F

Ez a lekérdezés eleje, ahol látszik is egy jó trükk: az összes kimeneti vonalat aktívba kapcsolja, majd megnézi, hogy a visszaolvasott adatban az összes bemeneti vonal passzív-e. Ha igen, akkor tuti nincs egy gomb se nyomva, tehát nem kell végigszkennelni az egész mátrixot. Ezt a PET-es változatnál nem lehet megcsinálni, ott a sorokat minimum végig kell pörgetni. De a rutin az adatregisztert írja, az adatirány-regisztert csak az inicializációs rutin állítja be, többet nem piszkálja semmi. (A ROM-ban levő rutinok részéről, természetesen.) Van még egy billentyű, a RESTORE, ami nem része a mátrixnak, ezzel a másik VIA-n keresztül NMI-t lehet kiváltani. (RUN/STOP + RESTORE, ismerős..?)

Tehát a VIC20 esetében van némi szemöldökráncolás a megoldást nézve, de vajon az utód, a hírös C64 hogyan is áll ezzel a témával? Igen hasonló az előzőhöz:

Itt a perifériák kezelését két 6526 CIA végzi, ebből az egyik van a billentyűk / Joy-portok (ebből itt kettő van) számára fenntartva. Kissé logikusabb mint az elődben, de tökéletesnek ezt se nevezném... :) Szerencsére itt már nincs nyoma a hiányos címdekódolásnak, a vizsgálandó csip a $DC00..$DCFF tartományban érhető el. A billentyűmátrix ugyanaz mint a VIC20-on, (Most direkt megnéztem: teljesen kompatibilis a csatlakozóval együtt a C64 billentyűzete a VIC20-éval, legalábbis a nálam levő CR változattal!) ugyanúgy 8×8-as. A CIA-k portja is egyénileg konfigurálható, a rajzból itt se derül ki a ki/bemenet, a ROM-ból viszont igen, perifériainicializálás részlet:

. FDBC  A2 00     LDX #$00
. FDBE  8E 03 DC  STX $DC03
. FDC1  8E 03 DD  STX $DD03
. FDC4  8E 18 D4  STX $D418
. FDC7  CA        DEX
. FDC8  8E 02 DC  STX $DC02

A PB7..0 bemenetre lesz kapcsolva, a PA7..0 meg kimenetre. A CIA adatlapja szerint a két port kimeneti felépítése megegyezik, minden lábon van belül felhúzás, magas szinten 1mA körülit tudnak hajtani, visszaolvasásnál mindegyik portnál a láb aktuális állapota látszik, nem a kimeneti regiszterbe írt érték. Erre már nagyjából rá lehet mondani, hogy oké... :) Persze a kapcsolásból látszik, hogy a két Joy-port jelei simán rá vannak kötve a billentyűzet sor / oszlop vonalakra, szóval ha aktív valamelyik Joy, a mátrix (egy jelentős része) nem kezelhető. Azért ezen illene már túllépni... :-D Sőt: az itt is jelenlevő RESTORE billentyű tulajdonképpen közvetlenül generál NMI-t; a VIC20-ban ezt a VIA átkonfigurálásával legalább le lehet tiltani, ellentétben az itteni megoldással.

Egy kicsit eddig túlteng a CBM, de létezik korabeli konkurencia is, bár azokat inkább manapság nézegetem, anno kimaradt szinte mind. Az Enterprise megoldásáról most csak annyit, hogy erősen hajaz a PET-féle verzióra, ugyanaz a 74LS145-ös dekóder hajtja a sorokat, csak a port-IC-k szokványos TTL-ekből vannak kifaragva. A mátrix 10 sor × (8 +3) oszlopos felépítésű, a 8 oszlop a billentyűzeté, a +3 oszlop a Joy-portokhoz van rendelve. A megoldás teljesen normális, de a korban azért akad olyan gép is, ahol ez nem mondható el.

Az „idétlenség kimaxolása” címet az Amstrad CPC szériája viszi nálam a következő megoldással:

Itt két, eddig még nem tárgyalt csip is akad, az egyik a 8255 PPI, ez egy 3×8 bites port-IC. A 24 I/O láb iránya némiképpen kötött az eddig megismert ilyen tokokhoz képest, itt összesen 4 bitnyi adatirány van, egy-egy bit a PORTA / PORTB számára, illetve kettő a PORTC alsó illetve felső 4 lábának. A rajzon a billentyűzet csatlakozója jobbra/középen van, a sorokat itt is egy 74LS145 hajtja, a 8255 PC3..0 vonalai mondják meg, hogy melyiket. Ez eddig még rendben is van. Az oszlopok visszaolvasása viszont „vicces” egy kicsit, ugyanis ehhez az AY-3-8912 típusjelű hanggenerátor IC-t használja, aminek van egy 8 bites GPIO portja, integrált felhúzó ellenállásokkal, az oszlopok ide vannak bekötve. Maga a „vicc” nem is ez, hanem ennek az IC-nek a CPU-hoz való illesztése, ami még véletlenül sincs a rendszerbuszhoz kapcsolva… Hanem a 8255-ön keresztül lehet címezni / írni / olvasni! Ha egy regisztert a CPU be akar írni vagy ki akar olvasni, akkor a 8255-ön keresztül tulajdonképpen „el kell neki bábozni” egy írás vagy olvasás buszciklust! Ugyan optimalizálni lehet a (tömeges) lekérdezést, de egy teljesen általános ciklust jó pár 8255-ös írás / olvasás árán lehet csak megoldani. Ez rendesen viszi az időt, nem csak a billentyűzet vizsgálatakor, de hanggeneráláskor is. A Joystick a billentyűzetmátrix egy sorának tűnik, de a rajzról több nem derül ki, ilyen gépem meg (egyelőre?) nincs.

Ez a gép eléggé sikeres volt, de errefelé valahogy nem terjedt túlságosan el. Ellentétben a szintén nagyon sikeres ZX Spectrum-mal. A billentyűzet-kezelés ott némileg trükkös:

Eléggé szerte-szét van a lényeg, kissé káoszos ez a rajz... Itt a billentyűzet egy 8×5-ös mátrix, az 5 bemenet a rajz jobb oldalán középtájon van, a KB1-es csatlakozó vonalai szépen fel vannak húzva ellenállásokkal a tápra, a jeleket a Spectrum mindenese, az ULA fogadja. Ezt a CPU az $FE I/O porton tudja olvasni. A 8 kimeneti sor a KB2 csatlakozóra jön, ez a rajz bal felén felül van, a vonalakon diódákkal, amik... ...a Z80-as A15..A8 vonalaira kapcsolódnak! Ez a felépítés a Z80 egy spéci tulajdonsága miatt tud működőképes lenni. A CPU tartalmaz külön I/O utasításokat, a hozzá tartozó címtérrel együtt. Ez a címtér viszont csak 8 bites, tehát elvileg 256 BYTE-nyi az I/O terület összesen. De! Amikor a Z80 egy I/O utasítást (bármilyet!) hajt végre, akkor az I/O cím kikerül az A7..A0 vonalaira. Ilyenkor a címként nem használt A15..A8 vonalakon valamelyik CPU regiszter (A vagy B, utasításfüggő) értéke megjelenik a ciklus alatt. Tehát a mátrix olvasása annyi, hogy amelyik sort be akarjuk olvasni, annak a bitjét 0-ba kell rakni, a többi 1, ezt az értéket abba a bizonyos regiszterbe kell tölteni. Utána az 0xFE I/O port olvasása alatt ez a regiszter kikerül az A15..A8 vonalakra, ami kiválasztja a kívánt sort, a ciklus végén meg a CPU tárolja az adatbuszt, amin a kiválasztott sor értéke szerepel. Több gomb (billentyűnek nagyképűség nevezni... :) ) lenyomásánál a sorokon levő diódák miatt nincs zárlat, ami amúgy meglehetősen kellemetlen lenne a címbuszon. Trükkös! Kevés alkatrészből meg van oldva a feladat... Az, hogy a CPU címbusza a többi utasítás végrehajtása alatt is rángatja a mátrix sorait? 1982-ben ez a kit érdekel kategória lehetett, EMI oldaláról viszont nem éppen szerencsés. Ezt a mátrix-kezelést amúgy már a ZX80/ZX81-en is használta a Sinclair, ami meg bevált, azon nem kell változtatni. Joy-portja az alap Speccy-nek nincs, illesztésnek csináltak több fajtát, egyik se kompatibilis a másikkal. :)

Egy kis Z80-as kitérő után jöjjön egy szintén CBM gép, a kedvenc plus/4. Az előző Sinclair csodákat azért citáltam ide, mert a CBM ezen sorozata tulajdonképpen egy Spectrum árszintű olcsó gépnek indult. (Csak mintha közben elveszett volna az eredeti irány. Ami leginkább közel áll a szériában ehhez az „olcsó kisgép” verzióhoz, az a C116) Az user inputok kezeléséhez a gép „mindenesébe”, a TED-be itt is beépítettek némi segítséget. Jöjjön a hozzá tartozó áramkörrészlet, de eredetileg ezt nem éppen így tervezték ám:

A TED K7..0 vonalai bemenetek, ezek fogadják a billentyűzet oszlopainak a jeleit, illetve a Joy-okét is, a felhúzó ellenállások integrálva, azok se kellenek külön. A két Joy első ránézésre párhuzamosan van kötve, de a látszat csal, külön lehet kezelni őket. Sőt: nem blokkolják a billentyűzetmátrixot, végre eljutottunk idáig... :-D A sorokat egy 6529 SPI csip hajtja, ez egy 8 bites port IC. Egyszerű mint a faék, egy írható és egy olvasható regisztere van (ugyanazon a címen). Ami az írhatóba belekerül, az megjelenik a Px lábain. Ezen lábak hajtása úgy van megoldva, mint ahogy a VIA PAx vonalai voltak: csak alacsonyat tud hajtani izomból, a magasat egy beépített felhúzó ellenállás produkálja. A csip olvasásakor mindig a lábak aktuális állapotát adja vissza, bemenetnek úgy kell használni, hogy az adott lábat 1-be kell állítani, majd a külső eszköz ezt lehúzhatja alacsonyra. Fantom-billentyűnél nincs gond, a „gyenge” magast nyugodtan le lehet húzni büntetlenül, ez a rész korrekt.

Na de a Joy-ok kezelése? Itt van egy „jó”, vagyis inkább „hírhedt” trükk: a vonalakat nem a földre kell lehúzni! Hanem tartozik hozzájuk egy-egy Joy-kiválasztó jel, a kontaktusokat ehhez kell hozzákötni. Ez csak akkor lesz alacsony, amikor éppen az a Joy van kiválasztva, így a TED Kx vonalai egy-egy diódán keresztül ekkor aktiválódnak (persze ha az adott kontaktus aktív). A diódák miatt a két Joy egymásra nincs hatással, viszont a billentyűzet segítségével azért lehet „fantom Joy-irányt” produkálni, csak hogy semmi se legyen tökéletes. :) Ez eddig a sima billentyűzet 8×8-as mátrixának a kiegészítése lenne két sorral, de a Joy-kiválasztó vonalak „mókásak” egy kicsit, ugyanis egy meghajtó kapun keresztül – tádámm! – a CPU egy-egy adatvonalára vannak kötve! (Hello EMI, újra itt? :-D ) Na de ez egyáltalán hogy működhet? A megoldás viszonylag egyszerű: a Kx vonalak a TED-en belül nem egy sima bemeneti portként vannak kialakítva, hanem tartozik hozzájuk egy tároló. Ezt a tárolót úgy lehet „tárolásra bírni”, hogy egy megfelelő címre kell írást végrehajtani a CPU-val. A tárolást az írás maga triggereli, a kiírt adat lényegtelen. Vagyis az lenne, ha nem pont az adatvezetékek választanák ki a Joy-okat... :)

Szóval egy kicsit trükkös a lekérdezés, ez a tankönyvek szerint a következő módon megy:

A billentyűzet sorkiválasztó 6529B az $FD30-as címen írható, a TED a Kx vonalak tárolását az $FF08-as regiszter írásakor hajtja végre, a letárolt adatot ugyaninnen kell visszaolvasni. A ROM természetesen tartalmaz ilyen kódot, billentyűzetkezelés részlet:

. DB70  8D 30 FD  STA $FD30
. DB73  8D 08 FF  STA $FF08
. DB76  AD 08 FF  LDA $FF08
. DB79  60        RTS

Ez a rutin megkapja a sor kiválasztásához szükséges adatot, kiválasztja vele a billentyűzet valamelyik sorát, majd ugyanezt az értéket kiírja $FF08-ra, ezzel megcsináltatja a TED-del a Kx vonalak tárolását. Majd beolvassa a letárolt adatot, amit visszaad. A Joy kezelése szintén egyszerű, ehhez a BASIC értelmező a JOY() függvényt biztosítja, részlet:

. BFCD  78        SEI
. BFCE  8E 08 FF  STX $FF08
. BFD1  AD 08 FF  LDA $FF08
. BFD4  8E 08 FF  STX $FF08
. BFD7  CD 08 FF  CMP $FF08
. BFDA  D0 F2     BNE $BFCE
. BFDC  58        CLI

Itt a kiválasztandó Joy sorát megkapja a rutin, azt kiírja $FF08-ra, a kiírás közben a CPU adatbusza kiválasztja a kívánt botot, a regiszter írására meg a TED eltárolja a Kx vonalakat. A visszaolvasott adatot visszaellenőrzi, ha nem változik (nem pereg :) ) akkor visszaadja. A SEI / CLI utasításpár a megszakítást tiltja le a lekérdezés idejére, mivel ezt a rutint a BASIC főprogramból hívja, a billentyűzetkezelést meg a megszakítási rutin végzi, így nem lesz keveredés.

Tulajdonképpen egyszerű, és ennyi a tankönyvi leírás is. Viszont azért ezzel vannak problémák, csak azzal valahogy senki se foglalkozik. Egyrészt a billentyűzetmátrix olvasásakor $FF08-ra ugyanaz az érték van kiírva, mint a sorkiválasztásnál, de ilyenkor a Joy-okat is kiválasztja a lekérdezés, azaz a Joystick húzogatása billentyűnyomásnak látszik! Ennek a megoldásnak meg is van az oka, ami megér egy kis kitérőt.

Mivel az eredeti koncepció az olcsó gép lett volna, ott a komplett billentyűzet kezelése úgy lett volna megoldva, mint most a Joy-oké, tehát a sorok kiválasztása a CPU adatvonalaival lett volna elkövetve, nem egy különálló sor-tárolóval, mint most. Hogy erre van-e bizonyíték? Például a régi C264-es tervek. Vagy az eredeti, alfa verziós nyák, azon is hiányzik a tároló. De van későbbi példa is, ez egy Commodore 264 (!):

A képek – megmondom őszintén – fogalmam sincs, honnan vannak (talán ez is a fent linkelt c128.com-ról), ha valakinek van tippje, ne tartsa magába! :) A bal-alsó sarokban látszik, hogy ebből még hiányzik a sormeghajtó 6529B. Meg mintha a diódákat is kifelejtették volna, azok a vonalakon amúgy meglevő ferritgyűrűs szűrések helyett lettek berakva... :) Ez a gép, ezzel a típusszámmal nem került forgalomba, valamilyen bemutató darab lehetett. De ide kívánkozik még egy érdekes gép, a szintúgy prototípus fázisban „megrekedt” V364 „alfa változatú” alaplapja is:

Ebben már ott a 6529B, de láthatólag utólag van az oda beszerelve, gyaníthatóan a diódák helyett. Szóval erősen úgy tűnik, hogy eredetileg ez az egyszerűsített, Spectrum-ra erősen hajazó billentyűzetkezelés lett volna itt is megvalósítva, csak azzal azért voltak gondok. (A CPU/memóriák nem biztos, hogy komálják a billentyűzet nem éppen elhanyagolható kapacitását, meg hát az emlegetett EMI... :) ) Na de a kitérőből ennyi elég is lesz.

Tehát a KERNAL jelenlegi billentyűzet-lekérdezése működne a külön sortároló nélkül is, ezt próbálgattam is anno a minimál-koncepciós kísérletezésnél. Mivel forgalomba ilyen verzió nem került, ezért a tankönyvi leírást érdemes pontosítani. Már csak azért is, mert a BASIC Joy-lekérdező rutinjával is vannak gondok. :-D Amikor $FF08-ra írás történik, akkor a Kx vonalakon levő érték eltárolódik, ahol a kiírt érték kiválasztja a kívánt Joy-t. DE! Ha a billentyűzet valamelyik sora előzőleg már ki volt választva, a lekérdezésnél a Joy-jal párhuzamosan annak az állapota is eltárolódik! Alapesetben a KERNAL megszakításból vizsgálja a billentyűzetet, ami pedig hagy egy kiválasztott sort a lekérdezés után... Emiatt van az, hogy a BASIC JOY() függvény esetén bizonyos billentyűk Joy-iránynak adódnak vissza.

A billentyűzetet / Joy-t a másiktól függetlenül simán le lehet kérdezni, a fentiekből egyértelműen következik, hogy hogyan, csak a tankönyvek erre nem térnek ki:

  • Csak billentyűzet, a Joy-ok nem szólnak bele:
       LDA #kblinemask     ;KB sor kiválasztása
       STA $FD30
       LDA #$FF            ;Joy-ok közül nincs kiválasztva egyik sem
       STA $FF08
       LDA $FF08
  • Csak Joy, billentyűk nélkül:
       LDA #$FF           ;Nincs KB sor kiválasztva
       STA $FD30
       LDA #joylinemask   ;Joy sor kiválasztása
       STA $FF08
       LDA $FF08

Aztán ennyi. A harmadik generációra a CBM eljutott oda, hogy külön lehet kezelni (nagyjából) a Joy-okat illetve a billentyűzetet! Bámulatos! :-D Hogy bele lehet-e kötni a megvalósításba? Hát, simán... A problémás rész nem más, mint a „hírhedt” trükk a Joy-ok részéről, a kiválasztó vonal használata a közönséges föld helyett. Direkt ehhez a szériához egyedül a CBM gyártott Joy-t, senki más. Átalakítót az eredeti Atari (/C64) -féle változatról viszont rengetegen. De ezek mindegyike egy sima passzív kábel, az egyik végén DE-9 a Joystick felé, a másikon 8 pólusú MINI-DIN dugó a gép csatlakozójába.

Elvileg egyszerű az ügy, mi baj is lehetne... Hát csak az, hogy az átalakítón a Joystick fele menő GND-re a gép Joy-kiválasztó jelét kell kötni. Ez alapból nem gáz, de a „jobb” botkormányok rendelkeznek egy kényelmi szolgáltatással, ami az „autofire” funkcióban valósul meg. Ez egy olyan elektronika, ami bekapcsolás esetén a júzer helyett nyomkodja a tűz-gombot, ami néhány korabeli játékban igencsak jól tud jönni. Ennek viszont kell táp és normális föld, ami itt nem éppen van meg. Emiatt az a minimum, hogy az „autofire” bekapcsolásakor az nem fog autofirélni...

Itt érdemes megjegyezni, hogy a TED-nek ezen a részen akad egy furcsa hibája. Ezt én is tapasztaltam régen, de sok beszámolót is hallottam arról, hogy a gép Joystick-kezelése – egy idő után – nem működik jól. Két probléma akad, az egyik: hülyeségeket csinál a Joy mozgatáskor, a másik, hogy egyáltalán nem működik, semmi életjelet nem ad. A TED kicserélésétől ezek az anomáliák megszűnnek, tehát a botkormány kezelése valahogy a TED-en belül romlik el. Ami meglehetősen furcsa jelenség, mert a billentyűzet továbbra is normálisan működik, az meg ugyanazokon a bemeneteken keresztül van kezelve, mint a Joy-ok. Sokan azt mondják, hogy a nem megfelelően működő „autofire” teszi tönkre a TED-ben ezt a részt, amiben lehet is valami, de! Nekem anno egy gyári, 1341-es Joy-om volt a C16-hoz, és azzal is ez történt, ugyanúgy elpusztult a botkormány bemenet, pedig abban semmi ilyen kényelmi szolgáltatás nincs! Szóval furcsa a dolog, nekem meg van minimum kettő Joy-hibás TED-em, bő 30 év után épp itt az ideje körbejárni, hogy mi is történik.

Az a szituáció, hogy a billentyűzet megy, a botkormány meg nem, arra enged következtetni, hogy a TED-en belül a vonalak állapotának a megjegyzését végző tárolóval lesz valami. A billentyűzetnél egy „statikus” állapotot kell beolvasni a CPU-nak, ekkor a tároló jellegre nincs szükség, az csak a Joy-ok beolvasásánál érdekes, mert azoknak az állapota csak egy „rövid ideig” van ott a bemeneteken. Erre már nagyon régen lett egy olyan ötletem, hogy ezt a tárolót meg lehet valósítani kívül egy megfelelő IC-vel, mondjuk egy 74HC(T)573-mal, ami egy 8 bites szint-vezérelt tároló. A TED Kx vonalai, illetve az alaplap közé be kell építeni (a bemeneti oldalon egy felhúzó ellenállás-hálóval), $FF08 írásakor engedélyezni, aztán a ciklus végén „örökre” megjegyzi a vonalak állapotát, ugyanúgy mint a TED eredetileg. Ezt az épített gépemben anno elő is készítettem, a TED alatt pont van is kb. megfelelő hely erre. Az IC „tárolás” jele egyelőre direktben „engedélyezés” szintre lett kötve, ekkor ez a tok egy sima buszmeghajtóként viselkedik, a kimenetén megjelenik a bemenetre kapcsolt adat. Az első meglepetés még akkor, ezen építkezés idején történt: a Joy-ok teljesen tökéletesen elkezdtek működni! Anélkül, hogy a tárolás funkció meg lett volna valósítva, azt továbbra is a TED végzi! Szóval lehet, hogy itt valami jelszint-probléma lesz? Na de teszteljünk MOST!

Pár napja a gépből a hibás TED-et átraktam egy gyári, módosítatlan alaplapba, hogy tudjak méricskélni, és a legnagyobb meglepetésemre a Joy-ok teljesen hibátlanul kezelődnek... Na, itt, már csodálkozás van, nem kicsi. Előbányásztam az ősrégi C16-om, amiben a TED tuti döglött ilyen oldalról. Teszt: az is tökéletesen működik! Előszedtem az összes, működő (és nem működő) plus/4-em, végigpróbálgattam az összes fellelt TED-et, mindegyikkel hibátlanul üzemel a Joystick-lekérdezés! Mi a búbánat történt? Az elmúlt 20 év szekrényben pihenéstől meggyógyult mind?! A történetre a pontot az tette fel, hogy a tárolóval ellátott gépemmel sikerült a „hülyeséget csinál a Joy” állapotot reprodukálnom a normál alaplapban jól működő TED-del. Ott a kiválasztó jeleket a gépbe utólag beépített CPLD valósítja meg, azt „visszabutítva” visszaállt a működőképes állapot, de a „bonyolult” változat ha rossz, akkor a „nem működik” állapotot kéne hogy produkálja! Ráadásul ha lehúztam a billentyűzetet, megjavult a lekérdezés! Na, itt elővettem az ünnepnapokra tartogatott WTF-nézésem.

Tehát a felállás most: minden úgy működik, ahogy kell. Hogy a vonalmeghajtós próbával értem-e el anno valamit, az nem derült ki, mert akkor elfelejtettem azt megnézni, hogy a TED jó volt-e már akkor is. (Ilyen hülyeséget leírni is furcsa... :) ) Hogy egy ilyen „megjavulós” történet egyáltalán lehetséges-e? Ezt magam is kétlem, de ha nem ez történt, akkor valamikor régen ezt a két TED-et ki kellett cserélnem. De ilyenre egyáltalán nem emlékszem!

A „teszteljünk MOST!” rossz alany hiányában itt ugyan megakadt, de közben kaptam az egyik fórumtárstól kölcsönbe egy tuti-rossz TED-et, amivel azért mégis sikerült egy kicsit vizsgálódni. A megakadás alatt nagyjából befejeztem egy billentyűzettesztelő programot, ezt már régen meg szerettem volna csinálni, hát épp itt volt az ideje... :) Ezzel bebizonyosodott az előbb emlegetett hibalehetőség, amit a tesztprogram külön vizsgál is:

Igen, a hibás TED-ben a tároló az simán „átereszt”, nem tárol. És igen: a hibás TED Kx vonalai hiába kaptak buszmeghajtót, a tároló ettől nem javult meg, szóval egyre gyanúsabb az a TED-csere, na de mikor? Meg mire? :)

Ami biztos: a TED-et fejlesztő mérnökök tuti nem bonyolították túl ezt a tárolót, a lehető legegyszerűbb felépítésű lesz belül. Talán ennek köszönhető, hogy a billentyűzetkezelés működőképes marad. Valószínű, hogy a TED-en belül ez a tár egy un. „transparent latch”, ami egy szintvezérelt tároló. Amíg a tárolás jel aktív, addig a kimenetén megjelenik a bemenet mindenféle módosítás nélkül. Ha ez a tárolás jel inaktív lesz a ciklus végén, akkor az éppen aktuális kimenet „megjegyződik”, utána már hiába változik a bemenet, a kimenet marad változatlan. Itt ezzel a tárolás jellel lesz valami, ezt kellene az $FF08 írásának kapcsolgatni. Ameddig tart az írás, addig a tároló átenged, az írási ciklus vége után meg megőrződik az adat, ez lenne az alapfelállás. A „fokozatosan elromlik” verziót talán úgy tudnám elképzelni, hogy az adat-átengedős időszak az elején csak simán hosszabb lesz, így először csak rossz időpontban történik meg a bemeneti állapot megjegyzése, amikor már a következő utasítás betöltését hajtja végre a CPU. Az adatvonalakon ekkor már nem az a bizonyos kiírt érték szerepel, hanem a következő utasítás op-kódja meg annak a folytatása, így olyan billentyűzet-sor kiválasztásnál is aktívnak látszik a Joy, ahol tulajdonképpen nem is lehetne az. Aztán ez az adat-átengedős időszak egyszer „végtelen” hosszúságú lesz, akkor meg már nem fog a tárolás megtörténni. Mivel a billentyűzet kiválasztott sora folyamatosan hajtja a bemeneteket, így annak a lekérdezésében ez nem okoz anomáliát, de a Joy-ok működésképtelenné válnak.

A tesztelésnek + méricskélésnek azért lett némi hozadéka. Az egyik, hogy a külső tárolós workaround működik, bár a legegyszerűbb változat nem 100%-os, de az esetek jelentős részében megfelelően működhet:

A külső tároló egy 74HC(T)573, aminek a bemenetei egy 4.7KΩ-os ellenálláshálóval a tápra vannak kötve, illetve ide jön az alaplapi 8 vonal a billentyűzet / Joy-ok felől. A kimenetek meg mennek közvetlenül a TED Kx vonalaira. A hajtást engedélyező jel fixen alacsony, a tárolást végző jelet viszont szimplán nincs hova bekötni, oda kell még egy kis elektronika. Tökéletes megoldás lenne az $FF08-as címre írás kikapuzása, de ahhoz sok alkatrész + rengeteg bekötendő jel tartozik, de az egyszerűsített változat is elég lehet, ami csak az írást kapuzza. Ehhez kell egy 74HCT00, ebben 4 db. NAND kapu van. Az egyik kapu egyik bemenetére jön az R/_W jel, a másik bemenet fix. magas, ez így egy sima inverter. A kapu kimenete jön egy másik kapu egyik bemenetére, a másikra meg a ø0, a CPU órajele. Ennek a kapunak a kimenete már csak írásciklus alatt aktív, de nem jó szinttel, ezt még meg kell fordítani, amit egy harmadik kapuval meg lehet csinálni. Ezért az előző kapu kimenete belejön a harmadik kapu egyik bemenetére, a másik bemenet fixen magas, ez is egy inverter így. Ennek a kapunak a kimenete meg jön a 74HC(T)573 LE bemenetére. Aztán nagyjából ennyi. (Persze a latch / kapuk tápja + földje értelemszerűen bekötendő.) Ez minden írás ciklus alatt latch-eli a billentyűzet / Joy bemeneteket, de a lekérdezések nagy százalékában az oszlopok beolvasása előtti utolsó írás pont az $FF08-ra kiírás lesz, így elég lehet ennyi. Az elektronikához nem kell más jel, csak az, mint ami a TED foglalatában / lábain elérhető.

A tesztelés másik hozadéka már konkrét mérési adat: a jól működő TED-ekben a Kx vonalakon alapból olyan 2.6 – 3 Volt körüli feszültség mérhető, a csipen belül ilyen feszültségre vannak a vonalak felhúzva. Ezeket egy külső ellenállással a földre kapcsolva nagyjából kideríthető, hogy ez a belső felhúzó ellenállás mekkora, itt ilyen 4.6 – 5.2 KΩ körüli értékek jöttek ki. Viszont a hibás TED esetén a feszültség közel van a táphoz, 5 Volt körüli, a terheléses méricskélés meg 1.7 KΩ körüli belső ellenállásra jön ki! Valami zárlat alakul ki a csipen belül?!

Ugyan az inputok kezelése szépen fejlődik, de azt azért el lehet mondani, hogy a Joy-kezeléssel itt is sikerült valami maradandót alkotni. :) A következő CBM gép a C128, ott a billentyűzetmátrix kiegészült 3 oszloppal, a Joy-ok viszont ugyanúgy vannak bekötve mint C64-en. Mint ahogy valószínűleg a C65 esetében is ugyanez a helyzet a kompatibilitási kényszerből kifolyólag. Teljesen más módon csak az AMIGA kezeli ezeket a perifériákat, ott a billentyűzet már a pécé mintájára saját mikrovezérlővel rendelkezik, soros interfészen keresztül billentyűkódokat kezel az alapgép maga, a Joy (/ egér) portok immár teljesen el vannak szeparálva. Kellett jó néhány év, hogy végre olyan legyen a megoldás, amit már a legelső verziók is megérdemeltek volna...

Konklúzió? Nem volt rossz ezeket így most végigrágni, sok év távlatából is rá lehet csodálkozni bizonyos megoldásokra. Manapság már a fóliát, amin a jel megy, azt se találni meg egy mai (számító)gépben, itt meg még nevethet is az ember néha egy-egy implementáción. ;) A fent mutatott billentyűzet-tesztelő programot közben publikusnak nyilvánítottam, ez egy tervezett „széria” második darabja, tervben van ezt több gépre is megcsinálni, ha lesz idő meg lelkesedés, akkor majd előveszem. Egy kezdetleges oldalt készítettem is hozzá.

Linkek:

balagesz

---

2018.09.23.
2018.12.16. Tesztprogram link
2019.03.29. Elírás jav.
2019.12.22. D8.

Hozzászólások

Nagyon tuti cikk, különösen a Specci féle megoldás említése tetszett.
Hogy legyen egy kis kapcsolódó magyar vonatkozása is a dolognak:
A Videoton TVC-ben a sor/oszlopdekódolást egészen "szofisztikáltan" oldották meg. Az sorok az adatbuszra közvetlenül rá voltak kötve az E1-es 74244 bufferrel amit az -RDTAST jel pollingolt. A buffer bemenetei 10k-s ellenállással voltak felhúzva. A sorvonalak, össze voltak kötve a joystick portok vonalaival, a 8-as pinjei kivételével.
Az oszlopok címzését az adatbuszra kötött F1 74174-es hexa flipflop végezte a G1 7445 HEXA-BCD dekóderen keresztül. Az F1 alsó 4 bitje ment a G1 bemeneteire, és a CP bemenetére a B5 74138-as címdekódoló 4-es kimenetére (-WR3) volt rákötve.
Működésileg úgy nézett ki, hogy a oszlopregiszter megcímzésével B5-ön kerül kiválasztásra került az adatbuszra kiírt lekérdezendő oszlop, majd ugyanezen címet olvasva a -RDTAST-al visszakerült a buszra a sorok állapota. A joystickok két plusz oszlopként jelennek meg.
A teljes billentyűzet/joystick lekérdezés 10 írási és olvasási ciklust jelentett.
Apró érdekesség, hogy a joystick portok a későbbi verziójú alaplapon (HBA2) már kaptak soros diódákat ESD védelem gyanánt.
--
"Maradt még 2 kB-om. Teszek bele egy TCP-IP stacket és egy bootlogót. "

Van egy TVC leírásom, de abban csak nagyon "gáz" rajz van. Van valamerre normális kapcsolási rajz a gépről? :)

A fentiek alapján ez egy rendes, TTL-ekből kifaragott I/O lesz, csak az akkori, itthon beszerezhető alkatrészekre hangolva. :) A Joyok ott is a mátrixba vannak bekötve? A HBA2-n levő soros diódák inkább az egymásra hatást szüntetik meg, nem az ESD-hez van közük, de ezt így látatlanba' írom.

A TVC-s gyűjtőoldalon fenn van a kapcsrajz mindkét alaplaphoz:
Első verzió (32k, 64k):
http://tvc.homeserver.hu/doc/tervrajzok/TVC_HBA_rajzok.pdf
Második verzió(64k+):
http://tvc.homeserver.hu/doc/tervrajzok/TVC_HBA2_rajzok.pdf

Igen klasszikus TTL I/O. Ezt imádtam a ebben a gépben, hogy nem varázsmágikus chipekbe volt minden beleágyazva. A legkomplexebb célchip a Hitachi HD46505 videó címmeghajtó IC volt.
A joystikoknak külön, negált selectje volt, és a 7445 miatt egyszerre csak egy volt kiválasztva. A 74244-nek a lábai és rajta keresztül az adatbusz mindenféle védelem nélkül volt kidrótozva a csatlakozóra.
Homályosan emlékszem valamilyen motor forgatós kapcsolásra is, ahol a joystick portok voltak az enkóderek bemenetei. Szóval, sanda gyanúm, hogy a diódák szerepe inkább egyfajta védelem volt, hogy ne lehessen 12V-ra felhúzni a buszt.
--
"Maradt még 2 kB-om. Teszek bele egy TCP-IP stacket és egy bootlogót. "

Köszi a linkeket! Valahogy ezek eddig kimaradtak, pedig még az oldalon is jártam... :-D

Ez az I/O klasszikus TTL-ekkel nekem is szimpatikus; mindig is az volt a véleményem, hogy egy számítógépbe, amire a felhasználó írhat programot, ott nem sok keresni valója van "általános" I/O csipeknek. (Ha valami kimenet, akkor ne lehessen már bemenetre állítani, vagyis inkább ne kelljen már irányt állítani, mert a júzer azt esetleg elronthatja.) Viszont az is igaz, hogy az ilyen összeintegrált csipektől lesz a gyártó TCO-ja kisebb, nem a rahedli TTL-től. :)

A rajzot megnézve én továbbra is azon a véleményen vagyok, hogy a diódák inkább a két Joy elszeparálására vannak, mert ha nincsenek a gépbe beépítve, akkor a Joyokba kellene beszerelni őket. Mivel a géphez lehet nem Videoton gyártmányú botot is csatlakoztatni, azokban meg belül nem lesz dióda, szóval na. (ESD gyanánt a föld felől is meg kellene a jelet fogni, mert a soros diódától még nyugodtan le lehetne húzni negatívba a vonalat.) Az viszont jópofa, hogy az egyik Joy a belsővel párhuzamosan van kötve. :)

Zseniális! Élvezet olvasni ezeket a leírásokat.

És ráadásul a VIA meg CIA-val néha nem átallnak "visszafelé" olvasni a billentyűzetet :) Azaz a PA lesz a kimenet, PB a bemenet. A joystick "jobbra" olvasáshoz meg is kell fordítani, de némelyik program megoldja a billentyűzetet is így. Van olyan program, aminek kicsit hibás az input rutinja, így a jobbra irány a datasette gombjaival is kapcsolható, és ebben az érdekesség, hogy ez a VIA1-en van, míg a jobbra irány a VIA2-n. De mégis annyit bűvészkedik a két VIA-ról beolvasott bitekkel, hogy a joy right és a datasett sense ugyanúgy jobbra mozgatja a figurát.
Aztán a szabadon programozható VIA-nak megvan a szépsége, hogy akár a sor és oszlop portokat is kimenetre lehet állítani, egymással szemben.

Amstrad CPC-nél meg amolyan "keressünk valamit, hova tudnánk kötni" megvalósítás lett, a billentyűzet a hang-chip PIO bemenetére van kötve, a hangchip meg egy 8255-ös PPI-re.

A megforgatást ezekkel az általános I/O csipekkel simán meg lehet csinálni, szerencsére azért bírják az "összehajtást", így szoftvertől nem mennek annyira simán tönkre. :) A VIC20-as Joy-kezelés eléggé - hogy is mondjam - furcsa, a leírás alapján arra gondoltam, hogy esetleg valami egyszerűsítéssel "olvassa össze" egy BYTE-ba az iránybiteket. De a magnó gombja még csak nem is azon a biten van, szóval jól el lehetett abba a kódba valami keverve.

Egyszerű kód, VIA irányregiszter beolvas - AND a megfelelő bitekre - visszaír - VIA olvasás, és ezt mindkettőre. Aztán a beolvasott byteokkal meg megy a zsonglőrködés.
Mikror rájöttem, hogy a VHDL-ben ki kéne cserélni a 0-t 1-re a magnó érzékelőnél, és akkor nem akar folyton jobbra menni, na az megfizethetetlen :D
Egyébként BASIC-ben érdekes még, ha a megfelelő POKE-kal megfordítod az irányt, hogy be tudd olvasni a joysticket, és elfelejted visszacsinálni, onnantól nem lesz billentyűzetkezelés.

Most már tényleg van elég, de szerintem mi, itt az országban annyira nem is voltunk rosszak ebből a szempontból. Rengeteg könyv jelent meg ezekről, nagy részük nyilván fordítás, de a terület azért nem volt elhanyagolva. Csak akkor még a leírások jelentős részét nem értettem... :)

Annyiban módosítanám a megjegyzésem, hogy bizonyos (nálunk elterjedtebb) típusokhoz akadt irodalom. Én anno leginkább azokkal találkoztam. A VIC20 nálunk azért kuriózumnak számított, rengeteg más egyéb géppel együtt. (Pl. a fent emlegetett CPC is ilyen, meg a komplett MSX verziók, de biztos lehetne még sorolni, amikről még nem is hallottam... :) ) Szóval ja. Volt doksi, de lehetett volna több is. :-D

Viszont ez nekem hatalmas motivációt adott. Manapság, ha azt mondanánk a gyereknek: -"Nesze, itt egy PC, van rajta valamilyen oprendszer, találd ki hogy működik, írj magadnak játékokat, segítségedre lesz pár előtelepített program, azokat elemezheted! Néha megbeszélheted a tapasztalataid pár hasonszőrű tarsaddal - postai levelezés útján!"... Asszem el lennék küldve anyámba. :)

--
"Nem akkor van baj amikor nincs baj, hanem amikor van!"
Népi bölcsesség

Hihetetlen mennyire másként működik a mai generáció, mint ahogy mi is másként működtünk, mint a szüleink. Úgy látszik a számítástechnika fejlődése szempontjából a generation-X volt az aranykor képviselője.

--
"Nem akkor van baj amikor nincs baj, hanem amikor van!"
Népi bölcsesség

"...a mozgó részek még kaptak egy kevés szilikonos zsírt is. Arról viszont nem vagyok meggyőződve, hogy egyáltalán kenőzsír-e, amit használtam. De a jelek biztatóak, a darab olyan, mint a vaj!

Egyrészt pont olyan sárga, :)..."
- a zsirozas nem feltetlen jo otlet, egyreszt ezez az egymason surlodo alkatreszek puha, onkeno muanyagbol keszulnek, masreszt a kulon kenoanyag kesobb okozhat problemat - vagy beleszarad es ragadni kezd, vagy belefolyik a kontakt-reszbe, vagy feloldja a szilikongumit. A besargult hazra nekem hatekony megoldas volt anno a hidrogen peroxidos oldatba aztatas.

--
"Nem akkor van baj amikor nincs baj, hanem amikor van!"
Népi bölcsesség

Igen, ez a zsíros téma nem szokásom, ezt fogjuk fel egy tesztnek. Majd az idő eldönti, hogy jó volt-e az ötlet. Ezt legalább szét lehet borítani, ha meg kell takarítani. :)

A sárgaság viszont annyira nem zavar, hogy vegyszereket szerezzek be hozzá, tehát az úgy marad! (A "szer" így fórumokról ismerős, de eddig nem próbálkoztam vele.)

Sajna én ennyire nem értek a témához, de ha már billentyűzet megoldások, mindenképp meg kellene említeni a Primo A széria billentyűzetkezelését, ami nem csak azért extrém, mert kapacitív, mindenféle mozgó alkatrész nélkül, hanem azért is, mert a gombok nem mátrixban vannak, hanem mindegyiknek egyedi PORT címe van, és külön kérdezhetők le.

Ennél már csak a VZ200 billenytűzet-kezelése tűnt számomra még extrémebbnek, ahol a 6x8-as billentyűzet mátrix nemes egyszerűséggel egy 2KB-os szeletet kapott a memóriacímzésből, ahol az egyes címbitek az egyes sorok, míg az adott címen tárolt bitek az egyes oszlopok ... :)