![]() | ZX Spectrum 48/+ | ![]() |
Pamięć w ZX Spectrum ma charakterystyczną organizację. Całym komputerem steruje 8-bitowy mikroprocesor Z80, który może bezpośrednio zaadresować tylko 64kB. Obszar ten musi być podzielony na pamięć ROM i RAM. Podstawową różnicą jest to, że pamięć ROM można tylko odczytywać, zaś pamięć RAM służy do przechowywania w niej danych i programów, można dowolnie modyfikować w jej zawartość. Pamięć ROM (Read Only Memory) jest pamięcią stałą, co oznacza, że nawet po wyłączeniu komputera nie ulega wyczyszczeniu. Natomiast zapisywalna pamięć RAM (Random Access Memory) działa niezawodnie tak długo, dopóki jest zasilana energią elektryczną (w dużym uproszczeniu).
ZX Spectrum jest prostym komputerem, dlatego też jego przestrzeń adresowa została podzielona na pewne obszary, w których nie ma dziur. W zasadzie pamięć Spectrum nie kryje tylu tajemnic co np. C-64. Podstawym podziałem jest rozdział na ROM i RAM. Dane można zapisywać tylko w obszarze RAM. Odczytywać można oczywiście całą przestrzeń od adresu 0 do 65535. Ale o szczegółach przeczytasz niżej, w tabelce. Pamięć ROM zaczyna się od adresu 0, gdyż od tego adresu mikroprocesor pobiera polecenia po rozpoczęciu pracy. W pamięci stałej jest zapisany interpreter języka BASIC oraz procedury obsługujące ekran, magnetofon, klawiaturę, drukarkę ZX Printer itp. Dzięki temu programista może korzystać z gotowych procedur systemowych w swoich programach. Zaraz za pamięcią stałą znajduje się specjalny obszar pamięci RAM - tzw. pamięć ekranu. Wszystko, co znajduje się w tym obszarze jest wyświetlane na monitorze. Czasami ten obszar (zazwyczaj jego większy fragment) bywa wykorzystywany przez "pamięciożerne" programy np. kopiery, do przechowywania danych (wtedy widać charakterystyczną sieczkę na ekranie). Dalej znajdują się obszary wykorzystywane przez sam system operacyjny, BASIC i pamięć do wykorzystania przez użytkownika. Standardowy podział obejmuje taką klasyfikację obszarów jak np. bufor drukarki, obszar zmiennych systemowych czy grafikę użytkownika, ale wprawny programista wie, które fragmenty tych obszarów może wykorzystać do innych celów w swoich programach.
Dobra znajomość mapy pamięci ZX Specgtrum pozwala na dokonywanie różnych sztuczek w programach w BASIC-u, na łamanie zabezpieczonych programów, przerabianie programów itp. To już zależy od pomysłowości programisty. Brak standardowego sposobu rozszerzania pamięci wymusza pisanie programów wykorzystujących optymalnie przestrzeń oferowaną przez producenta. Można, owszem, dorobić proste rozszerzenie np. popularne w Polsce 80kB, można też podłączyć odpowiedni interface z dodatkową pamięcią, lecz program napisany dla danej konfiguracji sprzętowej prawdopodobnie nawet nie ruszy na innej. W dodatku znane mi rozszerzenia pamięci są niezgodne (programowo) z podziałem pamięci w Spectrum 128.
Od poniższego podziału mogą istnieć odstępstwa w przypadku podłączenia do maszyny różnych rozszerzeń, które podmieniają pamięć. Można tu zaliczyć np. niektóre przystawki dla hackerów, które posiadają własny ROM i pamięć RAM itd. W podstawowym ZX Spectrum 48kB/+ pamięć jest zgodna z przestawionym tu opisem. Na pewno na jej organizacje nie wpływa podłączenie joysticka czy AY-greka (to informacja dla mniej zorientowanych).
Warto wspomnieć, że w system operacyjny ZX Spectrum 48 nie zajmuje całych 16kB pamięci. W obszarze obejmowanym przez ROM znajduje się "dziura", którą można wykorzystać. Można to zrobić dwojako - albo zastąpić ROM Spectrum przeprogramowaną pamięcią EPROM, albo budując interface przełączający ROM na zewnętrzny EPROM w razie odwoływania się do konkretnego obszaru pamięci. 1170 bajtów można wykorzystać na dopisanie do "systemu operacyjnego" własnych procedur. Rozwiązania układowe pomijam w tej części, poniżej przedstawiam mapę pamięci.
| Adres lub zmienna | Adres zmiennej | Pocz. wartość zmiennej | Obszar | Uwagi |
|---|---|---|---|---|
| 0 | ROM | Adresy w zapisie dziesiętnym | ||
| 14446 | ROM | "Dziura" - obszar wypełniony wartościami 255 | ||
| 15616 | ROM | generator znaków | ||
| 16384 | Pamięć ekranu | |||
| 22528 | Atrybuty | |||
| 23296 | Bufor drukarki | |||
| 23552 | Zmienne systemowe | Dokładny opis w osobnej tabelce | ||
| 23734 | Mapa microdrive'u | |||
| CHANS | 23631 | 23734 | Informacja o kanałach | Znacznik końca: 80h |
| PROG | 23635 | 23755 | Program w BASIC-u | Początek systemu BASIC |
| VARS | 23627 | Zmienne BASIC-a | Znacznik końca: 80h | |
| E_LINE | 23641 | Obszar (bufor) edytora BASIC-a | Na końcu obszaru są 2 bajty: 0Dh i 80h | |
| WORKSP | 23649 | Bufor instrukcji INPUT | Znacznik końca: 0Dh Za nim jest chwilowa przestrzeń pracy | |
| STKBOT | 23651 | Stos kalkulatora | ||
| STKEND | 23653 | Wolny obszar pamięci | ||
| rejestr SP (wskaźnik stosu) | Stos maszynowy | Wykorzystwany przez mikroprocesor | ||
| ERRSP | 23613 | Stos instrukcji GO SUB | To jest ostatni obszar systemu BASIC | |
| RAMTOP | 23730 | 65367 | Miejsce na kod maszynowy | Znacznik końca: 3Eh |
| UDG | 23675 | 65368 | Grafika definiowana | Np. na polskie znaki |
| P_RAMT | 23732 | 65535 | Koniec pamięci |
| Adres | Długość | Nazwa | Zawartość |
|---|---|---|---|
| 23552 | 8 | KSTATE | obszar roboczy procedury wczytywania znaków z klawiatury |
| 23560 | 1 | LAST K | kod ostatnio wciśniętego klawisza |
| 23561 | 1 | REPDEL | czas (1/50 s) przez jaki musi być wciśnięty klawisz, by został wczytany ponownie; domyślnie 35 |
| 23562 | 1 | REPPER | czas (1/50 s) pomiędzy kolejnymi wczytaniami wciśniętego klawisza; domyślnie 5 |
| 23563 | 2 | DEF ADD | adres argumentu funkcji FN |
| 23565 | 1 | K DATA | drugi bajt sterujący kolorem wprowadzonym z klawiatury |
| 23566 | 2 | TV DATA | bajty sterujące kolorem i pozycją (AT, TAB) znaków wprowadzanych na ekran |
| 23568 | 38 | STRMS | względne adresy kanałów dołączonych do poszczególnych strumieni: 23568 strumień 253 kanał "K" 23570 strumień 254 kanał "S" 23572 strumień 255 kanał "R" 23574 strumień 0 kanał "K" 23576 strumień 1 kanał "K" 23578 strumień 2 kanał "S" 23580 strumień 3 kanał "P" 23582 do 23606 strumienie 4...15 |
| 23606 | 2 | CHARS | adres (-256) graficznych form zbioru znaków (generatora znaków) |
| 23608 | 1 | RASP | długość dźwięku ostrzegawczego |
| 23609 | 1 | PIP | czas trwania dźwięku potwierdzającego wciśnięcie klawisza |
| 23610 | 1 | ERR NR | kod błędu (minus 1); początkowo 255 |
| 23611 | 1 | FLAGS | znaczniki we/wy. Znaczenie bitów: 0 - zapalony, jeśli przed słowem kluczowym nie drukuje się spacji 1 - zapalony, gdy współpracuje się z drukarką 2 - rodzaj kursora. "L/C"=1, "K"=0 3 - tryb wprowadzania; "L/C"=1, "K"=0 5 - zapalony, gdy wciśnięto klawisz 6 - typ wprowadzanych danych (1=liczna, 0=lancuch) 7 - 1=wykonywanie programu, 0=sprawdzanie składni |
| 23612 | 1 | TV FLAG | znaczniki ekranu. Znaczenie bitów: 0 - zapalony = wprowadzanie w dolną część ekranu (kanał "K") 3 - zapalony w trakcie poprawiania (edycji) linii (tryb EDIT) 4 - zapalony przy automatycznym listowaniu 5 - zapalony, jeślo po wciśnięciu klawisza dolna część ekranu ma zostać wyzerowana |
| 23613 | 2 | ERR SP | adres procedury obsługi błędu |
| 23615 | 2 | LIST SP | adres powrotu dla automatycznego listowania |
| 23617 | 1 | MODE | rodzaj kursora: 0 dla L/C, 1 dla E, 2 dla G, 4 dla K |
| 23618 | 2 | NEWPPC | numer linii, do której wykonywany jest skok |
| 23620 | 1 | NSPPC | numer instrukcji w linii, do której wykonywany jest skok |
| 23621 | 2 | PPC | numer aktualnie wykonywanej linii |
| 23623 | 1 | SUBPPC | numer instrukcji w aktualnie wykonywanej linii |
| 23624 | 1 | BORDCR | kolor brzegu ekranu (*8) |
| 23625 | 2 | E PPC | numer linii, w której znajduje się kursor programu (">") |
| 23627 | 2 | VARS | adres pola zmiennych programu w BASIC |
| 23629 | 2 | DEST | adres zmiennej, której aktualnie przypisywana jest wartość |
| 23631 | 2 | CHANS | adres pola rekordów kanałów |
| 23633 | 2 | CURCHL | adres aktualnie używanego kanału |
| 23635 | 2 | PROG | adres programu w języku BASIC |
| 23637 | 2 | NXTLIN | adres następnej linii w programie |
| 23639 | 2 | DATADD | adres początku następnej danej w zbiorze DATA |
| 23641 | 2 | E LINE | adres aktualnie poprawianej instrukcji |
| 23643 | 2 | K CUR | miejsce kursora we wprowadzanej/poprawianej linii |
| 23645 | 2 | CH ADD | adres następnego znaku do interpretacji |
| 23647 | 2 | X PTR | adres znaku po znaczniku "?" |
| 23649 | 2 | WORKSP | adres obszaru roboczego interpretera |
| 23651 | 2 | STKBOT | adres początku stosu kalkulatora |
| 23653 | 2 | STKEND | adres końca stosu kalkulatora |
| 23655 | 1 | BREG | rejestr B kalkulatora |
| 23656 | 2 | MEM | adres pamięci kalkulatora (zwykle MEMBOT) |
| 23658 | 1 | FLAGS | znaczniki (flagi). Bity: 0 - zapalony, jeśli właśnie wyzerowano ekran 1 - zgaszony, jeślibufor drukarki pusty 2 - zapalony, jeśli operuje się wewnątrz nawiasów 3 - zapalony, jeśli CAPS LOCK wciśnięty 4 - zapalony, jeśli "K" jest aktualnym kanałem |
| 23659 | 1 | DF SZ | liczba linii w oknie systemowym (dolnej części ekranu) |
| 23660 | 2 | S TOP | numer linii na początku automatycznego listingu |
| 23662 | 2 | OLDPPC | numer linii dla instrukcji CONTINUE |
| 23664 | 1 | OSPPC | numer instrukcji w linii dla CONTINUE |
| 23665 | 1 | FLAGX | znaczniki (flagi). Bit numer: 1 - zapalony, gdy było odwołanie do nieistniejącej zmiennej 5 - zapalony = tryb INPUT, zgaszony = tryb EDIT 7 - zapalony, gdy wykonuje się INPUT LINE |
| 23666 | 2 | STRLEN | długość aktualnie analizowanego łańcucha znaków |
| 23668 | 2 | T ADDR | adres następnej pozycji w tabeli analizy syntaktycznej |
| 23670 | 2 | SEED | podstawa generacji liczb losowych (RND) ustawiana przez RANDOMIZE |
| 23672 | 3 | FRAMES | licznik ramek TV zwiększany co 1/50 sekundy; pierwszy bajt najmniej znaczący |
| 23675 | 2 | UDG | adres pola grafiki definiowanej (UDG) |
| 23677 | 2 | COORDS | współrzędne (xy) ostatnio rysowanego punktu (PLOT) |
| 23679 | 1 | P POSN | numer kolumny drukowania |
| 23680 | 1 | PR CC | mniej znaczący bajt adresu pozycji znaku do drukowania z bufora drukarki |
| 23681 | 1 | nie używany | |
| 23682 | 2 | ECHO E | numer kolumny i numer wiersza na ekranie; numer końca bufora dla wprowadzania (INPUTz kanału "K") |
| 23684 | 2 | DF CC | adres kursora w górnej części ekranu (kanał "S") |
| 23686 | 2 | DFCCL | adres kursora w dolnej części ekranu (kanał "K") |
| 23688 | 2 | SPOSN | zawiera 33 minus numer kolumny (pozycja dla PRINT w kanale "S") 24 minus numer wiersza |
| 23690 | 2 | SPOSNL | j.w., ale dla okna systemowego (kanał "K") |
| 23692 | 1 | SCR CT | liczba przesunięć linii na ekranie (+1) do pytania "scroll?" |
| 23693 | 1 | ATTR P | atrybuty globalne (dla całego ekranu) |
| 23694 | 1 | MASK P | maska przezroczystych stałych kolorów |
| 23695 | 1 | ATTR T | atrybuty lokalne (PRINT, INPUT) |
| 23696 | 1 | MASK T | maska przezroczystych atrybutów lokalnych |
| 23697 | 1 | P FLAG | znaczniki barw. Znaczenie bitów: 0 - OVER (chwilowa) 1 - OVER (stała) 2 - INVERSE (chwilowe) 3 - INVERSE (stałe) 4 - INK 9 (chwilowe) 5 - INK (stałe) 6 - PAPER 9 (chwilowe) 7 - PAPER 9 (stałe) |
| 23698 | 30 | MEMBOT | pamięć kalkulatora |
| 23728 | 2 | nie używane | |
| 23730 | 2 | RAMTOP | adres ostatniego bajtu dostępnego dla BASIC-a |
| 23732 | 2 | P RAMT | adres ostatniego bajtu dołączonej pamięci RAM |
| Adres | Długość | Nazwa | Zawartość |
|---|---|---|---|
| 23734 | 1 | FLAGS 3 | znaczniki; bit zapalony podczas: 0 - realizacji rozszerzonego systemu instrukcji 1 - CLEAR 2 - zmian ERR SP 3 - pracy w sieci 4 - LOAD 5 - SAVE 6 - MERGE 7 - VERIFY |
| 23735 | 2 | VECTOR | adres używany do rozszerzenia interpretera BASIC-a (normalnie 01F0) |
| 23737 | 10 | SBRT | podprogram wywołania procedury z ROM-u Spectrum: LD HL, wartość CALL adres LD (23738), HL RET |
| 23747 | 2 | BAUD | szybkość przesyłania danych przez RS232 BAUD = (3500000/(26*szybkosc))-2 |
| 23749 | 1 | NTSTAT | własny numer w sieci (od 1 do 64) |
| 23750 | 1 | IOBORD | kolor brzegu ekranu podczas operacji we/wy |
| 23751 | 2 | SERFL | obszar roboczy RS232. Pierwszy bajt = znaczniki; drugi bajt = wprowadzany znak |
| 23753 | 2 | SECTOR | obszar roboczy microdrive'u - zwykle służy do zliczania sektorów |
| 23755 | 2 | CHADD | chwilowe przechowywanie zawartości CHADD |
| 23757 | 1 | NTRESP | kod zwrotny stacji w sieci |
| 23758 | 1 | NTDEST | numer stacji przeznaczenia w sieci |
| 23759 | 1 | NTSRCE | numer stacji nadającej w sieci |
| 23760 | 2 | NTNUMB | liczba bloków przesyłanych w sieci (0-65535) |
| 23762 | 1 | NTTYPE | nagłówek typu danych w sieci (0-dane, 1-EOF) |
| 23763 | 1 | NTLEN | długość bloku przesyłanego w sieci (0-255) |
| 23764 | 1 | NTDCS | suma kontrolna bloku przesyłanego w sieci |
| 23765 | 1 | NTHCS | suma kontrolna nagłówka bloku w sieci |
| 23766 | 2 | D STR 1 | początek 8-bajtowego pola nagłówka pliku, drugi bajt - numer microdrive'u (1-8) lub numer stacji przeznaczenia w sieci lub szybkość pracy łącza szeregowego |
| 23768 | 1 | S STR 1 | numer strumienia (0-15) |
| 23769 | 1 | L STR 11 | typ urządzenia: M, N, T, B |
| 23770 | 2 | N STR 1 | długość nazwy pliku |
| 23772 | 2 | T STR 1 | adres początku nazwy pliku |
| 23774 | 8 | D STR 2 | kolejne 8 bajtów nagłówka pliku w instrukcji MOVE i LOAD |
| 23782 | 1 | HD 00 | rodzaj pliku 0 - program 1 - tablica liczb 2 - tablica tekstów 3 - ciąg bajtów |
| 23783 | 2 | HD 0B | długość danych |
| 23785 | 2 | HD 0D | adres początku danych |
| 23787 | 2 | HD 0F | długość programu (lub nazwa tablicy) |
| 23789 | 2 | HD 11 | numer linii do automatycznego startu programu |
| 23791 | 1 | COPIES | liczba kopii tworzonych instrukcją SAVE |