completed the parallell port part now supporting all ports A,B and C, still WIP

This commit is contained in:
Joakim Larsson Edstrom 2016-06-10 10:31:32 +02:00
parent f812a76116
commit deb715cca6
2 changed files with 585 additions and 221 deletions

View File

@ -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;
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;
}

View File

@ -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