24. Pamäť počítača: Peek, Poke a premenné na adrese
Na čo to je
Atari sa ovláda cez pamäť. Farba pozadia, poloha kurzora, posledný stlačený kláves, stav joysticku – to všetko sú bajty na známych adresách. Kto vie čítať a zapisovať pamäť, vie z počítača dostať všetko, čo knižnica neponúka.
Pamäť Atari v skratke
Pamäť je rad 65536 bajtov s adresami 0 až 65535 ($0000 až $FFFF). Nie je to jednoliaty priestor:
| Adresy | Čo tam je |
|---|---|
$0000–$00FF | nultá stránka – pracovné bunky systému a jazyka |
$0100–$01FF | zásobník procesora |
$0200–$05FF | premenné operačného systému (farby, klávesnica, časovače) |
$0600–$06FF | šiesta stránka – 256 bajtov, ktoré systém nepoužíva; voľné pre programy |
$0700–… | DOS, ak je nahraný |
$2000–… | tvoj program (action26 ho sem predvolene ukladá) |
…–$BFFF | voľná pamäť a na jej konci pamäť obrazovky |
$D000–$D7FF | registre čipov: grafika, zvuk, joysticky |
$C000–$CFFF, $D800–$FFFF | operačný systém v ROM (pamäť len na čítanie) |
Zoznam užitočných adries je v prílohe D.
Adresy premenných v RAM ($0000–$05FF) a registrov sú vo všetkých verziách operačného systému rovnaké. Vnútro ROM nie: Atari 800, Atari XL/XE aj voľná náhrada AltirraOS majú na tých istých adresách v ROM iný kód. Do ROM sa preto skáče len cez oficiálne vstupné body – tabuľku od $E450 (napríklad $E456 pre vstup a výstup). Program, ktorý volá rutinu z vnútra ROM na pevnej adrese, beží len s jednou verziou systému.
Ako sa to píše
Rutiny knižnice
| Rutina | Čo robí |
|---|---|
Peek(adresa) | funkcia – vráti bajt z adresy |
PeekC(adresa) | funkcia – vráti CARD z adresy a adresy + 1 |
Poke(adresa, hodnota) | zapíše bajt na adresu |
PokeC(adresa, hodnota) | zapíše CARD na adresu a adresu + 1 |
Peek je anglicky „nakuknúť“, poke „štuchnúť“. Mená pochádzajú z jazyka BASIC.
Premenná na adrese
BYTE background=710To je deklarácia z kapitoly 6, pred ktorou si mal byť opatrný: číslo bez hranatých zátvoriek je adresa. Premenná background nedostane vlastné miesto – je bajtom na adrese 710. Zápis background=148 robí to isté ako Poke(710, 148), len sa lepšie číta a je rýchlejší.
Rovnako sa dá položiť na adresu pole:
BYTE ARRAY page6(256)=1536Celý program
Súbor examples/memory.act:
; Memory: reading and writing bytes by their address
BYTE background=710 ; this variable IS the byte at address 710
BYTE ARRAY page6(256)=1536 ; an array placed at address 1536 ($600)
PROC Main()
BYTE value
CARD word
Poke(1536, 65) ; write 65 to address 1536
value=Peek(1536) ; read it back
Print("Address 1536 holds ")
PrintBE(value)
PokeC(1538, 50000) ; a CARD takes two bytes: 1538 and 1539
word=PeekC(1538)
Print("Addresses 1538-1539 hold ")
PrintCE(word)
Print("Low byte ") PrintB(Peek(1538))
Print(", high byte ") PrintBE(Peek(1539))
page6(4)=7 ; the same memory through the array
Print("page6(4) is address 1540: ")
PrintBE(Peek(1540))
Print("page6(0) is address 1536: ")
PrintBE(page6(0))
background=148 ; the same as Poke(710, 148)
Print("Address 710 holds ")
PrintBE(Peek(710))
RETURNPreklad a spustenie
action26 memory.act --simČo uvidíš
Address 1536 holds 65
Addresses 1538-1539 hold 50000
Low byte 80, high byte 195
page6(4) is address 1540: 7
page6(0) is address 1536: 65
Address 710 holds 148Ako to funguje
Poke(1536, 65)aPeek(1536)– zápis a čítanie jedného bajtu. Adresa 1536 je začiatok šiestej stránky, kde programu nič nezavadzia.CARDzaberá dva bajty a nižší je prvý. 50000 je 195 × 256 + 80. Na adrese 1538 je 80 (nižší bajt), na 1539 je 195 (vyšší). Toto poradie platí na Atari všade.page6je pole položené na šiestu stránku.page6(4)a adresa 1540 sú to isté miesto.page6(0)ukazuje 65, ktoré tam zapísalPokena začiatku.background=148zapíše na adresu 710. V simulátore vidíš len číslo; v emulátore sa zmení farba pozadia na modrú, lebo 710 je bunka, z ktorej systém berie farbu pozadia textovej obrazovky.
Skús to v emulátore – pridaj na koniec GetD(7), aby program počkal na kláves (kapitola 2):
action26 memory.act --runNiekoľko adries na hranie
| Adresa | Meno v knihách | Čo robí |
|---|---|---|
| 710 | COLOR2 | farba pozadia textovej obrazovky |
| 709 | COLOR1 | jas písma |
| 712 | COLOR4 | farba okraja |
| 752 | CRSINH | 1 = kurzor je skrytý |
| 82 | LMARGN | ľavý okraj textu (predvolene 2) |
| 764 | CH | kód posledného stlačeného klávesu; 255 = žiadny |
| 20 | RTCLOK | počítadlo, ktoré sa zväčší 50-krát (v USA 60-krát) za sekundu |
| 53770 | RANDOM | pri každom čítaní náhodné číslo |
Farba je jedno číslo: 16 × odtieň + jas. 148 je odtieň 9 a jas 4.
Časté chyby
| Čo sa stalo | Čo sa stane |
|---|---|
BYTE x=710, keď si chcel počiatočnú hodnotu | x je bajt na adrese 710; každý zápis mení farbu pozadia |
Poke na adresu, ktorú nepoznáš | môže sa stať čokoľvek – od ničoho po zamrznutie počítača |
Poke do ROM ($C000 a vyššie okrem registrov) | nič – do pamäte len na čítanie sa zapísať nedá |
Peek z registra čipu vráti iné, ako si zapísal | je to normálne: veľa registrov má iný význam pri čítaní a pri zápise |
Zápis na zlú adresu počítač nepoškodí – stačí ho vypnúť a zapnúť. V emulátore a simulátore sa nemôže stať vôbec nič zlé, takže skúšaj smelo.
Vyskúšaj si
- V emulátore zmeň farbu okraja (adresa 712) a jas písma (709).
- Vypíš
Peek(53770)desaťkrát v slučke – v emulátore dostaneš zakaždým iné číslo. - Deklaruj
BYTE left=82, nastavleft=10a vypíš niekoľko riadkov textu. Čo sa stane v emulátore?
Zhrnutie
- Pamäť má adresy 0 až 65535; mnohé majú pevný význam.
Peek/Pokečítajú a píšu bajt,PeekC/PokeCdvojbajtové číslo.BYTE meno=adresaje premenná na danej adrese;BYTE meno=[hodnota]je premenná s počiatočnou hodnotou.- Dvojbajtové číslo má nižší bajt na nižšej adrese.
- Šiesta stránka (
$600–$6FF) je voľná pre programy. - Koľko pamäte ti ešte ostáva po preklade, povie
--memory(kapitola 32).
Späť: 23. Program vo viacerých súboroch · Ďalej: 25. Strojový kód