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:

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:

Action!
;@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))
RETURN

Preklad a spustenie

Simulátoru treba povedať, že má byť 130XE:

action26 m-banks.act --sim --sim-mem 130xe
Banks of extended memory: 4
Address $4000 in the banks: 10 20 30 40 
XPeek sees the RAM under the ROM: 99

Bez --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

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:

Action!
;@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()
RETURN
action26 m-bankdata.act --sim --sim-mem 130xe
The 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

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.dat
action26 m-bankdata.act --code-only -o story.xex

Na 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:

Action!
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

Časté chyby

Čo sa staloČo sa stane
banka, ktorá neexistujeErr: 101
zápis do registrov alebo vektorov pod ROMErr: 102
čítanie mena z bloku ORG … BANK priamo (story(0))error ACT243
program a XBank s kódom v oknewarning ACT242; program sa môže zrútiť
spustenie na počítači bez rozšírenej pamäteXBanks() vráti 0 – program to má ošetriť

Vyskúšaj si

  1. Spusti m-banks.act s --sim-mem 1088 – počítač s megabajtom pamäte. Koľko bánk nájde?
  2. Ulož do banky 2 čísla 0 až 255 na adresy $4000 až $40FF a vypíš súčet toho, čo prečítaš späť.
  3. Presuň text v druhom programe pod ROM: ORG $C000 … ENDORG. Čo vypíše BankOf(story)?

Zhrnutie

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