中国DOS联盟论坛

中国DOS联盟

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

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

游客:  注册 | 登录 | 命令行 | 会员 | 搜索 | 上传 | 帮助 »
作者:
标题: DOS下C的一个代码,求解,谢谢. 上一主题 | 下一主题
pptppt
新手上路





积分 8
发帖 3
注册 2008-4-23
状态 离线
『楼 主』:  DOS下C的一个代码,求解,谢谢.

以下是一个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);
}

2008-4-23 15:24
查看资料  发短消息 网志   编辑帖子  回复  引用回复
zyl910
中级用户





积分 282
发帖 126
注册 2006-5-17
状态 离线
『第 2 楼』:  

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 ]



人类存在的目的就是试图理解人类为何存在
2008-4-24 11:27
查看资料  发送邮件  访问主页  发短消息 网志   编辑帖子  回复  引用回复
zyl910
中级用户





积分 282
发帖 126
注册 2006-5-17
状态 离线
『第 3 楼』:  

该程序用到了DPMI,用汇编不好写
再加上有很多32位操作(_farnspokel、outportl),但Debug只支持16位汇编,而且应该没人愿意直接写机器码。用Debug是很不现实的



人类存在的目的就是试图理解人类为何存在
2008-4-24 11:34
查看资料  发送邮件  访问主页  发短消息 网志   编辑帖子  回复  引用回复
pptppt
新手上路





积分 8
发帖 3
注册 2008-4-23
状态 离线
『第 4 楼』:  

谢谢 2zyl910  我先.试试看. 

[ Last edited by pptppt on 2008-4-27 at 06:30 PM ]

2008-4-27 18:15
查看资料  发短消息 网志   编辑帖子  回复  引用回复
netwinxp
高级用户





积分 741
发帖 366
注册 2007-7-25
状态 离线
『第 5 楼』:  

_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 ]

2008-5-1 16:01
查看资料  发短消息 网志   编辑帖子  回复  引用回复
pptppt
新手上路





积分 8
发帖 3
注册 2008-4-23
状态 离线
『第 6 楼』:  

谢谢各位,还在学习中!!

2008-5-10 17:59
查看资料  发短消息 网志   编辑帖子  回复  引用回复

请注意:您目前尚未注册或登录,请您注册登录以使用论坛的各项功能,例如发表和回复帖子等。


可打印版本 | 推荐给朋友 | 订阅主题 | 收藏主题



论坛跳转: