REU - Rozszerzenie Pamięci
cz.1
Niniejszy artykuł dedykowany jest szerokiemu gronu użytkowników Commodore 64 oraz C128. Powstał on z potrzeby chwili, jako odzew na szereg (powtarzających się) Waszych pytań odnośnie tego modułu. Ale do rzeczy...
Jak mówi pewne stare przysłowie: "pamięci nigdy nie za wiele", pokusiłem się i Ja (tzn. TSD) o zakup tego cudeńka, ładnych kilka lat temu. Podobnie jak większość z Was, miałem wtedy blade pojęcie o jego wadach czy zaletach. Pewnym plusem okazała się wówczas dołączona instrukcja, w języku wprawdzie nie ojczystym - ale na szczęście dla mnie zrozumiałym. I teraz postaram się przekazać, czego można się było z niej dowiedzieć :)
Na początek rozszyfrujemy nazwę REU - Ram Expansion Module. Co jest trochę mylące, gdyż samo REU nie rozszerza pamięci ADRESOWALNEJ przez CPU (widzianej normalnie przez system, np. Basic), a jedynie zapewnia dostęp do tej dodatkowej pamięci - na drodze programowej. Przy zasadzie zbliżonej nieco do obsługi Ram-Dysku. Diabeł jak to mówią tkwi jednak w szczegółach, możemy więc mieć nawet aż 16 MB ram'u, ale nie bezpośrednio!
Inaczej mówiąc - pamięć tą możemy czytać i zapisywać, jednak bez możliwości uruchamiania w niej własnych programów. Co oznacza dla przeciętnego użytkownika - brak zastosowań praktycznych, gdyż większość gier i programów po prostu nie widzi tej dodatkowej pamięci, nie licząc kilku użytków czy systemu GEOS. Więc jeżeli czytasz jeszcze nadal ten tekst, oznacza to iż NIE jesteś już normalnym:) użytkownikiem komodorka. Pasjonują cię wyzwania... Zacznij zatem odkrywać i ujarzmiać owe niezmierzone przestrzenie RAM-u.
1. Wielkość pamięci
Podstawowym kryterium podziału REU, jest wielkość zamontowanej w nich pamięci. Najpopularniejsze są modele 1700, 1764, 1750 - mające odpowiednio 128 KB, 256 KB i 512 KB ram. Jednak rzesze zapaleńców wprawnie posługujących się lutownicą, zaczęły wyposażać je w dodatkowe kości pamięci i tak powstało REU 2 MB i większe:) My jednak dzięki emulatorom C-64, nie musimy już brać do rąk tego groźnego narzędzia. Odpalamy sobie tylko VICE lub CCS-a i cieszymy oczy szesnastoma MB.
2. Podział pamięci
Niezależnie od wielkości wbudowanej pamięci, dzieli się ona na tzw. Banki o wielkości 64 KB każdy! Więc model REU 1700 - wyposażony jest w dwa banki (numer 0 i 1), REU 1764 w cztery (0, 1, 2, 3) a 1750 w osiem itd. Spójrzcie zatem na poniższą tabelkę:
Model REU
|
Wielkość zamontowanej pamięci
|
Ilość banków
|
1700
|
128 KB
|
2
|
1764
|
256 KB
|
4
|
1750
|
512 KB
|
8
|
1 MB
|
1024 KB
|
16
|
2 MB
|
2048 KB
|
32
|
4 MB
|
4096 KB
|
64
|
8 MB
|
8192 KB
|
128
|
16 MB
|
16384 KB
|
256
|
3. Dostęp do pamięci
Uzyskujemy poprzez podanie numeru banku (liczonego od zera) i adresu danych. Sam adres zaś składa się z adresu względem początku banku (czyli zawsze liczonego od $0000) i długości danych do pobrania lub zapisania. Można uprościć sobie życie stosując pseudo zapis adresu w formacie 24-bitowym. Ja posługuje się czymś takim: $13:1a00, gdzie liczba po "$" to numer banku, a dane po ":" to adres wewnątrz tego banku. Ale o tym powiem więcej w drugiej części mego poradnika:) która powinna ukazać się już wkrótce...
4. Podtrzymywanie zawartości pamięci
Nie słyszałem o takim:( w fizycznym module REU, jednak w wirtualnym umożliwia to emulator VICE. Gdzie rolę pamięci modułu emuluje plik zdefiniowany przez użytkownika. Oznacza to iż tworzymy "lipny" plik i ustawiamy go jako obraz REU. Po inicjalizacji, emulator powiększy rozmiar pliku do żądanego przez nas rozmiaru. Co uwolni użytkownika od skomplikowanego stworzenia go samemu. Możemy więc przechowywać wiele obrazów REU równocześnie, przełączając się pomiędzy nimi wedle własnej woli.
5. Rejestry sterujące dostępem do pamięci
Nie jest tego za wiele, ale jak do tej pory - na co daję głowę - nie było wcześniej NIGDZIE opublikowane (mam tu na myśli Commodore & Amiga, Kebab, Bajtek) więc śpieszę naprawić te ewidentne niedopatrzenie... Pozbawiające Was tych informacji przyczynili się mimochodem do braku popularyzacji tego sprytnego urządzenia, które możemy umieścić w Expansion porcie. Jeszcze należy tylko wspomnieć, że sterowanie odbywa się poprzez obszar I/O przeznaczony dla modułów i jako taki UMIESZCZONY w pamięci od adresu $DF00 poczynając (nie w RAM'ie pod tym samym adresem - czyli do komórki $01 ładujemy $37 by odblokować ROM), polecam w tym celu lekturę mapy pamięci. Pytania i wątpliwości w tej materii nadsyłajcie na mój adres maniac64@nostalgia.pl.
PS. Ze względu na możliwość przekłamania (użycie przeze mnie potocznych nazw), przytaczam oryginalne angielskie nazewnictwo.
Address
|
Bits
|
Function
|
$DF00:0
|
7 - 0
|
Status Register - Read only
7 - Interrput Pending - 1 = Interrput waiting to be serviced
6 - End of Block - 1 = Transfer complete
5 - Fault - 1 = Block verify error
4 - Size - 0 = Total expansion = 128K
1 = Total expansion = 512K
3 - 0 - Version
Note: Bits 7-5 are cleared when this register is read
|
$DF00:1
|
7 - 0
|
Command Register - Read/Write
7 - Execute - 1 = Transfer per current config
6 - Reserved
5 - Load 1 = Enable AUTOLOAD option
4 - FF001 = Disable FF00 decode
3 - Reserved
2 - Reserved
1 - 0 - Transfer type 00 - transfer C128 -> RAM module
01 - transfer C128 <- RAM module
10 - swap C128 <-> RAM module
11 - verify C128 - RAM module
|
$DF00:2
|
7 - 0
|
C128 Base Address, LSB - Read/Write
Lower 8 bits of base address, C128
|
$DF00:3
|
7 - 0
|
C128 Base Address, MSB - Read/Write
Upper 8 bits of base address, C128
|
$DF00:4
|
7 - 0
|
Expansion RAM Address, LSB - Read/Write
Lower 8 bits of base address, expansion RAM
|
$DF00:5
|
7 - 0
|
Expansion RAM Address, MSB - Read/Write
Upper 8 bits of base address, expansion RAM
|
$DF00:6
|
7 - 0
|
Expansion RAM bank - Read/Write
Expansion RAM bank pointer
Bits 2 (MSB) to 0 (LSB) are significant
|
$DF00:7
|
7 - 0
|
Transfer lenght, LSB - Read./Write
Lower 8 bits of the byte counter
|
|
7 - 0
|
|
$DF00:8
|
7 - 0
|
Transfer lenght, MSB - Read./Write
Upper 8 bits of the byte counter
|
$DF00:9
|
7 - 5
|
Interrput mask register - Read/Write
7 - Interrput enable - 1 = Interrputs enabled
6 - End of Block mask - 1 = Interrput on end of block
5 - Verify error - 1 = Interrput on verify error
|
$DF00:A
|
7 - 6
|
Address control register - Read/Write
00 - Inrement both addresses (default)
01 - Fix expansion address
10 - Fix C128 address
11 - Fix both addresses
|
* np. zapis $DF00:8 oznacza adres $DF08
...a teraz małe uproszczenie w naszym języku i do naszego 1-16 MB REU dla C-64, gdyż różnice są symboliczne i tylko w adresie $DF00:01 - obsługa rejestru $FF00 czyli trybu DMA dla C128 w przypadku transferu przez REU, mam nadzieję iż właściciele C128 mi wybaczą :)
$DF00:1 - operacja na pamięci (tj. zapis/odczyt itd.)
$DF00:2-3 - adres początku pamięci dla C64
$DF00:4-5 - adres początku pamięci dla REU
$DF00:6 - bank dla REU
$DF00:7-8 - ilość danych
dodatkowo możemy ustalić czy REU ma nas powiadamiać o wyniku naszych poczynań, i tak w:
$DF00:0 - odczytamy status operacji na pamięci
$DF00:9 - ustalimy sposób czyli przyczynę powiadamiania nas o wyniku operacji
$DF00:A - dopasujemy obsługę licznika adresowego
W praktyce może to wyglądać jak np. w załączonym pliku reu-example.zip kopiującym zawartość ekranu tekstowego do i z modułu - odpowiednio SYS $1000 i $2000 po kompilacji pod TAS-em. Na tak ekstremalnie prostym przykładzie możemy już dostrzec potencjalne zastosowania REU. W następnym wcieleniu tego poradnika spróbuje was zarazić napisaniem własnego Ram-Dysku, opartego na tych kilku prostych komendach. Do tego czasu radzę ostro potrenować, bo wrzucę Was od razu na głęboką wodę. Pokażę, w jaki sposób możemy zaprojektować obsługę 16 MB RAM-u, mając zaledwie procka z 1 MHz na pokładzie.
Niech moc REU będzie z Wami :)
Tomasz 'TSD' Dzierkowski
maniac64@nostalgia.pl
|