登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

DOS编程技术

讨论在纯DOS下的编程技术

 
 
 

日志

 
 
关于我

1984年大学毕业,1985年底有机会开始接触PC机,1986年开始在PC机上做开发工作,曾接触过MS-DOS、CP/M、UNIX、VMS、LINUX、iRMX等众多的操作系统并在上面从事技术开发,擅长做底层与硬件相关的软件开发,目前主要在DOS和LINUX平台下工作,主要从事软件,在硬件开发上也有一定造诣,亦有在8051系列、6502系列(凌阳)、z80系列、ARM、X86等各类平台下开发软硬件的经历。更详细情况可以参考http://resume.whowin.net

关于源程序  

2008-08-25 11:10:02|  分类: 心灵记录 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
    基本上我的许多文章中都有源程序,而且绝大部分都提供了完整的源程序,或是下载,或是写在文章中,只有最开始的一篇,题目叫做《遍历PCI设备》的文章我没有给出完整的源程序清单,于是我收到了一些邮件所要这篇文章的源程序,因为我在文章的最后有一句话“如需完整源代码,请与我联系”,所以人家和我联系当然无可厚非,其实这个源代码在我的服务器上,所以开始,我告诉了他们下载地址,但说句心里话,我真的不想给他们提供这个源程序,所以后面来信所要源程序的我就没有再回信。
    还有,可能有一些找我要这篇文章的源程序的读者没有收到回信,如果你还在看我的博客,这篇文章算是给你们的回信,原谅我没有一一回复。
    为什么我不愿意给他们这个简单的源程序呢?现在我们把这个源程序写在文章的最后,程序加了行号,麻烦大家再去看一下原文章
《遍历PCI设备》,那里面有两端程序段落,如下:
    第一段:
        long unsigned int    i;
        __dpmi_regs           r;

        r.x.ax = 0xb101;
        __dpmi_int(0x1a, &r);
        i = r.x.flags;
        if ((i & 0x01) == 0) printf("\nSupport PCI BIOS");
        else printf("\nNot Suport PCI BIOS");
    第二段:
  printf("\nNo.  Vendor/Device  Bus No.  Dev No.  Func No.  Class");
  i = 0;
  for (busNo = 0; busNo < 5; busNo++) {                 // bus No
    for(deviceNo = 0; deviceNo < 32; deviceNo++) {      // device no
      for (funcNo = 0; funcNo < 8; funcNo++) {          // Function No
        //j = 0x80000000 + i * 2048;
        regVal = 0x80000000                             // bit31 使能
                 + (busNo << 16)                        // Bus No
                 + (deviceNo << 11)                     // Device No
                 + (funcNo << 8);                       // Function No
        outportl(0xCF8, regVal);
        retVal = inportl(0xCFC);                        // 得到配置空间偏移为0的双字
        if (retVal != 0xffffffff) {                     // 设备存在
          i++;
          vendorID = retVal & 0xffff;                   // 得到供应商代码
          devID    = (retVal >> 16) & 0xffff;           // 得到设备代码
          regVal += 0x08;                               // 得到配置空间偏移为08H的双字
          outportl(0xCF8, regVal);
          retVal = inportl(0xCFC);
          retVal = retVal >> 8;                         // 滤掉版本号
          class3 = retVal & 0x0FF;                      // 得到三个分类代码
          class2 = (retVal >> 8) &0x0FF;
          class1 = (retVal >> 8) &0x0FF;
          printf("\n%02d   %04x/%04x       %02x       %02x       %02x      %02x-%02x-%02x",
                 i, vendorID, devID, busNo, deviceNo, funcNo, class1, class2, class3);
          if (funcNo == 0) {                          // 如果是单功能设备,则不再查funcNo>0的设备
            regVal = (regVal & 0xFFFFFFF0) + 0x0C;
            outportl(0xCF8, regVal);
            retVal = inportl(0xCFC);
            retVal = retVal >> 16;
            if ((retVal & 0x80) == 0) funcNo = 8;
          }
        }
      }
    }
  }

    大家可以比对一下,第一段程序其实就是源程序的08--13行,第二段程序就是源程序的第14--45行,就是说我们只要把原文给出的两个程序段落合在一起,在前面加上:
01  #include <stdio.h>
02  #include <dpmi.h>

03  typedef unsigned long      UDWORD;
04  typedef unsigned short int UWORD;

05  int main() {
06    UDWORD i, busNo, deviceNo, funcNo, regVal, retVal;
07    UWORD  vendorID, devID, class1, class2, class3;
    一共7行,实际上没有03、04行,把06行的UDWORD改成unsigned long,把07行的UWORD改成unsigned short int也是可以的,如果这样,就只有5行了,而且,写程序时include文件要加吧,main要加吧,还有程序中用到的变量要定义吧,仅此而已,没有一句是真正的程序,当然光加这几行还不够,还需要在程序的最后加上下面两行:
46    return 0;
47  }
    我想为什么要加这两行我实在是不好意思再做解释了。
    所以,我只能说,找我要这个源程序的读者,要么是根本没有看这篇文章,要么是根本没有看懂这篇文章,要么根本就不会写程序,总之,我觉得即便给他们源程序也没有任何意义,至多在比他还烂的程序员中显摆一下而已。
    所以,我有点动摇继续为大家提供源代码的信念,如果在后面的文章中大家没有看到源代码的下载地址,请不要奇怪,没有一定有它没有的原因。

下面是《遍历PCI设备》中的完整源代码。
01  #include <stdio.h>
02  #include <dpmi.h>

03  typedef unsigned long      UDWORD;
04  typedef unsigned short int UWORD;

05  int main() {
06    UDWORD i, busNo, deviceNo, funcNo, regVal, retVal;
07    UWORD  vendorID, devID, class1, class2, class3;
 
08    __dpmi_regs r;

09    r.x.ax = 0xb101;
10    __dpmi_int(0x1a, &r);
11    i = r.x.flags;
12    if ((i & 0x01) == 0) printf("\nSupport PCI BIOS");
13    else printf("\nNot Support PCI BIOS");
 
14    printf("\nNo.  Vendor/Device  Bus No.  Dev No.  Func No.  Class");
15    i = 0;
16    for (busNo = 0; busNo < 5; busNo++) {                 // bus No
17      for(deviceNo = 0; deviceNo < 32; deviceNo++) {      // device no
18        for (funcNo = 0; funcNo < 8; funcNo++) {          // Function No
            //j = 0x80000000 + i * 2048;
19          regVal = 0x80000000                             // bit31 使能
                     + (busNo << 16)                        // Bus No
                     + (deviceNo << 11)                     // Device No
                     + (funcNo << 8);                       // Function No
20          outportl(0xCF8, regVal);
21          retVal = inportl(0xCFC);                        // 得到配置空间偏移为0的双字
22          if (retVal != 0xffffffff) {                     // 设备存在
23            i++;
24            vendorID = retVal & 0xffff;                   // 得到供应商代码
25            devID    = (retVal >> 16) & 0xffff;           // 得到设备代码
26            regVal  += 0x08;                              // 得到配置空间偏移为08H的双字
27            outportl(0xCF8, regVal);
28            retVal   = inportl(0xCFC);
29            retVal   = retVal >> 8;                        // 滤掉版本号
30            class3   = retVal & 0x0FF;                     // 得到三个分类代码
31            class2   = (retVal >> 8) &0x0FF;
32            class1   = (retVal >> 8) &0x0FF;
33            printf("\n%02d   %04x/%04x       %02x       %02x       %02x      %02x-%02x-%02x",
34                   i, vendorID, devID, busNo, deviceNo, funcNo, class1, class2, class3);
35            if (funcNo == 0) {                          // 如果是单功能设备,则不再查funcNo>0的设备
36              regVal = (regVal & 0xFFFFFFF0) + 0x0C;
37              outportl(0xCF8, regVal);
38              retVal = inportl(0xCFC);
39              retVal = retVal >> 16;
40              if ((retVal & 0x80) == 0) funcNo = 8;
41            }
42          }
43        }
44      }
45    }
46    return 0;
47  }

  评论这张
 
阅读(2346)| 评论(4)

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018