DPTP motor: ...
DPTP motor: ...
Írjunk játékot SEGA MD konzolra - 10. SEGA hangzás
Blog
2020-06-24 15:57
don_peter
Írások: 20

Írjunk játékot SEGA MD konzolra - 10. SEGA hangzás

Írjunk programot SEGA MD konzolra

A tizedik fejezet nem másról mint a SEGA MD hangképzéséről fog szólni. Próbálom konyhanyelven leírni, hogy miképpen képes a SEGA ilyen jó kis dallamokat lejátszani. Kezdjük is azzal, hogy a SEGA MD két jól elkülöníthető hangképző áramkört tartalmaz. Az egyik ilyen a szakzsargonban csak PSG néven ismert SN76489AN IC, amely igazából csak a fehér zajokat generál, mint társ vagy kiegészítő másodlagos hanggenerátor a jól ismert YAMAHA 2612-es FM szintézer mellett. A SEGA igazi hangereje ebben a YM2612-ben van, erre épít minden játék és program.

Apró kitérés mindazoknak, akik kifejezetten csak a nyers programot keresik ebben a bejegyzésben, attól tartok, hogy ez ebben a leírásban biztosan nem lesz nyilvános, révén még én sem írtam meg a bonyolultsága miatt. De azért elkeseredni még sem kell, mert a logikáját részletesen bemutatom és annak megértésével és persze a SEGA programozásban szerzett  tapasztalatok felhasználásával, ha nem is tök könnyen, de viszonylag egyszerűen le lehet programozni.

Specifikációk:
Az SN76489N összesen 4 csatornán tud meg szólalni, ebből 3 csatornán 3 különböző négyszöghullámot képes előállítani, mondhatni elég széles frekvenciatartományban, amelyeket 16 különböző hangerő szinten képes megszólaltatni. A 4. csatorna csak 2féle zajt tud generálni, fehér zajt illetve periodikus zajt, 3 különböző frekvencián és szintén mint az előző 3 csatorna esetében 16 különböző hangerőt lehet beállítani. Ennek a hanggenerátornak szüksége van külső órajelre, erre vagy fix oszcillátort használunk vagy egy óra jel generátor-t. Normál működési frekvenciája 3.58MHz. De ezt a kis IC-t nem csak mint hang előállító eszközként használták fel, hanem sok játék esetében támaszkodtak rá, mint társ vagy mint egyetlen számítási processzor vagy is volt, hogy speciálisan erre kis eszközre írtak kisebb programokat. Kifejezetten sok helyen, sok konzolban használták ezt a kis áramkört, párat listázok is nektek: ALF MC1 hangkártya (az Apple 2. kiegészítő kártyája 3db ilyen IC-t használ, összesen kilenc hang csatorna és 3 zaj generálásra volt képes), BBC Micro, CreatiVision, Geneve 9640, IBM PCjr, Neo Geo Pocket, Neo Geo Pocket Color, Game Gear (a VDP-jébe integrált klónt használt), Sega Genesis, Mester rendszer (a VDP-jébe integrált klónt használt), Mega tech, Pico, SG-1000, Sharp MZ-800, ...stb

SN76489AN PSG

VGP 1.70 program megírásakor a PSG-re írt adatállományból összességében csak 2 parancsra kell reagáljon a PSG, az egyik ilyen parancs a 0x4F a másik pedig a 0x50. Az előbbi esetben (0x4F) a GG vagy is a SEGA GAME GEAR hang adatát jelölik, utóbbi eseten pedig minden mást, amely a PSG-nek szól. Mindegyik parancsot a hang adata követi, vagy is egy a rá következő adatot kel vennünk. Első esetnél még figyelni kell, hogy a GG esetében egy az első adat amit ki kell küldeni a PSG-nek megelőzi egy 0x06 port parancs, amellyel tudatjuk a PSG-vel, hogy STEREO adattal van dolga. Mind ez egy vázlatként pszeudokódban leírva a következőként fest:

INDEX := 0x64
VETTADAT := 0
ELJÁRÁS PSG:
CIKUS AMÍG ADAT[INDEX] != 0x66-AL
    VETTADAT := ADAT[INDEX]
    HA VETTADAT <> 0x4F
        INDEX := INDEX+1
        PSG := 0x06
        PSG := ADAT[INDEX]
    HA VETTADAT <> 0x50
        INDEX := INDEX+1
        PSG := ADAT[INDEX]
    INDEX := INDEX+1
CIKLUS VÉGE
ELJÁRÁS VÉGE

       
Úgy gondolom ennyi erről az áramkörről illetve annak ismertetéséről bőven elég kell legyen, aki ennél többre kíváncsi az csapja fel a google keresőjét és keressen rá az SN76489AN szócskára, meg fog lepődni mennyi infó felbukkan. ;) Ha nem boldogulnál, akkor pedig ajánlom figyelmedbe a direkt a blog bejegyzéseknek fenntartott fórum topikot, melyre ide kattintva elnavigálhatod magad: Írjunk játékot SEGA MEGA DRIVE konzolra
Kérdezz bátran.

YAMAHA 2612 vagy másként YM2612, a fő góré.

Mondanom sem kell, hogy ez a SEGA MD lelke, legalább is ami a hangokat illeti, ez a kis áramkör brutálisan jól tud szólni, jöjjenek is a specifikációi: Összesen 7 csatorna, ebből 6 FM csatorna és 1 LFO csatorna, csatornánként négy operátor, két időintervallum, szinuszhullámú alacsony frekvenciájú oszcillátor, integrált sztereó kimeneti digitál-analóg átalakító (a legtöbb más Yamaha FM csipekhez külön külső D / A konverterre van szükség, ilyen lesz sajna a később górcső alá vett YM2610-is a NeoGeo hangprocija), csatornánként programozható sztereó hang (bal, jobb, illetve bal és jobb egyaránt, középpontot eredményezve), a harmadik csatorna esetében az operátor frekvenciái egymástól függetlenül beállíthatók, lehetővé téve a disszonanciaharmonikákat. Ez a típus azonban nem rendelkezik saját ADPCM csatornával, de képes a többi csatorna felfüggesztésével a 6. csatornán alapszintű PCM vagy is felvett hangmintákat lejátszani. Sajnos mivel nem rendelkezik saját dedikált ADPCM csatornával, így nem rendelkezik saját PCM időzítéssel sem, ezért minden olyan hang anyagot, amelyek a PCM csatornát használják, gondoskodni kell a meghajtó processzor programjában annak időzítéséről is. Ez utóbbit később majd még részletesebben is kifejtem, mert nekem is meggyűlik a bajom a PCM lejátszásával. (aszinkron elcsúsznak az időzítsek) Szintén mint a PSG esetében, itt is szükség van külső órajelre, ezt oszcillátor vagy beállítható jelgenerátorral kell létrehoznunk. Normál működési frekvenciája 7.67MHz.

YM2612 szintézer

VGP 1.70 program írásánál összességében csak 2 parancs hivatkozik a YM2612 szintézerre, de a PCM használata miatt fontos még további 3 parancs. Az első két parancs a 0x52 és a 0x53 ezzel a YM adatportra küldjük ki a soron következő adatot, a PCM részét illetően a 0x67 a 0x8F és 0xE0 parancsok fontosak. Előbbi vagy is a 0x67 a PCM adat betöltéséért felelős a 0x8F a soron következő PCM adat YM adatportjára történő kiírásáért felelős, utóbbi 0xE0 pedig a PCM adat pozíciójának változtatásában játszik fontos szerepet. Ennek vázlata pszeudokód kódban a következő képen mutat:

INDEX := 0
VETTADAT := 0
ADAT := 0
CIM := 0
PCMPOZ := 0
PCMPOZSTART := 0
ELJÁRÁS YM2612
    CIKLUS AMÍG ADAT[INDEX] != 0x66-AL
        VETTADAT := ADAT[INDEX]
        HA VETTADAT <> 0x52 VAGY 0x53
            INDEX := INDEX+1
            CIM := ADAT[INDEX]
            INDEX := INDEX+1
            ADAT := ADAT[INDEX]
            YMPORT := CIM
            YMPORT := ADAT
        HA VETTADAT <> 0x67
            INDEX := INDEX+2
            PCMPOZ := (ADAT[INDEX++] << 8) | (ADAT[INDEX++] << 8) | (ADAT[INDEX++] << 8) | ADAT[INDEX]
            PCMPOZSTART := INDEX
        HA VETTADAT <> 0x8F
            INDEX := INDEX+1
            CIM := 0x2A
            PCMPOZ := PCMPOZ+1
            ADAT := ADAT[INDEX+PCMPOZ]
            YMPORT := CIM
            YMPORT := ADAT
        HA VETTADAT <> 0xE0
            INDEX := INDEX+1
            PCMPOZ := PCMPOZSTART
            PCMPOZ += (ADAT[INDEX++] << 8) | (ADAT[INDEX++] << 8) | (ADAT[INDEX++] << 8) | ADAT[INDEX]
        INDEX := INDEX+1
    CIKLUS VÉGE
ELJÁRÁS VÉGE


Nos mind két eljárásban találkoztattatok a 0x66-os paranccsal, ez annyit tesz, hogy vége a VGM zenének, így ott vagy vége a ciklusnak vagy kezdjük előröl, a pszeudokódunkban csak addig tart a ciklus, ameddig 0x66-os parancs nem érkezik. Természetesen ennél jóval több parancsra kell majd figyelni, a fentebbi pszeudokódban csak az alapokat mondhatni a legfontosabb részeket emeltem ki, de további parancsok vannak az időzítésekre, amelyek létfontosságúak, hogy a hangokat a megadott ideig tartsa ki és ne tovább vagy éppen semennyire. Összesen a kész kódunkban 42 különféle paranccsal találkozhatunk ebből az itt fel nem sorolt vagy meg nem adott parancsok mindegyikének az időzítéshez van köze. A SEGA MD 44.1KHz-es mintaközökkel dolgozik, ezen minta közök ismétlődését határozzák meg az időzítéses parancsok. Ez időben amúgy 22.5uS (mikromásodperc, ami a másodperc milliomod része) vagy is egy hangminta köz 0.0000225 másodperc ideig tart. Ez alatt a 22.5uS alatt kell annak a programnak végrehajtódnia, amely a hangmintát beolvassa és kiküldi a célprocesszornak, esetünkben a YM2612-nek vagy PSG-nek.

C18-ban programozva

Mind ez ASM-ben kicsit nehézkes lesz, de majd később teszek egy kísérletet a megírására. Maga a SEGA M68K processzora minden egyéb mellett nem lenne képes erőforrásasiból annyit felszabadítani, amely elég lenne a zenei adatok kiküldésére YM és PSG részére, így egy köztes megoldást alkalmaz, mégpedig azt, hogy közbeiktat egy másik CPU-t, amely csak arra lesz hivatott, hogy a zenéket lejátssza. Most jön képbe a Z80, amely itt nem egy társprocesszor, hanem egy további hardveres ék, amellyel áthidalja a SEGA az erőforrás hiányt. A Z80-nak nincs semmi más dolga, csak egy előre megírt programot töltenek fel, amely a zene folyamatos lejátszását biztosítja, illetve ha kell valami váltás vagy effekt, akkor M68K a Z80 rendszerbuszon egy címmel és adattal elintézi azt. Jó és egyszerű megoldás, amely nem igényel M68K-tól extra nagy erőforrásokat. ;)

VGM
Végezetül egy nyersebb téma, amely maga a VGM adathalmaz vagy fájl adatszerkezetét hivatott kicsit bemutatni, persze nem túl részletesen mert erre vannak leírások és elég részletesek, de felületesen gondoltam átfutom nektek a fontosabb részeit. A VGM adatszerkezetet én személy szerint 4 részre tudom felosztani:
    1. VGM header - ezen része a fájlnak tartalmazza azt, hogy valóban VGM fájlról van e szó, vagy hogy mekkora a zene adat mérete, milyen hangprocesszorokat támogat az aktuális zene, mekkora frekvencián kell a lejátszásához,  milyen verziójú a VGM, GD3 adatok címét, minták számát, ...stb
    2. A VGM parancsok és adatok sorozata, ez a zene adat hosszának megfelelő adatsorozat
    3. PCM adatok, nem minden VGM tartalmaz PCM adatot, de amelyik igen annak van egy jól elkülönített része, amely ezeket a felvett hangmintákat tartalmazza
    4. GD3 adatok, ezek az adatok tartalmazzák a zenével kapcsolatos információkat, pl. ki a szerző, mi a címe, milyen játékhoz készült és mikor, ...stb.
Ezzel kapcsolatban további részletes leírást itt találsz: VGM 1.70

Én úgy gondolom körbe is jártam a témát és jelenleg nem tudok többet vagy csak érdemben többet hozzá tenni, ha bármi kérdésed lenne keress  a blog bejegyzés topikjába és tedd fel azt, ha kimaradt valami szívesen veszem a kiegészítéseket és vagy javaslatokat a javításra.

DPTP VGM Player 2.0

Az első és az utolsó képen a YM2612 és PSG együttes tesztelésére készült prototípus látható, melyek segítettek a pontosabb és jobb megértésben + tanítottak hardver és a szoftveres megoldások tekintetében is. Ezen megoldások működése közben jöttem rá egy csomó olyan dologra, amelyeket most le tudtam nektek írni és emelet kellemes szórakozást is nyújt a fejlesztés öröme. Ezen egységek elérhetőek lesznek, ha végére értem az optimalizálásnak és bárki hozzáférhet majd egy példányhoz, aki szeretne.. ;)

Az eddigi megjelent BLOG bejegyzéseim a témában:
Írjunk játékot SEGA MEGA DRIVE konzolra - 10. SEGA hangzás (itt vagy most)

Természetesen ezen cikk végéről sem maradhat le azon link mutatója, ahol feltehetitek kérdéseiteket a témában: Írjunk játékot SEGA MEGA DRIVE konzolra

A neo-geo.hu legyen veled!
DPTP motor: GDPR infomráció!
2018 Május 25.-től hatályba lépett adatvédelmi szabályzatról itt olvashatsz bővebben: Adatvédelmi tájékoztató
Az oldal további használatához el kell olvasnod és fogadnod az adatvédelmi és cookie-k használatával kapcsolatos tájékoztatonkat.

Elfoadom!
Nem fogadom el!