Ahogy közeledünk a befejező részhez, egyre izgalmasabbnak találtam a cikket ;-) úgyhogy nem is kíméltem magam és beszerkesztettem a harmadik részt is gyorsan!
Az áttörés Andy-vel kapcsolatos beszélgetéseim során jött. Konkrétan egyetlen scannelt oldalon múlt a dolog, amit volt szíves nekem elküldeni. A kérdéses oldal az MMU működését mutatja be röviden. Szép lett volna, ha tisztán saját erőmből mindenre rájövök, de valljuk be, ez szinte lehetetlen, mivel az MMU nem nevezhető egyszerűnek, több módja van, négy - nem is egyenlő nagyságú - ablakra osztja a memóriát, egyes módokban mindegyik szabadon állítható Kbyte-onként, illetve van olyan, hogy MMU mód mentése, majd visszaállítása, stb. Természetesen, a tudást azonnal felhasználtam az emulátoromban. És íme, az emulátor még tovább jutott, és közölte velem, hogy "Press a Key". Na, ez nehéz lesz - gondoltam -, mivel az még nincs emulálva. Mint írtam, a módszerre, amit a Commodore LCD használ nagyjából rájöttem már a kernal disassembly tanulmányozásával, most tehát nekiálltam implementálni. Nemsokára képes voltam a "Press a Key" kihívást teljesíteni az emulátorral, és wow, az emuláció eljutott arra a pontra, hogy egy neten talált képhez hasonló "menü" fogadott!
A menüben különböző applikációk futtathatóak, köztük szerepelt a BASIC is. Azt hozzá kell tenni, hogy mivel a billentyűzet mátrix kiosztását nem ismertem, ezért csupán egy 8*8-as mátrixot tettem ki az emulált LCD panel mellé, ahol egérrel lehetett "megnyomni" az adott pozícióban található billentyűt, legyen az bármi. A "Press a Key" kihíváson átmentem, ámde a menüben még mozogni sem tudtam, hiába próbálgattam az egyes sor/oszlop kombinációkat, sőt némelyiknél még "fagyott" is az emulátor (eltűnt minden a képernyőről). Vissza a disassembly-hez! Rájöttem, hogy a dolog azért nem annyira egyszerű, mint gondoltam, valójában van a 8*8 mátrix mellett még egy byte (amiben vannak misztikus "lefagyást okozó" byte-ok, illetve vélhetően a shift/ctrl/stb. gombok is itt vannak), és egy adott VIA port biten lehet megmondani, hogy én a mátrix állapotát akarom olvasni vagy ezt az extra byteot. Ez alapján módosítottam az emulációt. Nagy megelégedésemre sikerült, így már próbálgatással a kurzormozgató gombokat fellelnem, illetve a RETURN-t. Ezzel sikerült a BASIC app-ra navigálnom, és "indítani", így volt READY prompt is. :) Itt aztán elkezdtem egyenként az egyes billentyűzet pozíciókat "aktiválni" (az egérrel az említett mátrixban) és megnéztem, mi történik. Ez alapján lassan felépítettem a billentyűzet mátrix kiosztását, amit aztán implementáltam az emulátorban, hogy normál billentyűzet leütéseket fordítson át (mar egér nélkül), azaz normálisan lehessen a PC billentyűzeten gépelni. Az is kiderült, hogy a "misztikus lefagyasztó" bitek igazi Commodore LCD-n az akkumulátorral kapcsolatosak, és valószínűleg azért okoz kettő is "fagyást" mert azt lemerült akkumulátor jelzésének érzékelte és gyorsan lekapcsolta magát a gép (arra is rájöttem, hogy van egy olyan VIA port vonal, amivel saját magát software-esen képes lekapcsolni). Erre vélhetően azért van szükség, mert lekapcsolt állapotban is képes a RAM-okat táplálni (így nem törlődik a memóriában levő tartalom!), de ehhez nyilván nem szabad hagyni totálisan lemerülni az akkumulátort normál üzem során. Az egyik bit pl. csak azt eredményezi, hogy a menüben figyelmeztet arra, hogy alacsony feszültségszint, de még enged tovább dolgozni.
Mivel azt több forrás is említette, hogy grafikus módja is van a gépnek, ez is érdekelt természetesen. A BASIC használatával lehetővé vált, hogy egy GRAPHIC1 utasítással grafikus módba lépjek. Természetesen, mivel ez nem volt emulálva, nem történt túl sok minden, ámde ez remek módnak bizonyult, hogy próbálgassak, ha ezek után pl. egy kort rajzoltam a CIRCLE paranccsal. Nemi próbálgatás után kiderült, hogy grafikus módban $1000 címen kezdődik a video RAM. Az is feltűnt, hogy adott I/O regiszterekre pont módváltásnál megy írás művelet, feltételeztem tehát, hogy az az LCD vezérlő. A változásban könnyű volt megsaccolni, mi lehet a grafikus módot jelző bit. Azt is kikövetkeztettem a találgatásból, hogy hogyan lehet megadni a video memória kezdetet az LCD kontrollernek. Így először az emulátoromban, már nem csak feltételeztem fixen a videó RAM kezdetet és a videó módot, hanem emuláltam az LCD vezérlő I/O regisztereit, és ez alapján emuláltam. Az eredmény egy totálisan zavaros kép volt grafikus módban. Pontokat rakosgatva ki, rájöttem valamire: hasonlóan a karakteres módhoz (ahol 128 byte egy sor, de csak 80 van használva) grafikus módban is a kettő egy hatványára van felkerekítve egy sor mérete, de itt 64 byte egy sor, amiből 60 byte (480 bit) van használva. Ezt helyesen implementálva, már működött a grafikus mód is remekül!
Hozzá kell tenni, hogy még mindig akadt egy probléma. Ráadásul egy olyan, ami mind a mai napig nem oldódott meg. Ez pedig a következő: az tisztán látszott, hogy a Commodore LCD a többi hasonló Commodore gépnél megszokott módon két karakterkészletet használ. Van ugyebár a nagybetű+grafikus karakterek, illetve a kisbetű+nagybetű üzemmód. A probléma az, hogy a ROM image-ekben _csak_ az előbbi van meg, az utóbbi nem! Többször, részletesen átnéztem az említett bitmapként renderelési módszerrel a rendelkezésre álló ROM image-eket, de semmi. Ugyanakkor, az a Commodore LCD "menü" képernyőjén is tisztán látszott, hogy kis+nagy-betűs módot igényelne, hiszen például egyes szavak eleje vagy egész szavak csak grafikus jelekből álltak, ami azonban pont nagybetű lenne a másik karakter készletben. Első körben a gyors "megoldásom" az volt, hogy az emulátorban átkonvertálom ezeket mind. Így minden úgy jelent meg, mintha csak a nagybetű+grafikus készlet kellene. Ez azonban persze teljesen hibás megoldás, és zavart is.
Hol lehet a hiányzó karakterkészlet amúgy is? Az LCD vezérlő regisztereibe irt adatok alapján gyaníthatóvá vált, hogy melyik bit szabályozná a karakterkészlet kiválasztását, csak éppen nem volt miből választani. A neten fellelhető PCB fotókat nézegetve a szemem elé került egy, ahol egy igen rossz minőségű képen egy IC látszik, rajta a "charset ROM" felirattal. A dolog kezdett gyanússá válni, és a következőkre gondoltam: a Commodore LCD-nek valójában saját ROM-ja van a karakterkészlet tárolására! Erről pedig nincs ROM image-unk egyáltalán! Az valószínűleg csak a szerencse műve, hogy a kernal-ban ott van az egyik, tippem szerint az csak valami software célokra kellhet (tudom is én, BASIC grafikus módban karakter kiírása, vagy hasonló!), és valójában nem az a karakterkészlet, amit az LCD vezérlő használ, mivel ez utóbbi teljesen független ROM. A megoldás az emulátoromban - ROM image hiányában - az lett, hogy vadásztam az internetről egy random 6*8 mátrixszal rendelkező karakter készletet, ahol az angol ABC kisbetűi vannak. A kernal-ban találta nagybetű+grafikus készlet lett az egyik charset, illetve ezt klónoztam másodiknak is, csak ebben nemi módosítást eszközöltem: áthelyeztem a nagy betűket, illetve a fenti forrásból beszerzett kisbetűk mintáját beleerőszakoltam. Emulálva az LCD vezérlő set váltó bitjét, bár jól jelent még minden: a "menüben" volt kis és nagy betű is, BASIC-ben még kapásból csak nagy (de átváltható billentyűzetről, ahogy C64-en is).
Természetesen csak hardware "felderítés" ügyben is volt több kisebb kitérő, amit közben nem említettem: ilyen például az IEC busz emulálásának kérdése. A Commodore LCD rendelkezik soros IEC busszal, így elvileg akar egy 1541 is kapcsolható hozza például (alapból a Commodore LCD - leven hordozható gép - nem ezt használja, hanem "RAM diszket", de erről majd kesébb). Próbáltam emulálni ezt is, kezdve az alapvető IEC busz handshake-től, ámde ez valamiért nem jött össze (mellesleg közben írtam JavaScript-ban egy primitív C64 emulátort, mivel ott tudom persze, hogy az IEC busz tényleg működik, ott ment is). Azt mind a mai napig nem tudom, hogy ez Commodore LCD-vel miért nem jött össze. Ezt azért akartam megtenni, mert így "kissé" nehézkes a file beötlése és mentése, a Commodore LCD filozófiája alapból az, hogy emulál részben egy 1541-et amit "virtual 1541"-nek nevez, és valójában RAM disk. Mivel kikapcsolt állapotban is táplálja az akkumulátor a RAM-ot, ezért "nem felejti el", ámde egy JavaScript/web alapú emulátornál ez probléma, hiszen nem tudom megtartani a memória állapotát (a HTML5 localstorage eljárását felhasználtam, de sajnos így sem kaptam használható eredményt). Az is elképzelhető, hogy az általam írt VIA emuláció nem tökéletes, és ennek köszönhető a probléma (a C64-es "tanulmány emulátoromban" nyilván CIA van, 6526).
A másik kisebb hardware-es kitérő az RTC (Real Time Clock) chip emulációja volt. Már a kezdet kezdetén a (VIA emuláció írásánál) feltűnt, hogy az egyik VIA bizonyos portjainak "default” értéket adva mindig más dátum/idő jelenik meg a "menüben" a jobb felső sarokban. Ebből feltételeztem, hogy a Commodore LCD tartalmaz valamiféle hardware-es RTC elemeket. Az eredeti PDF is ír erről, azonban abban az eddig bizonyított használhatatlansága miatt nem tudtam megbízni. Ismét Andy segített ki, egy újabb scannelt oldalon, amit elküldött a VIA port kiosztása volt látható, és a billentyűzet is. Elsőként ellenőrizni tudtam a billentyűzetet, amire magamtól is rájöttem. Örömmel könyveltem el, hogy kb. pontos volt, amit kitaláltam magamtól is, habár a konkrét hardware más, mint aminek elképzeltem, software szempontból a hozzáférés tényleg úgy működött, illetve persze a billentyűzet mátrix is stimmelt (másképpen nem is lehetett volna, hiszen akkor nem működhetett volna jól e tekintetben az emulátorom). Másrészt, az IEC busz "bekötése" is meglett, amiben szintén nem tévedtem (de sajnos ennek emulálása - mint írtam – valamiért továbbra sem ment). Ezek mellett ott volt az RTC chip bekötése is a VIA portok tükrében. Apróbb bökkenő, hogy nem lehetett tudni, hogy konkrétan milyen RTC chipről van szó. Úgy látszik, Andy-t is elkezdte ez érdekelni, mert egy napon írt egy mail-t, hogy ő is talált a neten egy PCB fotót, amin nagyon nehezen olvasható, de sikerült kiolvasnia mi lehetett az említett IC-n a felirat. Ez alapján rákerestem a kérdéses IC adatlapjára a neten, és implementáltam annak funkcionalitását kissé amatőr módon, írni időt/dátumot nem lehet, olvasásnál még a JavaScript megfelelő dátumkezelő dolgai alapján az aktuális időt mondja. Ezek után emulátorom már a helyes időt és dátumot jelezte ki automatikusan.
Folytatás a befejező résszel hamarosan ...
A bejegyzés trackback címe:
Kommentek:
A hozzászólások a vonatkozó jogszabályok értelmében felhasználói tartalomnak minősülnek, értük a szolgáltatás technikai üzemeltetője semmilyen felelősséget nem vállal, azokat nem ellenőrzi. Kifogás esetén forduljon a blog szerkesztőjéhez. Részletek a Felhasználási feltételekben és az adatvédelmi tájékoztatóban.
2014.03.12. 12:13:06
-- Ugye eredetileg ezt tervezte a commodore, csak azután kiderült a "shift register bug" és gyorsan át kellett alakitani szoftveresre. --
Innentől mást kell emulálni máshogyan....és talán ez a baj, ezért nem megy. Nem mondom, hogy ez van, csak egy ötlet.
LGB 2014.03.24. 09:27:33