> // Инициализация вектора и контроллера Поскипано 13 строк...
Я на С писал, выглядит это примерно так:
disable();
oldinterrupt = getvect( com_port_hardware_interrupt_vector + 8 );
setvect( com_port_hardware_interrupt_vector + 8, &newinterrupt );
enable(); ---
> InitCOMport (0); > > _asm { > > in al, 21h > and al, 11100111b > out 21h,al У меня:
#define com_port_hardware_interrupt_vector 4
#define com_port_hardware_number 0x3f8
com_port_hardware_interrupt_mask = inp( 0x21 ) & ( 1 << com_port_hardware_interrupt_vector );
outp( 0x21, inp( 0x21 ) & ~( 1 << com_port_hardware_interrupt_vector ) ); ---
просто запоминаю предыдущее состояние
> //////////////// Зачем второй контроллер дергать?
> in al, 0xA1 > and al, 0 > out 0xA1,al > //////////////// > mov al, 0x20 > out 0x20, al > out 0xa0, al > > mov ax, tes > mov es, ax > sti > } > > ------------------------------------ > > > // Инициализация порта Поскипано 68 строк...
#define com_port_receiving_register ( com_port_hardware_number + 0 )
#define com_port_interrupt_control_register ( com_port_hardware_number + 1 )
#define com_port_interrupt_identification_register ( com_port_hardware_number + 2 )
#define com_port_line_control_register ( com_port_hardware_number + 3 )
#define com_port_modem_control_register ( com_port_hardware_number + 4 )
#define com_port_line_status_register ( com_port_hardware_number + 5 )
#define com_port_modem_status_register ( com_port_hardware_number + 6 )
com_port_line_control_mask = inp( com_port_line_control_register );
com_port_interrupt_control_mask = inp( com_port_interrupt_control_register );
com_port_modem_control_mask = inp( com_port_modem_control_register );
outp( com_port_line_control_register, 0x80 );
outp( com_port_receiving_register, 0x01 );
outp( com_port_interrupt_control_register, 0x00 );
outp( com_port_line_control_register, 0x03 );
outp( com_port_interrupt_control_register, 0x0f );
outp( com_port_modem_control_register, 0x0f );
com_port_modem_status_mask = inp( com_port_modem_status_register ); ---
Сначала сохраняю предыдущее состояние порта, чтобы потом все восстановить.
> // Обработчки прерывания > void interrupt COM_1 () { > > COMfunction(0); // Функция обработчика > > _asm { > mov al, 0x20 > out 0x20, al > //out 0xa0, al > } > } Обработчик выглядит примерно так:
com_port_interrupt_identification_mask = inp( com_port_interrupt_identification_register );
if( com_port_interrupt_identification_mask & 1 )
_chain_intr( oldinterrupt );
switch( ( com_port_interrupt_identification_mask >> 1 ) & 3 ){
case 0:
time0 = ticks() / freq;
com_port_modem_status_mask = inp( com_port_modem_status_register );
break;
case 1:
// outp( com_port_receiving_register, 0 );
break;
case 2:
inp( com_port_receiving_register );
break;
case 3:
inp( com_port_line_status_register );
break;
default:
break;
}
outp( 0x20, 0x20 );
---
Не забываю подтверждение контроллеру. Читать состояние, если изменилось состосние, читать данные, если пришли данные...
Если это 4 прерывание, но не от СОМпорта, передаю его дальше по цепочке.
|