uniwersalne poke czyli poprawianie loaderów do gier z MSX

Tytuł tego wpisu jest nieco mylący. Tak naprawdę chodzi o to, by gry z MSX1 wczytywały się na komputerze MSX2.

To mogą się nie wczytywać?

No mogą. Po pierwsze w świecie MSX panuje chaos banków ROM/RAM i slotów pamięci. Po drugie stacja dysków nie była przewidziana jako coś standardowego w komputerach MSX pierwszej generacji i bardzo dużo gier i programów zakłada pewną ilość pamięci RAM dostępnej z poziomu BASICa. I tutaj niestety – stacja dysków z MSXDOSem zajmuje trochę tej pamięci. Co więcej systemy dwudyskowe (np. mój Philips NMS8280) mają tej pamięci jeszcze mniej, i posiadanie 128k RAM niewiele tutaj pomaga.

Skąd ten temat?

Jak kupiłem swojego pierwszego MSXa, to w obroty poszły oczywiście obrazy dyskietek i zaczęły się problemy. TOSEC MSXa zawiera m.in. MSX-1-MANIA – bagatela 132 obrazy dyskietek ze składankami gier. Problem polega na tym, że ktoś kto robił te składanki niestety – nie dopracował loadera składanki. Tzn. na jego komputerze pewnie to działało. Działa też na emulatorze MSXa, ale już niekoniecznie działa na konkretnym modelu MSXa. Na szczęście temat jest znany – a ja wrzucam go tutaj – dla pamięci i ew. pomocy komuś, kto nie przebije się na szybko przez ileś forum, tematów, wpisów etc.

40 a nie 80 kolumn

Pierwsza generacja MSXa nie miała ot tak 80 kolumn, miało to tylko część modeli. Jako, że z poziomu MSX2 cofamy się nieco w czasie i możliwościach to wpisanie:

WIDTH 40

może pomóc, a napewno nie zaszkodzi.

Tryb 2

Screen 2 jest trybem tekstowym – część gier czy programów może się spodziewać go na starcie. Jeżeli w loaderze komendę LOAD “nazwa” poprzedzimy komendą:

SCREEN 2

może się okazać, że akurat to pomogło 🙂

Start komputera z CTRL

Jeżeli wystartujemy komputer z wciśniętym klawisze CTRL to “wyłączymy” obsługę drugiej stracji dysków, czym zwolnimy trochę pamięci RAM. To może pomóc.

Start komputera z SHIFT

Do załadowania niektórych programów w wersji kasetowej potrzebujemy wyłączyć MSXDOSa i obie stacje – i to zrobi wystartowanie komputera z klawiszem SHIFT. Będzie to szczególnie pomocne jeżeli posiadamy magnetofon do MSXa i jakieś gry do wczytania z kasety.

Na szczęście większość gier funkcjonuje w wersjach zrzuconych do plików binarnych przerobionych do ładowania z dyskietki. I to jest w sumie ciekawy przypadek – bo chyba jest to jedna z niewielu platform, gdzie kierunek przegrywania gier był tak intensywny z kasety na dyskietki (w odróżnieniu do piracenia dyskietkowych wersji gier na kasety na Atari czy Commodore).

“W czym problem, przecież gry na MSX wychodziły na kartach”

Też tak myślałem, ale takie myślenie to tylko przykład nieznajomości platformy. Tak wychodziły gry w Japonii (ale nie wszystkie). W Europie królowały tańsze nośniki (i piractwo :P).

Powrót do klasyków z MSX

Chciałem porobić sobie składanki tematyczne, ale nie będę nagrywał 132 dyskietek SD, żeby zagrać w 140 gier a na dodatek mam stację podwójnej gęstości, więc przegrywanie tak obrazów dyskietek to jak ciepłe piwo – tego się po prostu nie robi 🙂

Zacząłem od sentymentów – taki secik np. z MANIC MINER, JET SET WILLY obie częście plus klasyki Ultimate Play the Game no i zrobił się problem.

Parę gier nie chciało się odpalać pomimo wyłączania drugiej stacji klawiszem CTRL na starcie (co więcej – nie działało to ani na VG8235 i NMS8280). Po prostu w trakcie ładowania się wieszały.

Nie poddałem się i poczytałem. Jest coś takiego jak:

uniwersalne poke

Że co? Jak to uniwersalne? Jeżeli wychowałeś się na Atari czy ZX Spectrum to uwaga na oczy, pojawią się ujemne wartości adresowania, czyli na bank jakieś piekło 🙂

POKE -1,1.0625*(NOT(PEEK(-1))AND&HF0)

No wygląda na dość skomplikowany zapis (no i łatwo się pomylić przy wpisywaniu, nie wspominając o czasochłonności), na szczęście można to uprościć do takiego zapisu:

POKE-1,(15-PEEK(-1)\16)*17

Dlaczego lepiej jest wpisywać do komórki (ujemnej?!) wartości w oparciu o wartości odczytane, a nie jako określoną, stałą liczbę?

Po pierwsze: adresowanie w MSX BASIC

Z80 adresuje 64k, nic się nie zmieniło. czyli wartości od 0 do 65535 (dające łączny zakres 65536 czyli 2^8). W MSX BASIC dopuszcza się adresowanie na liczbach naturalnych czyli 0-65535 oraz ujemych w zakresie 7bitów czyli do -32768.

POKE -1,0

to to samo co co (nieco dłuższy zapis):

POKE (65536-1),0

tylko trochę krótszy/uproszczony zapis. Na szczęście ten zapis jest mi znany z Apple II więc byłem w domu. Adres wskazywany przez -1 to 65535.

Co znajduje się pod adresem 65535 w MSXie?

secondary slot select register

czyli rejestr pamięci rozszerzonej. To tutaj przechowywane są informacje o dodatkowej pamięci i jej rozłożeniu. Np. mój Philips NMS8280 mający 128k RAM po odczytaniu tego rejestru przez

PRINT PEEK(-1)

Wyświetla wartość 83. Binarnie to 01010011. Co to oznacza?

Skoro jest rejestr pamięci rozszerzonej, to warto wiedzieć, że jest też

primary port selector

Idąc dalej – nie da się tego zrozumieć bez poruszenia tematu takiego jak podział pamięci RAM w MSXach, ale to już za dużo jak na ten wpis, poświęcę pamięci MSXów osobny wpis innego dnia, a tak naprawdę zrobił się z jednego akapitu osobny wpis :).

Strony i sloty

Dlaczego nie powinno się stosować zapisu stałej wartości do rejestru pamięci rozszerzonej?

Jak wspomniałem MSXy były produkowane w ogromnej gamie modeli, konfiguracji. Każdy z producentów, a było ich kilkunastu stosował “swoje” przyporządkowanie banków pamięci RAM/ROM do slotów pamięci MSXa. I to powoduje czasem niekompatybilności oprogramowania pisanego pod pierwszą generację MSXa na nowszych komputerach drugiej generacji, które oprócz 64k pamięci RAM posiadają zwykle więcej tej pamięci, która jest przypisana i przełączana w ramach konkretnego slotu pamięci.

Policzmy co zmieni się w tym rejestrze pamięci rozszerzonej.

POKE-1,(15-PEEK(-1)\16)*17

(15-82/16)*17 = 9.875*17=167.875

mieliśmy w pamięci binarnie 01010010, uniwersalne poke zmienia to w 10100111.

Numery subslotów są określane dwubitowymi wartościami (czyli przechowują wartości 0-3 w każdych dwóch bitach). W internecie znajdziecie dość często wymieniane

POKE -1, 170

170 to binarnie 10101010

Oznacza to przypisanie wszystkich stron podstawowego RAM do subslotu 2 (binarnie 10). Jeżeli RAM Twojego MSXa znajduje się w slocie 3-2, ma to sens. Jeżeli niestety znajduje się w slocie 3-3 to komputer się zresetuje.

Jeżeli chodzi o mój komputer – Philips NMS8280 to rozkład slotów (zaczerpnięty ze strony msx.org) jest następujący:

Slot 0 Slot 1 Slot 2 Slot 3-0 Slot 3-1 Slot 3-2 Slot 3-3
Page C000h~FFFFh Cartridge
Slot 1
Cartridge
Slot 2
Sub-ROM
Mirror
128kB
Memory
Mapper
Mirror
Page 8000h~BFFFh Mirror
Page 4000h~7FFFh Main-ROM Disk ROM
Page 0000h~3FFFh Sub-ROM Mirror
  • 16KB Sub-ROM jest zduplikowany w stronach 0 – 3 w slocie 3-0
  • Disk ROM to obszar 16kB ROM – 4000h-7FFFh. Oczywiście rejestry FDC są dostępne na wszyskich 4 stronach.

W przypadku mojego “poke” przyporządkowanie slotów wygląda w w tej kolejności 2-2-1-3 vs poprzednie 1-1-0-2. I to np. pomaga wczytać Jet Set Willy, które wieszało się na loaderze skutkiem złego przypisania pamięci. Po prostu dla strony 2 i 3 wskazaliśmy obszar slot 3-2.

Podsumowanie

W przypadku komputerów pierwszej generacji ten adres jest zwykłą komórką pamięci – zapis w niej nie spowoduje niczego strasznego jak zawieszenie komputera. W przypadku komputera MSX2 musimy znać jego konfigurację slotów pamięci – na szczęście jest uniwersalne poke albo baza komputerów na msx.org – to dla ciekawych jakie wolty mogą robić konfiguracje slotów pamięci. Wkrótce głębsza “rozkminka” pamięci MSXa, bo jest to nadal dość złożone.