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

📄 low.c

📁 DOS_PCI_DRIVER,DOS环境下运行的PCI驱动程序,个人觉得比较好用.
💻 C
📖 第 1 页 / 共 4 页
字号:
	global_irq_table[13].vect_num = 0x75;
	global_irq_table[14].vect_num = 0x76;
	global_irq_table[15].vect_num = 0x77;
}

#pragma check_stack(off)

void SendEOI(unsigned short irq)
{
	if(irq < 8)
	{
		outb((u8)(EOI|irq),MASTER_PIC);
	}
	else
	{
		/* Issue master then slave EOI */
		outb((u8)(EOI|(irq - 8)),SLAVE_PIC);
		outb((u8)(EOI|2),MASTER_PIC);
	}
}

#pragma check_stack(on)

#pragma check_stack(off)

void EnableIRQ(unsigned short irq)
{
   unsigned short nPort;
   unsigned char temp;
   unsigned char temp1;

   // Build PIC Mask Port Addr. (BaseAddr + 1)...

   nPort= (irq <= 7) ? MASTER_PIC:SLAVE_PIC;
   nPort++;

   irq &= 0x0007;
   temp = inb(nPort);
   temp1 = (temp & (~(1 << irq)));
   if(temp1 != temp)
   {
       outb(temp1,nPort);
   }
}

void DisableIRQ(unsigned short irq)
{
   unsigned short nPort;
   unsigned char temp;
   unsigned char temp1;

   // Build PIC Mask Port Addr. (BaseAddr + 1)...

   nPort= (irq <= 7) ? MASTER_PIC : SLAVE_PIC;
   nPort++;

   irq &= 0x0007;
   temp = inb(nPort);
   temp1 = (temp | (1 << irq));
   if(temp != temp1)
   {
	outb(temp1,nPort);
   }
}

#pragma check_stack(on)

long request_irq(long irq, void (far * hcd_irq)(long,void far *), void far * hcd)
{
	struct irq_action far * action;

	if(irq >=16)
		return -EINVAL;

	action = (struct irq_action far *)
		     malloc( sizeof(struct irq_action) );
	if(!action)
		return -ENOMEM;

	local_irq_save(0);

	memset(action, 0, sizeof(struct irq_action));
	
	action->handler = hcd_irq;
	action->__hcd = hcd;

	list_add_tail(&action->node,&(global_irq_table[irq].irq_action_list));

	if(!global_irq_table[irq].old_handler)
	{
		#ifdef SET_VECT
			global_irq_table[irq].old_handler = 
			   _dos_getvect(global_irq_table[irq].vect_num);

			_dos_setvect(global_irq_table[irq].vect_num,
				global_irq_table[irq].new_handler);

			EnableIRQ((unsigned short)irq);
		#endif
	}

	local_irq_restore(0);

	return 0;
}	

void free_irq(long irq, void far * hcd)
{
	struct irq_action far * action;

	if(irq >=16)
		return;

	local_irq_save(0);

	irq_for_each_action(action,irq)
	{
		if(action->__hcd == hcd)
		{
			list_del((struct list_head far *)action);
			if(list_empty(&(global_irq_table[irq].irq_action_list)))
			{
			    #ifdef SET_VECT
					_dos_setvect(global_irq_table[irq].vect_num,
					    global_irq_table[irq].old_handler);
				#endif
				global_irq_table[irq].old_handler = 0;

				DisableIRQ((unsigned short)irq);
			}			
			
			free(action);

			local_irq_restore(0);
			return;
		}
	}

	local_irq_restore(0);
}

#pragma check_stack(off)

void interrupt far new_int8_handler(void)
{
	(* old_int8_handler)();

	++GlobalTickCount;
}

#pragma check_stack(on)

void init_event_handling(void)
{
	memset(&event_map,0,sizeof(struct eventmap));

	old_int1c_handler = _dos_getvect(0x1c);

	_dos_setvect(0x1c,new_int1c_handler);

	old_int8_handler = _dos_getvect(8);

	_dos_setvect(8,new_int8_handler);
}

void cleanup_evevnt_handling(void)
{
	struct event_item far * item;
	struct event_item far * item1;

	if(old_int1c_handler)
	{
	     _dos_setvect(0x1c,old_int1c_handler);
	     old_int1c_handler = NULL;
	}

	if(old_int8_handler)
	{
	     _dos_setvect(8,old_int8_handler);
	     old_int8_handler = NULL;
	}

	#ifdef SET_VECT

		for(item = event_item_i(global_event_list.next);
			item != event_item_i(&global_event_list);)	
		{
			item1 = event_item_i(item->node.next);
			internal_remove_event(item);
			item = item1;
		}

	#endif
}

#pragma check_stack(off)

struct event_item far * add_event(enum event_type type,unsigned long limit,
	void (_far * handler)(void far * priv),void far * priv,unsigned char is_active,
	unsigned char is_skip,unsigned long * pid)
{
	struct event_item far * item;
	unsigned long id;

	*pid = MAXEVENT;

	item = (struct event_item far * )malloc(sizeof(struct event_item));
	if(!item)
		return NULL;

	id = find_next_zero_bit(event_map.eventmap,MAXEVENT,event_next);
	if(id >= MAXEVENT)
		return NULL;

	event_next = (id + 1) % MAXEVENT;

	set_bit(id,event_map.eventmap);

	item->pid = pid;
	item->event_type = type;
	item->tick_count_limit = limit;
	item->tick_count = 0UL;
	
	item->is_active = 0;
	if(is_active)
		item->is_active = 1;
		
	item->is_skip = 0;
	if(is_skip)
		item->is_skip = 1;		
		
	item->event_handler = handler;
	item->event_handler_bak = handler;
	item->priv = priv;
	item->priv_bak = priv;

	list_add_tail(&item->node,&global_event_list);

	*pid = id;

	return item;
}

#pragma check_stack(on)

void internal_remove_event(struct event_item far * item)
{
	clear_bit( *(item->pid),event_map.eventmap);
	list_del((struct list_head far *)item);
	if(item)
		free(item);
}

long register_timer(struct TimerDef far * timer_def)
{
	struct event_item far * item;

	local_irq_save(0);

	item = add_event(EVENT_TIMER,timer_def->tick_count_limit,timer_def->event_handler,
		timer_def->priv,0,0,timer_def->pid);
	if(!item)
	{
		local_irq_restore(0);
		return -EINVAL;
	}

	local_irq_restore(0);
	return *(item->pid);
}

int timer_pending(struct TimerDef far * timer_def)
{
	return (timer_def->pid != NULL);
}

long register_thread(struct ThreadDef far * thread_def)
{
	struct event_item far * item;

	local_irq_save(0);

	item = add_event(EVENT_THREAD,thread_def->tick_count_limit,thread_def->event_handler,
		thread_def->priv,0,thread_def->is_skip,thread_def->pid);
	if(!item)
	{
		local_irq_restore(0);
		return -EINVAL;
	}

	local_irq_restore(0);
	return *(item->pid);
}

#pragma check_stack(off)

long register_tasklet(struct TaskletDef far * tasklet_def)
{
	struct event_item far * item;

	local_irq_save(0);

	item = add_event(EVENT_TASKLET,0L,tasklet_def->event_handler,tasklet_def->priv,1,
		0,tasklet_def->pid);
	if(!item)
	{
		local_irq_restore(0);
		return -EINVAL;
	}

	local_irq_restore(0);
	return *(item->pid);
}

#pragma check_stack(on)

void unregister_event(unsigned long id,
       void (_far * handler)(void far * priv),
       void far * priv)
{
	struct event_item far * item;
	struct event_item far * item1;

	for(item = event_item_i(global_event_list.next);
	    item != event_item_i(&global_event_list);)
	{
		item1 = event_item_i(item->node.next);
		if( *(item->pid) == id && item->event_handler == handler &&
		     item->priv == priv)
		{
			internal_remove_event(item);
			return;
		}

		item = item1;
	}
}

long check_item_valid(struct event_item far * item)
{
	if(item->event_type != EVENT_THREAD &&
		item->event_type != EVENT_TASKLET &&
	    item->event_type != EVENT_TIMER)
		return 0L;	

	if((item->event_handler != item->event_handler_bak) ||
		(item->priv != item->priv_bak))
		return 0L;

	return 1L;
}

void copy_thread_def(struct ThreadDef far * p_thread_def,struct event_item far * item)	
{
	p_thread_def->tick_count_limit = item->tick_count_limit;
	p_thread_def->event_handler = item->event_handler;
	p_thread_def->priv = item->priv;
	p_thread_def->pid = item->pid;
	p_thread_def->is_skip = item->is_skip;
}		

void event_loop(void)
{
	struct event_item far * item;
	struct event_item far * item1;
	struct ThreadDef thread_def;
	int temp;

	while(1)
	{
		temp = kbhit();
		if(temp)
		{
			temp = getch();
			if(temp == 'A' || temp == 'a')
			{
				#ifdef DEBUG_VERSION
				   safe_printf("quit from event_loop\n");
				#endif

			    break;
			}
		}

		if((!is_interrupt()) && (!list_empty(&global_event_list)))
		{
			for(item = event_item_i(global_event_list.next);
				item != event_item_i(&global_event_list) && !is_interrupt();)
			{
				global_irq_save();

				if(!check_item_valid(item))
				{
					list_del((struct list_head far * )item);
					free(item);
					global_irq_restore();
					break;
				}

				item1 = event_item_i(item->node.next);				

				if(item->is_active)
				{
					clear_bit(*(item->pid),event_map.eventmap);
					list_del((struct list_head far * )item);

					if(item->event_type == EVENT_THREAD)
					{
						copy_thread_def(&thread_def,item);							
						register_thread(&thread_def);
					}

					if(item->event_handler)
					{
						global_irq_restore();
						item->event_handler(item->priv);
						global_irq_save();
					}
		
					if(item)
					{
					    free(item);
					}

					global_irq_restore();
					break;
				}

				item = item1;
				global_irq_restore();
		    }
		}
	}
}

long schedule_timeout(unsigned long timeout,int (* check_status)(void far * priv),
	void far * priv)
{
	struct event_item far * item;
	struct event_item far * item1;
	struct ThreadDef thread_def;
	struct TimerDef timer_def;
	unsigned long id_timer;
	long status;

	if(timeout)
	{
		timer_def.pid = &id_timer;
		timer_def.event_handler = NULL;
		timer_def.priv = NULL;
		timer_def.tick_count_limit = ROUND_UP_TICK_COUNT(timeout);

		register_timer(&timer_def);
	}

	while(1)
	{
		if(check_status(priv))
		{
			status = 0L;
			goto check_done;
		}

		if((!is_interrupt()) && (!list_empty(&global_event_list)) 
			&& (!check_status(priv)))
		{
			for(item = event_item_i(global_event_list.next);
				item != event_item_i(&global_event_list) 
					&& !is_interrupt() 
					&& !check_status(priv);)
			{
				global_irq_save();

				if(!check_item_valid(item))
				{
					list_del((struct list_head far * )item);
					free(item);
					global_irq_restore();
					break;
				}

				item1 = event_item_i(item->node.next);

				if(item->is_active)
				{
					if(item->is_skip)
					{
					    goto outer_loop;
					}

					clear_bit(*(item->pid),event_map.eventmap);
					list_del((struct list_head far * )item);
					
					if(item->event_type == EVENT_THREAD)
					{
						copy_thread_def(&thread_def,item);							
						register_thread(&thread_def);
					}					

					if(item->event_handler)
					{
						global_irq_restore();
						item->event_handler(item->priv);
						global_irq_save();
					}
			
					if( (timeout)
						&& (item->event_type ==	EVENT_TIMER)
						&& (*(item->pid) == id_timer)
						&& (item->priv == NULL)
						&& (item->event_handler == NULL) )
					{
						status = -ETIMEDOUT;

						global_irq_restore();

						if(item)
							free(item);
						goto check_done;
					}

					if(item)
						free(item);

					global_irq_restore();

					break;
				}

				outer_loop:

					item = item1;
					global_irq_restore();
		    }
		}
	}

	check_done:

		if(timeout)
		{
			unregister_event(id_timer,timer_def.event_handler,timer_def.priv);
		}

		return status;
}

void safe_printf(const char _FAR_ * szFmt, ...)
{
	char szTmp[161];
	va_list Marker;
	unsigned short temp;
	unsigned short zero_intf;

	va_start(Marker,szFmt );
	vsprintf(szTmp,szFmt,Marker);
	va_end(Marker);

	_asm pushf
	_asm pop temp

	zero_intf = 1;

	if(temp & 0x200)
	{
		zero_intf = 0;
	}

	printf(szTmp);

	_asm pushf
	_asm pop temp

	if((temp & 0x200) && (zero_intf))
	{
		_asm cli
	}
}

#ifdef DEBUG_HARDWARE_INTERRUPT

#define LOG_SIZE (4096L * 1024L)

#define BUF_SIZE 4096L

#define LogFileName "debuglog.txt"

extern void (_interrupt _far * old_flush_handler)(void);

extern unsigned short iOffset1;
extern unsigned short iSeg1;
extern unsigned short XmsHandle;
extern unsigned long LoggedSize;
extern unsigned char IsLogging;
extern unsigned char IsLogChecked;
extern unsigned short PassCount;
extern unsigned short BeginCount;
extern unsigned short EndCount;

#endif

#pragma check_stack(off)

void AddLogToXms(const char _FAR_ * szFmt, ...)
{
	#ifdef DEBUG_HARDWARE_INTERRUPT
		char szTmp[161];
		va_list Marker;
		unsigned short len;

		if(is_interrupt())
		{
			if(IsLogging)
			{
				va_start( Marker, szFmt );
				my_vsprintf(szTmp,szFmt,Marker);
				va_end(Marker);
	
				len = strlen(szTmp);
				++len;
				if(LoggedSize + len < LOG_SIZE)
				{
					XMS_StoreToXMS(szTmp,XmsHandle,LoggedSize,len);
					LoggedSize += len;
				}
			}
		}
		else 
		{
			/*va_start( Marker, szFmt );
			vsprintf(szTmp,szFmt,Marker);
			va_end(Marker);

			printf(szTmp);*/
		}

	#else

		/*char szTmp[161];
		va_list Marker;

		if(!is_interrupt())
		{
			va_start( Marker, szFmt );
			vsprintf(szTmp,szFmt,Marker);
			va_end(Marker);

			printf(szTmp);
		}*/

	#endif
}

#pragma check_stack(on)

#ifdef DEBUG_HARDWARE_INTERRUPT

#pragma check_stack(off)

void interrupt far new_flush_handler(void)
{
		(* old_flush_handler)();

		FlushLog();
		UnCheckLog();
		_asm int 3
}

#pragma check_stack(on)

long XMSExist(void)
{
	unsigned short iAx;

	_asm mov ax, 0x4300
	_asm int 0x2f
	_asm xor ah, ah
	_asm mov iAx, ax
   
	if (iAx!=0x80)
		return -EINVAL;

	_asm mov ax, 0x4310
	_asm int 0x2f
	_asm mov iOffset1, bx
	_asm mov ax,es
	_asm mov iSeg1,ax

    return 0;   
}

long XMS_GetFreeSize(unsigned long * pMaxFree,unsigned long * pMaxTotal)
{
   unsigned short iAx, iDx;
   unsigned long XmsEntryPoint;

   XmsEntryPoint = ((unsigned long)iSeg1) * 65536L
	 + (unsigned long)iOffset1;		  

   _asm mov ah, 8
   _asm call dword ptr XmsEntryPoint
   _asm mov iAx, ax
   _asm mov iDx, dx
   _asm cmp bl,0
   _asm jnz return_error_1

   *pMaxFree = (unsigned long)iAx * 1024L;
   *pMaxTotal = (unsigned long)iDx * 1024L;

   return 0L;

   return_error_1:
		return -EINVAL;
}

long XMS_Alloc(unsigned long XmsSize, unsigned short * pXmsHandle)
{
    unsigned short iDx;
	unsigned long XmsEntryPoint;
	unsigned short XmsSizeKB;

	XmsEntryPoint = ((unsigned long)iSeg1) * 65536L
	 + (unsigned long)iOffset1;
	XmsSizeKB = (XmsSize % 1024L)?((XmsSize / 1024L) + 1):(XmsSize / 1024L);

    _asm mov ah, 9
    _asm mov dx, XmsSizeKB
    _asm call dword ptr XmsEntryPoint
    _asm mov iDx, dx
	_asm cmp bl,0
	_asm jnz return_error_2

    *pXmsHandle = iDx;
	return 0L;

	return_error_2:
			return -EINVAL;
}

long XMS_Free(unsigned short XmsHandle)
{
	unsigned long XmsEntryPoint;

	XmsEntryPoint = ((unsigned long)iSeg1) * 65536L
		+ (unsigned long)iOffset1;

    _asm mov ah, 0x0a
    _asm mov dx, XmsHandle
    _asm call dword ptr XmsEntryPoint
    _asm cmp bl,0
	_asm jnz return_error_3

    return 0L;

	return_error_3:	
		return -EINVAL;
}

long XMS_Lock(unsigned short XmsHandle, unsigned long * pAbsAddr)
{
    unsigned short iDx, iBx;
	unsigned long XmsEntryPoint;

	XmsEntryPoint = ((unsigned long)iSeg1) * 65536L
	 + (unsigned long)iOffset1;

    _asm mov ah, 0x0c
    _asm mov dx, XmsHandle
    _asm call dword ptr XmsEntryPoint
    _asm mov iDx, dx
    _asm mov iBx, bx
    _asm cmp ax,0
    _asm jz return_error_4

    *pAbsAddr = (unsigned long)iDx * 65536L + (unsigned long)iBx;

    return 0L;

	return_error_4:
			return -EINVAL;
}

long XMS_Unlock(unsigned short XmsHandle)
{
	unsigned long XmsEntryPoint;

	XmsEntryPoint = ((unsigned long)iSeg1) * 65536L
		+ (unsigned long)iOffset1;

    _asm mov ah, 0x0d
    _asm mov dx, XmsHandle
    _asm call dword ptr XmsEntryPoint
    _asm cmp bl,0
	_asm jnz return_error_5
	
	return 0L;

	return_error_5:
		return -EINVAL;
}

void InitLog(unsigned short begin_count,unsigned short end_count)
{
	unsigned long AbsAddr;

⌨️ 快捷键说明

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