diff options
author | fulivi <fulivi@users.noreply.github.com> | 2020-03-01 20:11:01 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-03-01 14:11:01 -0500 |
commit | 8b70a55e7df2cffbebdea70272b39234f0add571 (patch) | |
tree | 197112e49f61084eeebafbe9e24dbd5b91b12c53 /src/devices/machine | |
parent | bcefd9527534b1197cd28b45dec4dec95ce3ee50 (diff) |
hp80: HP82939 serial I/O module added (#6366)
* hp80: added HP82939 serial I/O module.
Fixed a small bug in INS8250 that prevented module self-test to pass.
Improved the interrupt handling of hp80 systems.
* hp80: changed scheduling to use "set_perfect_quantum"
Diffstat (limited to 'src/devices/machine')
-rw-r--r-- | src/devices/machine/1mb5.cpp | 63 | ||||
-rw-r--r-- | src/devices/machine/1mb5.h | 8 | ||||
-rw-r--r-- | src/devices/machine/ins8250.cpp | 32 |
3 files changed, 37 insertions, 66 deletions
diff --git a/src/devices/machine/1mb5.cpp b/src/devices/machine/1mb5.cpp index 50a3ea59365..8ed4384e3f5 100644 --- a/src/devices/machine/1mb5.cpp +++ b/src/devices/machine/1mb5.cpp @@ -76,26 +76,27 @@ READ8_MEMBER(hp_1mb5_device::cpu_r) case 1: // Read IB res = m_ib; - m_ibf = false; - update_halt(); + if (m_ibf) { + m_ibf = false; + update_halt(); + } break; } - //LOG("RD %u=%02x\n" , offset , res); + LOG("RD %u=%02x\n" , offset , res); return res; } WRITE8_MEMBER(hp_1mb5_device::cpu_w) { - //LOG("WR %u=%02x\n" , offset , data); - bool need_resched = false; + LOG("WR %u=%02x\n" , offset , data); switch (offset) { case 0: // Write CR m_cr = data; - need_resched |= set_reset(BIT(m_cr , 7)); - need_resched |= set_int(!BIT(m_cr , 0)); + set_reset(BIT(m_cr , 7)); + set_int(!BIT(m_cr , 0)); break; case 1: @@ -105,16 +106,11 @@ WRITE8_MEMBER(hp_1mb5_device::cpu_w) update_halt(); break; } - if (need_resched) { - LOG("resched %s\n" , space.device().tag()); - space.device().execute().yield(); - } } READ8_MEMBER(hp_1mb5_device::uc_r) { uint8_t res = 0; - bool need_resched = false; switch (offset) { case 0: @@ -132,14 +128,10 @@ READ8_MEMBER(hp_1mb5_device::uc_r) // Read OB res = m_ob; m_obf = false; - need_resched |= update_halt(); + update_halt(); break; } - if (need_resched) { - LOG("resched %s\n" , space.device().tag()); - space.device().execute().spin(); - } //LOG("RDU %u=%02x\n" , offset , res); return res; } @@ -147,32 +139,25 @@ READ8_MEMBER(hp_1mb5_device::uc_r) WRITE8_MEMBER(hp_1mb5_device::uc_w) { //LOG("WRU %u=%02x SR=%02x\n" , offset , data , m_sr); - bool need_resched = false; switch (offset) { case 0: // Write SR if (!BIT(m_sr , 0) && BIT(data , 0)) { - need_resched |= set_service(true); + set_service(true); } m_sr = data; m_hlten = BIT(m_sr , 7); - if (update_halt() && !m_halt) { - need_resched = true; - } + update_halt(); break; case 1: // Write IB m_ib = data; m_ibf = true; - need_resched |= update_halt(); + update_halt(); break; } - if (need_resched) { - LOG("resched %s\n" , space.device().tag()); - space.device().execute().spin(); - } } READ_LINE_MEMBER(hp_1mb5_device::irl_r) @@ -246,50 +231,38 @@ void hp_1mb5_device::device_reset() m_int_handler(true); } -bool hp_1mb5_device::set_service(bool new_service) +void hp_1mb5_device::set_service(bool new_service) { if (new_service != m_service) { m_service = new_service; - //LOG("irl=%d\n" , m_service); + LOG("irl=%d\n" , m_service); m_irl_handler(m_service); - return true; - } else { - return false; } } -bool hp_1mb5_device::update_halt() +void hp_1mb5_device::update_halt() { bool new_halt = m_hlten && m_obf && !m_ibf; if (new_halt != m_halt) { - //LOG("HALT=%d\n" , new_halt); + LOG("HALT=%d\n" , new_halt); m_halt = new_halt; m_halt_handler(m_halt); - return true; - } else { - return false; } } -bool hp_1mb5_device::set_reset(bool new_reset) +void hp_1mb5_device::set_reset(bool new_reset) { if (new_reset != m_reset) { m_reset = new_reset; m_reset_handler(m_reset); - return true; - } else { - return false; } } -bool hp_1mb5_device::set_int(bool new_int) +void hp_1mb5_device::set_int(bool new_int) { if (new_int != m_cint) { m_cint = new_int; LOG("cint=%d\n" , m_cint); m_int_handler(m_cint); - return true; - } else { - return false; } } diff --git a/src/devices/machine/1mb5.h b/src/devices/machine/1mb5.h index 18f8107896a..351b1f25d6c 100644 --- a/src/devices/machine/1mb5.h +++ b/src/devices/machine/1mb5.h @@ -71,10 +71,10 @@ private: bool m_reset; bool m_halt; - bool set_service(bool new_service); - bool update_halt(); - bool set_reset(bool new_reset); - bool set_int(bool new_int); + void set_service(bool new_service); + void update_halt(); + void set_reset(bool new_reset); + void set_int(bool new_int); }; // device type definition diff --git a/src/devices/machine/ins8250.cpp b/src/devices/machine/ins8250.cpp index 9c6121e9a2d..4dff4f85964 100644 --- a/src/devices/machine/ins8250.cpp +++ b/src/devices/machine/ins8250.cpp @@ -385,8 +385,9 @@ void ins8250_uart_device::ins8250_w(offs_t offset, u8 data) This register can be written, but if you write a 1 bit into any of bits 3 - 0, you could cause an interrupt if the appropriate IER bit is set. + Bits 7 - 4 are read-only. */ - m_regs.msr = data; + m_regs.msr = (m_regs.msr & 0xf0) | (data & 0x0f); if ( m_regs.msr & 0x0f ) trigger_int(COM_INT_PENDING_MODEM_STATUS_REGISTER); @@ -530,27 +531,24 @@ void ns16550_device::tra_complete() void ins8250_uart_device::rcv_complete() { + // According to datasheet (and HP82939 self-test) the received character is always + // extracted and stored in RBR even in case of overrun + receive_register_extract(); if(m_regs.lsr & INS8250_LSR_DR) { m_regs.lsr |= INS8250_LSR_OE; //overrun - trigger_int(COM_INT_PENDING_RECEIVER_LINE_STATUS); - receive_register_reset(); } - else - { - m_regs.lsr |= INS8250_LSR_DR; - receive_register_extract(); - - if (is_receive_framing_error()) - m_regs.lsr |= INS8250_LSR_FE; - if (is_receive_parity_error()) - m_regs.lsr |= INS8250_LSR_PE; - if ((m_regs.lsr & (INS8250_LSR_BI | INS8250_LSR_PE | INS8250_LSR_FE)) != 0) - trigger_int(COM_INT_PENDING_RECEIVER_LINE_STATUS); + m_regs.lsr |= INS8250_LSR_DR; - m_regs.rbr = get_received_char(); - trigger_int(COM_INT_PENDING_RECEIVED_DATA_AVAILABLE); - } + if (is_receive_framing_error()) + m_regs.lsr |= INS8250_LSR_FE; + if (is_receive_parity_error()) + m_regs.lsr |= INS8250_LSR_PE; + if ((m_regs.lsr & (INS8250_LSR_BI | INS8250_LSR_PE | INS8250_LSR_FE | INS8250_LSR_OE)) != 0) + trigger_int(COM_INT_PENDING_RECEIVER_LINE_STATUS); + + m_regs.rbr = get_received_char(); + trigger_int(COM_INT_PENDING_RECEIVED_DATA_AVAILABLE); } void ins8250_uart_device::tra_complete() |