Средства разработки приложений


Листинг 3. Работа с DSP и DMA


unit DSP_DMA; interface procedure DspOut(val:byte); {выводит байт на DSP} procedure SetupDMA(dmach,page,ofs,DMAcount,dmacmd:word); {установка режима DMA} procedure SetupDSP(dspcmd, mode, DSPcount, tc:word); {установка режима DSP} procedure SetMixer; {сброс платы и выбор источника сигнала} procedure EnableInterrupt(newvect:pointer); {установка векторов прерываний} procedure DisableInterrupt; {восстановление векторов прерываний} implementation uses getsbinf,crt,dos; var intvecsave :pointer; { старый вектор прерывания} intrnum :integer; { номер прерывания } intrmask :integer; { маска прерывания } { структура, содержащая данные контроллера DMA } type DmaPortRec = record addr,count,page : byte; end; const DmaPorts : array[0..7]of DmaPortRec = ( (addr:$00; count:$01; page:$87), {0} (addr:$02; count:$03; page:$83), {1} (addr:$04; count:$05; page:$81), {2 не используется} (addr:$06; count:$07; page:$82), {3} (addr:$00; count:$00; page:$00), {4 не используется} (addr:$C4; count:$C6; page:$8B), {5} (addr:$C8; count:$CA; page:$89), {6} (addr:$CC; count:$CE; page:$8A)); {7} procedure DspOut(val:byte);{выводит байт в DSP} begin while (Port[base + $0C] and $80) <> 0 do; Port[base + $0C] := val; end; function DspIn:byte;{читает байт из DSP} begin while (Port[base + $0E] and $80) = 0 do; dspin := Port[base + $0A]; end; procedure SetupDMA(dmach,page,ofs,DMAcount,dmacmd:word); { Программирует контроллер DMA} { для 8- или 16-разрядного канала} var mask,mode,ff : byte; begin if (dmach < 4) then begin mask := $0A; mode := $0B; ff := $0C; end else begin mask := $D4; mode := $D6; ff := $D8; ofs := (ofs shr 1) + ((page and 1) shl 15); end; Port[mask] := 4 or dmach; { маскируем DMA} Port[FF] := 0; { сбрасываем триггер-защелку} Port[mode] := dmacmd or (dmach and 3); { уст.режима DMA} Port[dmaports[dmach].addr] := lo(ofs); { младший байт адреса} Port[dmaports[dmach].addr] := hi(ofs);{ старший байт} Port[dmaports[dmach].page] := page; { номер страницы} Port[dmaports[dmach].count] := lo(DMAcount-1); { младший байт счетчика} Port[dmaports[dmach].count] := hi(DMAcount-1); { старший байт} Port[mask] := (dmach and 3); { сброс бита маски} end; procedure SetupDSP(dspcmd, mode, DSPcount, tc:word); { Программирует DSP звуковой платы} begin DspOut($40); {установка константы времени} DspOut(tc); DspOut(dspcmd); {команда Bx/Cx} DspOut(mode); DspOut(lo(DSPcount-1)); DspOut(hi(DSPcount-1)); end; procedure SetMixer;{сброс платы и выбор источника сигнала} var val:byte; begin Port[base + $06] := 1; {сброс DSP} delay(1); Port[base + $06] := 0; if (dspin <> $AA) then {проверка готовности} writeln('Sound Blaster не готов.'); Port[base + $04] := $3D; Port[base + $05] := 1; { левый канал:источник сигнала - микрофон} { Port[base + $04] := $3E; {для моно - не обязательно} { Port[base + $05] := 1; } { правый канал:источник сигнала - микрофон} Port[base + $04] := $3C; Port[base + $05] := 0; { на выходе отключаем все, что можно} end; procedure EnableInterrupt(newvect:pointer); {установка векторов прерываний} var intrmask1:word; begin if (irq < 8) then {вычисляем номера прерывания} intrnum := irq + 8 { для IRQ 0-7 прерывания 8-15.} else intrnum := irq - 8 + $70; { для IRQ 8-15 прерывания 70H-78H.} intrmask := 1 shl irq; {маска} GetIntVec(intrnum,intvecsave); { сохраняем старый вектор} SetIntVec(intrnum, newvect); { устанавливаем новый вектор} intrmask1 := intrmask; {разрешаем прерывания} Port[$21] := Port[$21] and not intrmask1; intrmask1 := intrmask1 shr 8; Port[$A1] := Port[$A1] and not intrmask1; end; procedure DisableInterrupt; {восстановление векторов прерываний} var intrmask1:word; begin intrmask1 := intrmask; {запрещаем прерывания} Port[$21] := Port[$21] or intrmask1; intrmask1 := intrmask1 shr 8; Port[$A1] := Port[$A1] or intrmask1; SetIntVec(intrnum,intvecsave);{восстанавливаем вектор} end; end.

После программирования DMAC то же самое проделывается и с DSP звуковой платы.


Начало  Назад  Вперед



Книжный магазин