⑴ 连续读取一段物理内存,如向0xD0000读出3000个字节的缓冲buf:
_dosmemgetb(0xD0000,3000,buf);
⑵ 读取0x 46c 处的连续4个字节的物理内存,正好是x86的时钟滴答数:
_farpeekl(_dos_ds,(unsigned long)(0x 46c ));
⑶ 从0xC000处读入一个字节
inportb(0xC000);
⑷ 分配一段2K字节的物理内存,放置于前640K处,可以用来作为DMA交换使用:
_go32_dpmi_seginfo info1;
info1.size =(2000*2+15)/16;
_go32_dpmi_allocate_dos_memory(&info1);
phys1=info1.rm_segment*16;
以后就可以象⑴所示的那样读取/写入该物理内存:
_dosmemgetb(phys1,1000,buf);
⑸ 使用主DMA5,块传递、自动预置、从外设读出至物理内存模式:
int sel; //描述符,后面释放申请的内存要用到它
int seg=__dpmi_allocate_dos_memory((2*2000*2+15)>>4,&sel); //2000个字节
if (seg==-1) return “不能分配物理内存“;
unsigned long phys=seg*16; //获得物理地址
if ((phys>>16)!=((phys+TOTAL_WORD)>>16))
phys+=2000; //跨了64k,物理地址就要改变
unsigned long off=(phys>>1) & 0xFFFF;//偏的算法:DOS 20位物理地址/2 再取低16位
unsigned long pag=phys>>16; //页的算法:DOS 20位物理地址 取高4位
outportb(0xd4,5); //设置屏蔽位
outportb(0xd8,0); //清空
outportb(0xd6,0x95);//设置模式字:0x95=1001 0101 块自动预置,通道5, M<===I/O
outportb(0xc4,(off & 0xFF)); //设置地址:先写off,后写pag
outportb(0xc4,(off >> 8));
outportb(0x8b,pag);
outportb(0xc6,(1024 & 0xFF)); // 设置传送长度,先传送1024个字
outportb(0xc6,(1024 >> 8));
outportb(0xd4,1); //设置屏蔽位
一旦主DMA设置成功,可以每次例如在中断中读出phys处的内容:
_dosmemgetb(phys,2000,buf);