Syntezator na Game Boya: implementacja Runglera w asemblerze
Tworzenie programowego syntezatora dla Game Boya (DMG/CGB) w oparciu o idee syntezy modularnej i sekwencjonowania. Projekt rozpoczął się od próby emulacji Rungler Circuit – układu Roba Hordjika z dwoma oscylatorami i rejestrem przesuwnym do chaotycznej modulacji. Implementacja w asemblerze Sharp SM83 bez sprzętowego urządzenia, tylko emulatory BGB i Same Boy.
Historia i inspiracje
Idea powstała po zapoznaniu się z pracami Essa Mattissona: jego utworem na Dirtywave M8 (jedna ścieżka) i wtyczką Junior do syntezy 4-bitowej, podobnej do LSDJ. RetroPlug umożliwia integrację emulatora Game Boya w DAW jako VST z obsługą MIDI. Cel – uzyskanie z APU Game Boya (4 kanały: 2x pulse, wave, noise) chaotycznych dźwięków: blipy, blupy, szumy.
Rungler Circuit: dwa oscylatory, jeden wyzwala 3-bitowy rejestr przesuwny (LFSR), którego wyjście (0–7) moduluje częstotliwości oscylatorów. Chaotyczność zgodnie z teorią chaosu – małe zmiany parametrów dają radykalne przesunięcia dźwiękowe.
Możliwości techniczne Game Boya
Rewizja APU i CPU pod kątem wykonalności:
- Rejestr przesuwny: 8-bitowy bajt z operacjami bitowymi (shift, OR). Łatwy do zaimplementowania.
- Oscylatory: Kanały 1–2 (pulse z duty cycle). Częstotliwość min. 64 Hz, dodano licznik dla dyskretyzacji. Kanał 1 obsługuje sweep.
- Modulacja: Zapis do rejestrów audio (np. $FF17 dla volume CH1). Brak sprzętowego mnożenia – operacje bitowe zamiast. Volume: 4-bit (0–$F). Częstotliwość: NR13/NR14, stosowana na końcu fragmentu bez retriggera.
- Odczyt oscylatorów: Tylko na GBC (niedokumentowane rejestry), emulatory BGB/SameBoy obsługują.
- UI: Sprity w VRAM, przerwanie VBlank (~60 Hz, 4560 cykli) dla aktualizacji. Grafika kafelkowa 160x144.
Problemy czasu rzeczywistego: retrigger kanału powoduje trzaski, modulacja częstotliwości jest stabilniejsza.
Rozwój w asemblerze
Narzędzia: RGBDS + wtyczka VSCode. Dlaczego asm, nie C? Optymalizacja dla czasu rzeczywistego, analiza cudzego kodu C wykazała inline asm.
Kluczowe wyzwania:
- Timing VBlank: Logika w przerwaniu, <1500 cykli (profilowanie). Przekroczenie – tearing (śmieci na ekranie).
- Arytmetyka 16-bit: Ręczne zarządzanie rejestrami A, zmienne – ręczne śledzenie.
- Operacje bitowe: Brak mul/div – tablice lub shifts/OR/XOR.
- Pamięć: Zapis VRAM tylko w VBlank (wiersze 0–153).
Początek: tutoriale, Pandocs, pomoc AI dla "Hello World". UI: kursor, parametry (częstotliwości, modulacja), reaktywne aktualizacje.
Implementacja i ograniczenia
- Logika LFSR: Wyzwalanie od oscylatora1, bramka od oscylatora2 ustawia wejście. 3 bity → DAC (0–7) → skalowanie + bias → rejestry.
- Sekwencjonowanie: LFSR dla wyzwalaczy, okresowy retrigger.
- Optymalizacje: Czyszczenie ekranu, rysowanie kursora, wizualizacja LFSR. Profilowanie: bezpieczna strefa.
Wynik: nie pełny Blippoo Box (ograniczenia 4-bit, timing), bliżej Double Knot. Dźwięki: pulsacje → szumy.
Co jest ważne:
- APU Game Boya nadaje się do modulacji LFSR, ale czas rzeczywisty ograniczony retriggerem i 4-bitowością.
- VBlank – krytyczne dla UI (<1500 cykli), asm konieczny dla korzyści.
- Rejestry GBC do odczytu oscylatorów – niedokumentowane, zależne od emulatora.
- Operacje bitowe zamiast mul: wystarczające dla efektów chaotycznych.
- Projekt skalowalny: wave CH3, Karplus-Strong w planach.
Perspektywy rozwoju
Dalej: synteza 4-bitowa (CH3 wave), Karplus-Strong/Risset Drum, performanse audiowizualne (inspiracja Robert Henke), debugowanie profilera, limity arytmetyki 16-bit.
— Editorial Team
Brak komentarzy.