![]() |
中国DOS联盟-- 联合DOS 推动DOS 发展DOS --联盟域名:www.cn-dos.net 论坛域名:www.cn-dos.net/forum |
| 游客 | 登录 | 注册 | 会员 | 搜索 | 中国DOS联盟 |
|
中国DOS联盟论坛 现在时间是 2026-08-01 21:01 |
共 48,037 主题排行 / 350,122 发帖 / 今日 2 篇 / 48,249 会员排行 |
| DOS开发编程 & 发展交流 (开发室) » DOS中中断处理冲突难题 |
| 可打印版本 1,334 / 3 |
| 第1楼 mrfstamp | 发表于 2006-06-17 16:45 |
| 新手上路 发帖 3 积分 10 | |
|
DOS中中断处理冲突难题 程序中包含两个中断,一个是定时中断,一个是串口中断,当我分别打开一个中断时,程序运行没有问题,如果同时打开两个中断,就会死机,那位高手可以指定以下,我应该注意些什么,或者我的处理哪里出了问题,谢了先!!!!
定时中断处理 void __far __interrupt new_int08(_CPPARGS) { /*以下是时间计数校准*/ if((++BA_Count%AsInB)!=0) ++stamp_timer_inc; else if((++CB_Count%BsInC)==0) if((++DC_Count%CsInD)!=0) ++stamp_timer_inc; stamp_timer_inc=stamp_timer_inc%2; if(stamp_timer_inc==0) stamp_timer++; //以下判断是否需要调用系统始终处理 1/18.3s处理一次 if (--flag==0) { flag=11; (*old_int08)();//dos系统时钟中断处理 } else { //写入8259处理结束,以便可以触发下一次中断 asm{ //这里是否需要处理8259主片的结束,但是我没有处理的情况下中断 //也可以正常的响应。 // mov al,0x20 // out 0xA0,al mov al,0x20 out 0x20,al } } } void setup_new_int08(void) { //修改8253计数值 asm{ cli mov al,0x34 out 0x43,al mov ax,0x1745 out 0x40,al mov al,ah out 0x40,al sti } 接管系统中断 old_int08=_dos_getvect(0x08); _disable();//pcm5330 _dos_setvect(0x08,new_int08); _enable();//pcm5330 } void restore_int08(void) { //恢复时钟计数 asm{ cli mov al,0x34 out 0x43,al mov ax,0xffff out 0x40,al mov al,ah out 0x40,al sti } //恢复系统时钟处理 _disable(); _dos_setvect(0x08,old_int08); _enable(); } 串口中断: 接管中断的处理语句: serial->new_com_vect为指向interrupt_manage(__CPPARGS)的函数指针,已初始化。 { serial->old_com_vect = _dos_getvect(ComIntn); _dos_setvect(ComIntn,serial->new_com_vect); } void __far __interrupt interrupt_manage(__CPPARGS) { _disable(); while((temp = (inportb(serial.portbase + IIR)) & IIR_MASK) != 1) { switch(temp) { case IIR_MS_ID: // modem status changed serial.modem_status_reg = inportb(serial.portbase+MSR); // read in useless char break; case IIR_TX_ID: // Request To Send char serial.tx_running = 0; c = queue_remove_item(&(serial.tx_queue)); if(c > -1){ serial.tx_running = 1; serial.serial_tx_count++; outportb(serial.portbase + THR, c&0xff); } break; case IIR_RX_ID: // character ready to be read in for( ; ; ){//如果有fifo,则将fifo中的数据完全读出才退出中断 c = (unsigned char) inportb(serial.portbase + RBR); if(!queue_add_item(&(serial.rx_queue),c)) serial.rs232_error = 1; serial.serial_rx_count++; if( !serial.fifo ) break; serial.line_status_reg = inp( serial.portbase + LSR ); //通过LSR上的状态标示来获知是否还有数据需要读取 if( !(serial.line_status_reg & LSR_DATA_READY) ) break; } break; case IIR_LN_ID: // line status has changed serial.line_status_reg = inportb(serial.portbase+LSR); // read in useless char break; case 0x0c: //超限错误处理 // break; default: break; } } _enable(); //恢复8259为可中断状态 outportb( PIC8259B_ICR, PIC8259_EOI ); //这里主片的控制字写不写对中断的处理影响都不很大,这是为什么呢? outportb(PIC8259A_ICR, PIC8259_EOI); } void comm_on(Serial *serial) { int temp, pnum; _disable(); outportb(serial->portbase + FCR , 0x0d); temp = inportb(serial->portbase + IIR); //判断FIFO是否有效 if(!(temp&0xc0)){ outportb(serial->portbase+FCR,0); serial->fifo = 0; } else serial->fifo = 1; temp = 0x0f; outportb(serial->portbase + MCR, temp); temp = IER_RX_INT|IER_TX_INT|IER_MS_INT|IER_LN_INT; outportb(serial->portbase + IER, temp); temp = inportb(PIC8259A_IMR) & ComIrqn; outportb(PIC8259A_IMR, temp); //我不能确定这里是否合理,因为在上面的处理中,我已经成功打开了串口中断, // temp = inportb(0x21) & 0xFB;//打开主片IRQ2 // outportb(0x21, temp); // temp = inportb(0xA1) & 0xF7;//打开从片IRQ11 // outportb(0xA1, temp); serial->modem_status_reg = inportb(serial->portbase + MSR); /*modem的状态纪录*/ serial->line_status_reg = inportb(serial->portbase + LSR); /*传输线的状态纪录*/ _enable(); } /*下面的处理,是关闭串口*/ void comm_off(Serial *serial) { int temp; _disable(); temp = inportb(serial->portbase + IIR); if(!(temp&0xc0)) outportb(serial->portbase+FCR,0); temp = inportb(PIC8259A_IMR) | ~ComIrqn; outportb(PIC8259A_IMR, temp); outportb(serial->portbase + IER, 0); outportb(serial->portbase + MCR, 0); _enable(); } [ Last edited by mrfstamp on 2006-6-17 at 17:41 ] |
|
| 第2楼 xiaoyuer06 | 发表于 2006-06-27 18:23 |
| 初级用户 发帖 35 积分 86 | |
|
定时中断好像不能直接用0x08,而应该用0x1c
|
|
| 第3楼 mrfstamp | 发表于 2006-06-29 14:38 |
| 新手上路 发帖 3 积分 10 | |
|
这两个有什么区别吗?
但是单独用一个的时候,即只有08中断的时候是没有问题的阿,这又是为什么呢? 另外我在看资料的时候,发现有这样一个说法:“保存DOS的数据交换区(SDA)可以安全地使用的DOS的功能.SDA保存了DOS几乎所有内部数据,如果保存(5D06H)和恢复(5D0BH)SDA ,DOS就变成在任何时候都可以重入的了.“ 谁可以给我解释一下吗?谢谢!!! |
|
| 第4楼 mrfstamp | 发表于 2006-06-29 16:10 |
| 新手上路 发帖 3 积分 10 | |
|
0x1C是软中断,08是硬中断,08为操作系统所用,我在修改后
|
|
|
[ 联系联盟系统管理团队 -
中国DOS联盟 -
标准版 ] Sponsored by ifanr Inc | © 2001–2023 |