Miután sikeresen kihevertük az előző programunk fáradalmait, itt az idő, hogy valamiféle szöveget írjunk a képernyőre. Mint eddig is, kezdjük kicsiben, aztán majd haladunk a bonyolultabb dolgok felé.
Ehhez viszont legelőször nem ártana tudni, hogy hogyan, és miből épül fel a képernyőn látott kép.
A VIC-II grafikus chip háromféle módot tud kezelni, ezek közül az egyik a bekapcsolás után látható, jól ismert ún. "karakteres" képernyő. A másik kettő "grafikus" mód, az egyik 2 színű, 320x200-as felbontással, a másik a 16 színű, 160x200 pixellel. (Kis hazugsággal, de erről majd később)
Mi most a karakteres módra fogunk koncentrálni az egyszerűségéből fakadóan.
Előzőleg már láttuk, hogy a VIC eléggé "buta", a megadott adatok alapján folyamatosan, másodpercenként 50-szer felépíti és kirajzolja nekünk a látható képet. Logikusnak tűnik a feltevés, hogy a karaktereket, a színeket és a kurzort is ő jeleníti meg, valamilyen hasonlóan "buta" módon. Ez így is van.
A háttér- és keretszín kezeléséhez hasonlóan itt is valamilyen memóriacímeket kell majd piszkálgatnunk, ha változást szeretnénk látni a képernyőn.
Hogyan épül fel a kép?
A chip a memória egy adott területét használja az úgynevezett "video RAM"-ként. ( Vagy screen RAM) Ezen a területen minden egyes byte, egy karakter pozíciót jelöl. A byte-ok tartalma azt mutatja meg, melyik karaktert kell kirajzolni. Na persze ez leírva így eléggé katyvasz, nézzünk egy képet:
A képernyőt elképzelhetjük úgy, mint egy kockás füzetet. (Oké, akkor négyzethálós 😙) Minden egyes cella 1 byte a memóriában. A VIC rendszeresen "végigrohan" ezen a területen, és ha valahol talál pl egy 1-es értéket, akkor kirajzol egy A betűt. Ha 2-est, akkor B-t, és így tovább...
Nem nehéz kiszámolni, hogy 40x25, vagyis pontosan 1000 byte-ra van szükségünk egy teljes képhez.
Ezen 1000 byteunk a memóriában a $0400-as címtől helyezkedik el. A $0400 a képernyő bal felső sarka, a $0401 az eggyel jobbra található karakter, a $0402 még eggyel jobbra, és így tovább végig a sorban. A 39. byte a sor végén lévő karakter, a 40. pedig a következő sor elején lévő lesz. (Mivel ugye 0-tól kezdjük a számolást, így 0->39-ig az pont 40 byte)
Így gyakorlatilag kapunk egy képzeletbeli koordinátarendszert, viszont itt a 0,0 pont a képernyő bal felső sarka, az X jobbra nő, az Y pedig lefelé. (Ne feledjük, hogy 0-től kezdjük a számozást)
Ha már kezdünk elveszni a számokban, lássuk ezt a gyakorlatban, úgy egyszerűbb:
A BASIC-nek a megszokott decimális számokat kell beírnunk, így lesz a $0400 átváltva 1024. Tehát az 1024-es memóriacellába beírunk egy 1-es értéket. Egyből meg is jelenik a képernyő bal felső sarkában egy kék A betű. Írjunk mellé egy B-t is.
Micsoda boszorkányság! Tényleg ott termett egy B is! Próbáljunk egy C-t írni a sor végére, és egy D-t az A alá. (Kis hint, a BASIC képes matematikai műveleteket kiértékelni, tehát nem kell bajlódnunk a fejszámolással)
Már megint direktben piszkáljuk a hardvert, semmi driver, semmi OS, csodás érzés, ugye? 😁😁
Itt már látszik, hogy az 1024 + 40 a második sor első karaktere, az 1024 + 80 a harmadik sor lesz, az 1024 + 120 a negyedik, stb, stb
Feladat: Mindenki baromkodjon kedvére, próbálkozzon különféle címekkel, és értékekkel.
Figyelem: a képernyőmemória az 1024 és 2023 közötti területen van, ezen kívül (főleg 1024 alatt) ne nagyon pokézgassunk, mert random memóriacímek átírásának csúnya fagyás lehet a vége... 😆
Természetesen ezt bonyolíthatjuk is úgy, hogy egy megadott koordinátára írjunk ki egy karaktert. A matekot már tudjuk. 1024-nél kezdődik a videoram, 40 karakter széles egy sor, tehát a matek: 1024 + Y*40 + X
Vagyis majdnem, mert mindent 0-tól sorszámozunk, tehát ha a a képernyő 6. sorába szeretnénk írni, akkor a képletbe csak 5 kerül majd. X koordinátánál ugyanez, ez is eggyel kevesebb.
Én most a "FASTLOAD" szövegbe akarok beleírni, ami a 6. sorban van. Ennek a 7. karakterét változtatom meg, vagyis a képletünk: 1024 + 5*40 + 6
Meg is jelent az angol ABC 15. betűje ( az O ) a megadott helyen. Miután kikuncogtuk magunkat a felettébb érett, semmiképp sem gyerekes humorérzékemet tükröző "FOSTLOAD" feliraton, vizsgáljuk meg kicsit jobban, mi is van a képernyőn.
Miért van az, hogy fent az A,B,C,D betűk kékek, az O pedig fehér lett?
Ugyanúgy, ahogyan a memória egy része tárolja a megjelenítendő karaktereket, egy másik rész ettől függetlenül az egyes pozíciók színeit. Mivel mi a színeket nem írtuk át, azok megmaradtak az eredeti kék, vagy épp fehér értéken.
A szin RAM (color RAM), a memória $D800-as (átváltva 55296 ) címén kezdődik , és ugyanúgy pont 1000 byte-t foglal, mint a karaktereket tartalmazó screen RAM. Azon most mindenki próbáljon meg nem leakadni, hogy a 64Kb memória szinte két ellentétes végén helyezkednek el, az egyik az elején, a másik a végén... 😬
A screen RAM tetszőlegesen áthelyezhető másik memóriaterületre, de mivel a gyári operációs rendszer fixen a $0400-at használja, így átállításával mi semmi hasznosat nem érnénk el. A teljes képernyős szerkesztőt használhatatlanná tennénk, így a screen RAM áthelyezése főleg saját programoknál lehet hasznos.
A fenti tudásunkat alkalmazva, könnyedén írhatunk mostmár egy sárga A betűt a bal felső sarokba. (Sárga = 7, egyéb színek itt)
Összefoglalás
A videochip a karakteres képernyőmódban, a kép összeállításához 2 memóriaterületről veszi az információkat, és jeleníti meg azok tartalmát teljesen automatikusan:
- képernyő RAM (screen RAM, video RAM): $0400-tól kezdődően 1000 byte (decimális 1024-től)
- szín RAM (color RAM): $D800-tól kezdődően 1000 byte (decimális 55296-tól)
Ezekre a memóriaterületekre adatokat írva befolyásolhatjuk a képernyő tartalmát, és a karakterek színeit.
Bár ebben a részben nem volt assembly, azért sejtésem szerint már látható, hogy hogyan is robogunk szépen apró lépéseinkkel egy "Hello világ" felé.
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.