Avocado uruchamia pierwszy program

Po kilkugodzinnej sesji czytania assemblera, analizy dumpów pamięci i żmudnego przeklikiwania się debuggerem po breakpointach udało mi się rozwiązać problem, który towarzyszył mi od początku projektu.

Problem

Wspominałem o nim w poprzednim poście - objawiał się tekstem "VSync: timeout", a efektem było wyłączanie przerwań systemowych, co z kolei blokowało wykonywanie kodu, gdyż BIOS jak i ładowane programy czekały na eventy (te generowane są przez przerwania).

Przez cały czas błędnie zakładałem, że to kod obsługujący przerwania znajdujący się w BIOSie wyłącza przerwania w systemie po kilku timeoutach. Przejrzałem dokładnie zdisassemblowany kod odpowiadający za wyświetlanie tego komunikatu, ale nie natrafiłem na nigdzie na modyfikację tej flagi. Znalazłem natomiast instrukcje SYSCALL. Okazuje się, że odpowiada ona za wchodzenie i wychodzenie z sekcji krytycznej - prościej mówiąc wyłącza i włącza przerwania na czas obsługi kodu związanego z przerwaniem. Zajrzałem do kodu emulującego tę instrukcję, a następnie do dokumentacji procesora i dowiedziałem się, że instrukcje SYSCALL i BREAK - w przeciwieństwie do skoków - wykonują się natychmiastowo i nie następuje branch delay slot, który spowodowałby załadowanie kolejnego opcodu po nich.

Rozwiązanie

Problemem był błędnie napisany kod obsługi wyjątków w module procesora, który nie czyścił delay slotu. Rozwiązaniem problemu było dodanie jednej linijki kodu:

Po tej zmianie emulator przestał zawieszać się na komunikacji ze sprzętem i wreszcie był w stanie załadować pierwszy program z płyty:

Gra bootowana z płyty

Timeout nadal się pojawia, ale przestało to wpływać na obsługę przerwań. Jego naprawa wymaga synchronizacji timerów, GPU i CPU.

Photo via VisualHunt.com
Ten wpis został opublikowany w kategorii Avocado, Daj się poznać 2017 - Avocado. Dodaj zakładkę do bezpośredniego odnośnika.