⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ch5.prg

📁 C 常用算法程序集 徐士良 编 清华大学出版社 1994.1
💻 PRG
📖 第 1 页 / 共 2 页
字号:

    1、重排代码段次序程序

;*********************************************************
;	程序名:	DOS_HDR.ASM
;	功能:	定义TC目标代码的段次序
;	说明:	本模块可以和任何TC产生的目标代码文件连接,
;		从而生成新的TC可执行代码。
;		操作步骤:	TASM DOS_HDR,M1
;				LINK M1+?????
;	程序员:	《用C语言写DOS设备驱动程序》,希望电脑公司
;*********************************************************
	name    dos_hdr.asm
_DATA   segment word public 'DATA'
_d@     label   byte
_DATA   ends

_BSS    segment word public 'BSS'
_b@     label   byte
_BSS    ends

_TEXT   segment byte public 'CODE'
DGROUP  group   _DATA,_BSS,_TEXT
	assume  cs:DGROUP,ds:DGROUP,ss:DGROUP
_TEXT   ends
	end

    2、替换命令描述文件DOS.ARR
    在该文件中,必需注意制表符的安排问题,一定要严格按照TCC产生的汇编
语言程序的格式,否则将找不到替换的对象。下面的该文本的清单∶

s/DGROUP	group	_DATA,_BSS/DGROUP	group _DATA,_BSS,_TEXT/
s/assume	cs:_TEXT/assume cs:DGROUP/
s/dw@/dwDGROUP:@/
s/dw	_Init_cmd/dw     DGROUP:_Init_cmd/
s/dw	_Media_check_cmd/dw     DGROUP:_Media_check_cmd/
s/dw	_Build_bpb_cmd/dw     DGROUP:_Build_bpb_cmd/
s/dw	_Ioctl_input_cmd/dw     DGROUP:_Ioctl_input_cmd/
s/dw	_Input_cmd/dw     DGROUP:_Input_cmd/
s/dw	_Input_no_wait_cmd/dw     DGROUP:_Input_no_wait_cmd/
s/dw	_Input_status_cmd/dw     DGROUP:_Input_status_cmd/
s/dw	_Input_flush_cmd/dw     DGROUP:_Input_flush_cmd/
s/dw	_Output_cmd/dw     DGROUP:_Output_cmd/
s/dw	_Output_verify_cmd/dw     DGROUP:_Output_verify_cmd/
s/dw	_Output_status_cmd/dw     DGROUP:_Output_status_cmd/
s/dw	_Output_flush_cmd/dw     DGROUP:_Output_flush_cmd/
s/dw	_Ioctl_output_cmd/dw     DGROUP:_Ioctl_output_cmd/
s/dw	_Dev_open_cmd/dw     DGROUP:_Dev_open_cmd/
s/dw	_Dev_close_cmd/dw     DGROUP:_Dev_close_cmd/
s/dw	_Remove_media_cmd/dw     DGROUP:_Remove_media_cmd/
s/dw	_Unknown_cmd/dw     DGROUP:_Unknown_cmd/
s/dw	_Ioctl_cmd/dw     DGROUP:_Ioctl_cmd/
s/dw	_Get_logical_device_map_cmd/dw    DGROUP:_Get_logical_device_map_cmd/
s/dw	_Set_logical_device_map_cmd/dw    DGROUP:_Set_logical_device_map_cmd/

    3、预处理程序清单

/*****************************************************************
          程序名:arrange.c
          功能:  修改_TEXT段属组及其相关引用
          说明:  未对读出文件的格式作容错匹配处理,强烈要求对照表
                 文件与源文件在制表符上的匹配。
          程序员:原作《用C语言写DOS设备驱动程序》,希望电脑公司;
                 修改: 吕强
          时间:  1993,8,23. 第1.10版
*****************************************************************/

#include        <stdio.h>
#include        <string.h>
#include        <stdlib.h>

#define MAXCMDS 100		/* 最大可接受的替换行数 */
#define LINEWID 100		/* 最大行宽度 */

/***********************************************************
	出错处理
***********************************************************/
error(char *s1,char *s2)
{
	fprintf(stderr,s1,s2);
	exit(1);
}

/*********************************************************
	在line行中按s行描述的替换对应进行替换
*********************************************************/
substitute(char *s,char *line)
{
	char *p;
	int i,slen;
	char source[LINEWID],target[LINEWID],tmpstr[LINEWID];

	char delimiter = *s;	/* 获得分界符 */

	/* 把s串中当前点至分界符处的字串搬入source串 */
	for (i=0,s++; *s!='\n' && *s!=delimiter; i++)
		source[i] = *s++;
	source[i] = '\0';

	if ((slen=strlen(source))<=0)	/* 验证source串有内容 */
		error("Line %s, source line cannot be empty",s);

	/* 把s串中当前点至分界符处的字串搬入target串 */
	for (i=0,s++; *s!='\n' && *s!=delimiter; i++)
		target[i] = *s++;
	target[i] = '\0';

	for (p=strstr(line,source); p; p=strstr(p+1,source))
	{ /* 在目标串中找到了source串 */
		strcpy(tmpstr,p+slen);	/* 在目标串中略去source串 */
		strcpy(p,target);	/* 把source串内容替换成target串 */
		strcpy(p+strlen(target),tmpstr);
	}
}

/*********************************************************
	命令行语法:	ARRANGE FILE1 FILE2 FILE3
			FILE1:对照表文件名(DOS.ARR)
			FILE2:源文件名(?.ASM)
			FILE3:目标文件名(?.ASM)
*********************************************************/
main(int argc, char *argv[])
{
	char *cmds[MAXCMDS];
	char line[LINEWID];
	FILE *fp_cmd_change_table;
	FILE *fpin, *fpout;
	int nl=0;

	/* 打开各个文件 */
	if ((fp_cmd_change_table=fopen(argv[1],"r")) == NULL)
		error("Can not open table file %s",argv[1]);
	if ((fpin=fopen(argv[2],"r")) == NULL)
		error("Can not open input file %s",argv[2]);
	if ((fpout=fopen(argv[3],"w")) == NULL)
		error("Can not open output file %s",argv[3]);

	/* 把对照表文件中的替换对应行读入cmds数组 */
	while (fgets(line,LINEWID,fp_cmd_change_table))
	{
		cmds[nl] = strdup(line);
		if (!cmds[nl]) error("strdup failed at line %s",line);
		if (++nl >= MAXLINE) error("Too many commands in table file","");
	}
	cmds[nl] = NULL;

	/* 在生成的汇编语言程序的头行插入.286c行 */
	line[0]='\0';
	strcpy(line,".286c\n");
	fputs(line,fpout);

	while (fgets(line,LINEWID,fpin))
	{ /* 依次取源文件的每一行 */
		int i;  char *p;
		for (i=0; p=cmds[i]; i++)
		{ /* 依次取该操作的描述行 */
			switch(*p)
			{
				case 's':	/* 是替换对应行命令 */
					substitute(++p,line); /* 按p所描述的进行处理 */
					break;
				default:	/* 只处理替换命令 */
					error("Unknown command %s",p);
					break;
			}
		}
		fputs(line,fpout);		/* 把经过替换处理的行写入目标文件 */
	}

	fcloseall();
}


二、块设备驱动程序框架程序

    1、变量定义文件

/*****************************************************************
          程序名:dos_ddh.h
          功能:  
          说明:
          程序员:原作《用C语言写DOS设备驱动程序》,希望电脑公司;
                 修改: 吕强
          时间:  1993,8,23. 第1.10版
*****************************************************************/

/* symbolic contansts */
#define DOS_CMDS        25      /* number of DOS commands */
#define STACK_LENGTH    512     /* DOS device driver stack */
#define DEVICES         1       /* number of block devices */
#define OP_COMPLETE     0x0000  /* no errors return code */

/* device attribute field definitons in DDH_struct.ddh_attribute */
#define CHAR_DD         0x8000
#define IOCTL_SUP       0x4000
#define NON_IBM         0x2000
#define REMOVABLE       0x0800
#define GET_SET         0x0040
#define CLOCK_DD        0x0008
#define NUL_DD          0x0004
#define STDOUT_DD       0x0002
#define STDIN_DD        0x0001
#define GEN_IOCTL       0x0001

struct DDH_struct
{
	struct DDH_struct far *next_DDH;
	unsigned int    ddh_attribute;
	unsigned int    ddh_strategy;
	unsigned int    ddh_interrupt;
	unsigned char   ddh_name[8];
};

/* device staus word mask word */
#define ERROR_BIT       0x8000  /* error bit mask */
#define ERROR_NUM       0x00FF  /* error number mask */
#define DONE_BIT        0x0100  /* device operation done */
#define BUSY_BIT        0x0200  /* device busy */

/* the value of the REQ_struct.status */
#define WRITE_PROTECT   0x00
#define UNKNOWN_UNIT    0x01
#define NOT_READY       0x02
#define UNKNOWN_CMD     0x03
#define CRC_ERROR       0x04
#define BAD_REQ_LEN     0x05
#define SEEK_ERROR      0x06
#define UNKNOWN_MEDIA   0x07
#define NOT_FOUND       0x08
#define OUT_OF_PAPER    0x09
#define WRITE_FAULT     0x0A
#define READ_FAULT      0x0B
#define GENERAL_FAIL    0x0C

/* device driver command codes in REQ_struct.command */
#define INIT            0
#define MEDIA_CHECK     1
#define BUILD_BPB       2
#define IOCTL_INPUT     3
#define INPUT           4
#define INPUT_NO_WAIT   5
#define INPUT_STATUS    6
#define INPUT_FLUSH     7
#define OUTPUT          8
#define OUTPUT_VERIFY   9
#define OUTPUT_STATUS   10
#define OUTPUT_FLUSH    11
#define IOCTL_OUTPUT    12
#define DEV_OPEN        13
#define DEV_CLOSE       14
#define REMOVE_MEDIA    15
#define RESERVED_1      16
#define RESERVED_2      17
#define RESERVED_3      18
#define IOCTL           19
#define RESERVED_4      20
#define RESERVED_5      21
#define RESERVED_6      22
#define GET_LOGICAL_DRIVE_MAP   23
#define SET_LOGICAL_DRIVE_MAP   24

/* request header of every command */
struct INIT_struct
{
	unsigned char	num_of_units;
	unsigned int far *end_ptr;
	unsigned int far *BPB_ptr;
	unsigned char   drive_num;
	unsigned int    last_drv;
};

struct MEDIA_CHECK_struct
{
	unsigned char   media_byte;
	unsigned char   return_info;
	unsigned char far *return_ptr;
};

struct BUILD_BPB_struct
{
	unsigned char   media_byte;
	unsigned char far *buffer_ptr;
	struct BPB_struct far *BPB_table;
};

struct I_O_struct /* IOCTL_INPUT,INPUT,OUTPUT,OUTPUT_VERIFY,IOCTL_OUTPUT */
{
	unsigned char   media_byte;
	unsigned char far *buffer_ptr;
	unsigned int    count;
	unsigned int    start_sector;
	unsigned char far *vol_id_ptr;
	unsigned long   start_sector_32;
};

struct INPUT_NO_WAIT_struct
{
	unsigned char   byte_read;
};

struct  IOCTL_struct
{
	unsigned char   majorgu_func;
	unsigned char   Minor_func;
	unsigned int    SI_reg;
	unsigned int    DI_reg;
	unsigned char far *ioctl_req_ptr;
};

struct L_D_MAP_struct
{
	unsigned char   unit_code;
	unsigned char   cmd_code;
	unsigned int    status;
	unsigned long   reserved;
};

struct REQ_struct
{
	unsigned char length;
	unsigned char unit;
	unsigned char command;
	unsigned int status;
	unsigned char reserved[8];
	union
	{
		struct INIT_struct      init_req;
		struct MEDIA_CHECK_struct media_check_req;
		struct BUILD_BPB_struct build_BPB_req;
		struct I_O_struct       i_o_req;
		struct INPUT_NO_WAIT_struct input_no_wait_req;
		struct IOCTL_struct     ioctl_req;
		struct L_D_MAP_struct   l_d_map_req;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -