6.2.1. Sound Blaster 16 felépítése és programozása
6.2.1.1. Lehetőségek
1) FM chip:
- Bővített OPL–3 FM chip, amely négyoperátoros hangkeltésre is alkalmas,
- Teljes kompatibilitás az előző ADLIB és SB (kivéve SB Pro) változatokkal,
- 18 kétoperátoros, vagy 6 négyoperátoros hangcsatorna,
2) Továbbfejlesztett DSP egység:
- 8- és 16 bites felvétel és lejátszás,
- Sztereó és mono felvétel és 8- és 16 bites módban,
- Dinamikus szűrők a felvételhez és a visszajátszáshoz,
- Két DMA csatorna a DMA vezérelt felvételhez és lejátszáshoz,
- Kibővített DSP parancskészlet,
- Lineáris lépésekben programozható mintavételi frekvencia 5-től 48 kHz-ig,
3) Bővített keverő (mixer):
- A bemeneti eszközök lehetséges keverése,
- Magas és mély állítási lehetőségek,
4) Szoftverből állítható hangerő minden kimenethez
5) Beépített sztereó erősítő:
- 4 W/csatorna, 4 ohmos hangszórókhoz,
- Automatikus, vagy fix erősítés mikrofonhoz,
- Külső, vagy belső erősítő a kimenetekhez
6) MIDI csatlakozó:
- SB, vagy MPU401–UART kompatibilis mód,
7) CD-ROM csatlakozó
8) Hardverbeállítások szoftverből:
- Szoftverből állítható megszakítási szint,
- Szoftverből állítható 8- és 16 bites DMA csatorna szám.
6.2.1.2. A DSP programozása
Az SB16 DSP-je a következő I/O címeken keresztül érhető el:
I/O relatív cím | I/O alapbeállítású cím | DSP funkció |
Base+$06 | $226 (write only) | A DSP alapállapotba hozása (DSP Reset) |
Base+$0A | $22A (read only) | Adat olvasása az ADC-ről (Read Data) |
Base+$0C | $22C (read/write) | Parancs/adat írása a DAC-ra (Write command/data)Bufferállapot olvasása (Read Buffer Status) |
Base+$0E | $22E (read only) | Adatérvényesség olvasása, a 8 bites megszakítás nyugtázása (Data Available, 8 bit IRQ Acknowledge) |
Base+$0F | $22F (read only) | A 16 bites megszakítás nyugtázása (16 bit IRQ Acknowledge) |
A fontosabb SB16 DSP parancsokat a T.2. foglalja össze.
T.2. Fontosabb SB16 DSP parancsok
Kód | Parancs | Parancsfunkció |
$1C | 8 bit auto-init DMA play | 8-bites auto-init DMA lejátszás |
$D0 | Pause 8 bit DMA | 8-bites DMA átvitel felfüggesztése |
$D1 | Speaker On | A DSP kimenetének bekapcsolása |
$D3 | Speaker Off | A DSP kimenetének kikapcsolása |
$D4 | Continue 8 bit DMA | 8-bites DMA átvitel folytatása |
$D5 | Pause 16 bit DMA | 16-bites DMA átvitel felfüggesztése |
$D6 | Continue 16 bit DMA | 16-bites DMA átvitel folytatása |
$D9 | Exit 16 bit auto-init DMA | 16 bites auto-init DMA leállítása |
$DA | Exit 8 bit auto-init DMA | 8 bites auto-init DMA leállítása |
$E1 | Get DSP version | DSP verziószámának lekérdezése |
$2C | 8 bit auto-init DMA record | 8bites auto-init DMA felvétel |
$40 | Set Time Constant | A mintavételezési időállandó beállítása |
$41 | Set play sample rate | Mintavételi frekvencia beállítása lejátszáshoz |
$42 | Set record sample rate | Mintavételi frekvencia beállítása felvételhez |
$48 | Set DMA block size | DMA blokkméret beállítása |
$B6 | 16 bit auto-init DMA play | 16 bites auto-init DMA lejátszás |
$BE | 16 bit auto-init DMA record | 16 bites auto-init DMA felvétel |
$B0 | 16 bit normal DMA play | 16 bites normál DMA lejátszás |
$B8 | 16 bit normal DMA record | 16 bites normál DMA felvétel |
$C6 | 8 bit auto-init DMA play | 8 bites auto-init DMA lejátszás |
$CE | 8 bit auto-init DMA record | 8 bites auto-init DMA felvétel |
$C0 | 8 bit normal DMA play | 8 bites normál DMA lejátszás |
$C8 | 8 bit normal DMA record | 8 bites normál DMA felvétel |
$F2 | IRQ request (8 bit) | DSP szoftveres megszakításkérés 8 bites átvitelhez |
$F3 | IRQ request (16 bit) | DSP szoftveres megszakításkérés 16 bites átvitelhez |
$FB | Read DSP status | DSP állapotának lekérdezése |
$FC | Get DSP information | További információ a DSP állapotáról |
$FD | Get last DSP command | Az utolsó DSP parancs lekérdezése |
A következő Pascal-ban használt Assembly betéteknek a DSP programozása során vehetjük hasznát. A DSP programozására készített teljes unit forrását F.25-ben találhatjuk.
function DSPreset:boolean; assembler;
asm
mov dx,BaseAddr { A báziscím:$220 a DX regiszterbe kerül. }
add dl,$06 { DX=$226, DSP Reset. }
mov al,$01
out dx,al { Egy $01 érték kiküldése. }
mov cx,100
rep lodsb { Várakozás. }
xor al,al
out dx,al { Egy $00 érték kiküldése. }
add dl,$08 { DX=$22E, Data Available. }
mov cx,128
@wait1: { Várakozás, amíg az adat érvényes nem lesz. }
in al,dx
and al,$80
jnz @test2 { Kiugrás, ha érvényes. }
loop @wait1
jmp @bad { Hiba, ha lejárt a ciklus. }
@test2:
mov cx,10240
sub dl,$04 { DX=$22A, DSP Read Data. }
@wait2:
in al,dx
cmp al,$0aa { A $AA értéket kell adnia. }
jz @good { Ugrás, ha a Reset sikeres. }
loop @wait2
@bad:
xor al,al { Hiba, ha Al=false. }
jmp @exit
@good:
mov al,$01 { Nincs hiba, ha AL=true. }
@exit:
end;
DSPreset: a Sound Blaster DSP egységének alapállapotba hozása. A függvény megpróbálja inicializálni a DSP egységet. Ha ez sikerül, vagyis a beállított időintervallumon belül a megfelelő értéket észleli, akkor igaz értékkel tér vissza. Ha az időzítési ciklus lejártával sem érzékeli a megfelelő eredményeket, akkor a DSP nem működik helyesen és hamis értékkel tér vissza.
procedure DSPwrite(DSPdata:byte); assembler;
asm
mov dx,BaseAddr { Báziscím:$220 a DX regiszterbe. }
add dl,0ch { DX=$22C, Read Buffer Status. }
@c1:
in al,dx
and al,$80 { Szabad már a regiszter? }
jnz @c1 { Várakozás, ha még nem. }
mov al,DSPdata { AL=adat/parancs. }
out dx,al { Write Command/Data. }
end;
DSPwrite: egy adat, illetve parancs kiküldése a DSP-nek.
function DSPread:byte; assembler;
asm
mov dx,BaseAddr { Báziscím:$220 a DX regiszterbe. }
add dl,$0e { DX=$22E, Data Available. }
@wait:
in al,dx { Várakozás, amíg az adat érvényes nem lesz. }
and al,$80
jz @wait
sub dl,$04 { DX=$22A, DSP Read Data. }
in al,dx { Az adat beolvasása AL-be. }
end;
DSPread: adat beolvasása a DSP-ről.
F.31-ben további példákat láthatunk a DSP programozására.
6.2.1.3. A mixer programozása
Az SB16 mixer a következő I/O címeken keresztül érhető el:
Regiszter I/O cím | Alapbeállítású I/O cím | Funkció |
Base+$04 | $224 |
Mixer címregiszter (address) |
Base+$05 | $225 (r/w) | Mixer adatregiszter (data) |
Az SB16 mixerének regisztereit a T.3. ismerteti részletesebben.
T.3. Az SB mixerének fontosabb regiszterei
Regiszter | Funkció |
$30 Master Volume Left | Kimeneti hangerő, bal oldal |
$31 Master Volume Right | Kimeneti hangerő, jobb oldal |
$32 DSP Voice Volume Left | DSP hangerő, bal oldal |
$33 DSP Voice Volume Right | DSP hangerő, jobb oldal |
$34 MIDI/FM Volume Left | MIDI/FM egység hangerő, bal oldal |
$35 MIDI/FM Volume Right | MIDI/FM egység hangerő, jobb oldal |
$36 CD Volume Left | Audio CD hangerő, bal oldal |
$37 CD Volume Right | Audio CD hangerő, jobb oldal |
$38 Line In Volume Left | Vonali bemeneti hangerő, bal oldal |
$39 Line In Volume Right | Vonali bemeneti hangerő, jobb oldal |
$3A Microphone Volume | Mikrofon hangerő |
$3B PC-Speaker Volume | PC-Speaker hangerő |
$3C Output Select | Kimeneti eszközök kiválasztása |
$3D Left Input Device Select | Bal oldali bemeneti eszközök kiválasztása |
$3E Right Input Device Select | Jobb oldali bemeneti eszközök kiválasztása |
$3F Left Input Gain Level | Bal oldali bemeneti erősítési szint |
$40 Right Input Gain Level | Jobb oldali bemeneti erősítési szint |
$41 Left Output Gain Level | Bal oldali kimeneti erősítési szint |
$42 Right Output Gain Level | Jobb oldali kimeneti erősítési szint |
$43 Microphone AGC Control | Mikrofon AGC engedélyezés/tiltás |
$44 Left Treble Level | Bal oldali magas szint szabályozás |
$45 Right Treble Level | Jobb oldali magas szint szabályozás |
$46 Left Bass Level | Bal oldali mély szint szabályozás |
$47 Right Bass Level | Jobb oldali mély szint szabályozás |
$80 Interrupt Level Select | Megszakítási vonal kiválasztása |
$81 DMA Channels Select | DMA csatornák kiválasztása (8, 16 bit) |
$82 Interrupt Request Status | Megszakításkérés állapot |
A mixer néhány fontosabb regiszterének részletezése
Reg. | 7. bit | 6. bit | 5. bit | 4. bit | 3. bit | 2. bit | 1. bit | 0. bit | Megjegyzés |
$3C | – | – | – | Line Lf | Line Rg | CD Lf | CD Rg | Mic | 0: tiltás,1: engedélyezés |
$3D | 0 (fix) | MIDI Lf | MIDI Rg | Line Lf | Line Rg | CD Lf | CD Rg | Mic | 0: tiltás,1: engedélyezés |
$3E | 0 (fix) | MIDI Lf | MIDI Rg | Line Lf | Line Rg | CD Lf | CD Rg | Mic | 0: tiltás,1: engedélyezés |
$42 | Gain | Gain | – | – | – | – | – | – | 00: egyszeres erősítés,01: kétszeres erősítés,10 négyszeres erősítés,
11: nyolcszoros erősítés |
$43 | – | – | – | – | – | – | – | FGC/AGC | $00: fix erősítés,$01: automatikus erősítésszabályozás |
$80 | – | – | – | – | IRQ 10 | IRQ 7 | IRQ 5 | IRQ 2 | Mindig csak egy bit legyen 1 |
$81 | DMA 7 | DMA 6 | DMA 5 | – | DMA 3 | – | DMA 1 | DMA 0 | Egyszerre csak egy bit lehet 1 mindkét részben |
High DMA | Low DMA | ||||||||
$82 | 1 (fix) | 0 (fix) | 0 (fix) | 0 (fix) | ? | UART | DSP 16 | DSP 8 | A regiszter alsó három bitje azt adja meg, hogy melyik eszköz okozta a megszakítást. |
A következő programrészleteknek a mixer programozása során vehetjük hasznát:
procedure SetMixer(RegNum,Value:byte); assembler;
asm
mov dx,Base { Báziscím:$220 }
add dx,$0004 { Mixer címregiszter:$224 }
mov al,RegNum
out dx,al { Cím kiküldése }
inc dx { Mixer adatregiszter:$225 }
mov al,Value
out dx,al { Adat kiküldése }
end;
A SetMixer eljárás segítségével a mixer egy adott regiszterét lehet beállítani.
function GetMixer(Regnum:byte):byte; assembler;
asm
mov dx,Base { Báziscím:$220 }
add dx,$0004 { Mixer címregiszter:$224 }
mov al,Regnum
out dx,al { Cím kiküldése }
inc dx { Mixer adatregiszter:$225 }
in al,dx { Adat beolvasása }
end;
A GetMixer függvény egy adott regiszter értékét kérdezi le.
A fenti rutinokat tartalmazó Pascal unit részletes listája a F.26-ban található [4] alapján. F.32-ben pedig egy olyan program tanulmányozható, amely kiírja az SB mixerének regisztereit, módosítható és fix bitjeikkel.
[4] László József: Hangkártya programozása Pascal és Assembly nyelven, Computer Books, Budapest, 1999