mirror of
https://github.com/holub/mame
synced 2025-04-25 09:50:04 +03:00
Improved reset, timer and port C behaviour
This commit is contained in:
parent
7d401c1ad9
commit
6845eabdf1
@ -20,7 +20,7 @@
|
||||
* - Complete support for clock and timers
|
||||
* - Add interrupt support
|
||||
* - Add DMA support
|
||||
* - Add double buffering for each submode
|
||||
* - Add apropriate buffering for each submode
|
||||
**********************************************************************/
|
||||
|
||||
#include "68230pit.h"
|
||||
@ -30,6 +30,7 @@
|
||||
#define LOGPRINT(x) { do { if (VERBOSE) logerror x; } while (0); }
|
||||
#define LOG(x) {} LOGPRINT(x)
|
||||
#define LOGR(x) {} LOGPRINT(x)
|
||||
#define LOGDR(x) {} LOGPRINT(x)
|
||||
#define LOGINT(x) {} LOGPRINT(x)
|
||||
#define LOGSETUP(x) {} LOGPRINT(x)
|
||||
#if VERBOSE > 1
|
||||
@ -137,7 +138,7 @@ void pit68230_device::device_start ()
|
||||
m_pb_out_cb.resolve_safe();
|
||||
m_pb_in_cb.resolve_safe(0);
|
||||
m_pc_out_cb.resolve_safe();
|
||||
m_pc_in_cb.resolve_safe(0);
|
||||
m_pc_in_cb.resolve(); // A temporary way to check if handler is installed with isnull(). TODO: Need better fix.
|
||||
m_h1_out_cb.resolve_safe();
|
||||
m_h2_out_cb.resolve_safe();
|
||||
m_h3_out_cb.resolve_safe();
|
||||
@ -179,16 +180,34 @@ void pit68230_device::device_reset ()
|
||||
m_pbddr = 0;
|
||||
m_pcddr = 0;
|
||||
m_pivr = 0x0f;
|
||||
m_pacr = 0; m_h2_out_cb(m_pacr);
|
||||
m_pbcr = 0;
|
||||
m_pacr = 0; m_h2_out_cb(CLEAR_LINE);
|
||||
m_pbcr = 0; m_h4_out_cb(CLEAR_LINE);
|
||||
m_padr = 0; m_pa_out_cb((offs_t)0, m_padr);
|
||||
m_pbdr = 0; m_pb_out_cb((offs_t)0, m_pbdr);
|
||||
m_pcdr = 0; m_pc_out_cb((offs_t)0, m_pcdr);
|
||||
m_psr = 0;
|
||||
m_tcr = 0;
|
||||
m_tivr = 0x0f;
|
||||
m_tsr = 0;
|
||||
}
|
||||
|
||||
void pit68230_device::tick_clock()
|
||||
{
|
||||
if (m_tcr & REG_TCR_TIMER_ENABLE)
|
||||
{
|
||||
if (m_cntr-- == 0) // Zero detect
|
||||
{
|
||||
LOG(("Timer reached zero!\n"));
|
||||
/* TODO: Check mode and use preload value if required or just rollover 24 bit */
|
||||
if ((m_tcr & REG_TCR_ZD) == 0)
|
||||
m_cntr = m_cpr;
|
||||
else // mask off to 24 bit on rollover
|
||||
m_cntr &= 0xffffff;
|
||||
m_tsr = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_timer - handler timer events
|
||||
//-------------------------------------------------
|
||||
@ -197,14 +216,7 @@ void pit68230_device::device_timer (emu_timer &timer, device_timer_id id, int32_
|
||||
switch(id)
|
||||
{
|
||||
case TIMER_ID_PIT:
|
||||
if (m_cntr-- == 0) // Zero detect
|
||||
{
|
||||
/* TODO: Check mode and use preload value if required or just rollover 24 bit */
|
||||
if ((m_tcr & REG_TCR_ZD) == 0)
|
||||
m_cntr = m_cpr;
|
||||
else // mask off to 24 bit on rollover
|
||||
m_cntr &= 0xffffff;
|
||||
}
|
||||
tick_clock();
|
||||
break;
|
||||
default:
|
||||
LOGINT(("Unhandled Timer ID %d\n", id));
|
||||
@ -214,16 +226,32 @@ void pit68230_device::device_timer (emu_timer &timer, device_timer_id id, int32_
|
||||
|
||||
void pit68230_device::h1_set (uint8_t state)
|
||||
{
|
||||
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_t bit, uint8_t state)
|
||||
void pit68230_device::portb_setbit(uint8_t bit, uint8_t state)
|
||||
{
|
||||
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 ()));
|
||||
}
|
||||
|
||||
// Bit updaters will make it possible to move registers to private data
|
||||
// TODO: Make sure to only update input bits and that the port is in the right alternate mode
|
||||
void pit68230_device::pa_update_bit(uint8_t bit, uint8_t state){ if (state) m_padr |= (1 << bit); else m_padr &= ~(1 << bit); }
|
||||
void pit68230_device::pb_update_bit(uint8_t bit, uint8_t state){ if (state) m_pbdr |= (1 << bit); else m_pbdr &= ~(1 << bit); }
|
||||
void pit68230_device::pc_update_bit(uint8_t bit, uint8_t state){ if (state) m_pcdr |= (1 << bit); else m_pcdr &= ~(1 << bit); }
|
||||
|
||||
void pit68230_device::update_tin()
|
||||
{
|
||||
static uint32_t counter = 0;
|
||||
|
||||
// Tick clock on falling edge. TODO: check what flank is correct
|
||||
if (((counter & 1) != 0))
|
||||
{
|
||||
tick_clock();
|
||||
}
|
||||
|
||||
pc_update_bit(REG_PCDR_TIN_BIT, counter & 1);
|
||||
counter++;
|
||||
}
|
||||
|
||||
#if VERBOSE > 2
|
||||
@ -298,20 +326,79 @@ void pit68230_device::wr_pitreg_pacr(uint8_t data)
|
||||
* 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
|
||||
if (m_pgcr & REG_PGCR_H12_ENABLE)
|
||||
{
|
||||
if (m_pacr & REG_PACR_H2_CTRL_IN_OUT)
|
||||
{
|
||||
switch(m_pacr & REG_PACR_H2_CTRL_MASK)
|
||||
{
|
||||
case REG_PACR_H2_CTRL_OUT_00:
|
||||
LOG((" - H2 cleared\n"));
|
||||
m_h2_out_cb(CLEAR_LINE);
|
||||
break;
|
||||
case REG_PACR_H2_CTRL_OUT_01:
|
||||
LOG((" - H2 asserted\n"));
|
||||
m_h2_out_cb(ASSERT_LINE);
|
||||
break;
|
||||
case REG_PACR_H2_CTRL_OUT_10:
|
||||
LOGSETUP((" - interlocked handshake not implemented\n"));
|
||||
break;
|
||||
case REG_PACR_H2_CTRL_OUT_11:
|
||||
LOGSETUP((" - pulsed handshake not implemented\n"));
|
||||
break;
|
||||
default: logerror(("Undefined H2 mode, broken driver - please report!\n"));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG((" - H2 cleared because beeing disabled in PGCR\n"));
|
||||
m_h2_out_cb(CLEAR_LINE);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO add support for sense status
|
||||
void pit68230_device::wr_pitreg_pbcr(uint8_t data)
|
||||
{
|
||||
LOG(("%s(%02x) \"%s\": %s - %02x\n", FUNCNAME, data, tag(), FUNCNAME, data));
|
||||
m_pbcr = data;
|
||||
if ((m_pgcr & REG_PGCR_H34_ENABLE) || ((m_pbcr & REG_PBCR_SUBMODE_MASK) == REG_PBCR_SUBMODE_1X))
|
||||
{
|
||||
if (m_pbcr & REG_PBCR_H4_CTRL_IN_OUT)
|
||||
{
|
||||
switch(m_pbcr & REG_PBCR_H4_CTRL_MASK)
|
||||
{
|
||||
case REG_PBCR_H4_CTRL_OUT_00:
|
||||
LOG((" - H4 cleared\n"));
|
||||
m_h4_out_cb(CLEAR_LINE);
|
||||
break;
|
||||
case REG_PBCR_H4_CTRL_OUT_01:
|
||||
LOG((" - H4 asserted\n"));
|
||||
m_h4_out_cb(ASSERT_LINE);
|
||||
break;
|
||||
case REG_PBCR_H4_CTRL_OUT_10:
|
||||
LOGSETUP((" - interlocked handshake not implemented\n"));
|
||||
break;
|
||||
case REG_PBCR_H4_CTRL_OUT_11:
|
||||
LOGSETUP((" - pulsed handshake not implemented\n"));
|
||||
break;
|
||||
default: logerror(("Undefined H4 mode, broken driver - please report!\n"));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG((" - H4 cleared because beeing disabled in PGCR\n"));
|
||||
m_h4_out_cb(CLEAR_LINE);
|
||||
}
|
||||
}
|
||||
|
||||
void pit68230_device::wr_pitreg_padr(uint8_t data)
|
||||
{
|
||||
LOG(("%s(%02x) \"%s\": %s - %02x\n", FUNCNAME, data, tag(), FUNCNAME, data));
|
||||
m_padr |= (data & m_paddr);
|
||||
// callbacks
|
||||
|
||||
// callback
|
||||
m_pa_out_cb ((offs_t)0, m_padr);
|
||||
}
|
||||
|
||||
@ -319,7 +406,8 @@ void pit68230_device::wr_pitreg_pbdr(uint8_t data)
|
||||
{
|
||||
LOG(("%s(%02x) \"%s\": %s - %02x\n", FUNCNAME, data, tag(), FUNCNAME, data));
|
||||
m_pbdr |= (data & m_pbddr);
|
||||
// callbacks
|
||||
|
||||
// callback
|
||||
m_pb_out_cb ((offs_t)0, m_pbdr & m_pbddr);
|
||||
}
|
||||
|
||||
@ -327,7 +415,8 @@ void pit68230_device::wr_pitreg_pcdr(uint8_t data)
|
||||
{
|
||||
LOG(("%s(%02x) \"%s\": %s - %02x\n", FUNCNAME, data, tag(), FUNCNAME, data));
|
||||
m_pcdr |= (data & m_pcddr);
|
||||
// callbacks
|
||||
|
||||
// callback
|
||||
m_pc_out_cb ((offs_t)0, m_pcdr);
|
||||
}
|
||||
|
||||
@ -482,7 +571,7 @@ void pit68230_device::wr_pitreg_cprl(uint8_t data)
|
||||
void pit68230_device::wr_pitreg_tsr(uint8_t data)
|
||||
{
|
||||
LOG(("%s(%02x) \"%s\": \n", FUNCNAME, data, tag()));
|
||||
m_tsr = data;
|
||||
if (data & 1) m_tsr = 0; // A write resets the TSR;
|
||||
}
|
||||
|
||||
WRITE8_MEMBER (pit68230_device::write)
|
||||
@ -592,7 +681,7 @@ uint8_t pit68230_device::rr_pitreg_padr()
|
||||
{
|
||||
m_padr &= m_paddr;
|
||||
m_padr |= (m_pa_in_cb() & ~m_paddr);
|
||||
LOGR(("%s %s <- %02x\n",tag(), FUNCNAME, m_padr));
|
||||
LOGDR(("%s %s <- %02x\n",tag(), FUNCNAME, m_padr));
|
||||
return m_padr;
|
||||
}
|
||||
|
||||
@ -607,15 +696,19 @@ uint8_t pit68230_device::rr_pitreg_pbdr()
|
||||
{
|
||||
m_pbdr &= m_pbddr;
|
||||
m_pbdr |= (m_pb_in_cb() & ~m_pbddr);
|
||||
LOGR(("%s %s <- %02x\n",tag(), FUNCNAME, m_pbdr));
|
||||
|
||||
LOGDR(("%s %s <- %02x\n",tag(), FUNCNAME, m_pbdr));
|
||||
return m_pbdr;
|
||||
}
|
||||
|
||||
uint8_t pit68230_device::rr_pitreg_pcdr()
|
||||
{
|
||||
m_pcdr &= m_pcddr;
|
||||
m_pcdr |= (m_pc_in_cb() & ~m_pcddr);
|
||||
LOGR(("%s %s <- %02x\n",tag(), FUNCNAME, m_pcdr));
|
||||
if (!m_pc_in_cb.isnull()) // Port C has alternate functions that may set bits apart from callback
|
||||
{
|
||||
m_pcdr &= m_pcddr;
|
||||
m_pcdr |= (m_pc_in_cb() & ~m_pcddr);
|
||||
}
|
||||
if (m_pcdr != 0) { LOGDR(("%s %s <- %02x\n",tag(), FUNCNAME, m_pcdr)); }
|
||||
return m_pcdr;
|
||||
}
|
||||
|
||||
@ -739,7 +832,7 @@ READ8_MEMBER (pit68230_device::read){
|
||||
case PIT_68230_CNTRL: data = rr_pitreg_cntrl(); break;
|
||||
case PIT_68230_TSR: data = rr_pitreg_tsr(); break;
|
||||
default:
|
||||
LOG (("Unhandled read register %02x\n", offset));
|
||||
LOG (("Unhandled read register %02x returning 0x00\n", offset));
|
||||
data = 0;
|
||||
}
|
||||
|
||||
|
@ -125,6 +125,13 @@ class pit68230_device : public device_t//, public device_execute_interface
|
||||
|
||||
void h1_set (uint8_t state);
|
||||
void portb_setbit (uint8_t bit, uint8_t state);
|
||||
void tick_clock();
|
||||
|
||||
// Bit updaters
|
||||
void pa_update_bit(uint8_t bit, uint8_t state);
|
||||
void pb_update_bit(uint8_t bit, uint8_t state);
|
||||
void pc_update_bit(uint8_t bit, uint8_t state);
|
||||
void update_tin();
|
||||
|
||||
void wr_pitreg_pgcr(uint8_t data);
|
||||
void wr_pitreg_psrr(uint8_t data);
|
||||
@ -173,7 +180,65 @@ class pit68230_device : public device_t//, public device_execute_interface
|
||||
|
||||
protected:
|
||||
|
||||
enum { // PGCR - Port Global Control register
|
||||
REG_PGCR_MODE_MASK = 0xc0,
|
||||
REG_PGCR_MODE_0 = 0x00, // 0 0 Unidirectional 8 bit mode
|
||||
REG_PGCR_MODE_1 = 0x40, // 0 1 Unidirectional 16 bit mode
|
||||
REG_PGCR_MODE_2 = 0x80, // 1 0 Bidirectional 8 bit mode
|
||||
REG_PGCR_MODE_3 = 0xc0, // 1 1 Bidirectional 16 bit mode
|
||||
REG_PGCR_H34_ENABLE = 0x20,
|
||||
REG_PGCR_H12_ENABLE = 0x10,
|
||||
REG_PGCR_H4_SENSE = 0x80,
|
||||
REG_PGCR_H3_SENSE = 0x40,
|
||||
REG_PGCR_H2_SENSE = 0x20,
|
||||
REG_PGCR_H1_SENSE = 0x10,
|
||||
};
|
||||
|
||||
enum {
|
||||
REG_PACR_SUBMODE_MASK = 0xc0,
|
||||
REG_PACR_SUBMODE_0 = 0x00, // 0 0
|
||||
REG_PACR_SUBMODE_1 = 0x40, // 0 1
|
||||
REG_PACR_SUBMODE_2 = 0x80, // 1 0
|
||||
REG_PACR_SUBMODE_3 = 0xc0, // 1 1
|
||||
REG_PACR_H2_CTRL_MASK = 0x38,
|
||||
REG_PACR_H2_CTRL_IN_OUT = 0x20, // H2 sense always cleared if set
|
||||
REG_PACR_H2_CTRL_OUT_00 = 0x20, // H2 output negated
|
||||
REG_PACR_H2_CTRL_OUT_01 = 0x28, // H2 output asserted
|
||||
REG_PACR_H2_CTRL_OUT_10 = 0x30, // H2 output in interlocked input handshake protocol
|
||||
REG_PACR_H2_CTRL_OUT_11 = 0x38, // H2 output in pulsed input handshake protocol
|
||||
REG_PACR_H2_INT_ENABLE = 0x04,
|
||||
REG_PACR_H1_SVCR_ENABLE = 0x02,
|
||||
REG_PACR_H1_STATUS_CTRL = 0x01,
|
||||
};
|
||||
|
||||
enum {
|
||||
REG_PBCR_SUBMODE_MASK = 0xc0,
|
||||
REG_PBCR_SUBMODE_00 = 0x00, // 0 0
|
||||
REG_PBCR_SUBMODE_01 = 0x40, // 0 1
|
||||
REG_PBCR_SUBMODE_10 = 0x80, // 1 0
|
||||
REG_PBCR_SUBMODE_11 = 0xc0, // 1 1
|
||||
REG_PBCR_SUBMODE_1X = 0x80, // submode 2 or 3
|
||||
REG_PBCR_H4_CTRL_MASK = 0x38,
|
||||
REG_PBCR_H4_CTRL_IN_OUT = 0x20, // H4 sense always cleared if set
|
||||
REG_PBCR_H4_CTRL_OUT_00 = 0x20, // H4 output negated
|
||||
REG_PBCR_H4_CTRL_OUT_01 = 0x28, // H4 output asserted
|
||||
REG_PBCR_H4_CTRL_OUT_10 = 0x30, // H4 output in interlocked input handshake protocol
|
||||
REG_PBCR_H4_CTRL_OUT_11 = 0x38, // H4 output in pulsed input handshake protocol
|
||||
REG_PBCR_H4_INT_ENABLE = 0x04,
|
||||
REG_PBCR_H3_SVCRQ_ENABLE= 0x02,
|
||||
REG_PBCR_H3_STATUS_CTRL = 0x01,
|
||||
};
|
||||
|
||||
enum {
|
||||
REG_PCDR_TIN_BIT = 2, // BIT number
|
||||
REG_PCDR_TIN = 0x04 // bit position
|
||||
};
|
||||
|
||||
enum {
|
||||
REG_TCR_TIMER_ENABLE = 0x01
|
||||
};
|
||||
|
||||
enum { // TCR - Timer Control register
|
||||
REG_TCR_ENABLE = 0x01,
|
||||
REG_TCR_CC_MASK = 0x06,
|
||||
REG_TCR_CC_PC2_CLK_PSC = 0x00,
|
||||
|
Loading…
Reference in New Issue
Block a user