5. fejezet: A Commodore-64 operációs rendszer Assembly nyelven

5 Fejezet A Commodore 64 Operacios Rendszer Assembly Nyelven



5.1 Bevezetés

A Commodore-64 számítógép operációs rendszere csak olvasható memóriában (ROM) található a számítógéppel együtt. A Commodore-64 memóriabájtjainak száma 0000 USD és FFFF USD között van (azaz 000016 és FFFF16 között, ami 010 és 65 53510 között van). Az operációs rendszer ára $E000 és $FFFF között van (azaz 57,34410 és 65,53610 között).

Miért érdemes a Commodore-64 operációs rendszert tanulmányozni?
Miért tanulmányozzuk ma a Commodore-64 operációs rendszert, amikor az egy számítógép operációs rendszere volt, amelyet 1982-ben adtak ki? Nos, a Commodore-64 számítógép a 6510-es központi feldolgozó egységet használja, amely a 6502 µP frissítése (bár nem nagy frissítése).







A 6502 µP-t még ma is nagy számban gyártják; már nem otthoni vagy irodai számítógépekhez, hanem elektromos és elektronikus készülékekhez (eszközökhöz) való. A 6502 µP a korabeli többi mikroprocesszorhoz képest is könnyen érthető és kezelhető. Ezek eredményeként az egyik legjobb (ha nem a legjobb) mikroprocesszor az assembly nyelv tanítására.



A még mindig a 6502 mikroprocesszor osztályba tartozó 65C02 µP 66 assembly nyelvű utasítással rendelkezik, amelyek mindegyike akár fejből is megtanulható. A modern mikroprocesszorok sok assembly nyelvű utasítással rendelkeznek, és nem tanulhatók meg fejből. Minden µP-nek megvan a maga assembly nyelve. Minden operációs rendszer, legyen az új vagy régi, assembly nyelvű. Ezzel a 6502-es assembly nyelv alkalmas arra, hogy kezdőknek tanítsuk az operációs rendszert. Miután megtanult egy operációs rendszert, például a Commodore-64-hez, egy modern operációs rendszer könnyen megtanulható ennek alapján.



Ez nem csak a szerző (magam) véleménye. Ez egy növekvő tendencia a világon. Egyre több cikk születik az interneten a továbbfejlesztett Commodore-64 operációs rendszerről, hogy modern operációs rendszernek tűnjön. A modern operációs rendszereket a következő fejezetben ismertetjük.





jegyzet : A Commodore-64 OS (Kernal) továbbra is jól működik a modern bemeneti és kimeneti eszközökkel (nem mindegyikkel).

Nyolc bites számítógép
Egy nyolc bites mikroszámítógépben, mint például a Commodore 64, az információkat nyolc bites bináris kódok formájában tárolják, továbbítják és manipulálják.



Memória térkép
A memóriatérkép egy olyan skála, amely a teljes memóriatartományt kisebb, különböző méretű tartományokra osztja, és megmutatja, hogy melyik tartományba mi (szubrutin és/vagy változó) tartozik. A változó egy címke, amely megfelel egy adott memóriacímnek, amelynek értéke van. A címkéket az alprogramok kezdetének azonosítására is használják. De ebben az esetben a szubrutinok neveként ismertek. Egy szubrutin egyszerűen rutinnak nevezhető.

Az előző fejezetben szereplő memóriatérkép (elrendezés) nem elég részletes. Ez egészen egyszerű. A Commodore-64 számítógép memóriatérképe három részletszinttel jeleníthető meg. Köztes szinten megjelenítve a Commodore-64 számítógép különböző memóriatérképekkel rendelkezik. A Commodore-64 számítógép alapértelmezett memóriatérképe középszinten:


5.11. ábra Commodore-64 memóriatérkép

Akkoriban volt egy népszerű számítógépes nyelv, a BASIC. Sok számítógép-felhasználónak tudnia kellett néhány minimális BASIC nyelvi parancsot, mint például a program betöltése a hajlékonylemezről (lemezről) a memóriába, egy program futtatása (végrehajtása) a memóriában, és a programból való kilépés (bezárás). Amikor a BASIC program fut, a felhasználónak soronként kell betáplálnia az adatokat. Nem olyan, mint manapság, amikor egy alkalmazást (számos program alkot egy alkalmazást) magas szintű nyelven írnak windows-al, és a felhasználónak csak egy ablakban speciális helyeken kell elférnie a különböző adatokkal. Bizonyos esetekben egérrel jelöljük ki az előre megrendelt adatokat. A BASIC akkoriban magas szintű nyelv volt, de nagyon közel áll az assembly nyelvhez.

Figyelje meg, hogy a memória nagy részét a BASIC foglalja el az alapértelmezett memóriatérképen. A BASIC parancsokkal (utasításokkal) rendelkezik, amelyeket az úgynevezett BASIC Interpreter hajt végre. Valójában a BASIC tolmács a ROM-ban van az A000 $ helytől a $ BFFF-ig (beleértve), ami állítólag egy RAM terület. Ez a 8 Kbyte akkoriban elég nagy! Valójában a ROM-ban van a teljes memória azon a helyén. Mérete megegyezik az operációs rendszerével, $E000-től $FFFF-ig (beleértve). A BASIC nyelven írt programok szintén a 0200 USD és a BFFF közötti tartományba kerülnek.

A felhasználói assembly nyelvű program RAM-ja 000 dollártól CFFF dollárig terjed, mindössze 4 kbyte a 64 kbyte-ból. Tehát miért használjuk vagy tanuljuk meg az assembly nyelvet? Az új és a régi operációs rendszerek assembly nyelvűek. A Commodore-64 operációs rendszere ROM-ban van, $E000-től $FFFF-ig. A 65C02 µP (6510 µP) assembly nyelven íródott. Alprogramokból áll. Az assembly nyelvű felhasználói programnak meg kell hívnia ezeket az alprogramokat, hogy interakcióba lépjen a perifériákkal (bemeneti és kimeneti eszközök). A Commodore-64 operációs rendszer assembly nyelvű ismerete lehetővé teszi a hallgató számára, hogy gyorsan, sokkal kevésbé unalmas módon megértse az operációs rendszereket. Ismétlem, akkoriban sok Commodore-64 felhasználói programot BASIC nyelven írtak, nem assembly nyelven. Az assembly nyelveket akkoriban inkább maguk a programozók használták technikai célokra.

A Kernal (K-e-r-n-a-l) a Commodore-64 operációs rendszere. A Commodore-64 számítógéphez ROM-ban érkezik, nem pedig lemezen (vagy hajlékonylemezen). A Kernal szubrutinokból áll. A perifériák eléréséhez az assembly nyelvű (gépi nyelv) felhasználói programnak ezeket az alprogramokat kell használnia. A kernelt nem szabad összetéveszteni a kernellel, amelyet a modern operációs rendszerek K-e-r-n-e-l-ként írnak, bár ezek szinte ugyanazok.

A 4 Kbyte 10 C000 (49 15210) USD és CFFF (6324810) USD közötti memóriaterület RAM vagy ROM. Ha RAM, akkor ez a perifériák elérésére szolgál. Ha ROM, akkor a karakterek képernyőre (monitorra) történő kinyomtatására szolgál. Ez azt jelenti, hogy vagy a karaktereket nyomtatják ki a képernyőre, vagy a perifériákat a memória ezen részének használatával érik el. A rendszeregységben (alaplapon) van egy bank ROM (karakter ROM), amelyet a teljes memóriaterületen ki-be kapcsolnak, hogy ezt elérjék. Előfordulhat, hogy a felhasználó nem veszi észre a váltást.

A memóriaterület 0100 dollártól (256 10 ) $01FF-ig (511 10 ) a verem. Az operációs rendszer és a felhasználói programok egyaránt használják. A verem szerepét ennek az online karrierkurzusnak az előző fejezetében ismertettük. A memória területe 0000 dollártól (0 10 ) 00 FF (255 10 ) használja az operációs rendszer. Sok mutató van hozzárendelve.

Kernal Jump Table
A Kernal olyan rutinokkal rendelkezik, amelyeket a felhasználói program hív meg. Ahogy az operációs rendszer új verziói megjelentek, ezeknek a rutinoknak a címei megváltoztak. Ez azt jelenti, hogy a felhasználói programok már nem tudtak működni az új operációs rendszer verziókkal. Ez nem történt meg, mert a Commodore-64 ugróasztalt biztosított. Az ugrótábla egy 39 bejegyzést tartalmazó lista. A táblázat minden bejegyzéséhez három cím tartozik (az utolsó 6 bájt kivételével), amelyek még az operációs rendszer verzióváltásával sem változtak.

Egy bejegyzés első címe JSR utasítással rendelkezik. A következő két cím egy kétbájtos mutatóból áll. Ez a kétbájtos mutató egy tényleges rutin címe (vagy új címe), amely még mindig az operációs rendszer ROM-jában van. A mutató tartalma változhat az operációs rendszer új verzióival, de az egyes ugrótábla-bejegyzések három címe soha nem változik. Vegyük például a $FF81, $FF82 és $FF83 címeket. Ez a három cím az alaplap képernyő- és billentyűzetáramkörök (regiszterek) inicializálására szolgáló rutin számára szolgál. Az $FF81 cím mindig tartalmazza a JSR műveleti kódját (egy bájt). Az $FF82 és $FF83 címek az inicializáláshoz szükséges szubrutin régi vagy új címével rendelkeznek (még az OS ROM-ban). Egy időben a $FF82 és $FF83 címek tartalma (címe) $FF5B volt, ami változhat a következő operációs rendszer verzióval. Az ugrótábla $FF81, $FF82 és $FF83 címei azonban soha nem változnak.

Minden három címből álló bejegyzéshez az első JSR-címhez tartozik egy címke (név). A $FF81 címkéje PCINT. A PCINT soha nem változik. Tehát a képernyő és a billentyűzet regisztereinek inicializálásához a programozó egyszerűen beírhatja a „JSR PCINT” parancsot, amely a Commodore-64 operációs rendszer összes verziójához használható. A tényleges szubrutin helye (kezdőcíme), például $FF5B, idővel változhat a különböző operációs rendszereken. Igen, a ROM OS-t használó felhasználói programban legalább két JSR utasítás szerepel. A felhasználói programban van egy JSR utasítás, amely az ugrótábla bejegyzésére ugrik. Az ugrótábla utolsó hat címének kivételével az ugrótábla bejegyzésének első címe JSR utasítással rendelkezik. A Kernalban egyes szubrutinok meghívhatják a többi szubrutint.

A Kernal ugrótábla $FF81-től (beleértve) indul felfelé, hármas csoportokban, kivéve az utolsó hat bájtot, amelyek három mutató alacsonyabb bájtcímekkel: $FFFA, $FFFC és $FFFE. Az összes ROM OS rutin újrafelhasználható kód. Tehát a felhasználónak nem kell átírnia őket.

A Commodore-64 rendszeregység blokkdiagramja
Az alábbi ábra részletesebb, mint az előző fejezetben:


5.12. ábra A Commodore_64 rendszeregység blokkdiagramja

A ROM és a RAM itt egy blokkként jelenik meg. Itt látható a képernyőre érkező információk kezelésére szolgáló Video Interface Chip (IC), amely az előző fejezetben nem volt bemutatva. A bemeneti/kimeneti eszközök egyetlen blokkja, amely az előző fejezetben látható, itt két blokkként jelenik meg: CIA #1 és CIA #2. A CIA a Complex Interface Adapter rövidítése. Mindegyiknek két párhuzamos nyolcbites portja van (nem tévesztendő össze a rendszeregység függőleges felületén lévő külső portokkal), amelyeket A és B portnak neveznek. Ebben a helyzetben a CIA öt külső eszközhöz csatlakozik. Az eszközök a billentyűzet, a joystick, a lemezmeghajtó/nyomtató és a modem. A nyomtató a lemezmeghajtó hátuljához csatlakozik. Van még egy hanginterfész eszközáramkör és egy programozható logikai tömb áramkör, amelyek nem láthatók.

Ennek ellenére van egy karakter-ROM, amely mindkét CIA-val felcserélhető, amikor egy karaktert elküldenek a képernyőre, és az nem jelenik meg a blokkdiagramon.

A RAM-címek $D000-tól $DFFF-ig a bemeneti/kimeneti áramköröknél karakter ROM hiányában a következő részletes memóriatérképpel rendelkeznek:

5.11. táblázat
Részletes memóriatérkép 000 dollártól DFFF dollárig
Alcímtartomány Áramkör Méret (byte)
D000 – D3FF VIC (Video Interface Controller (Chip)) 1K
D400 – D7FF SID (hangáramkör) 1K
D800 – DBFF Színes RAM 1K Nibbles
DC00 – DCFF CIA #1 (billentyűzet, joystick) 256
DD00 – DDFF CIA #2 (soros busz, felhasználói port/RS-232) 256
DE00 – DEF Nyissa meg az 1. I/O-nyílást 256
DF00 – DFFF Nyissa meg a 2. I/O-nyílást 256

5.2 A két komplex interfész adapter

A Commodore-64 rendszeregységben két speciális integrált áramkör (IC) található, és mindegyiket Complex Interface Adapternek nevezik. Ez a két chip a billentyűzet és más perifériák és a mikroprocesszor interfészére szolgál. A VIC és a képernyő kivételével a mikroprocesszor és a perifériák közötti összes bemeneti/kimeneti jel ezen a két IC-n halad át. A Commodore-64 esetében nincs közvetlen kommunikáció a memória és a perifériák között. A memória és a perifériák közötti kommunikáció a mikroprocesszor-akkumulátoron halad keresztül, és ezek egyike a CIA adapterek (IC-k). Az IC-k neve CIA #1 és CIA #2. A CIA a Complex Interface Adapter rövidítése.

Minden CIA-nak 16 regisztere van. A CIA időzítő/számláló regiszterei kivételével minden regiszter 8 bit széles és rendelkezik memóriacímmel. A CIA #1 memóriaregiszter-címei $DC00-tól származnak (56320 10 ) DC0F dollárra (56335 10 ). A CIA #2 memóriaregiszter-címei $DD00-tól származnak (56576 10 ) DD0F dollárra (56591 10 ). Bár ezek a regiszterek nincsenek az IC memóriájában, a memória részét képezik. A közbenső memóriatérképen a $D000 és $DFFF közötti I/O terület tartalmazza a CIA címeket $DC00 és $DC0F között, valamint $DD00 és $DD0F között. A RAM I/O memóriaterületének nagy része ($D000-tól $DFFF-ig) cserélhető a karakter-ROM memóriabankjával képernyőkarakterekre. Ezért amikor a karaktereket a képernyőre küldik, a perifériák nem tudnak működni; bár a felhasználó ezt nem veszi észre, mivel az oda-vissza csere gyors.

A CIA #1-ben két regiszter van, amelyeket A és B portnak neveznek. Címük $DC00 és $DC01. A CIA #2-ben két regiszter is van, az A és a B port. Természetesen ezek címe eltérő; ezek DD00 és DD01 dollárok.

A CIA A vagy B portja párhuzamos port. Ez azt jelenti, hogy egyszerre nyolc bitben tudja elküldeni az adatokat a perifériára, vagy egyszerre nyolc bitben fogadja az adatokat a mikroprocesszortól.

Az A vagy B porthoz egy adatirány-regiszter (DDR) kapcsolódik. A CIA #1 (DDRA1) A portjának adatirány-regisztere a $DC02 memóriabájt helyén található. A CIA #1 (DDRB1) B portjának adatirány-regisztere a $DC03 memóriabájt helyén található. A CIA #2 (DDRA2) A portjának adatirány-regisztere a $DD02 memóriabájt helyén található. A CIA #2 (DDRB2) B portjának adatirány-regisztere a $DD03 memóriabájt helyén található.

Most az A vagy B port minden bitje beállítható a megfelelő adatirányregiszterrel bemenetként vagy kimenetként. A bemenet azt jelenti, hogy az információ a perifériáról a mikroprocesszorba jut egy CIA-n keresztül. A kimenet azt jelenti, hogy az információ egy CIA-n keresztül jut el a mikroprocesszortól a periféria felé.

Ha egy port (regiszter) celláját kell bevinni, akkor az adatirány-regiszter megfelelő bitje 0. Ha egy port (regiszter) celláját kell kiadni, akkor az adatirány-regiszter megfelelő bitje 1. A legtöbb esetben a port mind a 8 bitje bemenetre vagy kimenetre van programozva. Amikor a számítógép be van kapcsolva, az A port kimenetre, a B port pedig bemenetre van programozva. A következő kód a CIA #1 A portot teszi kimenetként és a CIA #1 B portot bemenetként:

LDA #$FF
STA DDRA1 ; A $DC00 $DC02 rendezője
LDA #$00
STA DDRB1 ; A $DC01 $DC03 rendezője

A DDRA1 a $DC02 memóriabájt helyének címkéje (változó neve), a DDRB1 pedig a $DC03 memóriabájt helyének címke (változó neve). Az első utasítás 11111111-et tölt be a µP akkumulátorába. A második utasítás ezt bemásolja a CIA sz. A port adatirány-regiszterébe. 1. A harmadik utasítás 00000000-et tölt be a µP akkumulátorába. A negyedik utasítás ezt bemásolja a CIA sz. B portjának adatirány-regiszterébe. 1. Ez a kód az operációs rendszer egyik szubrutinjában található, amely ezt az inicializálást végzi el a számítógép bekapcsolásakor.

Mindegyik CIA-nak van egy megszakítási szolgáltatáskérő vonala a mikroprocesszorhoz. Az 1. számú CIA-ból származó a IRQ a µP tűje. A 2. számú CIA-ból származó a NMI a µP tűje. Emlékezz arra NMI magasabb prioritású, mint IRQ .

5.3 Billentyűzet összeállítás nyelvi programozása

Csak három lehetséges megszakítás lehetséges a Commodore-64 számára: IRQ , BRK és NMI . Az ugróasztal mutatója IRQ a $FFFE és $FFFF címen van a ROM-ban (operációs rendszer), amely megfelel egy még az operációs rendszerben (ROM) lévő szubrutinnak. A BRK ugrótábla mutatója az operációs rendszer $FFFC és $FFFD címén található, ami megfelel egy még az operációs rendszerben (ROM) lévő szubrutinnak. Az ugróasztal mutatója NMI az operációs rendszer $FFFA és $FFFB címén van, ami megfelel egy még az operációs rendszerben (ROM) lévő szubrutinnak. A IRQ , valójában két szubrutin létezik. Tehát a BRK szoftveres megszakításnak (utasításnak) van saját ugrótábla mutatója. Az ugróasztal mutatója IRQ a kódhoz vezet, amely eldönti, hogy a hardveres vagy a szoftveres megszakítás van-e bekapcsolva. Ha ez a hardveres megszakítás, a rutin a IRQ nak, nek hívják. Ha ez a szoftveres megszakítás (BRK), akkor a BRK rutin meghívásra kerül. Az egyik operációs rendszer verzióban a szubrutin a IRQ $EA31, a BRK szubrutin pedig $FE66. Ezek a címek $FF81 alatt vannak, tehát nem ugrótábla bejegyzések, és az operációs rendszer verziójától függően változhatnak. Három rutin érdekes ebben a témában: az, amelyik ellenőrzi, hogy lenyomott billentyűről vagy BRK-ról van-e szó, amelyik FE43 dollárnál van, és az, amelyik szintén változhat az operációs rendszer verziójával.

A Commodore-64 számítógép olyan, mint egy hatalmas írógép (felfelé), nyomtatási rész (fej és papír) nélkül. A billentyűzet a CIA #1-hez csatlakozik. A CIA #1 alapértelmezés szerint 1/60 másodpercenként önállóan pásztázza a billentyűzetet, programozási interferencia nélkül. Tehát minden 1/60 másodpercben a CIA #1 küld egy IRQ µP-re. Csak egy van IRQ tű a µP-nél, ami csak a CIA #1-től származik. Az egy bemeneti pin NMI a µP, amely különbözik a IRQ , csak a CIA #2-től származik (lásd a következő ábrát). A BRK valójában egy assembly nyelvű utasítás, amely egy felhasználói programban van kódolva.

Tehát minden 1/60 másodpercben a IRQ A $FFFE és a $FFFF által mutatott rutin meghívódik. A rutin ellenőrzi, hogy megnyomtak-e egy billentyűt vagy a BRK utasítást. Ha egy billentyűt lenyomnak, a gombnyomás kezelési rutin meghívódik. Ha ez egy BRK utasítás, akkor a BRK kezelésére szolgáló rutin meghívásra kerül. Ha egyik sem, akkor nem történik semmi. Egyik sem fordulhat elő, de a CIA #1 küld IRQ µP-re 1/60 másodpercenként.

A billentyűzet várólista, más néven billentyűzet puffer, a RAM bájtjainak tartománya 0277 és 0280 dollár között; 1010 bájt összesen. Ez egy First-In-First-Out puffer. Ez azt jelenti, hogy az elsőként érkező karakter az első, aki távozik. Egy nyugat-európai karakter egy bájtot vesz igénybe.

Tehát míg a program nem használ karaktereket egy billentyű lenyomásakor, a kulcs kódja ebbe a pufferbe (sorba) kerül. A puffer folyamatosan töltődik, amíg el nem fogy tíz karakter. A tizedik karakter után lenyomott karakterek nem kerülnek rögzítésre. Figyelmen kívül hagyja mindaddig, amíg legalább egy karaktert le nem kap (elfogyaszt) a sorból. Az ugrástáblázatban van egy bejegyzés egy szubrutinhoz, amely az első karaktert a sorból a mikroprocesszorba küldi. Ez azt jelenti, hogy az első karaktert, amely bekerül a sorba, a µP akkumulátorába helyezi. Az ehhez szükséges ugrótábla szubrutin neve GETIN (a Get-In számára). Az ugrótáblázatban a három bájtos bejegyzés első bájtja GETIN címkével van ellátva ($FFE4 cím). A következő két bájt az a mutató (cím), amely a ROM (OS) aktuális rutinjára mutat. A programozó felelőssége, hogy ezt a rutint lehívja. Ellenkező esetben a billentyűzet puffere tele marad, és a legutóbb lenyomott billentyűket figyelmen kívül hagyja. Az akkumulátorba kerülő érték a megfelelő kulcs ASCII-értéke.

Hogyan kerülnek először a kulcskódok a sorba? Létezik egy ugróasztal rutin, az úgynevezett SCNKEY (a letapogatási kulcshoz). Ezt a rutint szoftver és hardver egyaránt meghívhatja. Ebben az esetben egy elektronikai (fizikai) áramkör hívja a mikroprocesszorban, amikor az elektromos jelet IRQ alacsony. Ez az online karriertanfolyam nem foglalkozik azzal, hogy ez pontosan hogyan történik.

Az a kód, amely az első kulcskódot a billentyűzet pufferéből az A tárolóba kapja, csak egy sor:

BEJUTNI

Ha a billentyűzet puffer üres, 00 dollár kerül az akkumulátorba. Ne feledje, hogy a nulla ASCII-kódja nem 00 $; ez 30 dollár. A 00 dollár nullát jelent. Egy programban előfordulhat, hogy a programnak várnia kell a gombnyomásra. Ennek kódja:

VÁRJ JSR GETIN
CMP #$00
BÉKA VÁRJ

Az első sorban a „WAIT” egy címke, amely azonosítja a RAM-címet, ahová a JSR-utasítás be van írva. A GETIN is egy cím. Ez az ugrótábla megfelelő három bájtja közül az első címe. A GETIN bejegyzés, valamint az ugrótábla összes bejegyzése (az utolsó három kivételével) három bájtból áll. A bejegyzés első bájtja a JSR utasítás. A következő két bájt a tényleges GETIN szubrutin törzsének címe, amely még mindig a ROM-ban (OS), de az ugrótábla alatt van. Tehát a bejegyzés azt mondja, hogy ugorjunk a GETIN szubrutinra. Ha a billentyűzetsor nem üres, a GETIN behelyezi a First-In-First-Out sor ASCII-kulcskódját az akkumulátorba. Ha a sor üres, Null ($00) kerül az akkumulátorba.

A második utasítás összehasonlítja az akkumulátor értékét 00 dollárral. Ha 00 dollár, az azt jelenti, hogy a billentyűzetsor üres, és a CMP utasítás 1-et küld a processzorállapot-regiszter Z jelzőjéhez (ezt egyszerűen csak állapotregiszternek nevezzük). Ha az A-ban lévő érték nem 00 $, a CMP utasítás 0-t küld az állapotregiszter Z jelzőjéhez.

A harmadik „BEQ WAIT” utasítás visszaküldi a programot az első utasításhoz, ha az állapotregiszter Z jelzője 1. Az első, a második és a harmadik utasítás ismétlődően végrehajtódik egymás után, amíg meg nem nyomnak egy billentyűt a billentyűzeten. . Ha egy gombot soha nem nyomnak meg, a ciklus korlátlanul ismétlődik. Az ehhez hasonló kódszegmenseket általában egy időzítési kódszegmenssel írják, amely egy idő után kilép a ciklusból, ha soha nem nyomnak le gombot (lásd a következő tárgyalást).

jegyzet : A billentyűzet az alapértelmezett beviteli eszköz, a képernyő pedig az alapértelmezett kimeneti eszköz.

5.4 Csatorna, eszközszám és logikai fájlszám

Ebben a fejezetben a Commodore-64 operációs rendszer leírására használt perifériák a billentyűzet, a képernyő (monitor), a hajlékonylemezes meghajtó, a nyomtató és a modem, amely az RS-232C interfészen keresztül csatlakozik. Ahhoz, hogy ezen eszközök és a rendszeregység (mikroprocesszor és memória) közötti kommunikáció megtörténjen, létre kell hozni egy csatornát.

A csatorna pufferből, eszközszámból, logikai fájlszámból és opcionálisan másodlagos címből áll. E kifejezések magyarázata a következő:

Egy puffer
Figyeljük meg az előző szakaszból, hogy egy billentyű lenyomásakor a kódjának egy bájthelyre kell kerülnie a RAM-ban, tíz egymást követő hely sorozatából. Ez a tíz helyből álló sorozat a billentyűzet puffere. Minden bemeneti vagy kimeneti eszköznek (perifériának) van egy sor, egymást követő helye a RAM-ban, amelyet puffernek neveznek.

Készülék száma
A Commodore-64 esetében minden perifériához egy eszközszám tartozik. Az alábbi táblázat a különböző eszközöket és azok számát mutatja be:

5.41. táblázat
Commodore 64 készülékszámok és eszközeik
Szám Eszköz
0 Billentyűzet
1 Szalagos meghajtó
2 RS 232C interfész pl. egy modemet
3 Képernyő
4 Nyomtató #1
5 Nyomtató #2
6 Plotter #1
7 Plotter #2
8 Lemezmeghajtó
9
¦
¦
¦
30
8-tól (beleértve) akár 22 további tárolóeszközig

A számítógépekhez kétféle port létezik. Az egyik típus külső, a rendszeregység függőleges felületén található. A másik típus belső. Ez a belső port egy regiszter. A Commodore-64-nek négy belső portja van: A és B port a CIA 1 számára, valamint A és B port a CIA 2 számára. A Commodore-64 számára egy külső port található, amelyet soros portnak hívnak. A 3-as számmal feljebb lévő eszközök a soros portra csatlakoznak. Százszorszép láncban vannak összekapcsolva (az egyik a másik mögött van összekötve), amelyek mindegyike azonosítható eszközszáma alapján. A 8-as számmal feljebb lévő eszközök általában a tárolóeszközök.

jegyzet : Az alapértelmezett beviteli eszköz a 0-s eszközszámú billentyűzet. Az alapértelmezett kimeneti eszköz a 3-as eszközszámú képernyő.

Logikai fájlszám
A logikai fájlszám egy eszközhöz (perifériához) adott szám abban a sorrendben, ahogyan azok elérésre kerülnek. 010-től 255-ig terjednek 10 .

Másodlagos cím
Képzelje el, hogy két fájl (vagy egynél több fájl) van megnyitva a lemezen. A két fájl megkülönböztetésére a másodlagos címeket kell használni. A másodlagos címek számok, amelyek készülékenként változnak. A nyomtató másodlagos címeként használt 3 jelentése eltér a lemezmeghajtó másodlagos címeként használt 3 jelentésétől. A jelentés olyan funkcióktól függ, mint például, hogy egy fájlt olvasásra vagy mikor nyitnak meg írásra. A lehetséges másodlagos számok 0-tól származnak 10 15-ig 10 minden készülékhez. Számos eszköz esetében a 15-ös számot használják parancsok küldésére.

jegyzet : Az eszközszámot eszközcímnek, a másodlagos számot másodlagos címnek is nevezik.

Perifériás célpont azonosítása
Az alapértelmezett Commodore memórialeképezés esetén a 0200 $ és $02FF közötti memóriacímeket (2. oldal) kizárólag a ROM (Kernal) operációs rendszer használja, az operációs rendszer és a BASIC nyelv nem. Bár a BASIC továbbra is használhatja a helyeket a ROM OS-en keresztül.

A modem és a nyomtató két különböző periféria cél. Ha két fájlt nyit meg a lemezről, az két különböző cél. Az alapértelmezett memórialeképezésnél három egymást követő tábla (lista) van, amelyek egy nagy táblaként tekinthetők meg. Ez a három táblázat tartalmazza a logikai fájlszámok, az eszközszámok és a másodlagos címek közötti kapcsolatot. Ezzel egy adott csatorna vagy bemeneti/kimeneti célpont azonosíthatóvá válik. A három tábla neve Fájltáblázat. A RAM-címek és azok a következők:

0259 $ – 0262 $: Táblázat címkével, LAT, legfeljebb tíz aktív logikai fájlszámmal.
$0263 – $026C: táblázat címkével, FAT, legfeljebb tíz megfelelő eszközszámmal.
$026D – $0276: táblázat címkével, SAT, tíz megfelelő másodlagos címmel.

Itt a „–” azt jelenti, hogy „hoz”, és egy szám egy bájtot vesz igénybe.

Az olvasó felteheti a kérdést: „Miért nem szerepel az egyes eszközök puffere a csatorna azonosításában?” Nos, a válasz az, hogy a commodore-64-nél minden külső eszköznek (perifériának) van egy fix bájtsorozata a RAM-ban (memóriatérkép). Nyitott csatorna nélkül a pozícióik továbbra is ott vannak a memóriában. A billentyűzet puffere például 0277 és 0280 dollár között van rögzítve az alapértelmezett memóriatérképhez.

A kernal SETLFS és SETNAM szubrutinjai
A SETLFS és a SETNAM rendszermag-rutinok. A csatorna logikai fájlnak tekinthető. Egy csatorna megnyitásához meg kell adni a logikai fájlszámot, az eszközszámot és egy opcionális másodlagos címet. Szükség lehet egy opcionális fájlnévre (szöveg) is. A SETLFS rutin beállítja a logikai fájlszámot, az eszközszámot és egy opcionális másodlagos címet. Ezek a számok a megfelelő táblázatokban szerepelnek. A SETNAM rutin beállít egy karakterláncnevet a fájlhoz, amely kötelező lehet az egyik csatornánál, és opcionális egy másik csatornánál. Ez egy mutatóból (kétbájtos címből) áll a memóriában. A mutató a karakterlánc (név) elejére mutat, amely más helyen lehet a memóriában. A karakterlánc neve egy bájttal kezdődik, amely megadja a karakterlánc hosszát, amelyet a szöveg (név) követ. A név legfeljebb tizenhat bájt (hosszú) lehet.

A SETLFS rutin meghívásához a felhasználói programnak át kell ugrania (JSR) az operációs rendszer ugrástáblázatának $FFBA címére a ROM-ban az alapértelmezett memórialeképezéshez. Ne feledje, hogy az ugrótábla utolsó hat bájtja kivételével minden bejegyzés három bájtból áll. Az első bájt a JSR utasítás, amely ezután a szubrutinra ugrik, és a következő két bájtban lévő címen kezdődik. A SETNAM rutin meghívásához a felhasználói programnak ugrani (JSR) kell a ROM-ban lévő operációs rendszer ugrótáblázatának $FFBD címére. Ennek a két rutinnak a használatát a következő tárgyalás mutatja be.

5.5 Csatorna megnyitása, logikai fájl megnyitása, logikai fájl bezárása és az összes I/O csatorna bezárása

A csatorna egy memóriapufferből, egy logikai fájlszámból, egy eszközszámból (eszközcím) és egy opcionális másodlagos címből (egy számból) áll. A logikai fájlszámmal azonosított logikai fájl (absztrakció) egy perifériára, például nyomtatóra, modemre, lemezmeghajtóra stb. utalhat. A különböző eszközök mindegyikének eltérő logikai fájlszámmal kell rendelkeznie. Sok fájl van a lemezen. A logikai fájl egy adott fájlra is hivatkozhat a lemezen. Az adott fájlnak van egy logikai fájlszáma is, amely különbözik a perifériákétól, például a nyomtatóétól vagy a modemétől. A logikai fájl számát a programozó adja meg. Bármely szám lehet 010 (00 USD) és 25510 ($FF) között.

Az operációs rendszer SETLFS rutinja
Az OS SETLFS rutin, amely a $FFBA OS ROM ugrótáblájához való ugrással (JSR) érhető el, beállítja a csatornát. A logikai fájlszámot el kell helyeznie a fájltáblázatba, amely LAT ($0259 – $0262). Meg kell adnia a megfelelő eszközszámot a fájltáblázatban, amely FAT ($0263 – $026C). Ha a fájl- (eszköz-) hozzáféréshez másodlagos számra van szükség, akkor a megfelelő másodlagos címet (számot) el kell helyeznie a fájltáblázatba, amely SAT ($026D – $0276).

A működéshez a SETLFS szubrutinnak meg kell szereznie a logikai fájlszámot a µP akkumulátortól; meg kell szereznie az eszközszámot a µP X regiszterből. Ha a csatornának szüksége van rá, meg kell szereznie a másodlagos címet a µP Y regiszterből.

A logikai fájl számát a programozó határozza meg. A különböző eszközökhöz tartozó logikai fájlszámok eltérőek. Most, mielőtt meghívná a SETLFS rutint, a programozónak el kell helyeznie a logikai fájl számát a µP akkumulátorba. Az eszközszámot egy táblázatból (dokumentumból) olvassa ki, például az 5.41. táblázatban. A programozónak az eszköz számát is be kell írnia a µP X regiszterbe. Egy eszköz, például nyomtató, lemezmeghajtó stb. szállítója biztosítja az eszköz lehetséges másodlagos címeit és azok jelentését. Ha a csatornának másodlagos címre van szüksége, a programozónak azt az eszközhöz (perifériához) mellékelt dokumentumból kell megszereznie. Ha a másodlagos címre (számra) szükség van, a programozónak be kell írnia azt a µP Y regiszterbe, mielőtt meghívná a SETLFS szubrutint. Ha nincs szükség másodlagos címre, a programozónak be kell írnia a $FF számot a µP Y regiszterbe, mielőtt meghívná a SETLFS szubrutint.

A SETLFS szubrutin argumentum nélkül kerül meghívásra. Érvei már benne vannak a 6502 µP három regiszterében. A megfelelő számok regiszterekbe helyezése után a rutin meghívása a programban egyszerűen a következőkkel külön sorban:

JSR SETLFS

A rutin a különböző számokat megfelelően elhelyezi a fájltáblázataikban.

Az operációs rendszer SETNAM rutinja
Az OS SETNAM rutin úgy érhető el, hogy az OS ROM ugrótáblázatához ugorunk (JSR) a $FFBD helyen. Nem minden célhely rendelkezik fájlnévvel. Azoknál, amelyeknek van rendeltetési helyük (például a lemezen lévő fájlok), be kell állítani a fájlnevet. Tegyük fel, hogy a fájl neve „mydocum”, amely 7 bájtból áll, idézőjelek nélkül. Tételezzük fel, hogy ez a név a $C101-től a $C107-ig terjedő helyeken van (beleértve), és a $07 hossza a $C100 helyen van. A karakterláncok kezdőcíme: $C101. A kezdőcím alsó bájtja $01, a magasabb bájt pedig $C1.

A SETNAM rutin meghívása előtt a programozónak be kell helyeznie a $07 (karakterlánc hossza) számot a µP akkumulátorba. A $01 kezdőcímének alsó bájtja a µP X regiszterbe kerül. A $C1 karakterlánc kezdőcímének magasabb bájtja kerül a µP Y regiszterbe. Az alprogramot egyszerűen a következőkkel hívják:

JSR SETNAM

A SETNAM rutin a három regiszter értékeit társítja a csatornához. Az értékeknek ezután nem kell a regiszterekben maradniuk. Ha a csatornának nincs szüksége fájlnévre, a programozónak 00 dollárt kell tennie a µP akkumulátorba. Ebben az esetben az X és Y regiszterben lévő értékek figyelmen kívül maradnak.

Az OS OPEN rutin
Az OS OPEN rutin úgy érhető el, hogy az OS ROM ugrótáblájára ugrunk (JSR) $FFC0 értéknél. Ez a rutin a logikai fájlszámot, az eszközszámot (és a puffert), egy lehetséges másodlagos címet és egy lehetséges fájlnevet használja, hogy kapcsolatot biztosítson a commodore számítógép és a külső eszközön lévő fájl vagy maga a külső eszköz között.

Ez a rutin, mint az összes többi Commodore OS ROM rutin, nem vitatkozik. Bár µP regisztereket használ, egyik regisztert sem kellett argumentumokkal (értékekkel) előre feltölteni. A kódoláshoz csak írja be a következőt a SETLFS és a SETNAM meghívása után:

JSR OPEN

Hibák fordulhatnak elő az OPEN rutinnal. Például előfordulhat, hogy a fájl nem található olvasásra. Hiba esetén a rutin meghiúsul, és a megfelelő hibaszámot behelyezi az µP akkumulátorba, és beállítja az µP állapotregiszter átviteli jelzőjét (1-re). Az alábbi táblázat a hibaszámokat és azok jelentését tartalmazza:

5.51. táblázat
Kernal hibaszámok és jelentésük az OS ROM OPEN rutinhoz
Hiba száma Leírás Példa
1 TÚL SOK FÁJL NYITÁS, ha már tíz fájl megnyílik
2 FÁJL MEGNYITÁS OPEN 1,3: OPEN 1,4
3 A FÁJL NINCS MEGNYITVA PRINT#5 OPEN nélkül
4 FÁJL NEM TALÁLHATÓ BETÖLTÉS „NONEXISTENF”,8
5 AZ ESZKÖZ NINCS JELEN NYITÁS 11,11: NYOMTATÁS#11
6 NEM BEMENETI FÁJL „SEQ,S,W” NYITÁSA: GET#8,X$
7 NEM KIMENETI FÁJL NYITÁS 1,0: NYOMTATÁS#1
8 HIÁNYZIK FÁJLNÉV BETÖLTÉS „”,8
9 ILLEGÁLIS KÉSZÜLÉK SZ. BETÖLTÉS „PROGRAM”,3

Ez a táblázat úgy van bemutatva, ahogy az olvasó valószínűleg sok más helyen is láthatja.

Az operációs rendszer CHKIN rutinja
Az OS CHKIN rutin az OS ROM ugrótáblázatához való ugrással (JSR) érhető el $FFC6 értéknél. Egy fájl (logikai fájl) megnyitása után el kell dönteni, hogy a megnyitás bemenetre vagy kimenetre szolgál. A CHKIN rutin a megnyitást bemeneti csatornává teszi. Ennek a rutinnak ki kell olvasnia a logikai fájlszámot a µP X regiszterből. Tehát a programozónak be kell írnia a logikai fájl számát az X regiszterbe, mielőtt meghívná ezt a rutint. Egyszerűen így hívják:

JSR CHKIN

Az operációs rendszer CHKOUT rutinja
Az OS CHKOUT rutin az OS ROM ugrótáblázatához való ugrással (JSR) érhető el $FFC9 értéknél. Egy fájl (logikai fájl) megnyitása után el kell dönteni, hogy a megnyitás bemenetre vagy kimenetre szolgál. A CHKOUT rutin a megnyitást kimeneti csatornává teszi. Ennek a rutinnak ki kell olvasnia a logikai fájlszámot a µP X regiszterből. Tehát a programozónak be kell írnia a logikai fájl számát az X regiszterbe, mielőtt meghívná ezt a rutint. Egyszerűen így hívják:

JSR CHKOUT

Az OS CLOSE rutin
Az OS CLOSE rutin úgy érhető el, hogy az OS ROM ugrótáblázatára ugrunk (JSR) a $FFC3 helyen. A logikai fájl megnyitása és a bájtok továbbítása után a logikai fájlt be kell zárni. A logikai fájl bezárása felszabadítja a puffert a rendszeregységben, hogy más, még megnyitásra váró logikai fájl használhassa. A három fájltáblázat megfelelő paraméterei is törlődnek. A megnyitott fájlok számának RAM-helye 1-gyel csökken.

Amikor a számítógépet bekapcsolják, az alaplapon lévő mikroprocesszor és más fő chipek (integrált áramkörök) hardveres alaphelyzetbe állítása történik meg. Ezt követi néhány RAM memóriahely és egyes regiszterek inicializálása az alaplap egyes chipjein. Az inicializálási folyamat során a 0. oldalon lévő $0098 cím bájtos memóriahelye NFILES vagy LDTND címkével van megadva, az operációs rendszer verziójától függően. Amíg a számítógép működik, ez a 8 bites egybájtos hely tartalmazza a megnyitott logikai fájlok számát és az egymást követő három fájltábla kezdőcím-indexét. Más szóval, ez a bájt rendelkezik a megnyitott fájlok számával, amely 1-gyel csökken a logikai fájl bezárásakor. Amikor a logikai fájl be van zárva, a terminál (cél) eszközhöz vagy a lemezen lévő tényleges fájlhoz már nem lehet hozzáférni.

Egy logikai fájl bezárásához a programozónak be kell írnia a logikai fájl számát a µP akkumulátorba. Ez ugyanaz a logikai fájlszám, amelyet a fájl megnyitásakor használnak. A CLOSE rutinnak szüksége van rá az adott fájl bezárásához. Más OS ROM rutinokhoz hasonlóan a CLOSE rutin nem vesz fel argumentumot, bár az akkumulátorból használt érték némileg argumentum. Az assembly nyelvű utasítássor egyszerűen a következő:

JSR ZÁRVA

Az egyéni vagy előre meghatározott 6502-es assembly nyelvi szubrutinok (rutinok) nem vesznek fel argumentumokat. Az érvek azonban informálisan jönnek azáltal, hogy az alprogram által használt értékeket a mikroprocesszor-regiszterekbe helyezik.

A CLRCHN rutin
Az operációs rendszer CLRCHN rutinja az OS ROM ugrótáblázatához való ugrással (JSR) érhető el a $FFCC helyen. A CLRCHN a CLEaR CHanneL rövidítése. A logikai fájl bezárásakor a logikai fájlszám, az eszközszám és a lehetséges másodlagos cím paraméterei törlődnek. Tehát a logikai fájl csatornája törlődik.

A kézikönyv azt mondja, hogy az OS CLRCHN rutinja törli az összes megnyitott csatornát, és visszaállítja az alapértelmezett eszközszámokat és egyéb alapértelmezett értékeket. Ez azt jelenti, hogy a periféria eszközszáma módosítható? Hát nem egészen. Az operációs rendszer inicializálása során a $0099 cím bájthelye a DFLTI címkével együtt kerül megadásra, hogy a számítógép működése közben az aktuális bemeneti eszköz számát tartalmazza. A commodore-64 egyszerre csak egy perifériához férhet hozzá. Az operációs rendszer inicializálása során a $009A cím bájthelye a DFLTO címkével együtt kerül megadásra, amely tartalmazza az aktuális kimeneti eszköz számát, amikor a számítógép működik.

A CLRCHN szubrutin meghívásakor a DFLTI változót 0-ra ($00) állítja, amely az alapértelmezett beviteli eszközszám (billentyűzet). A DFLTO változót 3-ra állítja ($03), amely az alapértelmezett kimeneti eszközszám (képernyő). A többi eszközszám-változó is hasonlóan visszaáll. Ez a bemeneti/kimeneti eszközök normál (alapértelmezett értékek) visszaállításának (vagy visszaállításának) jelentése.

A Commodore-64 kézikönyv azt mondja, hogy a CLRCHN rutin meghívása után a megnyitott logikai fájlok nyitva maradnak, és továbbra is továbbíthatják a bájtokat (adatokat). Ez azt jelenti, hogy a CLRCHN rutin nem törli a megfelelő bejegyzéseket a fájltáblázatokból. A CLRCHN név jelentése meglehetősen kétértelmű.

5.6 A karakter elküldése a képernyőre

A karakterek és grafikák képernyőn történő megjelenítését kezelő fő integrált áramkört (IC) Video Interface Controller-nek (chipnek) hívják, amelynek rövidítése a Commodore-64-ben VIC (valójában VIC II a VIC 2-es verziójához). Ahhoz, hogy egy információ (értékek) a képernyőre kerüljön, át kell haladnia a VIC II-n, mielőtt elérné a képernyőt.

A képernyő 25 sorból és 40 oszlopból áll, karaktercellákból. Ez 40 x 25 = 1000 karaktert tesz ki, amely megjeleníthető a képernyőn. A VIC II beolvassa a megfelelő 1000 memória RAM egymást követő bájthelyeit a karakterek számára. Ezt az 1000 helyet együtt képernyőmemóriának nevezik. Ami ebbe az 1000 helyre kerül, azok a karakterkódok. A Commodore-64 esetében a karakterkódok eltérnek az ASCII-kódoktól.

A karakterkód nem karakterminta. Létezik az úgynevezett karakter-ROM is. A karakter-ROM mindenféle karaktermintából áll, amelyek egy része megegyezik a billentyűzeten lévő karaktermintákkal. A karakter-ROM eltér a képernyőmemóriától. Amikor egy karaktert meg kell jeleníteni a képernyőn, a karakterkód a képernyőmemória 1000 pozíciója közül egy helyre kerül. Innentől a képernyőn megjelenítendő karakter-ROM-ból kiválasztható a megfelelő minta. A helyes minta kiválasztását a karakter-ROM-ban egy karakterkódból a VIC II (hardver) végzi.

A $D000 és $DFFF közötti számos memóriahelynek két célja van: a képernyőn kívüli bemeneti/kimeneti műveletek kezelésére használják, vagy karakter-ROM-ként használják a képernyőhöz. Két memóriablokkról van szó. Az egyik a RAM, a másik a ROM a karakter ROM-hoz. A bankok cseréje a bemeneti/kimeneti vagy a karakterminták (karakter ROM) kezelésére szoftverrel történik (az operációs rendszer rutinja a ROM-ban $F000-tól $FFFF-ig).

jegyzet : A VIC regiszterekkel rendelkezik, amelyek a memóriaterület címei a $D000 és a $DFFF tartományon belül vannak.

A CHROUT rutin
Az OS CHROUT rutin az OS ROM ugrótáblázatára való ugrással (JSR) érhető el $FFD2 helyen. Ez a rutin, ha hívják, elveszi azt a bájtot, amelyet a programozó betett a µP akkumulátorba, és kinyomtatja a képernyőn, ahol a kurzor van. Az „E” karakter kinyomtatására szolgáló kódszegmens például a következő:

LDA #$05
CHROUT

A 0516 nem az „E” ASCII-kódja. A Commodore-64 saját karakterkódokkal rendelkezik a képernyőhöz, ahol a 05 dollár jelentése „E”. A #$05 szám a képernyőmemóriába kerül, mielőtt a VIC a képernyőre küldené. Ennek a két kódsornak a csatorna beállítása, a logikai fájl megnyitása és a CHKOUT rutin meghívása után kell megjelennie. A teljes kód:

; Csatorna beállítása
LDA #$40 ; logikai fájlszám
LDX #$03 ; A képernyő eszközszáma 03 USD
LDY #$FF ; nincs másodlagos cím
JSR SETLFS ; megfelelő csatorna beállítása
; nincs SETNAM, mivel a képernyőnek nincs szüksége névre
;
; Nyissa meg a logikai fájlt
JSR OPEN
; Állítsa be a kimeneti csatornát
LDX #$40 ; logikai fájlszám
JSR CHKOUT
;
; Kimeneti karakter a képernyőre
LDA #$05
JSR CHROUT
; Zárja be a logikai fájlt
LDA #40 dollár
JSR ZÁRVA

A nyílást be kell zárni egy másik program futtatása előtt. Tegyük fel, hogy a számítógép felhasználója beír egy karaktert a billentyűzetre, amikor az elvárható. A következő program egy karaktert nyomtat a billentyűzetről a képernyőre:

; Csatorna beállítása
LDA #$40 ; logikai fájlszám
LDX #$03 ; A képernyő eszközszáma 03 USD
LDY #$FF ; nincs másodlagos cím
JSR SETLFS ; megfelelő csatorna beállítása
; nincs SETNAM, mivel a képernyőnek nincs szüksége névre
;
; Nyissa meg a logikai fájlt
JSR OPEN
; Állítsa be a kimeneti csatornát
LDX #$40 ; logikai fájlszám
JSR CHKOUT
;
; Char bevitele a billentyűzetről
VÁRJ JSR GETIN ; 00 dollárt tesz az A-ba, ha a billentyűzetsor üres
CMP #$00 ; Ha 00 dollár került A-ba, akkor Z az összehasonlítással 1
BEQ VÁRJ ; GETIN ismét a sorból, ha a 0 az akkumulátorba került
BNE PRNSCRN ; menjen a PRNSCRN-be, ha Z 0, mert A-nak már nincs 00 dollárja
; Kimeneti karakter a képernyőre
PRNSCRN JSR CHROUT ; küldje el az A karaktert a képernyőre
; Zárja be a logikai fájlt
LDA #40 dollár
JSR ZÁRVA

jegyzet : A WAIT és a PRNSCRN a címeket azonosító címkék. A billentyűzetről az µP akkumulátorba érkező bájt ASCII kód. A Commodore-64 által a képernyőre küldendő kódnak eltérőnek kell lennie. Ezt az előző program az egyszerűség kedvéért nem vette figyelembe.

5.7 Bájtok küldése és fogadása lemezmeghajtóhoz

A Commodore-64 rendszeregységében (alaplapján) két VIA #1 és CIA #2 nevű komplex interfész adapter található. Mindegyik CIA-nak két párhuzamos portja van, amelyeket A és B portnak neveznek. A Commodre-64 rendszeregység hátulján a függőleges felületen van egy külső port, amelyet soros portnak neveznek. Ennek a portnak 6 érintkezője van, amelyek közül az egyik adatátvitelre szolgál. Az adatok sorosan lépnek be vagy hagyják el a rendszeregységet, bitenként.

A CIA #2 belső A portjából például nyolc párhuzamos bit kiléphet a rendszeregységből a külső soros porton keresztül, miután a CIA eltolási regisztere soros adatokká alakítja őket. A nyolc bites soros adatok a külső soros portról a CIA #2 belső A portjába kerülhetnek, miután a CIA eltolási regisztere párhuzamos adatokká alakítja őket.

A Commodore-64 rendszeregység (alapegység) külső lemezmeghajtót használ hajlékonylemezzel. Ehhez a lemezmeghajtóhoz egy nyomtatót lehet láncos módon csatlakoztatni (az eszközöket sorba kötve karakterláncként). A lemezmeghajtó adatkábele a Commodore-64 rendszeregység külső soros portjához csatlakozik. Ez azt jelenti, hogy ugyanahhoz a soros porthoz egy láncos nyomtató is csatlakozik. Ezt a két készüléket két különböző eszközszám azonosítja (jellemzően 8 és 4).

A lemezmeghajtó adatainak küldése vagy fogadása a korábban leírtak szerint történik. Azaz:

  • A logikai fájl nevének (számának) beállítása, amely megegyezik a tényleges lemezfájl nevével a SETNAM rutin segítségével.
  • A logikai fájl megnyitása az OPEN rutin segítségével.
  • Annak eldöntése, hogy a CHKOUT vagy a CHKIN rutin segítségével be- vagy kimenet.
  • Az adatok küldése vagy fogadása STA és/vagy LDA utasítással.
  • A logikai fájl bezárása a CLOSE rutin segítségével.

A logikai fájlt be kell zárni. A logikai fájl bezárása gyakorlatilag bezárja az adott csatornát. A lemezmeghajtó csatornájának beállításakor a logikai fájl számát a programozó határozza meg. Ez egy 00 USD és FF (beleértve) közötti szám. Ez nem lehet olyan szám, amelyet más eszközhöz (vagy tényleges fájlhoz) már kiválasztottak. Az eszközszám 8, ha csak egy lemezmeghajtó van. A másodlagos cím (szám) a lemezmeghajtó kézikönyvéből származik. A következő program a 2-t használja. A program „E” (ASCII) betűt ír a lemezen lévő „mydoc.doc” nevű fájlba. Feltételezzük, hogy ez a név a $C101 memóriacímmel kezdődik. Tehát a SETNAM rutin meghívása előtt a $01 alsó bájtjának az X regiszterben, a $C1 magasabb bájtjának pedig az Y regiszterben kell lennie. A SETNAM rutin meghívása előtt az A regiszternek is rendelkeznie kell a $09 számmal.

; Csatorna beállítása
LDA #$40 ; logikai fájlszám
LDX #$08 ; eszközszám az első lemezmeghajtóhoz
LDY #$02 ; másodlagos cím
JSR SETLFS ; megfelelő csatorna beállítása
;
; A lemezmeghajtón lévő fájlnak nevet kell adni (már a memóriában van)
LDA #$09
LDX #$01
LDY#$C1
JSR SETNAM
; Nyissa meg a logikai fájlt
JSR OPEN
; Állítsa be a kimeneti csatornát
LDX #$40 ; logikai fájlszám
JSR CHKOUT ;íráshoz
;
; Kimeneti karakter a lemezre
LDA 45 dollár
JSR CHROUT
; Zárja be a logikai fájlt
LDA #$40
JSR ZÁRVA

Ha egy bájtot szeretne beolvasni a lemezről a µP Y regiszterbe, ismételje meg az előző programot a következő változtatásokkal: A „JSR CHKOUT ; íráshoz”, használja a „JSR CHKIN ; olvasáshoz”. Cserélje ki a „; Kimeneti karakter a lemezre” a következővel:

; Char bevitele a lemezről
JSR CHRIS

Az OS CHRIN rutin az OS ROM ugrótáblára való ugrással (JSR) érhető el a $FFCF helyen. Ez a rutin meghívásakor egy bájtot kap a már bemeneti csatornaként beállított csatornától, és behelyezi a µP A regiszterbe. A GETIN ROM OS rutin is használható a CHRIN helyett.

Bájt küldése a nyomtatónak
A bájt nyomtatóra küldése hasonló módon történik, mint egy bájt küldése a lemezen lévő fájlba.

5.8 Az OS SAVE rutin

Az OS SAVE rutin az OS ROM ugrótáblázatára való ugrással (JSR) érhető el $FFD8 értékben. Az OS SAVE rutin a ROM-ban a memória egy részét fájlként (névvel) menti (kiírja) a lemezre. Ismerni kell a memóriában lévő szakasz kezdőcímét. Ismerni kell a szakasz végcímét is. A kezdőcím alsó bájtja a RAM nulla oldalán található, a $002B címen. A kezdőcím magasabb bájtja a következő bájtos memóriahelyre kerül a $002C címen. A nulladik oldalon a TXTTAB címke erre a két címre utal, bár a TXTTAB valójában a $002B címet jelenti. A végcím alsó bájtja a µP X regiszterbe kerül. A végcím magasabb bájtja plusz 1 kerül a µP Y regiszterbe. Az µP A regiszter a TXTTAB-hoz $2B értéket vesz fel ($002B). Ezzel a SAVE rutin a következőkkel hívható meg:

JSR SAVE

A mentendő memóriaszakasz lehet assembly nyelvű program vagy dokumentum. Egy dokumentumra példa lehet egy levél vagy egy esszé. A mentési rutin használatához a következő eljárást kell követni:

  • Állítsa be a csatornát a SETLFS rutin segítségével.
  • Állítsa be a logikai fájl nevét (számát), amely megegyezik a tényleges lemezfájl nevével a SETNAM rutin használatával.
  • Nyissa meg a logikai fájlt az OPEN rutin segítségével.
  • Tegye fájlba a kimenethez a CHKOUT használatával.
  • Ide kerül a fájl mentéséhez szükséges kód, amely „JSR SAVE”-re végződik.
  • Zárja be a logikai fájlt a CLOSE rutin segítségével.

A következő program elment egy fájlt, amely a $C101 és $C200 közötti memóriahelyektől kezdődik:

; Csatorna beállítása
LDA #$40 ; logikai fájlszám
LDX #$08 ; eszközszám az első lemezmeghajtóhoz
LDY #$02 ; másodlagos cím
JSR SETLFS ; megfelelő csatorna beállítása
;
; A lemezmeghajtóban lévő fájl neve (már a memóriában, $C301-nél)
LDA #$09 ; fájlnév hossza
LDX #$01
LDY#$C3
JSR SETNAM
; Nyissa meg a logikai fájlt
JSR OPEN
; Állítsa be a kimeneti csatornát
LDX #$40 ; logikai fájlszám
JSR CHKOUT ; az íráshoz
;
; Kimeneti fájl a lemezre
LDA #$01
STA 2B $ ; TXTTAB
LDA #$C1
STA $2C
LDX #$00
LDY#$C2
LDA #$2B
JSR SAVE
; Zárja be a logikai fájlt
LDA #$40
JSR ZÁRVA

Vegye figyelembe, hogy ez egy olyan program, amely a memória egy másik részét (nem a programrészt) menti lemezre (Commodore-64 lemezre).

5.9 Az OS LOAD rutinja

Az OS LOAD rutin az OS ROM ugrótáblázatához való ugrással (JSR) érhető el $FFD5 értéknél. Ha a memória egy szakaszát (nagy területét) a lemezre menti, akkor az egy fejléccel kerül mentésre, amely tartalmazza a szakasz kezdőcímét a memóriában. Az OS LOAD szubrutin egy fájl bájtjait tölti be a memóriába. Ennél a LOAD műveletnél az akkumulátor értékének 010-nek (00 $) kell lennie. Ahhoz, hogy a LOAD művelet beolvassa a kezdőcímet a lemez fejlécében, és a fájl bájtjait a RAM-ba helyezze ettől a címtől kezdve, a csatorna másodlagos címének 1-nek vagy 2-nek kell lennie (a következő program 2-t használ). Ez a rutin visszaadja a címet, valamint a betöltött legmagasabb RAM-hely 1-jét. Ez azt jelenti, hogy a RAM-ban lévő fájl utolsó címének alsó bájtja plusz 1 az µP X regiszterbe, a RAM plusz 1-es fájl utolsó címének magas bájtja pedig a µP Y regiszterbe kerül.

Ha a betöltés sikertelen, az µP A regiszter tartalmazza a hibaszámot (esetleg 4, 5, 8 vagy 9). A mikroprocesszor állapotregiszterének C jelzője is be van állítva (1-re készült). Sikeres betöltés esetén az A regiszter utolsó értéke nem számít.

Most, az online karrierkurzus előző fejezetében az assembly nyelvű program első utasítása azon a RAM-beli címen található, ahol a program elindult. Ennek nem kell ilyennek lennie. Ez azt jelenti, hogy a program első utasításának nem kell a program elején lennie a RAM-ban. A program indítási utasítása a RAM-ban lévő fájlon belül bárhol lehet. A programozónak azt tanácsoljuk, hogy az induló assembly nyelvű utasítást START-mal jelölje meg. Ezzel a program betöltése után újra lefut (végrehajtva) a következő assembly nyelvi utasítással:

JSR START

A „JSR START” az assembly nyelvű programban található, amely betölti a futtatandó programot. Egy másik assembly nyelvi fájlt betöltõ és a betöltött fájlt futtató assembly nyelv a következõ kódeljárással rendelkezik:

  • Állítsa be a csatornát a SETLFS rutin segítségével.
  • Állítsa be a logikai fájl nevét (számát), amely megegyezik a tényleges lemezfájl nevével a SETNAM rutin használatával.
  • Nyissa meg a logikai fájlt az OPEN rutin segítségével.
  • Legyen ez a beviteli fájl a CHKIN használatával.
  • A fájl betöltésének kódja ide kerül, és „JSR LOAD”-ra végződik.
  • Zárja be a logikai fájlt a CLOSE rutin segítségével.

A következő program betölt egy fájlt a lemezről, és futtatja:

; Csatorna beállítása
LDA #$40 ; logikai fájlszám
LDX #$08 ; eszközszám az első lemezmeghajtóhoz
LDY #$02 ; másodlagos cím
JSR SETLFS ; megfelelő csatorna beállítása
;
; A lemezmeghajtóban lévő fájl neve (már a memóriában, $C301-nél)
LDA #$09 ; fájlnév hossza
LDX #$01
LDY#$C3
JSR SETNAM
; Nyissa meg a logikai fájlt
JSR OPEN
; Állítsa be a bemeneti csatornát
LDX #$40 ; logikai fájlszám
JSR CHKIN ; olvasáshoz
;
; Beviteli fájl a lemezről
LDA #$00
JSR LOAD
; Zárja be a logikai fájlt
LDA #$40
JSR ZÁRVA
; Indítsa el a betöltött programot
JSR START

5.10 A modem és az RS-232 szabvány

A modem egy olyan eszköz (periféria), amely a számítógép bitjeit a megfelelő elektromos audiojelekké alakítja, amelyeket a telefonvonalon továbbítanak. A fogadó oldalon egy modem található a fogadó számítógép előtt. Ez a második modem az elektromos audiojeleket bitekké alakítja át a fogadó számítógép számára.

A modemet egy külső porton (a számítógép függőleges felületén) kell a számítógéphez csatlakoztatni. Az RS-232 szabvány egy adott típusú csatlakozóra vonatkozik, amely a modemet a számítógéphez csatlakoztatja (a múltban). Más szóval, a múltban sok számítógépnek volt külső portja, amely RS-232 vagy RS-232-kompatibilis csatlakozó volt.

A Commodore-64 rendszeregységnek (számítógépnek) van egy külső portja a hátsó függőleges felületén, amelyet felhasználói portnak neveznek. Ez a felhasználói port RS-232 kompatibilis. Ide modemes eszköz csatlakoztatható. A Commodore-64 ezen a felhasználói porton keresztül kommunikál modemmel. A Commodore-64 ROM operációs rendszere szubrutinokat tartalmaz a modemmel való kommunikációhoz, az úgynevezett RS-232 rutinokat. Ezeknek a rutinoknak vannak bejegyzései az ugrótáblázatban.

Átviteli sebesség
A számítógép nyolc bites bájtja nyolc bites sorozattá alakul, mielőtt elküldi a modemhez. Fordítva történik a modemtől a számítógépig. Az adatátviteli sebesség a másodpercenként sorosan továbbított bitek száma.

A memória alja
A „Memória alja” kifejezés nem a $0000 cím memóriabájtjának helyére vonatkozik. A RAM legalacsonyabb helyére utal, ahová a felhasználó elkezdheti elhelyezni adatait és programjait. Alapértelmezés szerint 0800 dollár. Emlékezzünk vissza az előző beszélgetésből, hogy a 0800 USD és a BFFF USD közötti helyek nagy részét a BASIC számítógépes nyelv és annak programozói (felhasználói) használják. Csak a $C000-tól $CFFF-ig terjedő címhelyek maradnak meg az assembly nyelvi programok és adatok számára; ez 4 Kbyte a memória 64 Kbyte-jából.

A memória teteje
Abban az időben, amikor az ügyfelek megvásárolták a Commodore-64 számítógépeket, némelyikhez nem érkezett minden memóriahely. Az ilyen számítógépek ROM-mal rendelkeztek az operációs rendszerrel E000 dollártól FFFF dollárig. RAM-juk volt 0000 dollártól egy limitig, ami nem DFFF dollár, az E000 dollár mellett. A limit $DFFF alatt volt, és ezt a korlátot „Top of Memory”-nak nevezik. Tehát a memória teteje nem a $FFFF helyre utal.

Commodore-64 pufferek RS-232 kommunikációhoz
Puffer átvitele
Az RS-232 átvitel (kimenet) puffere 256 bájtot foglal el a memória tetejétől lefelé. Az átviteli puffer mutatója ROBUF címkével van ellátva. Ez a mutató a nulla oldalon van, a $00F9 címekkel, majd a $00FA-val. A ROBUF valójában $00F9-et azonosít. Tehát, ha a puffer kezdetének címe $BE00, akkor a $BE00 alsó bájtja, ami $00, a $00F9 helyen van, és a $BE00 magasabb bájtja, ami $BE, a $00FA. elhelyezkedés.

Puffer fogadása
Az RS-232 bájt (bemenet) fogadására szolgáló puffer 256 bájtot vesz el az átviteli puffer aljáról. A fogadó puffer mutatója RIBUF címkével van ellátva. Ez a mutató a nulladik oldalon van, ahol a $00F7 címek, majd a $00F8. A RIBUF valójában $00F7-et azonosít. Tehát, ha a puffer kezdetének címe $BF00, akkor a $BF00 alsó bájtja, ami $00, a $00F7 helyen van, és a $BF00 magasabb bájtja, ami $BF, a $00F8. elhelyezkedés. Tehát a felső memória 512 bájtja a teljes RS-232 RAM puffer.

RS-232 csatorna
Ha egy modem a (külső) felhasználói porthoz csatlakozik, a modemmel folytatott kommunikáció csak RS-232 kommunikáció. A teljes RS-232 csatorna létrehozásának folyamata majdnem ugyanaz, mint az előző tárgyalásban, de van egy fontos különbség: a fájlnév egy kód, és nem egy karakterlánc a memóriában. A $0610 kód jó választás. 300 bit/sec adatátviteli sebességet és néhány egyéb műszaki paramétert jelent. Ezenkívül nincs másodlagos cím. Vegye figyelembe, hogy az eszköz száma 2. A teljes RS-232 csatorna beállításának folyamata a következő:

  • Csatorna beállítása SETLFS rutinnal.
  • A logikai fájl nevének beállítása, $0610.
  • A logikai fájl megnyitása az OPEN rutin segítségével.
  • A CHKOUT használatával kimeneti fájlként vagy a CHKIN használatával történő bevitelhez szükséges fájlként.
  • Az egyes bájtok küldése a CHROUT segítségével vagy az egyes bájtok fogadása a GETIN segítségével.
  • A logikai fájl bezárása a CLOSE rutin segítségével.

Az OS GETIN rutin az OS ROM ugrótáblázatához való ugrással (JSR) érhető el $FFE4 helyen. Ez a rutin meghívásakor veszi a vevő pufferbe küldött bájtot, és a µP akkumulátorba helyezi (visszaküldi).

A következő program az „E” (ASCII) bájtot küldi a modemnek, amely a felhasználói RS-232 kompatibilis porthoz csatlakozik:

; Csatorna beállítása
LDA #$40 ; logikai fájlszám
LDX #$02 ; eszközszám az RS-232-hez
LDY #$FF ; nincs másodlagos cím
JSR SETLFS ; megfelelő csatorna beállítása
;
; Az RS-232 neve egy kód, pl. 0610 dollár
LDA #$02 ; a kód hossza 2 bájt
LDX #10 dollár
LDY #$06
JSR SETNAM
;
; Nyissa meg a logikai fájlt
JSR OPEN
; Állítsa be a kimeneti csatornát
LDX #$40 ; logikai fájlszám
JSR CHKOUT
;
; Kimeneti karakter RS-232-re pl. modem
LDA 45 dollár
JSR CHROUT
; Zárja be a logikai fájlt
LDA #40 dollár
JSR ZÁRVA

Egy bájt fogadásához a kód nagyon hasonló, kivéve, hogy a „JSR CHKOUT” helyett „JSR CHKIN” lép, és:

LDA 45 dollár
JSR CHROUT

helyébe a „JSR GETIN” lép, és az eredmény az A regiszterbe kerül.

A bájtok folyamatos küldését vagy fogadását a kódszegmens küldésére vagy fogadására szolgáló hurok végzi.

Vegye figyelembe, hogy a Commodore bemenete és kimenete a legtöbb esetben hasonló, kivéve a billentyűzetet, ahol a rutinok egy részét nem a programozó hívja meg, hanem az operációs rendszer.

5.11 Számlálás és időzítés

Tekintsük a visszaszámlálási sorrendet, amely a következő:

2, 1, 0

Ez a visszaszámlálás 2-ről 0-ra. Most nézzük meg az ismétlődő visszaszámlálási sorrendet:

2, 1, 0, 2, 1, 0, 2, 1, 0, 2, 1, 0

Ez ugyanazon sorozat ismétlődő visszaszámlálása. A sorozat négyszer megismétlődik. A négyszer azt jelenti, hogy az időzítés 4. Egy sorozaton belül a számolás. Ugyanennek a sorozatnak az ismétlése az időzítés.

A Commodore-64 rendszeregységében két Complex Interface Adapter található. Mindegyik CIA-nak két számláló/időzítő áramköre van, amelyek neve A Timer (TA) és B időzítő (TB). A számláló áramkör nem különbözik az időzítő áramkörtől. A Commodore-64 számlálója vagy időzítője ugyanerre utal. Valójában mindegyik lényegében egy 16 bites regiszterre vonatkozik, amely mindig 0-ig számol vissza a rendszer órajel impulzusainál. A 16 bites regiszterbe különböző értékeket lehet beállítani. Minél nagyobb az érték, annál tovább tart a visszaszámlálás nulláig. Minden alkalommal, amikor az egyik időzítő nulla fölé megy, a IRQ megszakítási jelet küld a mikroprocesszornak. Ha a számlálás nulla fölé megy, azt alulcsordulásnak nevezzük.

Az időzítő áramkör programozásától függően az időzítő egyszeri vagy folyamatos üzemmódban futhat. Az előző ábrán az egyszeri mód azt jelenti, hogy „csinál 2, 1, 0” és állj le, miközben az óra impulzusai folytatódnak. A folyamatos mód a következőhöz hasonló: '2, 1, 0, 2, 1, 0, 2, 1, 0, 2, 1, 0 stb.' amely az óra impulzusaival folytatódik. Ez azt jelenti, hogy ha nulla fölé megy, ha nem adunk utasítást, a visszaszámlálási sorozat megismétlődik. A legnagyobb szám általában jóval nagyobb, mint 2.

A CIA #1 A (TA) időzítő generál IRQ rendszeres időközönként (időtartam) a billentyűzet szervizelésére. Valójában ez alapértelmezés szerint minden 1/60 másodperc. IRQ 1/60 másodpercenként küldi el a mikroprocesszornak. Csak akkor, amikor IRQ A program elküldi, hogy egy program ki tud olvasni egy kulcsértéket a billentyűzetsorból (puffer). Ne feledje, hogy a mikroprocesszornak csak egy érintkezője van IRQ jel. A mikroprocesszornak is csak egy tűje van a NMI jel. Az ¯NMI jel a mikroprocesszorhoz mindig a CIA #2-től érkezik.

A 16 bites időzítő regiszternek két memóriacíme van: egy az alacsonyabb bájthoz és egy a magasabb bájthoz. Mindegyik CIA-nak két időzítő áramköre van. A két CIA azonos. CIA #1 esetén a két időzítő címe: DC04 és DC05 a TA és DC06 és DC07 a TB esetében. A 2. CIA esetében a két időzítő címe: DD04 és DD05 a TA esetében, valamint DD06 és DD07 a TB esetében.

Tegyük fel, hogy a 25510-es számot el kell küldeni a CIA #2 TA időzítőjének visszaszámlálás céljából. 25510 = 00000000111111112 tizenhat bitből áll. 00000000111111112 = 000 USD FFF hexadecimális. Ebben az esetben a $FF a $DD04 címre, a $00 pedig a $DD05 címre kerül a regiszterbe – ez kevés. A következő kódszegmens elküldi a számot a regiszternek:

LDA #$FF
ÁLLAM DD04 $
LDA #$00
ÁLLAM DD05 USD

Bár a CIA regisztereinek van RAM-címe, fizikailag a CIA-ban vannak, és a CIA a RAM-tól vagy ROM-tól különálló IC.

Ez még nem minden! Ha az időzítő kapott egy számot a visszaszámláláshoz, például az előző kóddal, a visszaszámlálás nem indul el. A visszaszámlálás akkor kezdődik, amikor egy nyolc bites bájtot küldtek az időzítő megfelelő vezérlőregiszterébe. Ennek a bájtnak az első bitje a vezérlőregiszter számára jelzi, hogy el kell-e indulnia a visszaszámlálásnak. Ennek az első bitnek a 0 értéke a visszaszámlálás leállítását jelenti, míg az 1-es érték a visszaszámlálás megkezdését jelenti. A bájtnak azt is jeleznie kell, hogy a visszaszámlálás egyszeri (egyszeri) vagy szabadfutás módban (folyamatos üzemmód) történik. Az egyszeri üzemmód visszaszámlál, és leáll, ha az időzítő regiszter értéke nulla lesz. A szabad futás módban a visszaszámlálás megismétlődik a 0 elérése után. A vezérlőregiszterbe küldött bájt negyedik (index 3) bitje jelzi a módot: a 0 a szabad futási módot, az 1 az egyszeri üzemmódot jelenti.

A megfelelő szám az egylövés módban történő számolás megkezdéséhez a 000010012 = 09 USD hexadecimális formában. A szabad futási módban a számolás megkezdéséhez megfelelő szám a 000000012 = 01 $ hexadecimális formában. Minden időzítőregiszter saját vezérlőregiszterrel rendelkezik. A CIA #1-ben az A időzítő vezérlőregiszterének RAM-címe DC0E16, a B időzítő vezérlőregiszterének pedig DC0F16 RAM-címe. A CIA #2-ben az A időzítő vezérlőregiszterének RAM-címe DD0E16, a B időzítő vezérlőregiszterének pedig DD0F16 RAM-címe. A 16 bites szám visszaszámlálásához a CIA #2 TA-jában, egyszeri módban, használja a következő kódot:

LDA #$09
STA $DD0E

A 16 bites szám visszaszámlálásához a CIA #2 TA-jában szabadon futó módban használja a következő kódot:

LDA #$01
STA $DD0E

5.12 Az IRQ és NMI Kérések

A 6502 mikroprocesszor a IRQ és NMI vonalak (csapok). A CIA #1 és a CIA #2 egyaránt rendelkezik a IRQ pin a mikroprocesszorhoz. A IRQ A CIA #2 pin csatlakozik a NMI a µP tűje. A IRQ A CIA #1 pin csatlakozik a IRQ a µP tűje. Ez az egyetlen két megszakítási vonal, amely összeköti a mikroprocesszort. Így a IRQ A 2. számú CIA tűje az NMI forrás, és ¯NMI vonalként is látható.

A CIA #1 öt lehetséges azonnali forrással rendelkezik a IRQ jel a µP-hez. A 2. számú CIA felépítésében megegyezik az 1. CIA-val. Tehát a CIA #2-nek ugyanaz az öt lehetséges azonnali forrása van a megszakítási jel generálására, ami a NMI jel. Ne feledje, hogy amikor a µP megkapja a NMI jelet, ha kezeli a IRQ kérésére felfüggeszti, és kezeli a NMI kérés. Amikor befejezi a kezelést NMI kérésére, akkor folytatja a kezelését IRQ kérés.

A CIA #1 általában kívülről csatlakozik a billentyűzethez és egy játékeszközhöz, például egy joystickhoz. A billentyűzet többet használ a CIA #1 A portjából, mint a B portból. A játékeszköz többet használ a CIA #1 B portból, mint az A portja. A CIA #2 általában kívülről csatlakozik a lemezmeghajtóhoz (a nyomtatóhoz láncolva) és a modem. A lemezmeghajtó többet használ a CIA #2 A portjából (bár a külső soros porton keresztül), mint a B portjából. A modem (RS-232) többet használ a CIA #2 B portból, mint az A portjából.

Mindezek mellett honnan tudja a rendszeregység, hogy mi okozza a IRQ vagy NMI megszakítani? A CIA #1 és CIA #2 öt azonnali megszakítási forrással rendelkezik. Ha a megszakítási jel a µP-hez az NMI , a forrás egyike a CIA 2. számú közvetlen öt forrásának. Ha a megszakítási jel a µP-hez az IRQ , a forrás egyike a CIA 1. számú közvetlen öt forrásának.

A következő kérdés: „Hogyan tesz különbséget a rendszeregység az egyes CIA öt közvetlen forrása között?” Minden CIA-nak van egy nyolc bites regisztere, amelyet Interrupt Control Register (ICR) néven neveznek. Az ICR a CIA mindkét kikötőjét szolgálja ki. Az alábbi táblázat a megszakításvezérlő regiszter nyolc bitjének jelentését mutatja, a 0. bittől kezdve:

5.13. táblázat
Megszakítási vezérlőregiszter
Bit index Jelentése
0 Állítsa be (1 készült) az A időzítő alulcsordulásával
1 A B időzítő alulcsordulása állítja be
2 Állítsa be, hogy a Time-Of-Day órája mikor egyenlő az ébresztéssel
3 Állítsa be, ha a soros port megtelt
4 Külső eszköz állítja be
5 Nem használt (0 készült)
6 Nem használt (0 készült)
7 Állítsa be, ha az első öt bit bármelyike ​​be van állítva

Amint a táblázatból látható, minden közvetlen forrást az első öt bit egyike képvisel. Tehát amikor a megszakítási jel µP-n érkezik, a kódot végre kell hajtani, hogy beolvassuk a megszakításvezérlő regiszter tartalmát, hogy megtudjuk a megszakítás pontos forrását. A CIA #1 ICR RAM-címe DC0D16. A CIA #2 ICR RAM-címe DD0D16. A CIA #1 ICR tartalmának a µP akkumulátorba való olvasásához (visszaküldéséhez) írja be a következő utasítást:

LDA$DC0D

A CIA #2 ICR tartalmának a µP akkumulátorba való olvasásához (visszaküldéséhez) írja be a következő utasítást:

LDA $DD0D

5.13 Megszakítás vezérelt háttérprogram

A billentyűzet általában 1/60 másodpercenként megszakítja a mikroprocesszort. Képzelje el, hogy egy program fut, és eléri azt a pozíciót, hogy várjon egy billentyűre a billentyűzetről, mielőtt folytatná az alábbi kódrészletekkel. Tételezzük fel, hogy ha nem nyomunk le gombot a billentyűzetről, akkor a program csak egy kis ciklust hajt végre, és egy billentyűre vár. Képzelje el, hogy a program fut, és éppen a billentyűzet megszakítása után várt egy billentyűt a billentyűzettől. Ekkor az egész számítógép közvetve leáll, és nem csinál mást, csak a várakozási hurok ciklusát. Képzelje el, hogy a billentyűzet egy billentyűjét közvetlenül a következő billentyűzetmegszakítás következő kiadása előtt nyomják meg. Ez azt jelenti, hogy a számítógép körülbelül egy hatvanad másodpercig nem csinált semmit! Ez hosszú idő ahhoz, hogy egy számítógép ne csináljon semmit, még a Commodore-64 idejében sem. A számítógép mást is csinálhatott ezalatt (időtartam). Sok ilyen időtartam van egy programban.

Egy második program is írható úgy, hogy ilyen „tétlen” időtartamok alatt működjön. Egy ilyen program állítólag a fő (vagy első) program hátterében működik. Ennek egy egyszerű módja, ha egy módosított BRK megszakításkezelést kényszerítünk be, amikor billentyűt várunk a billentyűzettől.

Mutató a BRK utasításhoz
A RAM egymást követő helyén a $0316 és a $0317 címek a mutató (vektor) a tényleges BRK utasítás rutinhoz. Az alapértelmezett mutató akkor kerül oda, amikor a számítógépet a ROM-ban lévő operációs rendszer bekapcsolja. Ez az alapértelmezett mutató egy olyan cím, amely továbbra is az operációs rendszer ROM-jában található alapértelmezett BRK utasításkezelőre mutat. A mutató egy 16 bites cím. A mutató alsó bájtja a $0306 cím bájthelyére, a mutató magasabb bájtja pedig a $0317 bájt helyére kerül.

Egy második program úgy írható, hogy amikor a rendszer „tétlen”, a második program néhány kódját végrehajtja a rendszer. Ez azt jelenti, hogy a második programnak szubrutinokból kell állnia. Amikor a rendszer „tétlen” egy billentyűt vár a billentyűzetről, a második program következő alprogramja fut le. Az emberi interakció a számítógéppel lassú a rendszeregység működéséhez képest.

Ezt a problémát könnyű megoldani: Minden alkalommal, amikor a számítógépnek várnia kell egy billentyűre a billentyűzetről, illesszen be egy BRK utasítást a kódba, és cserélje ki a 0316 $ (és $ 0317) mutatót a második (és $ 0317) következő alprogramjának mutatójára. egyedi) program. Ily módon mindkét program nem sokkal hosszabb ideig futna, mint az egyedül futó fő program.

5.14 Összeállítás és összeállítás

Az assembler az összes címkét címekre cseréli. Az assembly nyelvű programokat általában úgy írják, hogy egy adott címen induljanak el. Az assembler eredményét (az összeszerelés után) „objektumkódnak” nevezzük, ahol minden binárisan van. Ez az eredmény a végrehajtható fájl, ha a fájl egy program és nem egy dokumentum. Egy dokumentum nem futtatható.

Egy alkalmazás egynél több (assembly nyelvi) programból áll. Általában van egy fő program. A helyzetet nem szabad összetéveszteni a megszakításvezérelt háttérprogramok helyzetével. Itt minden program előtérben van, de van első vagy fő program.

Az assembler helyett fordítóprogramra van szükség, ha egynél több előtérbeli program van. A fordító minden programot objektumkódba állít össze. Azonban lenne egy probléma: a kódrészletek egy része átfedi egymást, mert a programokat valószínűleg különböző emberek írják. A fordító megoldása az, hogy a memóriaterület első kivételével az összes átfedő programot eltolja, hogy a programok ne fedjék egymást. Most, amikor a változók tárolásáról van szó, néhány változó címe még mindig átfedésben van. A megoldás itt az, hogy az átfedő címeket az új címekre cseréljük (kivéve az első programot), hogy többé ne fedjék egymást. Ily módon a különböző programok a memória különböző részeibe (területeibe) illeszkednek.

Mindezzel lehetséges, hogy az egyik programban lévő rutin meghívjon egy másik program rutinját. Tehát a fordító elvégzi a linkelést. A linkelés azt jelenti, hogy egy szubrutin kezdőcíme az egyik programban van, majd egy másik programban meghívja azt; mindkettő az alkalmazás részét képezi. Mindkét programnak ugyanazt a címet kell használnia ehhez. A végeredmény egy nagy objektumkód, amelyben minden binárisan (bit) található.

5.15 Program mentése, betöltése és futtatása

Az assembly nyelvet általában valamilyen szerkesztő programban írják meg (amelyet az assembler programmal együtt szállítanak). A szerkesztő program jelzi, hogy a program hol kezdődik és hol végződik a memóriában (RAM). A Commodore-64 operációs rendszer ROM-jának Kernal SAVE rutinja képes a memóriában lévő programot a lemezre menteni. Csak kiírja a memória azon szakaszát (blokkját), amely tartalmazhatja az utasításhívást a lemezre. Célszerű a SAVE hívó utasítást elválasztani a mentés alatt álló programtól, hogy a program lemezről a memóriába való betöltésekor futás közben ne menjen újra. Az assembly nyelvű program lemezről való betöltése másfajta kihívás, mivel a program nem tudja betölteni magát.

A program nem tudja betölteni magát a lemezről oda, ahol a RAM-ban kezdődik és végződik. Abban az időben a Commodore-64 rendszerint BASIC tolmácsot kapott a BASIC nyelvi programok futtatásához. A gép (számítógép) bekapcsolásakor a következő parancssorral rendeződik: READY. Innen a BASIC parancsok vagy utasítások beírása után az „Enter” billentyű lenyomásával írhatók be. A BASIC parancs (utasítás) a fájl betöltéséhez:

LOAD “fájlnév”,8,1

A parancs a BASIC lefoglalt szóval kezdődik, ami a LOAD. Ezt egy szóköz követi, majd a fájlnév idézőjelben. A 8-as eszközszámot követi, amelyet vessző előz meg. A lemez másodlagos címét, amely 1, követi, és egy vessző előzi meg. Egy ilyen fájlnál az assembly nyelvű program kezdőcíme a fájl fejlécében van a lemezen. Amikor a BASIC befejezi a program betöltését, a program utolsó RAM-címe plusz 1-e kerül visszaadásra. A „visszaadva” szó itt azt jelenti, hogy az utolsó cím plusz 1-gyel az alsó bájtja a µP X regiszterbe, az utolsó cím plusz 1-gyel magasabb bájtja pedig a µP Y regiszterbe kerül.

A program betöltése után futni kell (végre kell hajtani). A program felhasználójának ismernie kell a memóriában a végrehajtás kezdőcímét. Itt ismét egy másik BASIC programra van szükség. Ez a SYS parancs. A SYS parancs végrehajtása után az assembly nyelvű program lefut (és leáll). Futás közben, ha bármilyen bevitelre van szükség a billentyűzetről, az assembly nyelvű programnak jeleznie kell ezt a felhasználónak. Miután a felhasználó beírta az adatokat a billentyűzeten és megnyomta az „Enter” billentyűt, az assembly nyelvű program a BASIC interpreter beavatkozása nélkül a billentyűzet bevitelével tovább fut.

Feltételezve, hogy az Assembly Language Program végrehajtási (futó) RAM-címének kezdete C12316, a C123 a SYS paranccsal való használata előtt tízes alapcímre alakul át. A C12316 átalakítása tízes alapra a következő:

Tehát a BASIC SYS parancs a következő:

SYS 49443

5.16 Bootolás a Commodore-64-hez

A Commodore-64 rendszerindítása két fázisból áll: a hardver-visszaállítási fázisból és az operációs rendszer inicializálási fázisából. Az operációs rendszer a Kernal a ROM-ban (és nem a lemezen). Van egy reset vonal (valójában RES ), amely egy érintkezőhöz csatlakozik a 6502 µP-nél, és az összes speciális hajón, mint például a CIA 1, CIA 2 és VIC II ugyanazon a tűnéven. A visszaállítási fázisban ennek a sornak köszönhetően az µP-ben és a speciális chipekben lévő összes regiszter 0-ra áll vissza (minden bitnél nulla lesz). Ezt követően a mikroprocesszor hardvere a veremmutatót és a processzorállapot-regisztert a kezdeti értékekkel együtt adja meg a mikroprocesszorban. A programszámláló ezután az értékkel (címmel) kerül megadásra az $FFFC és $FFFD helyeken. Emlékezzünk vissza, hogy a programszámláló a következő utasítás címét tartalmazza. Az itt tárolt tartalom (cím) a szoftver inicializálását elindító szubrutinhoz tartozik. Eddig mindent a mikroprocesszoros hardver csinál. Ebben a fázisban nem érintik az egész emléket. Ezután kezdődik az inicializálás következő fázisa.

Az inicializálást a ROM OS egyes rutinjai végzik. Az inicializálás azt jelenti, hogy a speciális chipek egyes regisztereihez megadjuk a kezdeti vagy alapértelmezett értékeket. Az inicializálás azzal kezdődik, hogy a speciális chipek egyes regisztereihez megadjuk a kezdeti vagy alapértelmezett értékeket. IRQ például 1/60 másodpercenként kell kiadnia. Tehát a megfelelő időzítőt a CIA #1-ben az alapértelmezett értékre kell állítani.

Ezután a Kernal RAM tesztet hajt végre. Minden helyet tesztel úgy, hogy egy bájtot küld a helynek, és visszaolvassa. Ha van különbség, legalább az a hely rossz. A Kernal azonosítja a memória tetejét és a memória alját is, és beállítja a megfelelő mutatókat a 2. oldalon. Ha a memória teteje $DFFF, akkor a $FF a $0283 helyre, a $DF pedig a $0284 bájt helyre kerül. A 0283 és a 0284 dolláron egyaránt megtalálható a HIRAM felirat. Ha a memória alja 0800 $, akkor a $00 a $0281 helyre, a $08 pedig a $0282 helyre kerül. Mind a 0281, mind a 0282 dolláros LORAM felirattal rendelkezik. A RAM teszt valójában 0300 dollártól a memória (RAM) tetejéig kezdődik.

Végül a bemeneti/kimeneti vektorok (mutatók) az alapértelmezett értékükre állnak. A RAM teszt valójában 0300 dollártól a memória (RAM) tetejéig kezdődik. Ez azt jelenti, hogy a 0., az 1. és a 2. oldal inicializálva van. A 0. oldalon különösen sok az operációs rendszer ROM mutatója, a 2. oldalon pedig sok BASIC mutató található. Ezeket a mutatókat változóknak nevezzük. Ne feledje, hogy az 1. oldal a verem. A mutatókat változóknak nevezzük, mert van nevük (címkéjük). Ebben a szakaszban a képernyő memóriája törlődik a képernyő (monitor) számára. Ez azt jelenti, hogy el kell küldeni a 20 dolláros tárhely kódját (amely történetesen megegyezik a 20 dolláros ASCII kóddal) az 1000 RAM-os képernyőhelyre. Végül a Kernal elindítja a BASIC értelmezőt, hogy megjelenítse a BASIC parancssort, amely a monitor (képernyő) tetején van KÉSZ.

5.17 Problémák

Javasoljuk, hogy az olvasó az összes problémát egy fejezetben oldja meg, mielőtt a következő fejezetre lépne.

  1. Írjon egy összeállítási nyelvi kódot, amely a CIA #2 A port összes bitjét teszi ki kimenetnek és CIA #2 B portot bemenetnek.
  2. Írjon egy 6502-es összeállítású nyelvi kódot, amely a billentyűzet billentyűjére vár, amíg meg nem nyomja.
  3. Írjon egy 6502-es összeállítású nyelvi programot, amely az „E” karaktert küldi a Commodore-64 képernyőjére.
  4. Írjon egy 6502-es összeállítású nyelvi programot, amely a billentyűkódot és az időzítést figyelmen kívül hagyva kivesz egy karaktert a billentyűzetről, és elküldi a Commodore-64 képernyőjére.
  5. Írjon egy 6502-es összeállítású nyelvi programot, amely egy bájtot kap a Commodore-64 hajlékonylemezről.
  6. Írjon egy 6502-asssembly nyelvű programot, amely a Commodore-64 hajlékonylemezre menti a fájlt.
  7. Írjon egy 6502-asssembly nyelvű programot, amely betölt egy programfájlt a Commodore-64 hajlékonylemezről, és elindítja azt.
  8. Írjon egy 6502-es összeállítású nyelvi programot, amely az „E” (ASCII) bájtot küldi a modemnek, amely a Commodore-64 felhasználói RS-232 kompatibilis portjához csatlakozik.
  9. Magyarázza el, hogyan történik a számlálás és az időmérés a Commodore-64 számítógépen.
  10. Magyarázza el, hogyan tud a Commodore-64 rendszeregység azonosítani 10 különböző azonnali megszakítási kérelem forrást, beleértve a nem maszkolható megszakítási kéréseket is.
  11. Magyarázza el, hogyan futhat egy háttérprogram egy előtérbeli programmal a Commodore-64 számítógépen.
  12. Röviden magyarázza el, hogyan lehet az assembly nyelvű programokat egyetlen alkalmazásba fordítani a Commodore-64 számítógéphez.
  13. Röviden magyarázza el a Commodore-64 számítógép indítási folyamatát.