Paměťový interface Na začátku jsem již napsal, že EMU je vybaveno 24-bitovým paměťovým interfacem. Adresace však neprobíhá po bytech, ale po wordech, a tím je EMU (bohu dík) odsouzeno k používání výhradně 16-bitových samplů. Paměťový prostor EMU je rozdělen do dvou částí. První část od adresy 000000h-1FFFFFh je obsazena 1MB (0.5MB) MGM ROM. Je to divné, ale EMU pro ROM vyhradilo 4MB. Zbylých 28MB od adresy 200000h je mapováno do DRAM, která je integrována mimo čip. Prostor 0FFFFE0h-0FFFFFFh je rezervován a není použit (pochybuju, že vám bude někdy chybět). Pro čtení nebo zápis dat do pamětí musí být jeden nebo více kanálů nastaveno na DMA přenos. Pokud si alokujete větší počet kanálů, rychlost přenosu je větší. Rychlost přenosu je odvozena od základního kmitočtu oscilátoru a ten je 44.1kHz, takže pokud si alokujete pro DMA všech 32 kanálů (což, jak se dále dočtete, není možné), tak je rychlost přenosu 32 x 44.1kHz = asi 1.34 MB/sec. Jak už jste si asi všimli v tabulce registrů, EMU má 4 druhy paměťových přístupů: Left Read, Right Read, Left Write, Right Write. Pro čtení a zápis jsou zde vždy dva kanály a u každého kanálu můžeme použít různou adresu. Asi jste si taky všimli, že registry SMLD a SMRD mají stejné číslo a datové porty jsou umístěny vedle sebe. Toto se přímo nabízí pro přenos stereofonních samplů, kde si např. naprogramujete Right DMA na adresu Left + délka samplu a pak budete kopírovat sampl po dwordech - oba kanály naráz. Nyní si popíšeme způsob, jak lze uvést oscilátor (kanál) do DMA režimu. Procedure SetChanelToDMA(o:oscilator,m:DMAmode); out(DCYSUSV[o],80h); {vypneme generátor obálek} out(VTFT[o],0); out(CVCF[o],0); {hlasitost a cutoff na nulu} out(PTRX[o],40000000h); out(CPF[o],40000000h); {pitch na nulu} out(PSST[o],0); out(CLS[o],0); {Loop Start a Loop End na nulu} out(CCCA[o],4000000+(m shl 24)); {nastav a povol DMA režim} Procedure_End; Mód CCCA Režim 0 4000000h Left Read 1 5000000h Right Read 2 6000000h Left Write 3 7000000h Right Write Adresa se poté zapíše do příslušného SMA registru. Adresa se automaticky inkrementuje. DMA režim se vypne, pokud do registru CCCA příslušného oscilátoru zapíšete nulu. Při zápisu se musí kontrolovat bit "FULL" v SMAxW registru. Pokud je tento bit nulový, je možné zapsat na SMxD registr další hodnotu, kterou chcete uložit do paměti. Při čtení se postupuje obdobně jako u zápisu, ale testujeme bit "EMPTY" v SMAxR registru. Pokud je bit nulový, můžeme číst další hodnotu. Při programování EMU a práci s pamětí jsou ovšem dva problémy. Prvním problémem je, že EMU neumí přehrávat jednoduché (single-shot) samply. Musíte si tedy přizpůsobit LOOP tak, aby byla při skončení samplu přehrávána krátká smyčka (obvykle 4 samply kvůli interpolaci). Druhý problém je to, že přídavná pamět je typu DRAM a tím pádem potřebuje občerstvovat. EMU ale občerstvování paměti neumí a tak musíme obětovat dva oscilátory (30 a 31) na občerstvování paměti. Kromě občerstvování paměti umí tento režim taky produkovat Reverb a Chorus pro FM OPL3. Tuto rutinu vám asi kompletně neokomentuju, protože sám nevím jak pracuje. Je to opsané z Grinusova AWE Control Packu a jak se mi svěřil, tak to zase opsal z AWE Developer Packu, takže jak to funguje, ví jenom u Creative a u EMU Systems. Berte to jako černou skříňku. :) Procedure RefreshFMEff(r:reverb,c:chorus); out(DCYSUSV[30],80h); out(PSST[30],0FFFFFFE0h); out(CSL[30],0FFFFE8h+(c shl 24)); out(PTRX[30],r shl 8); out(CPF[30],0); out(CCCA[30],0FFFFE3h); out(DCYSUSV[31],80h); out(PSST[31],0FFFFF0h); out(CSL[31],0FFFFE8h+(c shl 24)); out(PTRX[31],(r shl 8)+0FFh); out(CPF[31],8000h); out(CCCA[31],0FFFFF3h); asm cli mov dx,BASE+802h {E22h} mov ax,3Eh out dx,ax xchg bx,dx mov dx,BASE {620h} xor ax,ax out dx,ax xchg bx,dx L1: in ax,dx test ah,10h jz L1 L2: in ax,dx test ah,10h jnz L2 mov dx,bx add dx,2 mov ax,4828h out dx,ax mov dx,BASE+802h {E22h} mov ax,3Ch out dx,ax mov dx,bx add dh,4 xor ax,ax out dx,ax sti asm_end; out(VTFT[30],8000FFFFh); out(VTFT[31],8000FFFFh); Procedure_End; výheň