summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author AJR <ajrhacker@users.noreply.github.com>2019-07-19 19:13:28 -0400
committer AJR <ajrhacker@users.noreply.github.com>2019-07-19 19:16:25 -0400
commitd1e92898e416c135fcd02f2abea155eb3917ffb0 (patch)
treeebb6f44047d93cf8388cb068bddf740e6e47bb07
parent4d1582c79336c073f1d971ec88bed94b6fe77290 (diff)
i8155: Update port outputs upon mode change
-rw-r--r--src/devices/machine/i8155.cpp125
-rw-r--r--src/devices/machine/i8155.h1
2 files changed, 72 insertions, 54 deletions
diff --git a/src/devices/machine/i8155.cpp b/src/devices/machine/i8155.cpp
index b5027368633..761bcef000d 100644
--- a/src/devices/machine/i8155.cpp
+++ b/src/devices/machine/i8155.cpp
@@ -443,74 +443,91 @@ uint8_t i8155_device::io_r(offs_t offset)
return data;
}
-
//-------------------------------------------------
-// register_w - register write
+// write_command - set port modes and start/stop
+// timer
//-------------------------------------------------
-void i8155_device::register_w(int offset, uint8_t data)
+void i8155_device::write_command(uint8_t data)
{
- switch (offset & 0x07)
+ uint8_t old_command = std::exchange(m_command, data);
+
+ LOGMASKED(LOG_PORT, "Port A Mode: %s\n", (data & COMMAND_PA) ? "output" : "input");
+ LOGMASKED(LOG_PORT, "Port B Mode: %s\n", (data & COMMAND_PB) ? "output" : "input");
+
+ LOGMASKED(LOG_PORT, "Port A Interrupt: %s\n", (data & COMMAND_IEA) ? "enabled" : "disabled");
+ LOGMASKED(LOG_PORT, "Port B Interrupt: %s\n", (data & COMMAND_IEB) ? "enabled" : "disabled");
+
+ if ((data & COMMAND_PA) && (!old_command & COMMAND_PA))
+ m_out_pa_cb((offs_t)0, m_output[PORT_A]);
+ if ((data & COMMAND_PB) && (!old_command & COMMAND_PB))
+ m_out_pb_cb((offs_t)0, m_output[PORT_B]);
+
+ switch (data & COMMAND_PC_MASK)
{
- case REGISTER_COMMAND:
- m_command = data;
+ case COMMAND_PC_ALT_1:
+ LOGMASKED(LOG_PORT, "Port C Mode: Alt 1 (PC0-PC5 input)\n");
+ break;
- LOGMASKED(LOG_PORT, "Port A Mode: %s\n", (data & COMMAND_PA) ? "output" : "input");
- LOGMASKED(LOG_PORT, "Port B Mode: %s\n", (data & COMMAND_PB) ? "output" : "input");
+ case COMMAND_PC_ALT_2:
+ LOGMASKED(LOG_PORT, "Port C Mode: Alt 2 (PC0-PC5 output)\n");
+ if ((old_command & COMMAND_PC_MASK) != COMMAND_PC_ALT_2)
+ m_out_pc_cb((offs_t)0, m_output[PORT_C]);
+ break;
- LOGMASKED(LOG_PORT, "Port A Interrupt: %s\n", (data & COMMAND_IEA) ? "enabled" : "disabled");
- LOGMASKED(LOG_PORT, "Port B Interrupt: %s\n", (data & COMMAND_IEB) ? "enabled" : "disabled");
+ case COMMAND_PC_ALT_3:
+ LOGMASKED(LOG_PORT, "Port C Mode: Alt 3 (PC0-PC2 A handshake, PC3-PC5 output)\n");
+ break;
- switch (data & COMMAND_PC_MASK)
- {
- case COMMAND_PC_ALT_1:
- LOGMASKED(LOG_PORT, "Port C Mode: Alt 1\n");
- break;
+ case COMMAND_PC_ALT_4:
+ LOGMASKED(LOG_PORT, "Port C Mode: Alt 4 (PC0-PC2 A handshake, PC3-PC5 B handshake)\n");
+ break;
+ }
- case COMMAND_PC_ALT_2:
- LOGMASKED(LOG_PORT, "Port C Mode: Alt 2\n");
- break;
+ switch (data & COMMAND_TM_MASK)
+ {
+ case COMMAND_TM_NOP:
+ // do not affect counter operation
+ break;
- case COMMAND_PC_ALT_3:
- LOGMASKED(LOG_PORT, "Port C Mode: Alt 3\n");
- break;
+ case COMMAND_TM_STOP:
+ // NOP if timer has not started, stop counting if the timer is running
+ LOGMASKED(LOG_PORT, "Timer Command: Stop\n");
+ timer_stop_count();
+ break;
- case COMMAND_PC_ALT_4:
- LOGMASKED(LOG_PORT, "Port C Mode: Alt 4\n");
- break;
- }
+ case COMMAND_TM_STOP_AFTER_TC:
+ // stop immediately after present TC is reached (NOP if timer has not started)
+ LOGMASKED(LOG_PORT, "Timer Command: Stop after TC\n");
+ break;
- switch (data & COMMAND_TM_MASK)
- {
- case COMMAND_TM_NOP:
- // do not affect counter operation
- break;
+ case COMMAND_TM_START:
+ LOGMASKED(LOG_PORT, "Timer Command: Start\n");
- case COMMAND_TM_STOP:
- // NOP if timer has not started, stop counting if the timer is running
- LOGMASKED(LOG_PORT, "Timer Command: Stop\n");
- timer_stop_count();
- break;
-
- case COMMAND_TM_STOP_AFTER_TC:
- // stop immediately after present TC is reached (NOP if timer has not started)
- LOGMASKED(LOG_PORT, "Timer Command: Stop after TC\n");
- break;
-
- case COMMAND_TM_START:
- LOGMASKED(LOG_PORT, "Timer Command: Start\n");
-
- if (m_timer->enabled())
- {
- // if timer is running, start the new mode and CNT length immediately after present TC is reached
- }
- else
- {
- // load mode and CNT length and start immediately after loading (if timer is not running)
- timer_reload_count();
- }
- break;
+ if (m_timer->enabled())
+ {
+ // if timer is running, start the new mode and CNT length immediately after present TC is reached
}
+ else
+ {
+ // load mode and CNT length and start immediately after loading (if timer is not running)
+ timer_reload_count();
+ }
+ break;
+ }
+}
+
+
+//-------------------------------------------------
+// register_w - register write
+//-------------------------------------------------
+
+void i8155_device::register_w(int offset, uint8_t data)
+{
+ switch (offset & 0x07)
+ {
+ case REGISTER_COMMAND:
+ write_command(data);
break;
case REGISTER_PORT_A:
diff --git a/src/devices/machine/i8155.h b/src/devices/machine/i8155.h
index 2d6e49b2063..a4fe5b2938f 100644
--- a/src/devices/machine/i8155.h
+++ b/src/devices/machine/i8155.h
@@ -116,6 +116,7 @@ private:
inline int get_port_mode(int port);
inline uint8_t read_port(int port);
inline void write_port(int port, uint8_t data);
+ void write_command(uint8_t data);
void register_w(int offset, uint8_t data);
};