38. Skrytá pamäť: RAM pod ROM a banky 130XE
Rozšírenie action26; programy začínajú riadkom ;@modern (kapitola 35).
Na čo to je
Procesor Atari vidí naraz 64 kilobajtov. Počítač má však pamäte viac, než program bežne vidí – na dvoch miestach:
1. RAM pod ROM. Na adresách $C000–$FFFF je operačný systém v pamäti ROM. Počítače XL a XE majú na tých istých adresách aj obyčajnú pamäť RAM, len je zakrytá. Je to asi 14 kilobajtov, ktoré bežný program nevidí.
2. Banky. Atari 130XE má 128 kilobajtov. Druhých 64 je rozdelených na štyri banky po 16 kilobajtov. V jednej chvíli je vidieť jedna z nich, a to v „okne“ na adresách $4000–$7FFF, namiesto bežnej pamäte, ktorá tam inak je. Rozšírené počítače majú bánk 16 aj 64.
Prepínať medzi tým ručne je práca s registrom PORTB, zakazovaním prerušení a rizikom, že si program odpojí pamäť pod vlastnými nohami. Rutiny action26 to robia za teba.
Ako sa to píše
Všetky rutiny majú ako prvý parameter číslo banky:
- banka 0 je bežná pamäť – a v nej tieto rutiny vidia aj RAM pod ROM,
- banky 1, 2, 3 … sú banky rozšírenej pamäte; ich adresy sú
$4000–$7FFF.
| Rutina | Čo robí |
|---|---|
XBanks() | funkcia – počet bánk: 0 na obyčajnom XL, 4 na 130XE, viac na rozšírených |
XPeek(banka, adresa), XPeekC(…) | prečíta bajt / CARD |
XPoke(banka, adresa, hodnota), XPokeC(…) | zapíše bajt / CARD |
XMoveBlock(kam_banka, kam, odkiaľ_banka, odkiaľ, počet) | skopíruje blok medzi ľubovoľnými dvoma miestami |
XSetBlock(banka, adresa, počet, hodnota), XZero(banka, adresa, počet) | vyplní / vynuluje blok |
XPrint(banka, adresa, znak) | vypíše text ukončený znakom, ako PrintU |
XRead(kanál, banka, adresa, počet) | funkcia – načíta zo súboru do banky, vráti počet bajtov |
XWrite(kanál, banka, adresa, počet) | zapíše z banky do súboru |
XBank(banka) | nechá banku v okne natrvalo – dá sa potom čítať obyčajným poľom |
XAntic(banka) | ukáže banku obrazovému čipu – obrazovka z banky |
Sú to obdoby rutín Peek, Poke, MoveBlock, SetBlock, Zero a PrintU s jedným parametrom navyše.
Program 1: banky a RAM pod ROM
Súbor examples/m-banks.act:
;@modern
; Hidden memory: the banks of a 130XE and the RAM under the ROM
PROC Main()
BYTE banks, i
banks=XBanks()
Print("Banks of extended memory: ")
PrintBE(banks)
IF banks=0 THEN
PrintE("This program needs a 130XE.")
RETURN
FI
FOR i=1 TO banks ; the same address in each bank
DO
XPoke(i, $4000, i*10)
OD
Print("Address $4000 in the banks: ")
FOR i=1 TO banks
DO
PrintB(XPeek(i, $4000))
Put(' )
OD
PutE()
XPoke(0, $C000, 99) ; bank 0 is the ordinary memory, also under the ROM
Print("XPeek sees the RAM under the ROM: ")
PrintBE(XPeek(0, $C000))
RETURNPreklad a spustenie
Simulátoru treba povedať, že má byť 130XE:
action26 m-banks.act --sim --sim-mem 130xeBanks of extended memory: 4
Address $4000 in the banks: 10 20 30 40
XPeek sees the RAM under the ROM: 99Bez --sim-mem simuluje obyčajných 64 kilobajtov a program to spozná:
Banks of extended memory: 0
This program needs a 130XE.V emulátore nastav typ počítača na 130XE (v ponuke emulátora) a spusti program cez --run.
Ako to funguje
XBanks()zistí, koľko bánk počítač má. Vždy sa najprv opýtaj – program, ktorý siahne do banky, ktorá neexistuje, skončí chybou 101.- Slučka zapíše na tú istú adresu
$4000v každej banke inú hodnotu. Druhá slučka ich prečíta späť: sú štyri rôzne. To je dôkaz, že ide o štyri rôzne kusy pamäte. XPoke(0, $C000, 99)zapíše do RAM pod operačným systémom. ObyčajnýPoke($C000, 99)by nespravil nič (zápis do ROM) aPeek($C000)by vrátil bajt operačného systému.
Program 2: dáta nahrané rovno do banky
Dlhé texty a obrázky nemusia zaberať miesto v programe. S ORG adresa BANK n ich prekladač pripraví tak, že sa pri nahrávaní programu uložia rovno do banky.
Súbor examples/m-bankdata.act:
;@modern
; A text loaded into a bank together with the program
ORG $4000 BANK 1
CHAR ARRAY story="Once upon a time there was an Atari with twice the memory of the others. The upper half was hidden, and only those who knew the right register could reach it.~"
ENDORG
PROC Main()
IF XBanks()=0 THEN
PrintE("This program needs a 130XE.")
RETURN
FI
Print("The text lives in bank ")
PrintBE(BankOf(story))
XPrint(BankOf(story), story, '~)
PutE()
RETURNaction26 m-bankdata.act --sim --sim-mem 130xeThe text lives in bank 1
Once upon a time there was an Atari with twice the memory of the others. The upper half was hidden, and only those who knew the right register could reach it.Ako to funguje
ORG $4000 BANK 1 … ENDORGje blokORGz kapitoly 37 s číslom banky. RovnakoORG $C000 … ENDORG(adresa od$C000, bezBANK) uloží dáta do RAM pod ROM.- Text v takom bloku nemá dĺžkový bajt a môže byť dlhší ako 255 znakov. Ukončovací znak (
~) píšeš na jeho koniec sám. - Meno z takého bloku je len adresa.
story(3)aniPrint(story)nejdú – program dáta nevidí, kým sú v banke. Meno sa odovzdáva rutinámX…. BankOf(story)je číslo banky, v ktorejstoryleží. Keď dáta neskôr presunieš do inej banky, zvyšok programu sa nemení.
Dáta a program zvlášť
Veľké dáta sa dajú dať do samostatného súboru, aby sa program pri vývoji nahrával rýchlo:
action26 m-bankdata.act --data-only -o story.dataction26 m-bankdata.act --code-only -o story.xexNa Atari sa najprv nahrá story.dat (uloží dáta do banky a vráti sa), potom story.xex. Program s --code-only pri štarte skontroluje, či sú dáta nahrané, a ak nie, povie to a skončí.
XBank: banka ako obyčajné pole
XPeek a XPoke pri každom volaní banku zapnú a vypnú. Keď s bankou pracuješ dlhšie, je rýchlejšie nechať ju v okne:
BYTE ARRAY window(16384)=$4000 ; pole na adrese okna
XBank(2) ; v okne je banka 2
window(100)=7 ; obyčajný prístup do poľa
XBank(0) ; späť bežná pamäť
Jedno pravidlo: kým je v okne banka, nesmie v okne ležať nič z tvojho programu – ani kód, ani premenné. Program od $2000 sa do okna ($4000) dostane, až keď prerastie 8 kilobajtov. Prekladač na to upozorní varovaním ACT242.
Na čo si dať pozor
- Opýtaj sa
XBanks()skôr, než siahneš do banky. - RAM disk používa tie isté banky. Ak má používateľ v DOS-e zapnutý RAM disk, zápis do bánk mu zničí súbory.
- Adresy
$D000–$D7FFnie sú pamäť, ale registre čipov. Zápis tam cezXPokeskončí chybou 102. - Rutiny
X…sú pomalšie akoPeekaPoke; na veľké presuny použiXMoveBlock, nie slučku sXPoke.
Časté chyby
| Čo sa stalo | Čo sa stane |
|---|---|
| banka, ktorá neexistuje | Err: 101 |
| zápis do registrov alebo vektorov pod ROM | Err: 102 |
čítanie mena z bloku ORG … BANK priamo (story(0)) | error ACT243 |
program a XBank s kódom v okne | warning ACT242; program sa môže zrútiť |
| spustenie na počítači bez rozšírenej pamäte | XBanks() vráti 0 – program to má ošetriť |
Vyskúšaj si
- Spusti
m-banks.acts--sim-mem 1088– počítač s megabajtom pamäte. Koľko bánk nájde? - Ulož do banky 2 čísla 0 až 255 na adresy
$4000až$40FFa vypíš súčet toho, čo prečítaš späť. - Presuň text v druhom programe pod ROM:
ORG $C000 … ENDORG. Čo vypíšeBankOf(story)?
Zhrnutie
- XL a XE majú RAM skrytú pod ROM; 130XE navyše štyri banky po 16 KB v okne
$4000–$7FFF. - Rutiny
XPeek,XPoke,XMoveBlock,XPrint… berú banku a adresu; banka 0 je bežná pamäť vrátane RAM pod ROM. XBanks()povie, koľko bánk je.ORG adresa BANK nnahrá dáta do banky spolu s programom;BankOf(meno)vráti jej číslo.XBank(n)nechá banku v okne pre obyčajné pole.
Podrobnejšie: lekcie 27 až 31 v examples/modern/.
Späť: 37. Miesto v pamäti a assembler · Ďalej: 39. Dáta zo súboru a kompresia