summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Joakim Larsson Edstrom <joakimlarsson42@gmail.com>2016-06-10 10:31:32 +0200
committer Joakim Larsson Edstrom <joakimlarsson42@gmail.com>2016-06-10 10:31:32 +0200
commitdeb715cca6f43cbb91a00b07705b708b5b691ec3 (patch)
tree6a3138184cfc5dc422fa6e5c5ad7d4bba8fc785b
parentf812a76116c92b3bdd04eb5ff8ca6262e89ae062 (diff)
completed the parallell port part now supporting all ports A,B and C, still WIP
-rw-r--r--src/devices/machine/68230pit.cpp663
-rw-r--r--src/devices/machine/68230pit.h159
2 files changed, 593 insertions, 229 deletions
diff --git a/src/devices/machine/68230pit.cpp b/src/devices/machine/68230pit.cpp
index 927ece2cb75..fe84888ffbf 100644
--- a/src/devices/machine/68230pit.cpp
+++ b/src/devices/machine/68230pit.cpp
@@ -9,13 +9,31 @@
*
* Todo
* - Add clock and timers
+* - Add double buffering for each submode
* - Add all missing registers
* - Add configuration
**********************************************************************/
#include "68230pit.h"
-#define LOG(x) /* x */
+#define VERBOSE 0
+
+#define LOG(x) do { if (VERBOSE) logerror x; } while (0)
+#define LOGR(x) LOG(x)
+#if VERBOSE == 2
+#define logerror printf
+#endif
+
+#ifdef _MSC_VER
+#define FUNCNAME __func__
+#define LLFORMAT "%I64%"
+#else
+#define FUNCNAME __PRETTY_FUNCTION__
+#define LLFORMAT "%lld"
+#endif
+
+//#define LOG(x) x
+//#define logerror printf
//**************************************************************************
// DEVICE TYPE DEFINITIONS
@@ -27,22 +45,70 @@ const device_type PIT68230 = &device_creator<pit68230_device>;
// pit68230_device - constructors
//-------------------------------------------------
pit68230_device::pit68230_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, UINT32 variant, const char *shortname, const char *source)
- : device_t (mconfig, type, name, tag, owner, clock, shortname, source),
- device_execute_interface (mconfig, *this)
- , m_icount (0)
- , m_write_pa (*this)
- , m_write_h2 (*this), m_pgcr(0), m_psrr(0), m_paddr(0), m_pbddr(0), m_pcddr(0), m_pacr(0), m_pbcr(0), m_padr(0), m_pbdr(0), m_psr(0)
- {
+ : device_t (mconfig, type, name, tag, owner, clock, shortname, source),
+ device_execute_interface (mconfig, *this)
+ , m_icount (0)
+ , m_pa_out_cb(*this)
+ , m_pa_in_cb(*this)
+ , m_pb_out_cb(*this)
+ , m_pb_in_cb(*this)
+ , m_pc_out_cb(*this)
+ , m_pc_in_cb(*this)
+ , m_h1_out_cb (*this)
+ , m_h2_out_cb (*this)
+ , m_h3_out_cb (*this)
+ , m_h4_out_cb (*this)
+ , m_pgcr(0)
+ , m_psrr(0)
+ , m_paddr(0)
+ , m_pbddr(0)
+ , m_pcddr(0)
+ , m_pacr(0)
+ , m_pbcr(0)
+ , m_padr(0)
+ , m_pbdr(0)
+ , m_psr(0)
+ , m_tcr(0)
+ , m_cpr(0)
+ // , m_cprh(0)
+ // , m_cprm(0)
+ // , m_cprl(0)
+ , m_cntr(0)
+{
}
pit68230_device::pit68230_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
- : device_t (mconfig, PIT68230, "PIT68230", tag, owner, clock, "pit68230", __FILE__),
- device_execute_interface (mconfig, *this)
- , m_icount (0)
- , m_write_pa (*this)
- , m_write_h2 (*this), m_pgcr(0), m_psrr(0), m_paddr(0), m_pbddr(0), m_pcddr(0), m_pacr(0), m_pbcr(0), m_padr(0), m_pbdr(0), m_psr(0)
- {
+ : device_t (mconfig, PIT68230, "PIT68230", tag, owner, clock, "pit68230", __FILE__),
+ device_execute_interface (mconfig, *this)
+ , m_icount (0)
+ , m_pa_out_cb (*this)
+ , m_pa_in_cb(*this)
+ , m_pb_out_cb(*this)
+ , m_pb_in_cb(*this)
+ , m_pc_out_cb(*this)
+ , m_pc_in_cb(*this)
+ , m_h1_out_cb(*this)
+ , m_h2_out_cb(*this)
+ , m_h3_out_cb(*this)
+ , m_h4_out_cb(*this)
+ , m_pgcr(0)
+ , m_psrr(0)
+ , m_paddr(0)
+ , m_pbddr(0)
+ , m_pcddr(0)
+ , m_pacr(0)
+ , m_pbcr(0)
+ , m_padr(0)
+ , m_pbdr(0)
+ , m_psr(0)
+ , m_tcr(0)
+ , m_cpr(0)
+ // , m_cprh(0)
+ // , m_cprm(0)
+ // , m_cprl(0)
+ , m_cntr(0)
+{
}
//-------------------------------------------------
@@ -50,12 +116,18 @@ pit68230_device::pit68230_device(const machine_config &mconfig, const char *tag,
//-------------------------------------------------
void pit68230_device::device_start ()
{
- LOG (logerror ("PIT68230 device started\n"));
- m_icountptr = &m_icount;
-
- // resolve callbacks
- m_write_pa.resolve_safe ();
- m_write_h2.resolve_safe ();
+ LOG(("%s\n", FUNCNAME));
+ m_icountptr = &m_icount;
+
+ // resolve callbacks
+ m_pa_out_cb.resolve_safe();
+ m_pa_in_cb.resolve_safe(0);
+ m_pb_out_cb.resolve_safe();
+ m_pb_in_cb.resolve_safe(0);
+ m_h1_out_cb.resolve_safe();
+ m_h2_out_cb.resolve_safe();
+ m_h3_out_cb.resolve_safe();
+ m_h4_out_cb.resolve_safe();
}
//-------------------------------------------------
@@ -63,17 +135,18 @@ void pit68230_device::device_start ()
//-------------------------------------------------
void pit68230_device::device_reset ()
{
- LOG (logerror ("PIT68230 device reseted\n"));
- m_pgcr = 0;
- m_psrr = 0;
- m_paddr = 0;
- m_pbddr = 0;
- m_pcddr = 0;
- m_pacr = 0; m_write_h2 (m_pacr);
- m_pbcr = 0;
- m_padr = 0; m_write_pa ((offs_t)0, m_padr); // TODO: check PADDR
- m_pbdr = 0;
- m_psr = 0;
+ LOG(("%s %s \n",tag(), FUNCNAME));
+
+ m_pgcr = 0;
+ m_psrr = 0;
+ m_paddr = 0;
+ m_pbddr = 0;
+ m_pcddr = 0;
+ m_pacr = 0; m_h2_out_cb(m_pacr);
+ m_pbcr = 0;
+ m_padr = 0; m_pa_out_cb((offs_t)0, m_padr); // TODO: check PADDR
+ m_pbdr = 0;
+ m_psr = 0;
}
//-------------------------------------------------
@@ -85,16 +158,16 @@ void pit68230_device::device_timer (emu_timer &timer, device_timer_id id, INT32
void pit68230_device::h1_set (UINT8 state)
{
- LOG (logerror ("h1_set %d @ m_psr %2x => ", state, m_psr));
- if (state) m_psr |= 1; else m_psr &= ~1;
- LOG (logerror ("%02x %lld\n", m_psr, machine ().firstcpu->total_cycles ()));
+ LOG(("%s %s %d @ m_psr %2x => ",tag(), FUNCNAME, state, m_psr));
+ if (state) m_psr |= 1; else m_psr &= ~1;
+ LOG(("%02x %lld\n", m_psr, machine ().firstcpu->total_cycles ()));
}
void pit68230_device::portb_setbit (UINT8 bit, UINT8 state)
{
- LOG (logerror ("portb_setbit %d/%d @ m_pbdr %2x => ", bit, state, m_pbdr));
- if (state) m_pbdr |= (1 << bit); else m_pbdr &= ~(1 << bit);
- LOG (logerror ("%02x %lld\n", m_pbdr, machine ().firstcpu->total_cycles ()));
+ LOG(("%s %s %d/%d @ m_pbdr %2x => ", tag(), FUNCNAME, bit, state, m_pbdr));
+ if (state) m_pbdr |= (1 << bit); else m_pbdr &= ~(1 << bit);
+ LOG(("%02x %lld\n", m_pbdr, machine ().firstcpu->total_cycles ()));
}
//-------------------------------------------------
@@ -109,157 +182,373 @@ void pit68230_device::execute_run ()
} while (m_icount > 0);
}
-LOG (static INT32 ow_cnt = 0)
-LOG (static INT32 ow_data = 0)
-LOG (static INT32 ow_ofs = 0)
-
-WRITE8_MEMBER (pit68230_device::write){
- switch (offset) {
- case PIT_68230_PGCR:
- m_pgcr = data;
- break;
-
- case PIT_68230_PSRR:
- m_psrr = data;
- break;
-
- case PIT_68230_PADDR:
- m_paddr = data;
- break;
-
- case PIT_68230_PBDDR:
- m_pbddr = data;
- break;
-
- case PIT_68230_PCDDR:
- m_pcddr = data;
- break;
-
- case PIT_68230_PACR:
- m_pacr = data;
- // callbacks
- /*PACR in Mode 0
- * 5 43 H2 Control in Submode 00 && 01
- * ------------------------------------
- * 0 XX Input pin - edge-sensitive status input, H2S is set on an asserted edge.
- * 1 00 Output pin - negated, H2S is always clear.
- * 1 01 Output pin - asserted, H2S is always clear.
- * 1 10 Output pin - interlocked input handshake protocol, H2S is always clear.
- * 1 11 Output pin - pulsed input handshake protocol, H2S is always clear.
- *
- * 5 43 H2 Control in Submode 1x
- * ------------------------------------
- * 0 XX Input pin - edge-sensitive status input, H2S is set on an asserted edge.
- * 1 X0 Output pin - negated, H2S is always cleared.
- * 1 X1 Output pin - asserted, H2S is always cleared.
- */
- m_write_h2 (m_pacr & 0x08 ? 1 : 0); // TODO: Check mode and submodes
- break;
-
- case PIT_68230_PBCR:
- m_pbcr = data;
- break;
-
- case PIT_68230_PADR:
- m_padr = data;
- // callbacks
- m_write_pa ((offs_t)0, m_padr); // TODO: check PADDR
- break;
-
- case PIT_68230_PSR:
- m_psr = data;
- break;
-
- default:
- LOG (logerror ("unhandled register %02x", offset));
- }
-
- LOG (if (offset != ow_ofs || data != ow_data || ow_cnt >= 1000) {
- logerror ("\npit68230_device::write: previous identical operation performed %02x times\n", ow_cnt);
- ow_cnt = 0;
- ow_data = data;
- ow_ofs = offset;
- logerror ("pit68230_device::write: offset=%02x data=%02x %lld\n", ow_ofs, ow_data, machine ().firstcpu->total_cycles ());
- }
- else
- ow_cnt++; )
-}
-
-LOG (static INT32 or_cnt = 0)
-LOG (static INT32 or_data = 0)
-LOG (static INT32 or_ofs = 0)
+#if VERBOSE > 2
+static INT32 ow_cnt = 0;
+static INT32 ow_data = 0;
+static INT32 ow_ofs = 0;
+#endif
+
+void pit68230_device::wr_pitreg_pgcr(UINT8 data)
+{
+ LOG(("%s(%02x) \"%s\": %s - %02x\n", FUNCNAME, data, m_owner->tag(), FUNCNAME, data));
+ m_pgcr = data;
+}
+
+void pit68230_device::wr_pitreg_psrr(UINT8 data)
+{
+ LOG(("%s(%02x) \"%s\": %s - %02x\n", FUNCNAME, data, m_owner->tag(), FUNCNAME, data));
+ m_psrr = data;
+}
+
+void pit68230_device::wr_pitreg_paddr(UINT8 data)
+{
+ LOG(("%s(%02x) \"%s\": %s - %02x\n", FUNCNAME, data, m_owner->tag(), FUNCNAME, data));
+ m_paddr = data;
+}
+
+void pit68230_device::wr_pitreg_pbddr(UINT8 data)
+{
+ LOG(("%s(%02x) \"%s\": %s - %02x\n", FUNCNAME, data, m_owner->tag(), FUNCNAME, data));
+ m_pbddr = data;
+}
+
+void pit68230_device::wr_pitreg_pcddr(UINT8 data)
+{
+ LOG(("%s(%02x) \"%s\": %s - %02x\n", FUNCNAME, data, m_owner->tag(), FUNCNAME, data));
+ m_pcddr = data;
+}
+
+void pit68230_device::wr_pitreg_pacr(UINT8 data)
+{
+ LOG(("%s(%02x) \"%s\": %s - %02x\n", FUNCNAME, data, m_owner->tag(), FUNCNAME, data));
+ m_pacr = data;
+ // callbacks
+ /*PACR in Mode 0
+ * 5 43 H2 Control in Submode 00 && 01
+ * ------------------------------------
+ * 0 XX Input pin - edge-sensitive status input, H2S is set on an asserted edge.
+ * 1 00 Output pin - negated, H2S is always clear.
+ * 1 01 Output pin - asserted, H2S is always clear.
+ * 1 10 Output pin - interlocked input handshake protocol, H2S is always clear.
+ * 1 11 Output pin - pulsed input handshake protocol, H2S is always clear.
+ *
+ * 5 43 H2 Control in Submode 1x
+ * ------------------------------------
+ * 0 XX Input pin - edge-sensitive status input, H2S is set on an asserted edge.
+ * 1 X0 Output pin - negated, H2S is always cleared.
+ * 1 X1 Output pin - asserted, H2S is always cleared.
+ */
+ m_h2_out_cb (m_pacr & 0x08 ? 1 : 0); // TODO: Check mode and submodes
+}
+
+void pit68230_device::wr_pitreg_pbcr(UINT8 data)
+{
+ LOG(("%s(%02x) \"%s\": %s - %02x\n", FUNCNAME, data, m_owner->tag(), FUNCNAME, data));
+ m_pbcr = data;
+}
+
+void pit68230_device::wr_pitreg_padr(UINT8 data)
+{
+ LOG(("%s(%02x) \"%s\": %s - %02x\n", FUNCNAME, data, m_owner->tag(), FUNCNAME, data));
+ m_padr = data;
+ // callbacks
+ m_pa_out_cb ((offs_t)0, m_padr); // TODO: check PADDR
+}
+
+void pit68230_device::wr_pitreg_psr(UINT8 data)
+{
+ LOG(("%s(%02x) \"%s\": %s - %02x\n", FUNCNAME, data, m_owner->tag(), FUNCNAME, data));
+ m_psr = data;
+}
+
+/* The timer control register (TCR) determines all operations of the timer. Bits 7-5 configure the PC3/TOUT
+and PC7/TIACKpins for port C, square wave, vectored interrupt, or autovectored interrupt operation bit
+4 specifies whether the counter receives data from the counter preload register or continues counting when
+zero detect is reached ; bit 3 is unused and is read as zero bits 2 and 1 configure the path from the CLK
+and TINpins to the counter controller ; and bit 0 ena-bles the timer. This register is readable and writable
+at all times. All bits are cleared to zero when the RESET pin is asserted.
+
+TCR bits
+ 7 6 5 TOUT/TIACK Control
+----------------------------
+ 0 0 X The dual-function pins PC3/TOUT and PC7/TIACK carry the port C function.
+ 0 1 X The dual-function pinPC3/TOUT carries the TOUT function. In the run state it is used as a squarewave
+ output and is toggled on zero detect. The TOUT pin is high while in the halt state. The dualfunction
+ pin PC7/TIACK carries the PC7 function.
+ 1 0 0 The dual-function pin PC3/TOUT carries the TOUT function. In the run or halt state it is used as
+ a timer interrupt request output. The timer interrupt is disabled, thus, the pin is always three stated.
+ The dual-function pin PC7/TIACK carries the TIACK function ; however, since interrupt request is
+ negated, the PI/T produces no response (i.e., no data or DTACK) to an asserted TIACK. Refer to
+ 5.1.3. Timer Interrupt Acknowledge Cycles for details.
+ 1 0 1 The dual-function pin PC3/TOUT carries the TOUTfunction and is used as a timer interrupt request
+ output. The timer interrupt is enabled ; thus, the pin is low when the timer ZDS status bit is one.
+ The dual-function pin PC7/TIACK carries the TIACK function and is used as a timer interrupt acknowledge
+ input. Refer to the5.1.3. Timer InterruptAcknowledge Cycles fordetails. Thiscombination
+ supports vectored timer interrupts.
+ 1 1 0 The dual-function pin PC3/TOUT function. In the run or halt state it is used as a timer interrupt
+ request output. The timer interrupt is disabled ; thus, the pin is always three-stated. The dual-function
+ pin PC7/TIACK carries the PC7 function.
+ 1 1 1 The dual-function pin PC3/TOUT carries the TOUTfunction and is used as a timer interrupt request
+ output. The timer interrupt is enabled ; thus, the pin is low when the timer ZDS status bit is one.
+ The dual-function pin PC7/TIACK carries the PC7 function and autovectored interrupts are supported.
+
+TCR bit 4 - Zero Detect Control
+ 0 The counter is loaded fromthe counter preload register on the first clock to the 24-bit counter after
+ zero detect, then resumes counting.
+ 1 The counter rolls over on zero detect, then continues counting.
+
+TCR bit 3 - Unused and is always read as zero.
+
+TCR bits
+ 2 1 Clock Control
+ 0 0 The PC2/TIN input pin carries the port C function, and the CLK pin and prescaler are used. The
+ prescaler is decremented on the falling transition of the CLKpin ; the 24-bit counter is decremented,
+ rolls over, or is loaded from the counter preload registers when the prescaler rolls over from $OO
+ to $1F. The timer enable bit determines whether the timer is in the run or halt state.
+ 0 1 The PC2/TIN pin serves as a timer input, and the CLK pin and prescaler are used. The prescaler
+ is decremented on the falling transition of the CLK pin ; the 24-bit counter is decremented, rolls
+ over, or is loaded from the counter preload registers when the prescaler rolls over from $00 to $1F.
+ The timer is in the run state when the timer enable bit is one and the TIN pin is high ; otherwise,
+ the timer is in the halt state.
+ 1 0 The PC2/TIN pin serves as a timer input and the prescaler is used. The prescaler is decremented
+ following the rising transition of the TIN pin after being synchronized with the internal clock. The
+ 24-bit counter is decremented, rolls over, or is loaded from the counter preload registers when the
+ prescaler rolls over from $00 to $1F. The timer enable bit determines whether the timer is in the
+ run or halt state.
+ 1 1 The PC2/TIN pin serves as a timer input and the prescaler is not used. The 24-bit counter is decremented,
+ rolls over, or is loaded from the counter preload registers following the rising edge of
+ the TIN pin after being synchronized with the internal clock. The timer enable bit determines whether
+ the timer is in the run or halt state.
+TCR bit 0 - Timer Enable
+ 0 Disabled
+ 1 Enabled
+*/
+void pit68230_device::wr_pitreg_tcr(UINT8 data)
+{
+ LOG(("%s(%02x) \"%s\": %s - %02x Timer %s\n",
+ FUNCNAME, data, m_owner->tag(), FUNCNAME, data, data & REG_TCR_ENABLE ? "enabled" : "disabled"));
+ m_tcr = data;
+}
+
+void pit68230_device::wr_pitreg_cprh(UINT8 data)
+{
+ LOG(("%s(%02x) \"%s\": %s - %02x\n", FUNCNAME, data, m_owner->tag(), FUNCNAME, data));
+ m_cpr &= ~0xff0000;
+ m_cpr |= ((data << 16) & 0xff0000);
+ // m_cprh = data;
+}
+
+void pit68230_device::wr_pitreg_cprm(UINT8 data)
+{
+ LOG(("%s(%02x) \"%s\": %s - %02x\n", FUNCNAME, data, m_owner->tag(), FUNCNAME, data));
+ m_cpr &= ~0x00ff00;
+ m_cpr |= ((data << 8) & 0x00ff00);
+ // m_cprm = data;
+}
+
+void pit68230_device::wr_pitreg_cprl(UINT8 data)
+{
+ LOG(("%s(%02x) \"%s\": %s - %02x\n", FUNCNAME, data, m_owner->tag(), FUNCNAME, data));
+ m_cpr &= ~0x0000ff;
+ m_cpr |= ((data << 0) & 0x0000ff);
+ // m_cprl = data;
+}
+
+WRITE8_MEMBER (pit68230_device::write)
+{
+ LOG(("%s %s \n",tag(), FUNCNAME));
+ switch (offset) {
+ case PIT_68230_PGCR: wr_pitreg_pgcr(data); break;
+ case PIT_68230_PSRR: wr_pitreg_psrr(data); break;
+ case PIT_68230_PADDR: wr_pitreg_paddr(data); break;
+ case PIT_68230_PBDDR: wr_pitreg_pbddr(data); break;
+ case PIT_68230_PCDDR: wr_pitreg_pcddr(data); break;
+ case PIT_68230_PACR: wr_pitreg_pacr(data); break;
+ case PIT_68230_PBCR: wr_pitreg_pbcr(data); break;
+ case PIT_68230_PADR: wr_pitreg_padr(data); break;
+ case PIT_68230_PAAR: break; // RO register so ignored
+ case PIT_68230_PBAR: break; // RO register so ignored
+ case PIT_68230_PSR: wr_pitreg_psr(data); break;
+ case PIT_68230_TCR: wr_pitreg_tcr(data); break;
+ case PIT_68230_CPRH: wr_pitreg_cprh(data); break;
+ case PIT_68230_CPRM: wr_pitreg_cprm(data); break;
+ case PIT_68230_CPRL: wr_pitreg_cprl(data); break;
+ default:
+ LOG (("Unhandled Write of %02x to register %02x", data, offset));
+ }
+
+#if VERBOSE > 2
+ if (offset != ow_ofs || data != ow_data || ow_cnt >= 1000) {
+ logerror ("\npit68230_device::write: previous identical operation performed %02x times\n", ow_cnt);
+ ow_cnt = 0;
+ ow_data = data;
+ ow_ofs = offset;
+ logerror ("pit68230_device::write: offset=%02x data=%02x %lld\n", ow_ofs, ow_data, machine ().firstcpu->total_cycles ());
+ }
+ else
+ ow_cnt++;
+#endif
+
+}
+
+#if VERBOSE > 2
+static INT32 or_cnt = 0;
+static INT32 or_data = 0;
+static INT32 or_ofs = 0;
+#endif
+
+UINT8 pit68230_device::rr_pitreg_pgcr()
+{
+ LOGR(("%s %s <- %02x\n",tag(), FUNCNAME, m_pgcr));
+ return m_pgcr;
+}
+
+UINT8 pit68230_device::rr_pitreg_psrr()
+{
+ LOGR(("%s %s <- %02x\n",tag(), FUNCNAME, m_psrr));
+ return m_psrr;
+}
+
+UINT8 pit68230_device::rr_pitreg_paddr()
+{
+ LOGR(("%s %s <- %02x\n",tag(), FUNCNAME, m_paddr));
+ return m_paddr;
+}
+
+UINT8 pit68230_device::rr_pitreg_pbddr()
+{
+ LOGR(("%s %s <- %02x\n",tag(), FUNCNAME, m_pbddr));
+ return m_pbddr;
+}
+
+UINT8 pit68230_device::rr_pitreg_pcddr()
+{
+ LOGR(("%s %s <- %02x\n",tag(), FUNCNAME, m_pcddr));
+ return m_pcddr;
+}
+
+UINT8 pit68230_device::rr_pitreg_pacr()
+{
+ LOGR(("%s %s <- %02x\n",tag(), FUNCNAME, m_pacr));
+ return m_pacr;
+}
+
+UINT8 pit68230_device::rr_pitreg_pbcr()
+{
+ LOGR(("%s %s <- %02x\n",tag(), FUNCNAME, m_pbcr));
+ return m_pbcr;
+}
+
+UINT8 pit68230_device::rr_pitreg_padr()
+{
+ LOGR(("%s %s <- %02x\n",tag(), FUNCNAME, m_padr));
+ return m_padr;
+}
+
+/* 4.6.2. PORT B DATA REGISTER (PBDR). The port B data register is a holding
+ * register for moving data to and from port B pins. The port B data direction
+ * register determines whether each pin is an input (zero) or an output (one).
+ * This register is readable and writable at all times. Depending on the chosen
+ * mode/submode, reading or writing may affect the double-buffered handshake
+ * mechanism. The port B data register is not affected by the assertion of the
+ * RESET pin. PB0-PB7 sits on pins 17-24 on a 48 pin DIP package */
+UINT8 pit68230_device::rr_pitreg_pbdr()
+{
+ LOGR(("%s %s <- %02x\n",tag(), FUNCNAME, m_pbdr));
+ return m_pbdr;
+}
+
+/* The port A alternate register is an alternate register for reading the port A pins.
+It is a read-only address and no other PI/T condition is affected. In all modes,
+the instantaneous pin level is read and no input latching is performed except at the
+data bus interface. Writes to this address are answered with DTACK, but the data is ignored.*/
+UINT8 pit68230_device::rr_pitreg_paar()
+{
+ // NOTE: no side effect emulated so using ..padr
+ UINT8 ret;
+ ret = m_pa_in_cb();
+ LOGR(("%s %s <- %02x\n",tag(), FUNCNAME, ret));
+ return ret;
+}
+
+/* The port B alternate register is an alternate register for reading the port B pins.
+It is a read-only address and no other PI/T condition is affected. In all modes,
+the instantaneous pin level is read and no input latching is performed except at the
+data bus interface.Writes to this address are answered with DTACK, but the data is ignored.*/
+UINT8 pit68230_device::rr_pitreg_pbar()
+{
+ // NOTE: no side effect emulated so using ..pbdr
+ UINT8 ret;
+ ret = m_pb_in_cb();
+ LOGR(("%s %s <- %02x\n",tag(), FUNCNAME, ret));
+ return ret;
+}
+
+/* 4.8. PORT STATUS REGISTER (PSR) The port status register contains information about
+ * handshake pin activity. Bits 7-4 show the instantaneous level of the respective handshake
+ * pin, and are independent of the handshake pin sense bits in the port general control
+ * register. Bits 3-0 are the respective status bits referred to throughout this document.
+ * Their interpretation depends on the programmed mode/submode of the PI/T. For bits
+ * 3-0 a one is the active or asserted state. */
+UINT8 pit68230_device::rr_pitreg_psr()
+{
+ LOGR(("%s %s <- %02x\n",tag(), FUNCNAME, m_psr));
+ return m_psr;
+}
+
+UINT8 pit68230_device::rr_pitreg_cntrh()
+{
+ LOGR(("%s %s <- %02x\n",tag(), FUNCNAME, (m_cntr >> 16) & 0xff));
+ return (m_cntr >> 16) & 0xff;
+}
+
+UINT8 pit68230_device::rr_pitreg_cntrm()
+{
+ LOGR(("%s %s <- %02x\n",tag(), FUNCNAME, (m_cntr >> 8) & 0xff));
+ return (m_cntr >> 8) & 0xff;
+}
+
+UINT8 pit68230_device::rr_pitreg_cntrl()
+{
+ LOGR(("%s %s <- %02x\n",tag(), FUNCNAME, (m_cntr >> 0) & 0xff));
+ return (m_cntr >> 0) & 0xff;
+}
READ8_MEMBER (pit68230_device::read){
- UINT8 data;
-
- switch (offset) {
- case PIT_68230_PGCR:
- data = m_pgcr;
- break;
-
- case PIT_68230_PSRR:
- data = m_psrr;
- break;
-
- case PIT_68230_PADDR:
- data = m_paddr;
- break;
-
- case PIT_68230_PBDDR:
- data = m_pbddr;
- break;
-
- case PIT_68230_PCDDR:
- data = m_pcddr;
- break;
-
- case PIT_68230_PACR:
- data = m_pacr;
- break;
-
- case PIT_68230_PBCR:
- data = m_pbcr;
- break;
-
- case PIT_68230_PADR:
- data = m_padr;
- break;
-
- case PIT_68230_PBDR:
- /* 4.6.2. PORT B DATA REGISTER (PBDR). The port B data register is a holding
- * register for moving data to and from port B pins. The port B data direction
- * register determines whether each pin is an input (zero) or an output (one).
- * This register is readable and writable at all times. Depending on the chosen
- * mode/submode, reading or writing may affect the double-buffered handshake
- * mechanism. The port B data register is not affected by the assertion of the
- * RESET pin. PB0-PB7 sits on pins 17-24 on a 48 pin DIP package */
- data = m_pbdr;
- break;
-
- case PIT_68230_PSR:
- /* 4.8. PORT STATUS REGISTER (PSR) The port status register contains information about
- * handshake pin activity. Bits 7-4 show the instantaneous level of the respective handshake
- * pin, and are independent of the handshake pin sense bits in the port general control
- * register. Bits 3-0 are the respective status bits referred to throughout this document.
- * Their interpretation depends on the programmed mode/submode of the PI/T. For bits
- * 3-0 a one is the active or asserted state. */
- data = m_psr;
- break;
-
- default:
- LOG (logerror ("unhandled register %02x", offset));
- data = 0;
- }
-
- LOG (if (offset != or_ofs || data != or_data || or_cnt >= 1000) {
- logerror ("\npit68230_device::read: previous identical operation performed %02x times\n", or_cnt);
- or_cnt = 0;
- or_data = data;
- or_ofs = offset;
- logerror ("pit68230_device::read: offset=%02x data=%02x %lld\n", or_ofs, or_data, machine ().firstcpu->total_cycles ());
- }
- else
- or_cnt++; )
-
- return data;
+ UINT8 data;
+
+ switch (offset) {
+ case PIT_68230_PGCR: data = rr_pitreg_pgcr(); break;
+ case PIT_68230_PSRR: data = rr_pitreg_psrr(); break;
+ case PIT_68230_PADDR: data = rr_pitreg_paddr(); break;
+ case PIT_68230_PBDDR: data = rr_pitreg_pbddr(); break;
+ case PIT_68230_PCDDR: data = rr_pitreg_pcddr(); break;
+ case PIT_68230_PACR: data = rr_pitreg_pacr(); break;
+ case PIT_68230_PBCR: data = rr_pitreg_pbcr(); break;
+ case PIT_68230_PADR: data = rr_pitreg_padr(); break;
+ case PIT_68230_PBDR: data = rr_pitreg_pbdr(); break;
+ case PIT_68230_PAAR: data = rr_pitreg_paar(); break;
+ case PIT_68230_PBAR: data = rr_pitreg_pbar(); break;
+ case PIT_68230_PSR: data = rr_pitreg_psr(); break;
+ case PIT_68230_CNTRH: data = rr_pitreg_cntrh(); break;
+ case PIT_68230_CNTRM: data = rr_pitreg_cntrm(); break;
+ case PIT_68230_CNTRL: data = rr_pitreg_cntrl(); break;
+ default:
+ LOG (("Unhandled read register %02x\n", offset));
+ data = 0;
+ }
+
+#if VERBOSE > 2
+ if (offset != or_ofs || data != or_data || or_cnt >= 1000) {
+ logerror ("\npit68230_device::read: previous identical operation performed %02x times\n", or_cnt);
+ or_cnt = 0;
+ or_data = data;
+ or_ofs = offset;
+ logerror ("pit68230_device::read: offset=%02x data=%02x %lld\n", or_ofs, or_data, machine ().firstcpu->total_cycles ());
+ }
+ else
+ or_cnt++;
+#endif
+
+ return data;
}
diff --git a/src/devices/machine/68230pit.h b/src/devices/machine/68230pit.h
index 2a2f2c6824c..7712419f7fc 100644
--- a/src/devices/machine/68230pit.h
+++ b/src/devices/machine/68230pit.h
@@ -43,14 +43,35 @@
// INTERFACE CONFIGURATION MACROS
//**************************************************************************
-#define MCFG_PIT68230_PA_OUTPUT_CALLBACK(_write) \
- devcb = &pit68230_device::set_pa_wr_callback (*device, DEVCB_ ## _write);
+#define MCFG_PIT68230_PA_INPUT_CB(_devcb) \
+ devcb = &pit68230_device::set_pa_in_callback (*device, DEVCB_##_devcb);
-#define MCFG_PIT68230_PB_OUTPUT_CALLBACK(_write) \
- devcb = &pit68230_device::set_pb_wr_callback (*device, DEVCB_ ## _write);
+#define MCFG_PIT68230_PA_OUTPUT_CB(_devcb) \
+ devcb = &pit68230_device::set_pa_out_callback (*device, DEVCB_##_devcb);
-#define MCFG_PIT68230_H2_CALLBACK(_write) \
- devcb = &pit68230_device::set_h2_wr_callback (*device, DEVCB_ ## _write);
+#define MCFG_PIT68230_PB_INPUT_CB(_devcb) \
+ devcb = &pit68230_device::set_pb_in_callback (*device, DEVCB_##_devcb);
+
+#define MCFG_PIT68230_PB_OUTPUT_CB(_devcb) \
+ devcb = &pit68230_device::set_pb_out_callback (*device, DEVCB_##_devcb);
+
+#define MCFG_PIT68230_PC_INPUT_CB(_devcb) \
+ devcb = &pit68230_device::set_pc_in_callback (*device, DEVCB_##_devcb);
+
+#define MCFG_PIT68230_PC_OUTPUT_CB(_devcb) \
+ devcb = &pit68230_device::set_pc_out_callback (*device, DEVCB_##_devcb);
+
+#define MCFG_PIT68230_H1_CB(_devcb) \
+ devcb = &pit68230_device::set_h1_out_callback (*device, DEVCB_##_devcb);
+
+#define MCFG_PIT68230_H2_CB(_devcb) \
+ devcb = &pit68230_device::set_h2_out_callback (*device, DEVCB_##_devcb);
+
+#define MCFG_PIT68230_H3_CB(_devcb) \
+ devcb = &pit68230_device::set_h3_out_callback (*device, DEVCB_##_devcb);
+
+#define MCFG_PIT68230_H4_CB(_devcb) \
+ devcb = &pit68230_device::set_h4_out_callback (*device, DEVCB_##_devcb);
/*-----------------------------------------------------------------------
* Registers RS1-RS5 R/W Description
@@ -84,46 +105,100 @@
//**************************************************************************
class pit68230_device : public device_t, public device_execute_interface
{
-public:
-// construction/destruction
-pit68230_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, UINT32 variant, const char *shortname, const char *source);
-pit68230_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
-template<class _Object> static devcb_base &set_pa_wr_callback (device_t &device, _Object object)
-{
- return downcast<pit68230_device &>(device).m_write_pa.set_callback (object);
-}
-template<class _Object> static devcb_base &set_h2_wr_callback (device_t &device, _Object object)
-{
- return downcast<pit68230_device &>(device).m_write_h2.set_callback (object);
-}
+ public:
+ // construction/destruction
+ pit68230_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, UINT32 variant, const char *shortname, const char *source);
+ pit68230_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+ template<class _Object> static devcb_base &set_pa_in_callback (device_t &device, _Object object){ return downcast<pit68230_device &>(device).m_pa_in_cb.set_callback (object); }
+ template<class _Object> static devcb_base &set_pa_out_callback (device_t &device, _Object object){ return downcast<pit68230_device &>(device).m_pa_out_cb.set_callback (object); }
+ template<class _Object> static devcb_base &set_pb_in_callback (device_t &device, _Object object){ return downcast<pit68230_device &>(device).m_pb_in_cb.set_callback (object); }
+ template<class _Object> static devcb_base &set_pb_out_callback (device_t &device, _Object object){ return downcast<pit68230_device &>(device).m_pb_out_cb.set_callback (object); }
+ template<class _Object> static devcb_base &set_pc_in_callback (device_t &device, _Object object){ return downcast<pit68230_device &>(device).m_pc_in_cb.set_callback (object); }
+ template<class _Object> static devcb_base &set_pc_out_callback (device_t &device, _Object object){ return downcast<pit68230_device &>(device).m_pc_out_cb.set_callback (object); }
+ template<class _Object> static devcb_base &set_h1_out_callback (device_t &device, _Object object){ return downcast<pit68230_device &>(device).m_h1_out_cb.set_callback (object); }
+ template<class _Object> static devcb_base &set_h2_out_callback (device_t &device, _Object object){ return downcast<pit68230_device &>(device).m_h2_out_cb.set_callback (object); }
+ template<class _Object> static devcb_base &set_h3_out_callback (device_t &device, _Object object){ return downcast<pit68230_device &>(device).m_h3_out_cb.set_callback (object); }
+ template<class _Object> static devcb_base &set_h4_out_callback (device_t &device, _Object object){ return downcast<pit68230_device &>(device).m_h4_out_cb.set_callback (object); }
+
+ DECLARE_WRITE8_MEMBER (write);
+ DECLARE_READ8_MEMBER (read);
-DECLARE_WRITE8_MEMBER (write);
-DECLARE_READ8_MEMBER (read);
+ void h1_set (UINT8 state);
+ void portb_setbit (UINT8 bit, UINT8 state);
-void h1_set (UINT8 state);
-void portb_setbit (UINT8 bit, UINT8 state);
+ void wr_pitreg_pgcr(UINT8 data);
+ void wr_pitreg_psrr(UINT8 data);
+ void wr_pitreg_paddr(UINT8 data);
+ void wr_pitreg_pbddr(UINT8 data);
+ void wr_pitreg_pcddr(UINT8 data);
+ void wr_pitreg_pacr(UINT8 data);
+ void wr_pitreg_pbcr(UINT8 data);
+ void wr_pitreg_padr(UINT8 data);
+ void wr_pitreg_paar(UINT8 data);
+ void wr_pitreg_pbar(UINT8 data);
+ void wr_pitreg_psr(UINT8 data);
+ void wr_pitreg_tcr(UINT8 data);
+ void wr_pitreg_cprh(UINT8 data);
+ void wr_pitreg_cprm(UINT8 data);
+ void wr_pitreg_cprl(UINT8 data);
+
+ UINT8 rr_pitreg_pgcr();
+ UINT8 rr_pitreg_psrr();
+ UINT8 rr_pitreg_paddr();
+ UINT8 rr_pitreg_pbddr();
+ UINT8 rr_pitreg_pcddr();
+ UINT8 rr_pitreg_pacr();
+ UINT8 rr_pitreg_pbcr();
+ UINT8 rr_pitreg_padr();
+ UINT8 rr_pitreg_pbdr();
+ UINT8 rr_pitreg_paar();
+ UINT8 rr_pitreg_pbar();
+ UINT8 rr_pitreg_psr();
+ UINT8 rr_pitreg_cntrh();
+ UINT8 rr_pitreg_cntrm();
+ UINT8 rr_pitreg_cntrl();
protected:
-// device-level overrides
-virtual void device_start () override;
-virtual void device_reset () override;
-virtual void device_timer (emu_timer &timer, device_timer_id id, int param, void *ptr) override;
-virtual void execute_run () override;
-int m_icount;
-devcb_write8 m_write_pa;
-devcb_write_line m_write_h2;
-
-// peripheral ports
-UINT8 m_pgcr; // Port General Control register
-UINT8 m_psrr; // Port Service Request register
-UINT8 m_paddr; // Port A Data Direction register
-UINT8 m_pbddr; // Port B Data Direction register
-UINT8 m_pcddr; // Port C Data Direction register
-UINT8 m_pacr; // Port A Control register
-UINT8 m_pbcr; // Port B Control register
-UINT8 m_padr; // Port A Data register
-UINT8 m_pbdr; // Port B Data register
-UINT8 m_psr; // Port Status Register
+
+ enum {
+ REG_TCR_ENABLE = 0x01
+ };
+
+ // device-level overrides
+ virtual void device_start () override;
+ virtual void device_reset () override;
+ virtual void device_timer (emu_timer &timer, device_timer_id id, int param, void *ptr) override;
+ virtual void execute_run () override;
+ int m_icount;
+
+ devcb_write8 m_pa_out_cb;
+ devcb_read8 m_pa_in_cb;
+ devcb_write8 m_pb_out_cb;
+ devcb_read8 m_pb_in_cb;
+ devcb_write8 m_pc_out_cb;
+ devcb_read8 m_pc_in_cb;
+ devcb_write_line m_h1_out_cb;
+ devcb_write_line m_h2_out_cb;
+ devcb_write_line m_h3_out_cb;
+ devcb_write_line m_h4_out_cb;
+
+ // peripheral ports
+ UINT8 m_pgcr; // Port General Control register
+ UINT8 m_psrr; // Port Service Request register
+ UINT8 m_paddr; // Port A Data Direction register
+ UINT8 m_pbddr; // Port B Data Direction register
+ UINT8 m_pcddr; // Port C Data Direction register
+ UINT8 m_pacr; // Port A Control register
+ UINT8 m_pbcr; // Port B Control register
+ UINT8 m_padr; // Port A Data register
+ UINT8 m_pbdr; // Port B Data register
+ UINT8 m_psr; // Port Status Register
+ UINT8 m_tcr; // Timer Control Register
+ int m_cpr; // Counter Preload Registers (3 x 8 = 24 bits)
+ // UINT8 m_cprh; // Counter Preload Register High
+ // UINT8 m_cprm; // Counter Preload Register Mid
+ // UINT8 m_cprl; // Counter Preload Register Low
+ int m_cntr; // - The 24 bit Counter
};
// device type definition