中国DOS联盟

-- 联合DOS 推动DOS 发展DOS --

联盟域名:www.cn-dos.net 论坛域名:www.cn-dos.net/forum
DOS,代表着自由开放与发展,我们努力起来,学习FreeDOS和Linux的自由开放与GNU精神,共同创造和发展美好的自由与GNU GPL世界吧!

中国DOS联盟论坛
现在时间是 2026-06-16 23:04
中国DOS联盟论坛 » DOS开发编程 & 发展交流 (开发室) » DOS下C的一个代码,求解,谢谢. 查看 1,454 回复 5
楼 主 DOS下C的一个代码,求解,谢谢. 发表于 2008-04-23 15:24 ·  中国 广东 广州 天河区 电信
新手上路
积分 8
发帖 3
注册 2008-04-23 14:49
UID 116696
性别 男
状态 离线
以下是一个C写的DOS运行的代码,是一个程序的部分.是BIOS看门狗的,
请教一下具体每句的意思,如果用Debug 汇编怎么写. 谢谢了.
------------------------------------------------------------------------------------------------
#include <stdio.h>
#include <string.h>
#include <dos.h>
#include <stdlib.h>
#include <inlines/pc.h>
#include <dpmi.h>
#define INDEX_PORT 0x2e
#define DATA_PORT 0x2f
#define WDTBaseAddress 0xDF300000;
int selector[0];
__dpmi_meminfo mi[0];


void InitWDTimer()
{
mi[0].address=WDTBaseAddress; //WDT timer base address//
mi[0].size=0x10; //WDT register //
__dpmi_physical_address_mapping(&(mi[0]));
selector[0]=__dpmi_allocate_ldt_descriptors(1);
__dpmi_set_segment_base_address(selector[0],mi[0].address);
__dpmi_set_segment_limit(selector[0],mi[0].size-1);
}

void SetWDtimer(unsigned long timer)
{
_farsetsel(selector[0]);
//; perform unlock sequence for preload 1//
_farnspokeb(0x0C,0x80);
_farnspokeb(0x0C,0x86);
timer = timer * 1000; // Msec hange to Sec//
_farnspokel( 0x00, timer);
//; perform unlock sequence for preload 2//
_farnspokeb(0x0C,0x80);
_farnspokeb(0x0C,0x86);
_farnspokel(0x04, 0x01);
outportl(0x0cf8,0x8000EC00+0x68); //;enable WDT timer//
outportl(0x0cfc,0x00000002);
}
2 发表于 2008-04-24 11:27 ·  中国 广东 广州 越秀区 电信
中级用户
★★
积分 282
发帖 126
注册 2006-05-17 22:29
UID 55724
状态 离线
InitWDTimer函数还算简单,利用DPMI得到一个指向WDTBaseAddress的选择子。由于该地址超过实模式24位地址范围,所以用到了DPMI(DOS保护模式接口)

至于SetWDtimer函数。
第一句用_farsetsel设好段描述符后,后面的_farnspokeb、_farnspokel就是端口操作,与具体的接口命令字设计有关。
最后的outportl是用来写PCI配置。0x0cf8是PCI地址端口,0x8000EC00是设备号(分为 总线、设备、功能三级,具体位含义去查PCI规范,我不太记得了),0x68是指该设备的0x68地址的寄存器(自定义寄存器,功能不详,与具体的接口命令字设计有关)。0x0cfc是PCI数据端口,该程序往刚才指定的0x68寄存器写了一个32位数据(0x00000002)。

[ Last edited by zyl910 on 2008-4-24 at 11:38 AM ]
人类存在的目的就是试图理解人类为何存在
3 发表于 2008-04-24 11:34 ·  中国 广东 广州 越秀区 电信
中级用户
★★
积分 282
发帖 126
注册 2006-05-17 22:29
UID 55724
状态 离线
该程序用到了DPMI,用汇编不好写
再加上有很多32位操作(_farnspokel、outportl),但Debug只支持16位汇编,而且应该没人愿意直接写机器码。用Debug是很不现实的
人类存在的目的就是试图理解人类为何存在
4 发表于 2008-04-27 18:15 ·  中国 广东 广州 电信
新手上路
积分 8
发帖 3
注册 2008-04-23 14:49
UID 116696
性别 男
状态 离线
谢谢 2zyl910  我先.试试看. 

[ Last edited by pptppt on 2008-4-27 at 06:30 PM ]
5 发表于 2008-05-01 16:01 ·  中国 福建 厦门 电信
高级用户
★★★
积分 741
发帖 366
注册 2007-07-25 19:11
UID 94024
性别 男
状态 离线
_farpeekb、farpeekw、_farpeekl
_farnspeekb、_farnspeekw、_farnspeekl
_farpokeb、_farpokew、_farpokel
_farnspokeb、void _farnspokew、_farnspokel
这些是dpmi读、写保护模式内存的接口函数。
_farsetsel、 _fargetsel是设置和取得LDT的接口函数。
===以上部分需要学习保护模式编程的资料才能较好滴体会===
后面两句比较简单——
1、该硬件使用PCI配置空间8000EC00段(每段256字节),BUSID=0,DEVICEID=29。
2、其68H是BIOS看门狗定时器使能寄存器(该配置空间具体寄存器分布、格式和功能你最好找厂家索取)。
3、设置该寄存器值为2时使能定时器。
注:定时器的值好像在保护模式内存空间DF300000处
如果你非要用DEBUG来编写,那很多语句只能采用机器语言。推荐你采用masm611,用.386模式,如果你熟悉了保护模式编程,你可以用INT 15H调用完全脱离DPMI。

[ Last edited by netwinxp on 2008-5-1 at 04:39 PM ]
6 发表于 2008-05-10 17:59 ·  中国 广东 广州 电信
新手上路
积分 8
发帖 3
注册 2008-04-23 14:49
UID 116696
性别 男
状态 离线
谢谢各位,还在学习中!!
论坛跳转: