summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/machine
diff options
context:
space:
mode:
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
commit8b70a55e7df2cffbebdea70272b39234f0add571 (patch)
tree197112e49f61084eeebafbe9e24dbd5b91b12c53 /src/devices/machine
parentbcefd9527534b1197cd28b45dec4dec95ce3ee50 (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.cpp63
-rw-r--r--src/devices/machine/1mb5.h8
-rw-r--r--src/devices/machine/ins8250.cpp32
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()