Биты маски записи
БИТ | Функция
----------+-----------------------------------
Биты 7:3 | Неиспользуемый ( Набор к 0 )
|
Бит 2 | Установить/сбросить бит маски
1 | Установить бит маски ( Отключите канал )
0 | Сбросить бит маски ( Доступен канал )
----------+------------------------------------
Биты 1:0 | Биты выбора Канала
00 | канал 0 (4)
01 | канал 1 (5)
10 | канал 2 (6)
11 | канал 3 (7)
DMAC2 используется для работы с 16 битами и DMAC1 используется для
работы с 8 битами. Вот пример программирования DMA:
1) Вычислите абсолютный линейный адрес вашего буфера
LinearAddr = MK_SEG( Buf ) * 16L + MK_OFF ( Buf );
2) Отключите канал DMA звуковой платы установкой бита маски
outp(MaskPort, 1 + ( DMAChannel % 4 ));
3) Очистите указатель байта flip-flop
outp(ClrPort, DMAChannel );
4) Запишите режим DMA для пересылки
Биты выбора режима должны устанавливаться в 00h для режима запроса.
Адрес бита +/- должен устанавливаться в 0 для приращения адреса.
Бит автоинициализации должен устанавливаться соответственно.
Биты пересылки должны устанавливаться в 10h для воспроизведения и
01h для записи. Выбор канала должен устанавливаться так же как и на
канал DMA звуковой платы.
outp(ModePort, Mode + ( DMAChannel % 4 ));
Некоторые часто используемые режимы:
48h + Канал - одиночный цикл воспроизведение
58h + Канал - автоинициализируемое воспроизведение
44h + Канал - запись одиночного цикла
54h + Канал - автоинициализируемая запись
5) Запишите смещение буфера, младший байт затем старший байт. Для
шестнадцати разрядных данных, смещение должно быть в словах от начала
128k-байтной страницы, для 8-битных от 64K. Самый простой метод для
вычисления смещения с 16 битами - это разделить линейный адрес на
два перед вычислением смещения.
#define lo(value) (unsigned char)((value) & 0x00FF)
#define hi(value) (unsigned char)((value) >> 8)
if ( SixteenBit==1 )
BufOffset= ( LinearAddr / 2 ) % 65536;
else BufOffset= LinearAddr % 65536;
outp(BaseAddrPort, lo(BufOffset));
outp(BaseAddrPort, hi(BufOffset));
6) Запишите длину пересылки в соответствующий порт счета, младший
байт затем старший байт. Для пересылки с 8 битами, запишите
длину в байтах минус единица. Для пересылки с 16 битами, запишите
номер длину в словах минус единица.
if ( SixteenBit==1 )
TransferLength/=2;
outp(CountPort, lo(TransferLength-1));
outp(CountPort, hi(TransferLength-1));
7) Запишите страницу буфера в регистр страницы DMA.
outp(PagePort, ( LinearAddr / 65536));
8) Включите DMA звуковой платы очистив соответствующий бит маски
outp(MaskPort, DMAChannel % 4);
Пример :
int MaskPort, ClrPort, ModePort, ModeDMA, CountPort, PagePort,
BaseAddrPort;
int pageports[4]={ 0x87, 0x83, 0x81, 0x82 };
MaskPort=0x0A; ClrPort=0xC; ModePort=0xB;
ModeDMA=0x48+DMAChannel;
CountPort=1+DMAChannel*2;
BaseAddrPort=DMAChannel*2;
PagePort=pageports[DMAChannel];
outportb(MaskPort, 4 + DMAChannel);
outportb(ClrPort, DMAChannel );
outportb(ModePort, ModeDMA );
outportb(BaseAddrPort,lo(aligned_physical));
outportb(BaseAddrPort,hi(aligned_physical));
outportb(PagePort,(unsigned char)((aligned_physical>>16)&0xFF));
outportb(CountPort,lo(len-1));
outportb(CountPort,hi(len-1));
outportb(MaskPort, DMAChannel );
Просьба писать ваши замечания, наблюдения и все остальное,
что поможет улучшить предоставляемую информацию на этом сайте.
ВСЕ КОММЕНТАРИИ МОДЕРИРУЮТСЯ ВРУЧНУЮ, ТАК ЧТО СПАМИТЬ БЕСПОЛЕЗНО!