📄 low.c
字号:
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 + -