Minął pierwszy miesiąc od startu Daj się poznać 2017 i uznałem to za dobry moment, aby podzielić się w jakim stanie znajduje się mój projekt oraz z jakimi problemami walczę na ten moment.
Muszę nadmienić, że w momencie startu tegorocznej edycji projekt był kontynuowany, a nie rozpoczynany od zera.
Co widać
Co się dzieje
Emulator ładuje BIOS konsoli i bez większych przeszkód wykonuje kod. Jak widać zaimplementowana jest obsługa GPU, a za ładny rendering tego co wyświetla GPU odpowiada OpenGL - jest obsługa trójkątów, prostokątów i sprite'ów, dzięki czemu wyświetla się animacja startowa oraz logo PlayStation. BIOS czyta pierwsze sektory z emulowanego napędu i przechodzi do procesu uruchamiania znajdującego się na płycie programu. W tym momencie emulator się zatrzymuje.
Czego brakuje
Niestety na ekranie nie widać modelu 3d, który powinien pokazać się po załadowaniu płyty. Jest to wina braku implementacji GTE - jednostki odpowiadającej za przekształcenia 3d.
W terminalu widać powtarzający się komunikat VSync: timeout(4:3) - jest to obecnie największy bloker. BIOS oczekuje przerwania VSync w miarę równych i dokładnych odstępach czasowych - 60 razy na sekundę (dla regionu NTSC). Niestety to w jaki sposób emuluję podzespoły wprowadza drobne różnice czasowe pomiędzy GPU, CPU i Timerami. BIOS czekając na następną klatkę zgłasza timeout i wyłącza przerwania sprzętowe. Objawia się to tym, że podzespoły takie jak CDROM czy Timery nie mogą zgłosić przerwania i BIOS zawiesza się w niektórych momentach czekając na zakończenie pewnych działań (np. odczyt sektoru).
Problem ten nie ogranicza się do BIOSu - obejmuje praktycznie wszystkie programy uruchamiane na emulatorze. Nawet proste gry homebrew w swoim kodzie oczekują na VSync (koniec klatki), aby synchronizować renderowanie do 60Hz.
Dla testów ręcznie wyzwalam przerwania co odblokowuje program, dzięki czemu emulator próbuje bootować płytę, jednak takie działanie często powoduje crashe i nie rozwiązuje problemu, a jedynie go tymczasowo omija.
Co robię
W ostatnich commitach refactorowałem kod: rozdzieliłem kod odpowiadający za renderowaniem pod Windowsem do osobnych plików, dzięki czemu wersja Linuksowa nie potrzebuje SDL i OpenGL do zbudowania. Poprawiłem synchronizację GPU z CPU z pozostałymi podzespołami, ale nie usunęło to błedu, o którym pisałem wyżej. Pozbyłem się obsługi GDB - debugger okazał się zbyt ograniczający, a jego interfejs jest bardzo nieintuicyjny dla osoby używającej Visual Studio.
Dodałem obsługę WebSockets - dzięki temu mogę stworzyć wygodny w obsłudze interfejs w HTML+JS i sterować wykonaniem emulatora z poziomu przeglądarki. W tym momencie komunikacja jest jednostronna i wyświetlane jest kilka rejestrów, ale efekty są zachęcające i bardzo chciałbym dopracować tą funkcjonalność. Używam Rivets.js do data bindingu.