The Klątwa Set - Part II: Tajemnice przeklętej taśmy
Wstęp, czyli zanim zacznie się właściwa klątwa
To był spokojny majowy wieczór 2026 roku. Dość dziwny był ten maj, bo całkiem chłodny, i nic nie zapowiadało wydarzeń, które miały za chwilę nastąpić...
No dobra, żartuję sobie trochę ;P, ale nie mogę obiecać, że dalej będzie "normalniej". Tematy, które tutaj poruszam, nie są przeznaczone dla ludzi "normalnych" - takie rzeczy tylko dla retro-świrów ;) Zatem zapnijcie pasy i jedziemy z tematem. Jak to u mnie bywa, zanim dopłynę do brzegu, poruszę pewnie masę tematów pobocznych i będę opowiadał o sprawach, które mój mózg jakoś łączy w jedność, choć większość ludzi nie zobaczy w tym żadnego "wspólnego mianownika" ani spójnej, logicznej całości... Wybaczcie, ja już tak mam ;-) Nie da się mnie naprawić.
Sprzęt do zgrywania, czyli dlaczego SHARP i Tascam
Operacja zgrywania kasety zaczęła się jak zwykle: stary deck SHARP, rejestrator cyfrowy Tascam DR-05X. Dlaczego taki zestaw do zgrywania? To zaraz się wyjaśni. Na początku chciałem jednak pokrótce opisać drogę, którą przeszedłem przy zgrywaniu taśm. Być może w jakiś sposób pomoże to komuś w przyszłości, jeśli zechce powalczyć ze starymi kasetami.
Wiem, że czekacie na opis zawartości kasety, ale skoro już jestem w fazie "lania wody", to wykorzystam ten moment "twórczego amoku" mojej słabości do opisania paru faktów z przeszłości. Liczę, że może kogoś zachęci to do zgrywania kaset, które ma pod ręką. Nigdy nie wiadomo, czy nie ma tam jakichś ciekawych artefaktów z przeszłości.
Zaczynałem - nazwijmy to może dość łagodnie - od "przerostu formy nad treścią", a potem stopniowo upraszczałem swoją konfigurację. Piszę o tym tylko dlatego, abyście nie sądzili, że do takich operacji potrzebna jest jakaś superkosmiczna konfiguracja i studyjny sprzęt za grube pieniądze. W 99% przypadków wystarczą proste i tanie rozwiązania. Ja mogę służyć tutaj jako "anty-przykład", z tym że ja ten sprzęt miałem już wcześniej i wykorzystywałem go do innych celów. To nie było tak, że kupiłem go specjalnie na potrzeby zgrywania kaset.
Początkowo do zgrywania kaset używałem komputera PC, karty "E-MU 1212M" oraz decka Technics RS-BX501. Ta konfiguracja była jednak zdecydowanie "przewymiarowana" i zupełnie niepotrzebna. Do tego miała poważną wadę: konstrukcja samego decka oraz jego mechanizmu z obrotową głowicą (auto-reverse) była zupełnie nieprzystosowana do łatwej regulacji głowicy przez użytkownika. Kasety zgrywałem zatem z fabrycznym ustawieniem głowicy, co w przypadku niektórych kaset stanowiło problem, ponieważ były one nagrane na różnych rozklekotanych sprzętach, często z "losowym" ustawieniem głowicy.
Z czasem trafiłem na takiego taniutkiego SHARP-a z lat 80., w którym bardzo łatwo można było zdjąć osłonę szuflady, do której wkłada się kasetę. Dzięki temu mam łatwy dostęp do śruby regulującej skos głowicy, co umożliwiało mi indywidualne dobranie skosu głowicy do każdej kasety, która wpadała w moje ręce.
Warto jednak krótko wyjaśnić, że w przypadku kaset w kiepskim stanie, nagranych na magnetofonach z rozjechaną/rozregulowaną głowicą, taki zabieg pozwalał mi wyciągnąć największą możliwą stromość zboczy odczytywanego sygnału. Każda odchyłka głowicy od idealnego środka ścieżki magnetycznej powodowała utratę tonów wysokich, a co za tym idzie - zmniejszenie stromości zboczy sygnału reprezentującego zapisane dane.
Ten stary SHARP, w którym mogłem bez problemu kręcić głowicą, sprawdził się o wiele lepiej niż jakiś Technics z garścią dodatkowych systemów na pokładzie - zupełnie nieużytecznych w przypadku zgrywania "surowych danych" z kaset, które przez "naście" lat leżały często w mało komfortowych warunkach.
A skąd w ogóle pomysł na E-MU? To nie była moja fanaberia ani wymysł, że potrzebuję super jakości 24-bit/192 kHz, aby zgrywać stare kasety. Karta była wykorzystywana przeze mnie wcześniej, gdy pomagałem Xray-owi w przygotowywaniu różnych materiałów dla Radia UXA. A to zgrywałem jakieś kawałki z OPL3/Adlib, C64/SID czy też paru innych platform. Karta sprawdziła się znakomicie w tej roli. Wcześniejszy Behringer BCA-2000 umarł śmiercią naturalną wraz z Windows XP, na którym producent postanowił zakończyć jego wsparcie - no ale dość dygresji. Chodziło mi jedynie o wyjaśnienie, że nie kupowałem E-MU 1212M tylko po to, aby zgrywać stare kasety z programami dla Atari ;-) Zapewne w większości przypadków sprawdzi się dowolna karta dźwiękowa, nawet ta wbudowana w system, którego używacie.
Początkowo, gdy używałem E-MU 1212M, a były to czasy, gdy królował jeszcze Windows 7 (E-MU działało sprawnie jedynie pod Windows), wszystko sprawdzało się idealnie. Soft dołączony do karty świetnie sprawdzał się przy zgrywaniu danych, nie gubił żadnych próbek, sterowniki ASIO działały znakomicie, a cały proces zgrywania materiału mógł działać w tle, podczas gdy ja wykorzystywałem komputer do robienia innych rzeczy. Z czasem kolejne poprawki dla systemu Windows powodowały coraz większe problemy z działaniem E-MU. Firmę "E-MU Systems" kupił Creative Labs, co skończyło się porzuceniem produktu i jego naturalną śmiercią: brakiem aktualizacji sterowników, coraz większymi problemami z zapewnieniem jakości zgrywanego strumienia danych itd.
Ja jeszcze przez jakiś czas próbowałem eksperymentów z innymi rozwiązaniami, ale szybko doszedłem do wniosku, że mam dość walki z tym wszystkim (uśmiercaniem produktów poprzez brak wsparcia i aktualizacji sterowników przez producentów) i że jedyną sensowną drogą jest jakieś urządzenie, które działa niezależnie, nie potrzebuje aktualizacji i po zakupie nie może zostać uśmiercone przez producenta przez brak sterowników czy zakończenie wsparcia. Zacząłem się przyglądać różnym rozwiązaniom dostępnym na rynku.
Początkowo co prawda wymyśliłem sobie, że sam mogę zrobić jakiś rodzaj rejestratora - ale wiecie co, zacząłem grzebać i szybko mi się znudziło. W dodatku zobaczyłem, że są gotowe rozwiązania, dostępne od ręki. Zacząłem się przyglądać różnym rejestratorom cyfrowym i koniec końców mój wybór padł na TASCAM DR-05X. Czemu akurat ten? Bo trafiłem na niego, gdy był dostępny w jakiejś promocji, w całkiem rozsądnej cenie.
Użycie niezależnego rejestratora cyfrowego umożliwiło mi "uwolnienie" komputera od procesu zgrywania kaset. Nie musiałem już pilnować, czy coś dzieje się w tle, nie musiałem również uważać, aby nie zrobić restartu albo nie spowodować takiego dociśnięcia CPU, że program zgrywający dane zacznie się "dusić" i pominie jakieś próbki ze strumienia danych napływającego z karty dźwiękowej.
Wrzucałem kasetę, regulowałem głowicę (albo na ucho, albo z użyciem oscyloskopu), wciskałem REC na rejestratorze i mogłem zająć się czymś innym. Po kilkudziesięciu minutach plik audio był bezpiecznie zapisany na karcie micro-SD.
Powrót do przeklętej kasety
Ufff! Teraz chyba możemy wrócić do przerwanego wcześniej wątku...
Operacja zgrywania kasety zaczęła się jak zwykle: stary deck SHARP, rejestrator cyfrowy Tascam DR-05X, ustawienie głowicy "na słuch", wciśnięcie "REC" na rejestratorze, ustawienie poziomów i zajęcie się czymś innym na najbliższe 45 minut. Kaseta SKC, na której były zapisane programy, miała bowiem 90 minut długości (po ~45 minut na stronę).
Pierwsze objawy klątwy
Po zgraniu strony A przeniosłem plik audio (WAV, 48 kHz, 16-bit), szybko wrzuciłem go do Audacity i zacząłem słuchać oraz "oglądać" kształty zgranych fal. Wtedy zacząłem dostrzegać pierwsze oznaki "klątwy".
Tymi oznakami były nietypowe pyknięcia w sygnale pilotującym. Po drugie, natychmiast zauważyłem, że już pierwsze nagranie nie jest zapisane w standardowym formacie "Turbo 2000". Pierwszy blok był standardowy, jednak to, co następowało dalej po pierwszym bloku danych, nie było dalszymi standardowymi rekordami danych. "Na słuch" początkowo wyglądało to jak coś w stylu "*Speedy 2700/*AJEK", jednak po chwili słuchania dotarło do mnie, że to nie jest "Speedy 2700". Ten format danych brzmiał inaczej. Wyglądało na to, że pomiędzy impulsami 0/1 występują tony brzmiące jak "sync/pilot". Wtedy zaczęło mi coś majaczyć w pamięci: że kiedyś na giełdzie przy ul. Saskiej chłopaki wspominały o nowym formacie zapisu i nowej wersji oprogramowania systemowego dla Turbo 2000F.
Mając plik wave już na dysku, mogłem zacząć robić szybkie eksperymenty z użyciem emulatora. Do dyspozycji miałem Atari800 5.2.0 zmodyfikowany przez FUJI-ego tak, aby wspierał obsługę systemów turbo, lub Altirra, którą musiałem uruchamiać z użyciem Wine (używam Linuksa jako systemu operacyjnego "codziennego użytku").
Aby już nie przedłużać tego wywodu, powiem tylko, że chwilę mi zajęło, zanim zorientowałem się, czemu nie mogę poprawnie wczytać żadnego programu zgranego z tej kasety. Albo pojawiał się błąd 140 przy próbie wczytywania pierwszego bloku, albo - gdy już udało się to zrobić - następowało natychmiastowe wysypanie się komputera. Praca na emulatorze przyspieszyła zorientowanie się, co i gdzie się sypie oraz dlaczego. Szybko odkryłem, że pierwszy blok to loader, który próbuje ładować się bardzo nisko, przez co nadpisuje system turbo ulokowany w pamięci (używałem obrazu zrzuconego z cartridge'a "Klątwa"). Następne kroki polegały na użyciu wersji systemu Turbo 2000F od MUEL, który lokował się pod OS-ROM. Dzięki temu mogłem sprawdzić poprawność wczytywania programów zapisanych w "nowym formacie".
Co udało się odczytać ze strony A
Po wstępnej analizie zgranego materiału ze strony A okazało się, że ktoś przeprowadzał sobie na tej taśmie jakieś eksperymenty. Część gier została nadpisana inną zawartością, część była ucięta, a fragmenty niektórych nagrań były nieczytelne (pozostałości po starym/poprzednim zapisie). Zacznijmy może zatem od spisu tego, co udało mi się z tej kasety odczytać - oto "spis treści":
[NEW] Little Devil
[NEW] Decathlon
[NEW] Skateboard
[OLD] Tutunkhamun
[NEW] Jet Set Willy
[OLD] Kick Off [loader only]
[OLD] Hans Kloss
[---] nieczytelne pozostałości starego nagrania (Kick Off?)
[NEW] Screaming Wings
[NEW] Draconus (obcięty koniec nagrania)
[NEW] Rechnung Simulation
[NEW] TOTO-SYSTEM
[---] nieczytelne pozostałości
[OLD] Silent Service (LO-MEM SYS / loader)
[OLD] Silent Service (main program)
[NEW] Sex Test
[NEW] Moon Patrol
[NEW] Nadral
[NEW] Aztec
[NEW] Da'FUZZ
[NEW] Spellbound
[NEW] Zaxxon
[NEW] Taipei
[NEW] Draconus
[NEW] Super Cobra
[OLD] Fantastic Soccer (LO-MEM SYS / loader)
[OLD] Fantastic Soccer (main program)
[NEW] Yogi Bear and Friends in the Greed Monster
[NEW] Stack Up
[---] nieczytelne pozostałości poprzedniego nagrania
[NEW] World Soccer
Teraz mogę dodać krótki komentarz do powyższego spisu. [NEW]/[OLD] oznaczają format, w jakim zapisano daną grę/program. Pozycje oznaczone [---] to nieczytelne fragmenty.
Część "oryginalnych" pozycji na kasecie została nadpisana innymi programami. Np. gra "Kick Off" została ewidentnie nadpisana grą "Hans Kloss". Idąc dalej: końcówka gry "Draconus" (tej nagranej zaraz za Screaming Wings) została uszkodzona, tzn. ostatni segment gry, zawierający wektor RUN, jest ucięty, przez co loader "new format" nie uruchamia gry, tylko wraca do nadrzędnego systemu turbo.
Przyglądając się pozycjom Silent Service, Fantastic Soccer, World Soccer i analizując dodany "loader", z całą pewnością można potwierdzić, że ta kaseta była stworzona/nagrana dla systemu Turbo 2000F lokującego się pod OS-ROM. Skąd to stwierdzenie? Otóż ten "loader" to nic innego jak wersja systemu Turbo 2000F, która po załadowaniu lokuje się w niskich regionach pamięci (od $0700), ustawiając MEMLO na $199D (o ile dobrze zapamiętałem). Zresztą bardzo łatwo się o tym przekonać: po załadowaniu takiego loadera wciskamy RESET i lądujemy w wersji systemu Turbo 2000F, który siedzi na dole pamięci.
Ten właśnie "loader" nagrano przed grami, które podczas wczytywania ładowały się do pamięci pod OS-ROM. Właśnie stąd wniosek, że owa kaseta była używana z wersją cartridge'a, który zawierał soft dla Turbo 2000F ładujący się pod OS-ROM.
To jednoznacznie potwierdza, że cartridge "Klątwa" nie mógł poprawnie załadować większości programów zapisanych na tej kasecie. Żadna pozycja zapisana w "new format" nie miała szans, bo loader "nie współpracował" z softem zaszytym w karcie. Byłaby natomiast szansa na wczytanie pozycji "Hans Kloss", "Silent Service" czy "Fantastic Soccer", gdyby nie "pyknięcia" obecne w tonie pilotującym, których nie trawi wersja softu z "Klątwy".
Krótki bilans odzysku
Finalnie udało się odzyskać wszystko, co nie było na taśmie fizycznie zniszczone albo realnie nadpisane inną zawartością. Pliki, które sprawiały problemy, potraktowałem różnymi metodami korekcji, filtracji i wzmocnienia sygnału - dałoby się o tym napisać kolejne kilkadziesiąt kilobajtów, ale to już temat na osobny wpis, a nie na tę część sagi.
Przetwarzanie WAV do HEX
No ale kurczę, do brzegu... do brzegu... Płynąc dalej, mogę napisać parę słów o tym, jak wyglądał proces przetworzenia zgranego pliku dźwiękowego. W tym wypadku, ponieważ zgrałem całą stronę jako jeden plik, używając emulatora i obrazu carta Turbo 2000F, próbowałem wczytywać "na żywca" poszczególne pliki, jednocześnie zaznaczając w projekcie miejsca, gdzie zaczynają się i kończą poszczególne nagrania. Po zakończeniu obróbki wyglądało to mniej więcej tak:

Mając już tak "obrobiony" projekt, bardzo łatwo mogłem dokonać eksportu poszczególnych fragmentów nagrania do oddzielnych plików ".wav". Potem do akcji wkraczał a8cas-util.pl, który rozpoznaje zarówno klasyczny format Turbo 2000/F/KSO, jak i pojedyncze bloki danych zapisane niezależnie. Konwersja przebiegała mniej więcej w ten sposób:
a8cas-util.pl conv -t turbo2000 05_jest_set_willy_05.14_07.08.dlt.wav 05_jest_set_willy_05.14_07.08.dlt.hex
Starting ecasound... started.
SUMMARY: Data blocks: 29 (0 Errors).
62 HEX blocks stored in file 05_jest_set_willy_05.14_07.08.dlt.hex.
Oczywiście zdarza się, że plik nie poddaje się konwersji bez różnych problemów. Wtedy przyglądam się plikowi w Audacity i stosuję różne korekcje albo zmiany parametrów konwersji.
Konwersję wykonuję zwykle do plików .hex, aby móc szybko obejrzeć strukturę przetworzonego nagrania. Gdy już otrzymam "paczkę" plików *.hex, które udało się skonwertować bez błędów, to teoretycznie mógłbym uznać sprawę za zakończoną i takie pliki opublikować. Najpierw chciałbym jednak, abyśmy przyjrzeli się strukturze takiego pliku "HEX", zawierającego opis struktury pliku po konwersji z pliku .wav.
Anatomia pliku HEX
Zapytacie: po co? To stanie się jasne nieco później. Na początek przykład na fragmencie pliku z kasety "Klątwy". Jest to gra "Jet Set Willy", zapisana w nowym formacie. Oczywiście powycinałem masę danych nieistotnych dla problemu, który chcę naświetlić. "..." reprezentują wycięte dane nieistotne dla tego przykładu.
A8CAS-HEX
FUJI
pwms msb_first rising_edge_first 48000
pwmc 00093 46 4024 ; count=1
pwmd 12 23 00 ff 50 52 4f 47 52 41 4d 3a 35 20 a6 ; block no=1 ; length=13 ; checksum(modulo256)=a6 OK
pwmc 00000 46 1 ; count=1
pwmc 00151 46 584 12 1 23 1 46 3463 ; count=4
pwmd 12 23 f5 01 ff ff 06 08 ee 09 a9 80 8d 21 09 a9 00 ... 00 00 a9 ; block no=2 ; length=3075 ; checksum(modulo256)=a9 OK
pwmc 00000 46 1 46 1792 ; count=2
pwmd 12 23 ff ff 00 0c b4 19 d7 00 ; block no=3 ; length=8 ; checksum(modulo256)=d7 OK
pwmc 00000 46 11 ; count=1
pwmd 12 23 00 00 00 00 00 00 00 00 00 00 00 e0 f0 38 ... 01 70 00 ; block no=4 ; length=3511 ; checksum(modulo256)=70 OK
pwmc 00001 46 6 ; count=1
pwmd 12 23 00 20 75 29 be 00 ; block no=5 ; length=6 ; checksum(modulo256)=be OK
pwmc 00000 46 11 ; count=1
Zatem co widzimy w takim pliku? Nie wnikając w format zapisanych danych, chodzi mi tylko o fizyczną budowę takiego pliku HEX opisującego to, co "działo się" na taśmie.
Na początku mamy prosty nagłówek identyfikujący plik:
Po nagłówku następuje sekcja "pwms", która mówi o tym, jak traktować i interpretować dane oraz bloki (np. pwmc, pwmd) występujące dalej w pliku:
pwms msb_first rising_edge_first 48000
^^^ to mówi nam, że transmitowane bity są w kolejności od najstarszego (msb_first), potem że jako pierwsza leci narastająca krawędź zbocza (rising_edge_first), a następnie mamy określoną częstotliwość próbkowania. Ta częstotliwość jest kluczowa dla wyznaczenia czasu trwania impulsów, które reprezentują poszczególne stany (np. pilot, 0, 1).
Teraz warto zastanowić się, co tak naprawdę reprezentują bloki pwmc i pwmd. Zacznijmy może od bloku "pwmc":
pwmc 00093 46 4024 ; count=1
Co oznaczają te liczby?
00093 oznacza długość "ciszy" występującej przed rozpoczęciem sekwencji danych (w tym wypadku 93 ms).
46 oznacza długość pojedynczego impulsu (długość wyrażona w próbkach danych, tzw. samples). Aby obliczyć czas trwania, musimy pomnożyć długość impulsu przez odwrotność częstotliwości próbkowania (określonej w bloku pwms). W tym wypadku 46 próbek * (1/48 kHz) = 0,958 ms. Patrząc na specyfikację struktury zapisu dla formatu Turbo 2000, możemy domyślić się, że ta długość jest po prostu pilotem/tonem synchronizującym.
4024 - ta liczba określa liczbę impulsów, które zostaną wygenerowane.
Zestawiając to ze specyfikacją formatu, ten blok opisuje wstępny ton pilotujący, który powinien zawierać 4096 impulsów o długości 1 ms. Teoria teorią, a rzeczywistość rzeczywistością... Jak widać, po pierwsze długość impulsu nie wynosi dokładnie 1 ms, a po drugie a8cas-util wyliczył tylko 4024 impulsy zamiast 4096. Oczywiście jest to zupełnie normalne zjawisko. Po pierwsze, prędkości obrotowe silników zarówno magnetofonu zapisującego, jak i odczytującego mogą się nieznacznie różnić. Po drugie, będzie występowała nieliniowość przesuwu taśmy. Po trzecie, start silnika powoduje, że początkowe impulsy nie będą miały odpowiedniej długości i nie będą traktowane jako ton pilota. Wszystko to będzie powodowało, że każdy z takich zdekodowanych bloków będzie miał nieco inne parametry (w tym wypadku mozolnie obliczane przez a8cas-util).
Oczywiście procedury odczytu danych są na te wszystkie "niedoskonałości" zapisu przygotowane i wykazują się dużą tolerancją na tego rodzaju odchyłki. Dlatego to wszystko działa mimo tego, iż sam zapis magnetyczny, jak i taśma, na której jest on dokonywany, są dalekie od doskonałości.
Dodam jeszcze szybko opis bloku pwmd:
pwmd 12 23 00 ff 50 52 4f 47 52 41 4d 3a 35 20 a6 ; block no=1 ;
^^^ ta sekcja zawiera 3 znaczące części: pierwsze dwie liczby (uwaga! są w formacie dziesiętnym!) określają długości impulsów reprezentujących stany logiczne dla "0" i "1", a dalej występuje blok bajtów zapisanych jako ciąg cyfr hex, znajdujący się w danym bloku danych. W tym wypadku:
12 - oznacza długość impulsu kodującego logiczne "0" --> 12 * (1/48 kHz) = 0,25 ms
23 - oznacza długość impulsu kodującego logiczne "1" --> 23 * (1/48 kHz) = 0,497 ms
następne bajty to zawartość danego bloku danych
Jak widać na ww. przykładzie, długości impulsów "0" i "1" mieszczą się prawie idealnie w specyfikacji dla formatu Turbo 2000, czyli:
Normalizacja i ręczne egzorcyzmy
Teraz możemy wrócić do powodu, dla którego o tym wszystkim piszę. Teoretycznie wystarczyłoby te pliki .hex zamienić na .cas albo od razu konwertować je do formatu .cas, jednak uznałem, że skoro dokonujemy odczytu i odzyskiwania plików z kaset nierzadko w stanie agonalnym, to warto takie pliki po konwersji przywrócić do stanu "idealnego", tzn. zgodnego ze specyfikacją danego formatu (czy to będzie Turbo 2000, Blizzard, AST, etc.).
Pisząc "stan idealny", mam na myśli np. wyrównanie długości wszystkich impulsów, wyrównanie długości tonów sync/pilot, etc.
Idąc za ciosem: wyżej widać było, że długość impulsu pilota wynosiła 46 próbek (wartość idealna w przypadku plików 48 kHz to 48, gdyż 48 * (1/48 kHz) = 1 ms), "0" --> 12 (wszystko ok), "1" --> 23 (niewielka odchyłka, bo wartość idealna to 24).
Dlatego po takiej konwersji w większości przypadków "normalizuję" takie pliki, korygując wszystkie odchylenia od wartości standardowych.
Cały powyższy opis i tłumaczenie znaczenia poszczególnych liczb w pliku .hex miały na celu ułatwienie wam zrozumienia całego procesu i sposobu mojego postępowania. Być może zainspiruje to też kogoś do rozpoczęcia takich działań we własnym zakresie.
Jakie narzędzia wykorzystuję do tego celu? Początkowo robiłem to "półautomatycznie", używając edytora tekstowego i funkcji search&replace, jednak z czasem stało się to na tyle monotonne, że obecnie automatyzuję cały proces. Często wystarczy sed/awk, czasem prosty skrypt w Perlu, a coraz częściej jakiś skrypt w Pythonie. Początkowo walczyłem dzielnie i pisałem sobie jakieś dziwne wyrażenia regularne, jednak w dzisiejszych czasach, jeżeli dobrze napisze się prompt, to dowolny LLM bez problemu poradzi sobie z takim zadaniem, generując np. odpowiedni skrypt w Pythonie do przetworzenia wszystkich plików .hex do określonej, "znormalizowanej" postaci.
Jak było w tym wypadku? Wszystkiego po trochu. W niektórych przypadkach również "ręczna" edycja plików .hex i poprawki w krytycznych miejscach (np. uszkodzone bloki z nazwami plików), czasami jakiś skrypt w Perlu. Tutaj np. jeden z Perl-owych przykładów zmieniający długość pilota występującego po loaderze:
perl -pi.bak -e 's/^(pwmc 0000[01] 48 )2048(\s*;.*)?$/${1}2560${2}/' *.hex
^^^ zmieniamy długości wszystkich tonów pilotujących o długości 2048 impulsów na takie, które mają 2560 impulsów. Na wszelki wypadek tworzymy sobie od razu kopię plików (.bak).
Czasami nie da się zautomatyzować całego procesu i pozostaje ręczne dłubanie. Dotyczy to np. nagrań uszkodzonych lub taśm słabej jakości, z których mało co da się wycisnąć na poziomie automatycznego odzyskania czytelnego zapisu. Wtedy pozostaje ręczne dłubanie, zgadywanie i uzupełnianie brakujących fragmentów zapisu albo bajtów w wynikowym pliku .hex.
Po doprowadzeniu wszystkiego do jakiego takiego porządku i przetestowaniu, że wszystko się wczytuje, można dokonać konwersji na pliki .cas.
Od jakiegoś czasu uznałem, że nie ma sensu publikować oryginalnych ("surowych") plików .wav, bo po pierwsze zajmuje to dużo miejsca na serwerze, a po drugie często te pliki nie mają wartości bez odpowiedniej obróbki czy korekty. Byłyby kolejnym śmieciem w internecie, na który ktoś po latach by trafił i zmagał się z takim artefaktem, nie wiedząc, co się właściwie dzieje. Jeżeli uważacie inaczej, dajcie znać - mogę wrzucać i "surowe" zrzuty, o ile pigwa wytrzyma ;D
A i jeszcze jedno. Wcześniej pisałem o tych "pyknięciach" występujących w tonie pilotującym, które rozkładały na łopatki procedurę odczytu, powodując błąd 140. Tak wyglądało to w surowym pliku po konwersji:
pwmc 00151 46 584 12 1 23 1 46 3463 ; count=4
^^^ Jak widać, na tych "pyknięciach" potykał się "trochę" a8cas-util. Interpretując powyższy blok pwmc, widzimy, że:
na początku mamy 151 ms ciszy
584 impulsy tonu pilota (długość imp. 46)
jeden impuls "0" (długość imp. = 12)
jeden impuls "1" (długość imp. = 23)
3463 impulsy tonu pilota (długość imp. 46)
Jak widać, śmieć na taśmie był interpretowany przez a8cas-util jako sekwencja bitów 0 i 1 następujących po sobie. To wystarczyło, aby procedura odczytu potraktowała te impulsy 0,1 jako początek bloku danych (skończył się już sync tone). Jednak po chwili znowu pojawiały się impulsy o długości tonu pilota, co powodowało, że procedura odczytu protestowała, bo po dwóch bitach danych pojawiał się impuls o długości, której procedura odczytu już nie dopuszczała po jej zdaniem "poprawnej" synchronizacji. To kończyło się błędem odczytu nr 140.
Co z tym zrobić? Najłatwiej poprawić takie bloki pwmc ręcznie, zastępując tę całą serię jednostajnym tonem pilotującym:
pwmc 00151 48 4096 ; count=1
Pliki CAS i wymagany system Turbo 2000F
Nie przynudzając dalej, nie pozostaje mi nic innego, jak wrzucić linki do plików CAS, które zostały już poprawione, "znormalizowane" i oczyszczone z większości zbędnego śmiecia (przynajmniej tego, który zauważyłem): "The Klątwa Tape" - archiwum zawiera pliki hex/cas. Wszystkie pliki są w takim stanie, w jakim były na oryginalnej taśmie (pozostawiłem oryginale loadery, nie podmieniałem żadnych plików), a więc pliki w "new format" zawierają oryginalny loader, który wymaga odpowiedniej wersji Turbo 2000F.
Dodać należy, że są to pliki "znormalizowane" i oczyszczone (mówię tutaj o długościach impulsów, pilotów, etc. zero ingerencji w dane zapisane na taśmie), jednak nadal pozostaje problem: jak je wczytać? W pierwszej części opisywałem, że loader "new format" wymaga konkretnej wersji systemu Turbo 2000F - tej lokującej się pod OS-ROM i mającej MEMLO na poziomie $0800. Taką wersją systemu jest np. wersja, którą dystrybuowała ze swoim Turbo 2000F firma MUEL. Poniżej w archiwum znajduje się zarówno obraz cartridge'a, jak i wersja .XEX, którą można uruchomić z dowolnie wybranego medium. Plik .bin (obraz carta) należy uruchamiać jako typ "Blizzard 4K cartridge". Zmodyfikowałem minimalnie kod procedury startowej, aby sama odłączała cartridge, co ułatwia testy pod emulatorem. Archiwum do pobrania tutaj: Muel Turbo 2000F - wersja rezydująca pod OS-ROM.
Strona B
A co ze stroną B? Otóż strona B nie zawierała sensownej zawartości. Ktoś próbował nagrać sobie kilka razy grę "Snowball". Przyznam, że jakość tego materiału była na tyle mało warta uwagi, że zupełnie się nim nie zajmowałem.
Ciekawostka crack-scenowa
Może poruszę jeszcze jeden temat. Na taśmie znajdują się dwie interesujące pozycje, biorąc pod uwagę atarowską crack-scenę, mianowicie:
Yogi Bear and Friends in the Greed Monster oraz Stack Up to releasy sygnowane przez Bloody Coders - taka ciekawostka historyczna. Pliki spakowane są za pomocą Power Packer-a z Amigi.
Co dalej?
Na dziś to chyba na tyle. Pozostaje mi do napisania część trzecią, w której udostępnię kod źródłowy nowej wersji loadera - takiej, która zadziała z każdą wersją cartridge'a. Dodatkowo udostępnię pliki .cas zawierające "odklątwioną" wersję plików z tej kasety. Te pliki CAS będzie można ładować używając dowolnego cartridge'a zawierającego system z serii 200X (2000F, 2001, KSO). Trzecia część chyba będzie najkrótsza. Muszę tylko nieco uporządkować źródła i wrzucić repo na GitHub.
PS: kolejny objaw klątwy
Już przy ostatnim teście dopadła mnie kolejna część klątwy. Zauważyłem, że pozycje Silent Service, Fantastic Soccer oraz World Soccer, do których dołączony jest loader - a właściwie cały system Turbo lokujący się na dole pamięci - mają problem z uruchomieniem. Ściślej mówiąc, problem dotyczy uruchomienia tego loadera w systemie Turbo 2000F od MUEL, do którego linkowałem powyżej. Tego problemu nie ma natomiast w przypadku użycia Turbo 2000 (pozycja 1 z menu) z cartridge'a od SONIX, o którym wspominałem w pierwszej części. Nie wnikałem co jest powodem bo wyszło mi to dosłownie przed chwilą, ale ponieważ chcę już opublikować ten post, zostawiam wszystko w takim stanie jak jest. Tym bardziej, że za chwilę będę wrzucał "poprawioną" wersję plików z tej kasety - czyli wszystko w formacie "NEW", z nowym loaderem, który powinien uruchomić się z każdej wersji systemu.
ps2) część tej klątwy (MUEL) wyjaśniona, powodem był problem z tym że w emu miałem włączone urządzenie "H:", a loader w ciemno zakładał standardową konfigurację i zerował część tablicy HTABS "na ślepo", co powodowało że usuwał wpis dotyczący urządzenia "H:", zamiast "D:", a ponowa próba instalacji handlera dla urządzenia "D:" kończyła się niepowodzeniem.