summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices
diff options
context:
space:
mode:
author AJR <ajrhacker@users.noreply.github.com>2020-03-24 23:07:22 -0400
committer AJR <ajrhacker@users.noreply.github.com>2020-03-24 23:28:03 -0400
commit6dcdbc9088be267ee1f201225b2bb6ccc44c8ea4 (patch)
treef45d3a987ef289d833fa0821608cb1871f1f838c /src/devices
parent09e533a9fb660823dc3aaccb25ee8052104c5d62 (diff)
i8x9x: Implement quasi-bidirectional port structure (nw)
s50: Map the 63H149 (nw)
Diffstat (limited to 'src/devices')
-rw-r--r--src/devices/cpu/mcs96/i8x9x.cpp39
-rw-r--r--src/devices/cpu/mcs96/i8x9x.h22
2 files changed, 53 insertions, 8 deletions
diff --git a/src/devices/cpu/mcs96/i8x9x.cpp b/src/devices/cpu/mcs96/i8x9x.cpp
index 9a43dc78350..f4aae129d3e 100644
--- a/src/devices/cpu/mcs96/i8x9x.cpp
+++ b/src/devices/cpu/mcs96/i8x9x.cpp
@@ -21,6 +21,7 @@ i8x9x_device::i8x9x_device(const machine_config &mconfig, device_type type, cons
m_out_p1_cb(*this), m_in_p1_cb(*this),
m_out_p2_cb(*this), m_in_p2_cb(*this),
base_timer2(0), ad_done(0), hsi_mode(0), hso_command(0), ad_command(0), hso_time(0), ad_result(0), pwm_control(0),
+ port1(0), port2(0),
ios0(0), ios1(0), ioc0(0), ioc1(0), sbuf(0), sp_con(0), sp_stat(0), serial_send_buf(0), serial_send_timer(0)
{
for (auto &hso : hso_info)
@@ -46,9 +47,9 @@ void i8x9x_device::device_resolve_objects()
m_serial_tx_cb.resolve_safe();
m_in_p0_cb.resolve_safe(0);
m_out_p1_cb.resolve_safe();
- m_in_p1_cb.resolve_safe(0);
+ m_in_p1_cb.resolve_safe(0xff);
m_out_p2_cb.resolve_safe();
- m_in_p2_cb.resolve_safe(0);
+ m_in_p2_cb.resolve_safe(0xc2);
}
void i8x9x_device::device_start()
@@ -67,6 +68,9 @@ void i8x9x_device::device_start()
state_add(I8X9X_SP_CON, "SP_CON", sp_con).mask(0x1f);
state_add(I8X9X_SP_STAT, "SP_STAT", sp_stat).mask(0xe0);
state_add(I8X9X_BAUD_RATE, "BAUD_RATE", baud_reg);
+ if (i8x9x_has_p1())
+ state_add<u8>(I8X9X_PORT1, "PORT1", [this]() -> u8 { return port1; }, [this](u8 data) { port1_w(data); });
+ state_add<u8>(I8X9X_PORT2, "PORT2", [this]() -> u8 { return port2; }, [this](u8 data) { port2_w(data); }).mask(i8x9x_p2_mask());
state_add(I8X9X_IOC0, "IOC0", ioc0).mask(0xfd);
state_add(I8X9X_IOC1, "IOC1", ioc1);
state_add(I8X9X_IOS0, "IOS0", ios0);
@@ -89,6 +93,8 @@ void i8x9x_device::device_start()
save_item(NAME(ad_command));
save_item(NAME(hso_time));
save_item(NAME(ad_result));
+ save_item(NAME(port1));
+ save_item(NAME(port2));
save_item(NAME(pwm_control));
save_item(NAME(ios0));
save_item(NAME(ios1));
@@ -112,6 +118,8 @@ void i8x9x_device::device_reset()
hso_command = 0;
hso_time = 0;
timer2_reset(total_cycles());
+ port1 = 0xff;
+ port2 = 0xc1 & i8x9x_p2_mask(); // P2.5 is cleared
ios0 = ios1 = 0x00;
ioc0 &= 0xaa;
ioc1 = (ioc1 & 0xae) | 0x01;
@@ -122,6 +130,8 @@ void i8x9x_device::device_reset()
sp_stat &= 0x80;
serial_send_timer = 0;
brh = false;
+ m_out_p1_cb(0xff);
+ m_out_p2_cb(0xc1);
m_hso_cb(0);
}
@@ -144,7 +154,9 @@ void i8x9x_device::commit_hso_cam()
void i8x9x_device::ad_start(u64 current_time)
{
ad_result = 8 | (ad_command & 7);
- if (m_ach_cb[ad_command & 7].isnull())
+ if (!BIT(i8x9x_p0_mask(), ad_command & 7))
+ logerror("Analog input on ACH%d does not exist on this device\n", ad_command & 7);
+ else if (m_ach_cb[ad_command & 7].isnull())
logerror("Analog input on ACH%d not configured\n", ad_command & 7);
else
ad_result |= m_ach_cb[ad_command & 7]() << 6;
@@ -286,29 +298,40 @@ u8 i8x9x_device::port0_r()
last = m_in_p0_cb();
logerror("read p0 %02x\n", last);
}
- return m_in_p0_cb();
+ return m_in_p0_cb() & i8x9x_p0_mask();
}
void i8x9x_device::port1_w(u8 data)
{
- logerror("io port 1 %02x (%04x)\n", data, PPC);
+ if (!i8x9x_has_p1())
+ {
+ logerror("%s: Write %02x to nonexistent port 1\n", machine().describe_context(), data);
+ return;
+ }
+
+ port1 = data;
m_out_p1_cb(data);
}
u8 i8x9x_device::port1_r()
{
- return m_in_p1_cb();
+ if (!i8x9x_has_p1())
+ return 0xff;
+
+ return m_in_p1_cb() & port1;
}
void i8x9x_device::port2_w(u8 data)
{
- logerror("io port 2 %02x (%04x)\n", data, PPC);
+ data &= 0xe1 & i8x9x_p2_mask();
+ port2 = data;
m_out_p2_cb(data);
}
u8 i8x9x_device::port2_r()
{
- return m_in_p2_cb();
+ // P2.0 and P2.5 are for output only (but can be read back despite what Intel claims?)
+ return (m_in_p2_cb() | 0x21 | ~i8x9x_p2_mask()) & (port2 | 0x1e);
}
void i8x9x_device::sp_con_w(u8 data)
diff --git a/src/devices/cpu/mcs96/i8x9x.h b/src/devices/cpu/mcs96/i8x9x.h
index 3a8f459865f..d3ee1777ad4 100644
--- a/src/devices/cpu/mcs96/i8x9x.h
+++ b/src/devices/cpu/mcs96/i8x9x.h
@@ -21,6 +21,8 @@ public:
I8X9X_HSO_COMMAND,
I8X9X_AD_COMMAND,
I8X9X_AD_RESULT,
+ I8X9X_PORT1,
+ I8X9X_PORT2,
I8X9X_PWM_CONTROL,
I8X9X_SBUF_RX,
I8X9X_SBUF_TX,
@@ -52,6 +54,10 @@ public:
void serial_w(u8 val);
+ virtual u8 i8x9x_p0_mask() const noexcept { return 0xff; }
+ virtual bool i8x9x_has_p1() const noexcept { return true; }
+ virtual u8 i8x9x_p2_mask() const noexcept { return 0xff; }
+
protected:
i8x9x_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, int data_width);
@@ -129,6 +135,7 @@ private:
u8 hsi_mode, hso_command, ad_command;
u16 hso_time, ad_result;
u8 pwm_control;
+ u8 port1, port2;
u8 ios0, ios1, ioc0, ioc1;
u8 sbuf, sp_con, sp_stat;
u8 serial_send_buf;
@@ -150,6 +157,11 @@ private:
class c8095_90_device : public i8x9x_device {
public:
c8095_90_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+
+protected:
+ virtual u8 i8x9x_p0_mask() const noexcept override { return 0xf0; }
+ virtual bool i8x9x_has_p1() const noexcept override { return false; }
+ virtual u8 i8x9x_p2_mask() const noexcept override { return 0x27; }
};
class n8097bh_device : public i8x9x_device {
@@ -160,11 +172,21 @@ public:
class p8098_device : public i8x9x_device {
public:
p8098_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+
+protected:
+ virtual u8 i8x9x_p0_mask() const noexcept override { return 0xf0; }
+ virtual bool i8x9x_has_p1() const noexcept override { return false; }
+ virtual u8 i8x9x_p2_mask() const noexcept override { return 0x27; }
};
class p8798_device : public i8x9x_device {
public:
p8798_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+
+protected:
+ virtual u8 i8x9x_p0_mask() const noexcept override { return 0xf0; }
+ virtual bool i8x9x_has_p1() const noexcept override { return false; }
+ virtual u8 i8x9x_p2_mask() const noexcept override { return 0x27; }
};
DECLARE_DEVICE_TYPE(C8095_90, c8095_90_device)