- MCR bit 3 (OUT2) controls the serial interrupt generation, but has no effect
on the IIR (only depends on the IER). - IER write code rewritten. The "THR empty" interrupt will be generated immediately after enabling this interrupt reason.
This commit is contained in:
parent
78e2cc110d
commit
fbba69380b
@ -1,5 +1,5 @@
|
|||||||
/////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////
|
||||||
// $Id: serial.cc,v 1.37 2003-10-24 11:16:25 danielg4 Exp $
|
// $Id: serial.cc,v 1.38 2003-10-28 18:40:00 vruppert Exp $
|
||||||
/////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// Copyright (C) 2002 MandrakeSoft S.A.
|
// Copyright (C) 2002 MandrakeSoft S.A.
|
||||||
@ -159,7 +159,6 @@ bx_serial_c::init(void)
|
|||||||
BX_SER_THIS s[i].ls_ipending = 0;
|
BX_SER_THIS s[i].ls_ipending = 0;
|
||||||
BX_SER_THIS s[i].ms_ipending = 0;
|
BX_SER_THIS s[i].ms_ipending = 0;
|
||||||
BX_SER_THIS s[i].rx_ipending = 0;
|
BX_SER_THIS s[i].rx_ipending = 0;
|
||||||
BX_SER_THIS s[i].tx_ipending = 0;
|
|
||||||
BX_SER_THIS s[i].ls_interrupt = 0;
|
BX_SER_THIS s[i].ls_interrupt = 0;
|
||||||
BX_SER_THIS s[i].ms_interrupt = 0;
|
BX_SER_THIS s[i].ms_interrupt = 0;
|
||||||
BX_SER_THIS s[i].rx_interrupt = 0;
|
BX_SER_THIS s[i].rx_interrupt = 0;
|
||||||
@ -337,7 +336,6 @@ bx_serial_c::read(Bit32u address, unsigned io_len)
|
|||||||
}
|
}
|
||||||
|
|
||||||
BX_SER_THIS s[0].tx_interrupt = 0;
|
BX_SER_THIS s[0].tx_interrupt = 0;
|
||||||
BX_SER_THIS s[0].tx_ipending = 0;
|
|
||||||
|
|
||||||
val = BX_SER_THIS s[0].int_ident.ipending |
|
val = BX_SER_THIS s[0].int_ident.ipending |
|
||||||
(BX_SER_THIS s[0].int_ident.int_ID << 1) |
|
(BX_SER_THIS s[0].int_ident.int_ID << 1) |
|
||||||
@ -442,6 +440,7 @@ bx_serial_c::write(Bit32u address, Bit32u value, unsigned io_len)
|
|||||||
UNUSED(this_ptr);
|
UNUSED(this_ptr);
|
||||||
#endif // !BX_USE_SER_SMF
|
#endif // !BX_USE_SER_SMF
|
||||||
bx_bool prev_cts, prev_dsr, prev_ri, prev_dcd;
|
bx_bool prev_cts, prev_dsr, prev_ri, prev_dcd;
|
||||||
|
bx_bool new_rx_ien, new_tx_ien, new_ls_ien, new_ms_ien;
|
||||||
bx_bool gen_int = 0;
|
bx_bool gen_int = 0;
|
||||||
|
|
||||||
/* SERIAL PORT 1 */
|
/* SERIAL PORT 1 */
|
||||||
@ -469,12 +468,10 @@ bx_serial_c::write(Bit32u address, Bit32u value, unsigned io_len)
|
|||||||
if (BX_SER_THIS s[0].line_status.tsr_empty) {
|
if (BX_SER_THIS s[0].line_status.tsr_empty) {
|
||||||
BX_SER_THIS s[0].tsrbuffer = BX_SER_THIS s[0].thrbuffer;
|
BX_SER_THIS s[0].tsrbuffer = BX_SER_THIS s[0].thrbuffer;
|
||||||
BX_SER_THIS s[0].line_status.tsr_empty = 0;
|
BX_SER_THIS s[0].line_status.tsr_empty = 0;
|
||||||
if (BX_SER_THIS s[0].modem_cntl.out2) {
|
if (BX_SER_THIS s[0].int_enable.txhold_enable) {
|
||||||
if (BX_SER_THIS s[0].int_enable.txhold_enable) {
|
BX_SER_THIS s[0].tx_interrupt = 1;
|
||||||
BX_SER_THIS s[0].tx_interrupt = 1;
|
if (BX_SER_THIS s[0].modem_cntl.out2) {
|
||||||
DEV_pic_raise_irq(4);
|
DEV_pic_raise_irq(4);
|
||||||
} else {
|
|
||||||
BX_SER_THIS s[0].tx_ipending = 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bx_pc_system.activate_timer(BX_SER_THIS s[0].tx_timer_index,
|
bx_pc_system.activate_timer(BX_SER_THIS s[0].tx_timer_index,
|
||||||
@ -490,7 +487,6 @@ bx_serial_c::write(Bit32u address, Bit32u value, unsigned io_len)
|
|||||||
DEV_pic_lower_irq(4);
|
DEV_pic_lower_irq(4);
|
||||||
}
|
}
|
||||||
BX_SER_THIS s[0].tx_interrupt = 0;
|
BX_SER_THIS s[0].tx_interrupt = 0;
|
||||||
BX_SER_THIS s[0].tx_ipending = 0;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
BX_ERROR(("write to tx hold register when not empty"));
|
BX_ERROR(("write to tx hold register when not empty"));
|
||||||
@ -511,35 +507,47 @@ bx_serial_c::write(Bit32u address, Bit32u value, unsigned io_len)
|
|||||||
#endif // USE_RAW_SERIAL
|
#endif // USE_RAW_SERIAL
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
BX_SER_THIS s[0].int_enable.rxdata_enable = value & 0x01;
|
new_rx_ien = value & 0x01;
|
||||||
BX_SER_THIS s[0].int_enable.txhold_enable = (value & 0x02) >> 1;
|
new_tx_ien = (value & 0x02) >> 1;
|
||||||
BX_SER_THIS s[0].int_enable.rxlstat_enable = (value & 0x04) >> 2;
|
new_ls_ien = (value & 0x04) >> 2;
|
||||||
BX_SER_THIS s[0].int_enable.modstat_enable = (value & 0x08) >> 3;
|
new_ms_ien = (value & 0x08) >> 3;
|
||||||
if ((BX_SER_THIS s[0].ms_ipending == 1) &&
|
if (new_ms_ien != BX_SER_THIS s[0].int_enable.modstat_enable) {
|
||||||
(BX_SER_THIS s[0].int_enable.modstat_enable == 1)) {
|
BX_SER_THIS s[0].int_enable.modstat_enable = new_ms_ien;
|
||||||
BX_SER_THIS s[0].ms_interrupt = 1;
|
if ((BX_SER_THIS s[0].ms_ipending == 1) &&
|
||||||
BX_SER_THIS s[0].ms_ipending = 0;
|
(BX_SER_THIS s[0].int_enable.modstat_enable == 1)) {
|
||||||
gen_int = 1;
|
BX_SER_THIS s[0].ms_interrupt = 1;
|
||||||
|
BX_SER_THIS s[0].ms_ipending = 0;
|
||||||
|
gen_int = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if ((BX_SER_THIS s[0].tx_ipending == 1) &&
|
if (new_tx_ien != BX_SER_THIS s[0].int_enable.txhold_enable) {
|
||||||
(BX_SER_THIS s[0].int_enable.txhold_enable == 1)) {
|
BX_SER_THIS s[0].int_enable.txhold_enable = new_tx_ien;
|
||||||
BX_SER_THIS s[0].tx_interrupt = 1;
|
if (BX_SER_THIS s[0].int_enable.txhold_enable == 1) {
|
||||||
BX_SER_THIS s[0].tx_ipending = 0;
|
BX_SER_THIS s[0].tx_interrupt = BX_SER_THIS s[0].line_status.thr_empty;
|
||||||
gen_int = 1;
|
if (BX_SER_THIS s[0].tx_interrupt) gen_int = 1;
|
||||||
|
} else {
|
||||||
|
BX_SER_THIS s[0].tx_interrupt = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if ((BX_SER_THIS s[0].rx_ipending == 1) &&
|
if (new_rx_ien != BX_SER_THIS s[0].int_enable.rxdata_enable) {
|
||||||
(BX_SER_THIS s[0].int_enable.rxdata_enable == 1)) {
|
BX_SER_THIS s[0].int_enable.rxdata_enable = new_rx_ien;
|
||||||
BX_SER_THIS s[0].rx_interrupt = 1;
|
if ((BX_SER_THIS s[0].rx_ipending == 1) &&
|
||||||
BX_SER_THIS s[0].rx_ipending = 0;
|
(BX_SER_THIS s[0].int_enable.rxdata_enable == 1)) {
|
||||||
gen_int = 1;
|
BX_SER_THIS s[0].rx_interrupt = 1;
|
||||||
if ((BX_SER_THIS s[0].ls_ipending == 1) &&
|
BX_SER_THIS s[0].rx_ipending = 0;
|
||||||
(BX_SER_THIS s[0].int_enable.rxlstat_enable == 1)) {
|
gen_int = 1;
|
||||||
BX_SER_THIS s[0].ls_interrupt = 1;
|
}
|
||||||
BX_SER_THIS s[0].ls_ipending = 0;
|
|
||||||
gen_int = 1;
|
|
||||||
}
|
}
|
||||||
|
if (new_ls_ien != BX_SER_THIS s[0].int_enable.rxlstat_enable) {
|
||||||
|
BX_SER_THIS s[0].int_enable.rxlstat_enable = new_ls_ien;
|
||||||
|
if ((BX_SER_THIS s[0].ls_ipending == 1) &&
|
||||||
|
(BX_SER_THIS s[0].int_enable.rxlstat_enable == 1)) {
|
||||||
|
BX_SER_THIS s[0].ls_interrupt = 1;
|
||||||
|
BX_SER_THIS s[0].ls_ipending = 0;
|
||||||
|
gen_int = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (gen_int == 1)
|
if ((gen_int == 1) && BX_SER_THIS s[0].modem_cntl.out2)
|
||||||
DEV_pic_raise_irq(4);
|
DEV_pic_raise_irq(4);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -691,19 +699,17 @@ bx_serial_c::tx_timer(void)
|
|||||||
BX_SER_THIS s[0].line_status.overrun_error = 1;
|
BX_SER_THIS s[0].line_status.overrun_error = 1;
|
||||||
BX_SER_THIS s[0].rxbuffer = BX_SER_THIS s[0].tsrbuffer;
|
BX_SER_THIS s[0].rxbuffer = BX_SER_THIS s[0].tsrbuffer;
|
||||||
BX_SER_THIS s[0].line_status.rxdata_ready = 1;
|
BX_SER_THIS s[0].line_status.rxdata_ready = 1;
|
||||||
if (BX_SER_THIS s[0].modem_cntl.out2) {
|
if (BX_SER_THIS s[0].int_enable.rxdata_enable) {
|
||||||
if (BX_SER_THIS s[0].int_enable.rxdata_enable) {
|
gen_int = 1;
|
||||||
gen_int = 1;
|
BX_SER_THIS s[0].rx_interrupt = 1;
|
||||||
BX_SER_THIS s[0].rx_interrupt = 1;
|
} else {
|
||||||
} else {
|
BX_SER_THIS s[0].rx_ipending = 1;
|
||||||
BX_SER_THIS s[0].rx_ipending = 1;
|
}
|
||||||
}
|
if (BX_SER_THIS s[0].int_enable.rxlstat_enable) {
|
||||||
if (BX_SER_THIS s[0].int_enable.rxlstat_enable) {
|
gen_int = 1;
|
||||||
gen_int = 1;
|
BX_SER_THIS s[0].ls_interrupt = 1;
|
||||||
BX_SER_THIS s[0].ls_interrupt = 1;
|
} else {
|
||||||
} else {
|
BX_SER_THIS s[0].ls_ipending = 1;
|
||||||
BX_SER_THIS s[0].ls_ipending = 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
#if USE_RAW_SERIAL
|
#if USE_RAW_SERIAL
|
||||||
@ -720,13 +726,9 @@ bx_serial_c::tx_timer(void)
|
|||||||
if (!BX_SER_THIS s[0].line_status.thr_empty) {
|
if (!BX_SER_THIS s[0].line_status.thr_empty) {
|
||||||
BX_SER_THIS s[0].tsrbuffer = BX_SER_THIS s[0].thrbuffer;
|
BX_SER_THIS s[0].tsrbuffer = BX_SER_THIS s[0].thrbuffer;
|
||||||
BX_SER_THIS s[0].line_status.thr_empty = 1;
|
BX_SER_THIS s[0].line_status.thr_empty = 1;
|
||||||
if (BX_SER_THIS s[0].modem_cntl.out2) {
|
if (BX_SER_THIS s[0].int_enable.txhold_enable) {
|
||||||
if (BX_SER_THIS s[0].int_enable.txhold_enable) {
|
gen_int = 1;
|
||||||
gen_int = 1;
|
BX_SER_THIS s[0].tx_interrupt = 1;
|
||||||
BX_SER_THIS s[0].tx_interrupt = 1;
|
|
||||||
} else {
|
|
||||||
BX_SER_THIS s[0].tx_ipending = 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
bx_pc_system.activate_timer(BX_SER_THIS s[0].tx_timer_index,
|
bx_pc_system.activate_timer(BX_SER_THIS s[0].tx_timer_index,
|
||||||
(int) (1000000.0 / BX_SER_THIS s[0].baudrate *
|
(int) (1000000.0 / BX_SER_THIS s[0].baudrate *
|
||||||
@ -736,7 +738,7 @@ bx_serial_c::tx_timer(void)
|
|||||||
BX_SER_THIS s[0].line_status.tsr_empty = 1;
|
BX_SER_THIS s[0].line_status.tsr_empty = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gen_int) {
|
if ((gen_int == 1) && BX_SER_THIS s[0].modem_cntl.out2) {
|
||||||
DEV_pic_raise_irq(4);
|
DEV_pic_raise_irq(4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -803,7 +805,8 @@ bx_serial_c::rx_timer(void)
|
|||||||
BX_SER_THIS s[0].line_status.rxdata_ready = 1;
|
BX_SER_THIS s[0].line_status.rxdata_ready = 1;
|
||||||
if (BX_SER_THIS s[0].int_enable.rxdata_enable) {
|
if (BX_SER_THIS s[0].int_enable.rxdata_enable) {
|
||||||
BX_SER_THIS s[0].rx_interrupt = 1;
|
BX_SER_THIS s[0].rx_interrupt = 1;
|
||||||
DEV_pic_raise_irq(4);
|
if (BX_SER_THIS s[0].modem_cntl.out2)
|
||||||
|
DEV_pic_raise_irq(4);
|
||||||
} else {
|
} else {
|
||||||
BX_SER_THIS s[0].rx_ipending = 1;
|
BX_SER_THIS s[0].rx_ipending = 1;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////
|
||||||
// $Id: serial.h,v 1.10 2003-09-14 20:16:25 vruppert Exp $
|
// $Id: serial.h,v 1.11 2003-10-28 18:40:00 vruppert Exp $
|
||||||
/////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// Copyright (C) 2002 MandrakeSoft S.A.
|
// Copyright (C) 2002 MandrakeSoft S.A.
|
||||||
@ -60,7 +60,6 @@ typedef struct {
|
|||||||
bx_bool ls_ipending;
|
bx_bool ls_ipending;
|
||||||
bx_bool ms_ipending;
|
bx_bool ms_ipending;
|
||||||
bx_bool rx_ipending;
|
bx_bool rx_ipending;
|
||||||
bx_bool tx_ipending;
|
|
||||||
|
|
||||||
int baudrate;
|
int baudrate;
|
||||||
int tx_timer_index;
|
int tx_timer_index;
|
||||||
|
Loading…
Reference in New Issue
Block a user