24.06.2018, 18:31:47 *
Witamy, Gość. Zaloguj się lub zarejestruj.

Zaloguj się podając nazwę użytkownika, hasło i długość sesji
Aktualności: Zapraszamy do rejestracji na forum wszystkich fanów Pegasusa!
 
   Strona główna   Help Szukaj Zaloguj się Rejestracja  
Strony: [1]
  Drukuj  
Autor Wątek: Kardridż do zgrania zawartości nietypowej konsoli PEGASUS  (Przeczytany 322 razy)
krzysiobal
Aktywny użytkownik
***
Wiadomości: 225


Naprawie pegasusa każdemu!


Zobacz profil
« : 03.05.2018, 11:20:01 »


W tym artykule opiszę zmagania z odczytem nietypowej składanki, wbudowanej w konsole typu Pegasus. Projekt to pomysł + stworzenie PCB + napisanie kodu w assemblerze 6502.

 

Motywacja
Niedawno w moje ręce trafiła dość oryginalna konsola (oznaczenie BOS-2800 CONSOLE TV). Jej rzadkość polega na tym, że w jej wnętrze wchodzą cztery baterie R20. I brak możliwości podpięcia dodatkowego zasilania DC. Nikt o zdrowych zmysłach nie kupowałby oczywiście takich wielkich (i drogich) baterii, aby pograć kilka godzin aż do rozładowania, więc konsolę przerobiłem na zasilanie z zewnętrznego 9V DC (z tyłu była nawet zaślepka na gniazdo).


Jednak po włączeniu urządzenia, zaciekawiło mnie zupełnie co innego - wbudowana składanka gier. Jest ona o tyle nietypowa, że wszystkie z nich to znane hity, ale w przebraniu. Przerobieniu uległa muzyka, postacie oraz krajobrazy. I tak np. zamiast wyścigów formuły 1 (F1 Race), ścigamy się statkiem kosmicznym wśród gwiazd, a strzelanie do kaczek  (Duck Hunt zostało zmienione na strzelanie do spodków. Nigdy wcześniej nie widziałem czegoś takiego, więc postanowiłem znaleźć jakiś sposób, na zgranie tej składanki na PC.



Idea wbudowywania gier w konsole to chleb powszedni w pegasusopodobnych podróbkach - zwykle we wnętrzu takiej konsoli dostępne jest drugie gniazdo (od spodu), do którego włożona jest płytka drukowana z wbudowaną składanką lub wręcz jest ona wlutowana na kablach.


Trochę mnie to dziwi, bo z ekonomicznego punktu widzenia chyba taniej byłoby po prostu dołożyć dyskietkę jako oddzielny nośnik. W omawianej konsoli składanka obecna jest jako dodatkowy układ-glut na płytce drukowanej. I jak tu zgrać ją?


Gdyby nawet popodłączać się do wszystkich mikroskopijnych ścieżek kabelkami, a następie wygenerować kolejne adresy i odczytać magistralę danych, to sygnały przez nas wystawiane kolidowałyby z tymi od procesora konsoli (drugi glut). Można byłoby się pokusić o odcięcie ścieżek od CPU, jednak byłby to zabieg wyjątkowo ryzykowny i z całą pewnością destruktywny dla konsoli. Więc może jest jakiś prostszy sposób?

Pomysł i plan
Pierwszym krokiem jest określenie, w jaki sposób konsola wykrywa obecność kardridża w gnieździe (i dezaktywuje wbudowaną składankę). Konsole, z jakimi miałem do czynienia robiły to na różne sposoby, jednak idea była podobna: wykorzystanie, że 99% kardridży posiada zwarte i do niczego nie podłączone dwa piny:
- CIRAM !CE i PPU !A13 (te służą do rozszerzania rozmiarów planszy wyświetlanej na ekranie)
- AUDIO-IN i AUDIO-OUT (możliwość dodania nowych kanałów dźwiękowych).

Po stronie konsoli jeden z pinów podłączano do masy (lub zasilania) i badano stan na drugim pinie. Oczywiście, gdyby jednak w gnieździe znalazł się kardridż, który owe piny do czegoś wykorzystuje, mogłoby dojść do zwarć i jego uszkodzenia.

W omawianej konsoli konstruktor wykorzystał sprytny fakt, że kardridż posiada dwa piny do zasilania +5V, a w każdej dystkietce, z jaką się spotkałem, są one ze sobą połączone. Wystarczy więc tylko podać zasilanie na jeden z nich (tutaj pin nr 30), natomiast drugi (pin nr 31) będzie służył jako detekcja, czy kardridż jest włożony (wtedy jest na nim +5V) czy nie.

Zwarcie podczas działania wewnętrznej składanki pinu nr 31 do +5V powoduje natychmiastowe zawieszenie (kardridż sie dezaktywuje), zatem świadczy to o tym, że przełączenia można dokonać nawet już w czasie działania konsoli.

Zgrywanie
Wymyśliłem dość oryginalny sposób na zgranie, mianowicie: stworzenie kardridża z programowalną pamięcią typu flash, który sterowałby właśnie stanem logicznym pinu 31, dzięki czemu mógłby aktywować/dezaktywować wewnętrzną pamięć w konsoli w trakcie jej działania. Schemat działania byłby następujący:



1. Tuż po włączeniu zasilania, aktywny jest zewnętrzny kardridż, który kopiuje swój kod wykonywalny do pamięci RAM (*) w konsoli i zaczyna go wykonywać:
3a. Aktywuje wewnętrzny kardridż
3b. Kopiuje porcję danych z wewnętrznego kardridża do pamięci RAM
3c. Aktywuje zewnętrzny kardridż i zaprogramuj obecną w nim pamięć flash skopiowaną porcją danych z pamięci RAM
3d. Jeśli nie skopiowano jeszcze wszystkiego, skacze do punktu 3a
Kardridż taki następnie zostanie wyjęty z konsoli i włożony do zgrywarki (Kazzo) i jego zawartość zostanie odczytana.

(*) Kopiowanie kodu wykonywalnego do pamięci RAM jest konieczne z dwóch względów:
* Zapewnia możliwość wykonywania go nawet, gdy aktywna jest wewnętrzna składanka,
* Zapewnia możliwość programowania pamięci Flash (nie da się jednocześnie wykonywać kodu z pamięci Flash i jej programować, bo cykl zaprogramowania jednego bajtu składa się z czterech cykli zapisu i nie można go przerwać operacją odczytu)


Dodatkowa funkcjonalność wymagała dołożenia jedynie jednego scalaka (7474) i kilku elementów biernych. Kilka kruczków:
* Nie można pinu 31 podłączyć bezpośrednio do wyjścia 7474, bo gdy taki kardridż umieścimy w zgrywarce (lub innej zwykłej konsoli), gdzie oba piny 30/31 są podpięte do +5V, nastąpi zwarcie
* Kardridż sam musi dezaktywować swoją pamięć (zarówno PRG jak i CHR), gdy włączy on wewnątrzną składankę w konsoli,
* Pamięć CHR w zasadzie nie jest potrzebna, ale dzięki jej obecności taki kardridż można też wykorzystać do wykonania na nim zwykłej gry.

Z technicznego punktu widzenia, kardridż taki przypomina popularny mapper UNROM (a właściwie jego odmianę - #71 Camerica):
Kod:
Odczyt:
  $8000-$bfff: przełączalny bank
  $c000-$ffff: wskazuje na ostatni bank

Zapis:
 $8000-$bfff: programowanie obszaru pamięci flash
 $c000-$ffff: E--P PPPP
              |  | ||||
              |  +-++++- ustaw numer banku dla obszaru $8000-$bfff
              +--------- włącz (1) lub wyłącz (0) wewnętrzną skladankę

Po wykonaniu, kardridż prezentuje się jak poniżej:
 


Uruchamianie - 1 podejście
Na start napisałem jakiś prosty program w 6502 aby sprawdzić, czy uda się zaprogramować pamięć Flash chociażby kilkoma bajtami. Oczywiście, nie działał. Przyczyną była obecność w konsoli, w szeregu z zasilaniem kardridża diody, która obniżała napięcie z 5 V do ~4.3 V. Po jej zwarciu kardridż (i kilka innych gier, które na tej konsoli nie chodziły) zaczął działać. Obecność diody jest dla mnie zagadką, ale prawdopodobnie została ona umieszczona, aby  poziomy logiczne generowane przez kardridż nie przekraczały 4.3V, dzięki czemu może współpracować on z układami 3.3V (być może gluty w konsoli wykonano właśnie w takiej technologii)

Uruchamianie - 2 podejście
Próbowałem odczytać obszary $8000-$bfff i $c000-$ffff, jednak tuż po włączeniu wewnętrznej składanki, ich odczyt zwracał otwartą magistralę. Dopiero dodanie odstępu ok 10 ms pomiędzy włączeniem (oraz wyłączeniem) składanki rozwiązało problem - wtedy wreszcie mogłem zobaczyć na oczy pierwsze poprawne bajty, które pochodziły już ze składanki.

Uruchamianie - 3 podejście
W wyniku analizy odczytanych obszarów $8000-$bfff i $c000-$ffff, dostałem już działające menu składanki (oczywiście bez działającej grafiki - więc albo grafika w tej składance jest w oddzielnej pamięci CHR-ROM, albo jest w pamięci PRG-ROM z programem, ale w innym banku)


Następnie mogłem sprawdzić, jakie banki próbują być włączone po starcie kardridża oraz po wybraniu każdej z gry z listy. To pozwoliło przekonać się, że przy zapisie liczy się adres zapisywanej wartości

Kod:
                                           Cykl zapisu po wybraniu
Nazwa        Oryginalna gra      Rozm M  Hex   Bin
------------------------------------------------------------------
-Menu-                              ? ?  $8000 100000000 0 000 000
Tennis       Tennis                16 V  $8048 100000000 1 001 000
Mars         Star Force            16 V  $8052 100000000 1 010 010
Sky Invader  Sky Destroyer         16 H  $80db 100000001 1 011 011
Cow Boy      Wild Gunman           16 V  $8064 100000000 1 100 100
Forest Guard Hogans Alley          16 V  $806d 100000000 1 101 101
Space 2050   Duck Hunt             16 V  $8076 100000000 1 110 110
Ufo Race     F1 Race               16 V  $807f 100000000 1 111 111
                                                               
Ufo Shoot    Duck Hunt Clay Shoot  16 V  $8076 100000000 1 110 110
                                                       | | ||| |||
                                                       | | ||| +++- PRG bank
                                                       | | +++ ---- CHR bank
                                                       | + --- ---- mode (0=32K, 1=16K)
                                                       + - --- ---- mirroring (0=V, 1=H)


Uruchamianie - 4 podejście
Kolejnym krokiem było zganie całej pamięci z kodem oraz z grafiką oraz dopisanie do emulatora (FCEUX) kodu realizującego obsługiwany sposób bankowania pamięci w kardridżu (nie widziałem żadnych gotowych numerów mapperów, które mógłbym wykorzystać):



Po tej czynności, wszystkie gry już działały. Niestety, wyświetlana grafika miała błędy::


Wyglądało na to, jakby była przesunięta o jedną linie w pionie (pierwsza linia to jakieś śmieci). Długo nie wiedziałem, o co chodzi, a po analizie odczytanych bajtów wyszło, że pierwszy poprawny bajt jest drugim, drugi trzecim, itp. Dopiero potem mnie olśniło, że przecież tak działa mechanizm odczytu, że gdy CPU chce odczytać dane z magistrali PPU, ustawiając adres przez PPUADDR, a potem odczytując dane przez PPUDATA, pierwsza odczytana wartość pochodzi z rejestru tymczasowego, dopiero kolejne są już prawidłowe. Po uwzględnieniu tego, kardridż wyświetla się już poprawnie i cel został osiągnięty:
Zapisane
Pegasus Gry - forum Pegasusa i gier na Pegasusa
« : 03.05.2018, 11:20:01 »

 Zapisane
Mcin
Twój Moderator
Moderator Globalny
Stały bywalec PG
*****
Wiadomości: 2776



Zobacz profil
« Odpowiedz #1 : 03.05.2018, 12:12:03 »

Pełen szacunek!

Ja niestety jestem w stanie jedynie podziwiać, bo to wszystko dla mnie za mądre, ale chętnie potestuje gotową składankę na emulatorze Uśmiech
Zapisane
VertekS
Aktywny użytkownik
***
Wiadomości: 169



Zobacz profil
« Odpowiedz #2 : 03.05.2018, 18:52:07 »

"Cow Boy"... Super gra słowna, naprawdę. Twórca tego graficznego hacka musiał mieć z tego niezły ubaw. Oglądałem gameplay z tej składanki na YT kiedyś tam dawno i Ufo Race ma klimat muszę przyznać.

- CIRAM !CE i PPU !A13 (te służą do rozszerzania rozmiarów planszy wyświetlanej na ekranie)
Te linie adresowe są podpięte do dodatkowej pamięci RAM w kartridżu służącej do dodatkowych 2 nametable (4 - ekranowy mirroring)? Jedyne co mi przyszło do głowy jak przeczytałem "rozszerzanie rozmiarów planszy", a pytam bo z hardware to noga jestem i fajnie jest się czegoś nowego dowiedzieć z takich wpisów.

Wyglądało na to, jakby była przesunięta o jedną linie w pionie (pierwsza linia to jakieś śmieci). Długo nie wiedziałem, o co chodzi, a po analizie odczytanych bajtów wyszło, że pierwszy poprawny bajt jest drugim, drugi trzecim, itp. Dopiero potem mnie olśniło, że przecież tak działa mechanizm odczytu, że gdy CPU chce odczytać dane z magistrali PPU, ustawiając adres przez PPUADDR, a potem odczytując dane przez PPUDATA, pierwsza odczytana wartość pochodzi z rejestru tymczasowego, dopiero kolejne są już prawidłowe.
Jedno z wielu nietypowych zachowań tej konsoli, że Nintendo poskładało to jakoś do kupy to naprawdę hehe. Nie nazwałbym tego rejestrem tymczasowym tylko buforem i dostaje się jakąś kiedyś tam ustawioną wartość przy ostatnim odczycie na której nie można polegać. Wiem, czepiam się nazewnictwa.

Może za jakieś sto wpisów moja wiedza będzie na tyle duża, żeby wszystko zrozumieć heh. Tak jak pisze Mcin, pełen szacunek.
Zapisane
krzysiobal
Aktywny użytkownik
***
Wiadomości: 225


Naprawie pegasusa każdemu!


Zobacz profil
« Odpowiedz #3 : 07.05.2018, 23:02:30 »

Cytuj
Ja niestety jestem w stanie jedynie podziwiać, bo to wszystko dla mnie za mądre, ale chętnie potestuje gotową składankę na emulatorze
Na FCEUX powinno działać, na innych - nie testowałem
https://ufile.io/p78q0

Cytuj
Te linie adresowe są podpięte do dodatkowej pamięci RAM w kartridżu służącej do dodatkowych 2 nametable (4 - ekranowy mirroring)?
Jeśli w kardridżu jest dodatkowa pamięć która ma zastąpić wewnęrzną pamięć w konsoli, to wewnętrzną pamięc w konsoli można całkowicie wyłączyć.
Jeśli natomiast dodatkowa pamięć ma tylko rozszerzać pamięć w konsoli, to można ją włączać tylko w odpowiednich momentach.

PPU !A13 może też być czasami używane jeśli z jakichś powodów kardridż potrzebuje takiego sygnału (zamiast korzystać z PPU A13 + negatora) - raz się z tym spotkałem w SMB3 pirate bootleg:
https://forums.nesdev.com/viewtopic.php?f=9&t=16123
Zapisane
Strony: [1]
  Drukuj  
 
Skocz do:  

Powered by SMF 1.1.21 | SMF © 2006-2007, Simple Machines
Sitemap
pegasus