From deb715cca6f43cbb91a00b07705b708b5b691ec3 Mon Sep 17 00:00:00 2001 From: Joakim Larsson Edstrom Date: Fri, 10 Jun 2016 10:31:32 +0200 Subject: [PATCH] completed the parallell port part now supporting all ports A,B and C, still WIP --- src/devices/machine/68230pit.cpp | 649 ++++++++++++++++++++++--------- src/devices/machine/68230pit.h | 157 ++++++-- 2 files changed, 585 insertions(+), 221 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 - 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; + LOG(("%s\n", FUNCNAME)); + m_icountptr = &m_icount; - // resolve callbacks - m_write_pa.resolve_safe (); - m_write_h2.resolve_safe (); + // 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) +#if VERBOSE > 2 +static INT32 ow_cnt = 0; +static INT32 ow_data = 0; +static INT32 ow_ofs = 0; +#endif -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++; ) +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; } -LOG (static INT32 or_cnt = 0) -LOG (static INT32 or_data = 0) -LOG (static INT32 or_ofs = 0) +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; + UINT8 data; - switch (offset) { - case PIT_68230_PGCR: - data = m_pgcr; - break; + 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; + } - case PIT_68230_PSRR: - data = m_psrr; - break; +#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 - 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; + 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 static devcb_base &set_pa_wr_callback (device_t &device, _Object object) -{ - return downcast(device).m_write_pa.set_callback (object); -} -template static devcb_base &set_h2_wr_callback (device_t &device, _Object object) -{ - return downcast(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 static devcb_base &set_pa_in_callback (device_t &device, _Object object){ return downcast(device).m_pa_in_cb.set_callback (object); } + template static devcb_base &set_pa_out_callback (device_t &device, _Object object){ return downcast(device).m_pa_out_cb.set_callback (object); } + template static devcb_base &set_pb_in_callback (device_t &device, _Object object){ return downcast(device).m_pb_in_cb.set_callback (object); } + template static devcb_base &set_pb_out_callback (device_t &device, _Object object){ return downcast(device).m_pb_out_cb.set_callback (object); } + template static devcb_base &set_pc_in_callback (device_t &device, _Object object){ return downcast(device).m_pc_in_cb.set_callback (object); } + template static devcb_base &set_pc_out_callback (device_t &device, _Object object){ return downcast(device).m_pc_out_cb.set_callback (object); } + template static devcb_base &set_h1_out_callback (device_t &device, _Object object){ return downcast(device).m_h1_out_cb.set_callback (object); } + template static devcb_base &set_h2_out_callback (device_t &device, _Object object){ return downcast(device).m_h2_out_cb.set_callback (object); } + template static devcb_base &set_h3_out_callback (device_t &device, _Object object){ return downcast(device).m_h3_out_cb.set_callback (object); } + template static devcb_base &set_h4_out_callback (device_t &device, _Object object){ return downcast(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