Example #1
0
UINT8 pia6821_device::reg_r(UINT8 offset)
{
	UINT8 ret;

	switch (offset & 0x03)
	{
		default: // impossible
		case 0x00:
			if (OUTPUT_SELECTED(m_ctl_a))
			{
				ret = port_a_r();
			}
			else
			{
				ret = ddr_a_r();
			}
			break;

		case 0x01:
			ret = control_a_r();
			break;

		case 0x02:
			if (OUTPUT_SELECTED(m_ctl_b))
			{
				ret = port_b_r();
			}
			else
			{
				ret = ddr_b_r();
			}
			break;

		case 0x03:
			ret = control_b_r();
			break;
	}

	return ret;
}
Example #2
0
void pia6821_device::reg_w(UINT8 offset, UINT8 data)
{
	switch (offset & 0x03)
	{
		default: // impossible
		case 0x00:
			if (OUTPUT_SELECTED(m_ctl_a))
			{
				port_a_w(data);
			}
			else
			{
				ddr_a_w(data);
			}
			break;

		case 0x01:
			control_a_w( data);
			break;

		case 0x02:
			if(OUTPUT_SELECTED(m_ctl_b))
			{
				port_b_w(data);
			}
			else
			{
				ddr_b_w(data);
			}
			break;

		case 0x03:
			control_b_w(data);
			break;
	}
}
Example #3
0
void pia_write (int which, int offset, int data)
{
	struct pia6821 *p = pia + which;

	switch (pia_offsets[offset & 7])
	{
		/******************* port A output/DDR write *******************/
		case 0:

			/* write output register */
			if (OUTPUT_SELECTED (p->ctl_a))
			{
				/* update the output value */
				p->out_a = data & p->ddr_a;

				/* send it to the output function */
				if (p->out_a_func) p->out_a_func (0, p->out_a);
			}

			/* write DDR register */
			else
				p->ddr_a = data;
			break;

		/******************* port B output/DDR write *******************/
		case 1:

			/* write output register */
			if (OUTPUT_SELECTED (p->ctl_b))
			{
				/* update the output value */
				p->out_b = data & p->ddr_b;

				/* send it to the output function */
				if (p->out_b_func) p->out_b_func (0, p->out_b);

				/* CB2 is configured as output and in write strobe mode */
				if (C2_OUTPUT (p->ctl_b) && C2_STROBE_MODE (p->ctl_b))
				{
					/* this will cause a transition low; call the output function if we're currently high */
					if (p->out_cb2)
						if (p->out_cb2_func) p->out_cb2_func (0, 0);
					p->out_cb2 = 0;

					/* if the CB2 strobe is cleared by the E, reset it right away */
					if (STROBE_E_RESET (p->ctl_b))
					{
						if (p->out_cb2_func) p->out_cb2_func (0, 1);
						p->out_cb2 = 1;
					}
				}
			}

			/* write DDR register */
			else
				p->ddr_b = data;
			break;

		/******************* port A control write *******************/
		case 2:

			/* CA2 is configured as output and in set/reset mode */
			/* 10/22/98 - MAB/FMP - any C2_OUTPUT should affect CA2 */
			if (C2_OUTPUT (data))
			{
				/* determine the new value */
				int temp = SET_C2 (data) ? 1 : 0;

				/* if this creates a transition, call the CA2 output function */
				if (p->out_ca2 ^ temp)
					if (p->out_ca2_func) p->out_ca2_func (0, temp);

				/* set the new value */
				p->out_ca2 = temp;
			}

			/* update the control register */
			p->ctl_a = data;
			break;

		/******************* port B control write *******************/
		case 3:

			/* CB2 is configured as output and in set/reset mode */
			/* 10/22/98 - MAB/FMP - any C2_OUTPUT should affect CB2 */
			if (C2_OUTPUT (data))
			{
				/* determine the new value */
				int temp = SET_C2 (data) ? 1 : 0;

				/* if this creates a transition, call the CA2 output function */
				if (p->out_cb2 ^ temp)
					if (p->out_cb2_func) p->out_cb2_func (0, temp);

				/* set the new value */
				p->out_cb2 = temp;
			}

			/* update the control register */
			p->ctl_b = data;
			break;
	}
}
Example #4
0
int pia_read (int which, int offset)
{
	struct pia6821 *p = pia + which;
	int val = 0;

	switch (pia_offsets[offset & 7])
	{
		/******************* port A output/DDR read *******************/
		case 0:

			/* read output register */
			if (OUTPUT_SELECTED (p->ctl_a))
			{
				/* update the input */
				if (p->in_a_func) p->in_a = p->in_a_func (0);

				/* combine input and output values */
				val = (p->out_a & p->ddr_a) + (p->in_a & ~p->ddr_a);

				/* IRQ flags implicitly cleared by a read */
				p->irq_a1 = p->irq_a2 = 0;

				/* CA2 is configured as output and in read strobe mode */
				if (C2_OUTPUT (p->ctl_a) && C2_STROBE_MODE (p->ctl_a))
				{
					/* this will cause a transition low; call the output function if we're currently high */
					if (p->out_ca2)
						if (p->out_ca2_func) p->out_ca2_func (0, 0);
					p->out_ca2 = 0;

					/* if the CA2 strobe is cleared by the E, reset it right away */
					if (STROBE_E_RESET (p->ctl_a))
					{
						if (p->out_ca2_func) p->out_ca2_func (0, 1);
						p->out_ca2 = 1;
					}
				}
			}

			/* read DDR register */
			else
				val = p->ddr_a;
			break;

		/******************* port B output/DDR read *******************/
		case 1:

			/* read output register */
			if (OUTPUT_SELECTED (p->ctl_b))
			{
				/* update the input */
				if (p->in_b_func) p->in_b = p->in_b_func (0);

				/* combine input and output values */
				val = (p->out_b & p->ddr_b) + (p->in_b & ~p->ddr_b);

				/* IRQ flags implicitly cleared by a read */
				p->irq_b1 = p->irq_b2 = 0;
			}

			/* read DDR register */
			else
				val = p->ddr_b;
			break;

		/******************* port A control read *******************/
		case 2:

			/* Update CA1 & CA2 if callback exists, these in turn may update IRQ's */
			if (p->in_ca1_func) pia_set_input_ca1(which, p->in_ca1_func (0));
			if (p->in_ca2_func) pia_set_input_ca2(which, p->in_ca2_func (0));

			/* read control register */
			val = p->ctl_a;

			/* set the IRQ flags if we have pending IRQs */
			if (p->irq_a1) val |= PIA_IRQ1;
			if (p->irq_a2 && C2_INPUT (p->ctl_a)) val |= PIA_IRQ2;
			break;

		/******************* port B control read *******************/
		case 3:

			/* Update CB1 & CB2 if callback exists, these in turn may update IRQ's */
			if (p->in_cb1_func) pia_set_input_cb1(which, p->in_cb1_func (0));
			if (p->in_cb2_func) pia_set_input_cb2(which, p->in_cb2_func (0));

			/* read control register */
			val = p->ctl_b;

			/* set the IRQ flags if we have pending IRQs */
			if (p->irq_b1) val |= PIA_IRQ1;
			if (p->irq_b2 && C2_INPUT (p->ctl_b)) val |= PIA_IRQ2;
			break;
	}

	return val;
}
Example #5
0
void pia_write(int which, int offset, int data)
{
	struct pia6821 *p = pia + which;

	/* adjust offset for 16-bit and ordering */
	offset &= 3;
	if (p->addr & PIA_ALTERNATE_ORDERING) offset = swizzle_address[offset];

	switch (offset)
	{
		/******************* port A output/DDR write *******************/
		case PIA_DDRA:

			/* write output register */
			if (OUTPUT_SELECTED(p->ctl_a))
			{
				LOG(("%04x: PIA%d port A write = %02X\n", activecpu_get_previouspc(), which, data));

				/* update the output value */
				p->out_a = data;/* & p->ddr_a; */	/* NS990130 - don't mask now, DDR could change later */

				/* send it to the output function */
				if (p->intf->out_a_func && p->ddr_a) p->intf->out_a_func(0, p->out_a & p->ddr_a);	/* NS990130 */
			}

			/* write DDR register */
			else
			{
				LOG(("%04x: PIA%d DDR A write = %02X\n", activecpu_get_previouspc(), which, data));

				if (p->ddr_a != data)
				{
					/* NS990130 - if DDR changed, call the callback again */
					p->ddr_a = data;

					/* send it to the output function */
					if (p->intf->out_a_func && p->ddr_a) p->intf->out_a_func(0, p->out_a & p->ddr_a);
				}
			}
			break;

		/******************* port B output/DDR write *******************/
		case PIA_DDRB:

			/* write output register */
			if (OUTPUT_SELECTED(p->ctl_b))
			{
				LOG(("%04x: PIA%d port B write = %02X\n", activecpu_get_previouspc(), which, data));

				/* update the output value */
				p->out_b = data;/* & p->ddr_b */	/* NS990130 - don't mask now, DDR could change later */

				/* send it to the output function */
				if (p->intf->out_b_func && p->ddr_b) p->intf->out_b_func(0, p->out_b & p->ddr_b);	/* NS990130 */

				/* CB2 is configured as output and in write strobe mode */
				if (C2_OUTPUT(p->ctl_b) && C2_STROBE_MODE(p->ctl_b))
				{
					/* this will cause a transition low; call the output function if we're currently high */
					if (p->out_cb2)
						if (p->intf->out_cb2_func) p->intf->out_cb2_func(0, 0);
					p->out_cb2 = 0;

					/* if the CB2 strobe is cleared by the E, reset it right away */
					if (STROBE_E_RESET(p->ctl_b))
					{
						if (p->intf->out_cb2_func) p->intf->out_cb2_func(0, 1);
						p->out_cb2 = 1;
					}
				}
			}

			/* write DDR register */
			else
			{
				LOG(("%04x: PIA%d DDR B write = %02X\n", activecpu_get_previouspc(), which, data));

				if (p->ddr_b != data)
				{
					/* NS990130 - if DDR changed, call the callback again */
					p->ddr_b = data;

					/* send it to the output function */
					if (p->intf->out_b_func && p->ddr_b) p->intf->out_b_func(0, p->out_b & p->ddr_b);
				}
			}
			break;

		/******************* port A control write *******************/
		case PIA_CTLA:

			/* Bit 7 and 6 read only - PD 16/01/00 */

			data &= 0x3f;


			LOG(("%04x: PIA%d control A write = %02X\n", activecpu_get_previouspc(), which, data));

			/* CA2 is configured as output and in set/reset mode */
			/* 10/22/98 - MAB/FMP - any C2_OUTPUT should affect CA2 */
//			if (C2_OUTPUT(data) && C2_SET_MODE(data))
			if (C2_OUTPUT(data))
			{
				/* determine the new value */
				int temp = SET_C2(data) ? 1 : 0;

				/* if this creates a transition, call the CA2 output function */
				if (p->out_ca2 ^ temp)
					if (p->intf->out_ca2_func) p->intf->out_ca2_func(0, temp);

				/* set the new value */
				p->out_ca2 = temp;
			}

			/* update the control register */
			p->ctl_a = data;

			/* update externals */
			update_6821_interrupts(p);
			break;

		/******************* port B control write *******************/
		case PIA_CTLB:

			/* Bit 7 and 6 read only - PD 16/01/00 */

			data &= 0x3f;

			LOG(("%04x: PIA%d control B write = %02X\n", activecpu_get_previouspc(), which, data));

			/* CB2 is configured as output and in set/reset mode */
			/* 10/22/98 - MAB/FMP - any C2_OUTPUT should affect CB2 */
//			if (C2_OUTPUT(data) && C2_SET_MODE(data))
			if (C2_OUTPUT(data))
			{
				/* determine the new value */
				int temp = SET_C2(data) ? 1 : 0;

				/* if this creates a transition, call the CA2 output function */
				if (p->out_cb2 ^ temp)
					if (p->intf->out_cb2_func) p->intf->out_cb2_func(0, temp);

				/* set the new value */
				p->out_cb2 = temp;
			}

			/* update the control register */
			p->ctl_b = data;

			/* update externals */
			update_6821_interrupts(p);
			break;
	}
}
Example #6
0
int pia_read(int which, int offset)
{
	struct pia6821 *p = pia + which;
	int val = 0;

	/* adjust offset for 16-bit and ordering */
	offset &= 3;
	if (p->addr & PIA_ALTERNATE_ORDERING) offset = swizzle_address[offset];

	switch (offset)
	{
		/******************* port A output/DDR read *******************/
		case PIA_DDRA:

			/* read output register */
			if (OUTPUT_SELECTED(p->ctl_a))
			{
				/* update the input */
				if ((FPTR)(p->intf->in_a_func) > 0x100)
					p->in_a = p->intf->in_a_func(0);
#ifdef MAME_DEBUG
				else if ((p->ddr_a ^ 0xff) && !(p->in_set & PIA_IN_SET_A)) {
					logerror("PIA%d: Warning! no port A read handler. Assuming pins %02x not connected\n",
					         which, p->ddr_a ^ 0xff);
					p->in_set |= PIA_IN_SET_A; // disable logging
				}
#endif // MAME_DEBUG

				/* combine input and output values */
				val = (p->out_a & p->ddr_a) + (p->in_a & ~p->ddr_a);

				/* IRQ flags implicitly cleared by a read */
				p->irq_a1 = p->irq_a2 = 0;
				update_6821_interrupts(p);

				/* CA2 is configured as output and in read strobe mode */
				if (C2_OUTPUT(p->ctl_a) && C2_STROBE_MODE(p->ctl_a))
				{
					/* this will cause a transition low; call the output function if we're currently high */
					if (p->out_ca2)
						if (p->intf->out_ca2_func) p->intf->out_ca2_func(0, 0);
					p->out_ca2 = 0;

					/* if the CA2 strobe is cleared by the E, reset it right away */
					if (STROBE_E_RESET(p->ctl_a))
					{
						if (p->intf->out_ca2_func) p->intf->out_ca2_func(0, 1);
						p->out_ca2 = 1;
					}
				}

				LOG(("%04x: PIA%d read port A = %02X\n", activecpu_get_previouspc(),  which, val));
			}

			/* read DDR register */
			else
			{
				val = p->ddr_a;
				LOG(("%04x: PIA%d read DDR A = %02X\n", activecpu_get_previouspc(), which, val));
			}
			break;

		/******************* port B output/DDR read *******************/
		case PIA_DDRB:

			/* read output register */
			if (OUTPUT_SELECTED(p->ctl_b))
			{
				/* update the input */
				if ((FPTR)(p->intf->in_b_func) > 0x100)
					p->in_b = p->intf->in_b_func(0);
#ifdef MAME_DEBUG
				else if ((p->ddr_b ^ 0xff) && !(p->in_set & PIA_IN_SET_B)) {
					logerror("PIA%d: Error! no port B read handler. Three-state pins %02x are undefined\n",
					         which, p->ddr_b ^ 0xff);
					p->in_set |= PIA_IN_SET_B; // disable logging
				}
#endif // MAME_DEBUG

				/* combine input and output values */
				val = (p->out_b & p->ddr_b) + (p->in_b & ~p->ddr_b);

				/* IRQ flags implicitly cleared by a read */
				p->irq_b1 = p->irq_b2 = 0;
				update_6821_interrupts(p);

				LOG(("%04x: PIA%d read port B = %02X\n", activecpu_get_previouspc(), which, val));
			}

			/* read DDR register */
			else
			{
				val = p->ddr_b;
				LOG(("%04x: PIA%d read DDR B = %02X\n", activecpu_get_previouspc(), which, val));
			}
			break;

		/******************* port A control read *******************/
		case PIA_CTLA:

			/* Update CA1 & CA2 if callback exists, these in turn may update IRQ's */
			if ((FPTR)(p->intf->in_ca1_func) > 0x100)
				pia_set_input_ca1(which, p->intf->in_ca1_func(0));
#ifdef MAME_DEBUG
			else if (!(p->in_set & PIA_IN_SET_CA1)) {
				logerror("PIA%d: Warning! no CA1 read handler. Assuming pin not connected\n",which);
				p->in_set |= PIA_IN_SET_CA1; // disable logging
			}
#endif // MAME_DEBUG
			if ((FPTR)(p->intf->in_ca2_func) > 0x100)
				pia_set_input_ca2(which, p->intf->in_ca2_func(0));
#ifdef MAME_DEBUG
			else if (C2_INPUT(p->ctl_a) && !(p->in_set & PIA_IN_SET_CA2)) {
				logerror("PIA%d: Warning! no CA2 read handler. Assuming pin not connected\n",which);
				p->in_set |= PIA_IN_SET_CA2; // disable logging
			}
#endif // MAME_DEBUG

			/* read control register */
			val = p->ctl_a;

			/* set the IRQ flags if we have pending IRQs */
			if (p->irq_a1) val |= PIA_IRQ1;
			if (p->irq_a2 && C2_INPUT(p->ctl_a)) val |= PIA_IRQ2;

			LOG(("%04x: PIA%d read control A = %02X\n", activecpu_get_previouspc(), which, val));
			break;

		/******************* port B control read *******************/
		case PIA_CTLB:

			/* Update CB1 & CB2 if callback exists, these in turn may update IRQ's */
			if ((FPTR)(p->intf->in_cb1_func) > 0x100)
				pia_set_input_cb1(which, p->intf->in_cb1_func(0));
#ifdef MAME_DEBUG
			else if (!(p->in_set & PIA_IN_SET_CB1)) {
				logerror("PIA%d: Error! no CB1 read handler. Three-state pin is undefined\n",which);
				p->in_set |= PIA_IN_SET_CB1; // disable logging
			}
#endif // MAME_DEBUG
			if ((FPTR)(p->intf->in_cb2_func) > 0x100)
				pia_set_input_cb2(which, p->intf->in_cb2_func(0));
#ifdef MAME_DEBUG
			else if (C2_INPUT(p->ctl_b) && !(p->in_set & PIA_IN_SET_CB2)) {
				logerror("PIA%d: Error! no CB2 read handler. Three-state pin is undefined\n",which);
				p->in_set |= PIA_IN_SET_CB2; // disable logging
			}
#endif // MAME_DEBUG

			/* read control register */
			val = p->ctl_b;

			/* set the IRQ flags if we have pending IRQs */
			if (p->irq_b1) val |= PIA_IRQ1;
			if (p->irq_b2 && C2_INPUT(p->ctl_b)) val |= PIA_IRQ2;

			LOG(("%04x: PIA%d read control B = %02X\n", activecpu_get_previouspc(), which, val));
			break;
	}

	return val;
}
Example #7
0
void C6821::Write(BYTE byRS, BYTE byData)
{
  byRS &= 3;

  switch( byRS )
  {
    /******************* port A output/DDR write *******************/
  case PIA_DDRA:

    // write output register
    if ( OUTPUT_SELECTED( m_byCTLA ) )
    {
      // update the output value
      m_byOA = byData;

      // send it to the output function
      if ( m_byDDRA )
        PIA_W_CALLBACK( m_stOutA, m_byOA & m_byDDRA );
    }

    // write DDR register
    else
    {
      if ( m_byDDRA != byData )
      {
        m_byDDRA = byData;

        // send it to the output function
        if ( m_byDDRA )
          PIA_W_CALLBACK( m_stOutA, m_byOA & m_byDDRA );
      }
    }
    break;

    /******************* port B output/DDR write *******************/
  case PIA_DDRB:

    // write output register
    if ( OUTPUT_SELECTED( m_byCTLB ) )
    {
      // update the output value
      m_byOB = byData;

      // send it to the output function
      if ( m_byDDRB )
        PIA_W_CALLBACK( m_stOutB, m_byOB & m_byDDRB );

      // CB2 is configured as output and in write strobe mode
      if ( C2_OUTPUT( m_byCTLB ) && C2_STROBE_MODE( m_byCTLB ) )
      {
        // this will cause a transition low; call the output function if we're currently high
        if ( m_byOCB2 )
          PIA_W_CALLBACK( m_stOutCB2, 0 );
        m_byOCB2 = 0;

        // if the CB2 strobe is cleared by the E, reset it right away
        if ( STROBE_E_RESET( m_byCTLB ) )
        {
          PIA_W_CALLBACK( m_stOutCB2, 1 );
          m_byOCB2 = 1;
        }
      }
    }
    // write DDR register
    else
    {
      if ( m_byDDRB != byData )
      {
        m_byDDRB = byData;

        // send it to the output function
        if ( m_byDDRB )
          PIA_W_CALLBACK( m_stOutB, m_byOB & m_byDDRB );
      }
    }
    break;

    /******************* port A control write *******************/
  case PIA_CTLA:
    // Bit 7 and 6 read only
    byData &= 0x3f;

    // CA2 is configured as output and in set/reset mode
    if ( C2_OUTPUT( byData ) )
    {
      // determine the new value
      int temp = SET_C2( byData ) ? 1 : 0;

      // if this creates a transition, call the CA2 output function
      if ( m_byOCA2 ^ temp)
        PIA_W_CALLBACK( m_stOutCA2, temp );

      // set the new value
      m_byOCA2 = temp;
    }

    // update the control register
    m_byCTLA = ( m_byCTLA & ~0x3F ) | byData;

    // update externals
    UpdateInterrupts();
    break;

    /******************* port B control write *******************/
  case PIA_CTLB:

    /* Bit 7 and 6 read only - PD 16/01/00 */

    byData &= 0x3f;

    // CB2 is configured as output and in set/reset mode
    if ( C2_OUTPUT( byData ) )
    {
      // determine the new value
      int temp = SET_C2( byData ) ? 1 : 0;

      // if this creates a transition, call the CA2 output function
      if ( m_byOCB2 ^ temp)
        PIA_W_CALLBACK( m_stOutCB2, temp );

      // set the new value
      m_byOCB2 = temp;
    }

    // update the control register
    m_byCTLB = ( m_byCTLB & ~0x3F ) | byData;

    // update externals
    UpdateInterrupts();
    break;
  }

}
Example #8
0
BYTE C6821::Read(BYTE byRS)
{
  BYTE retval = 0;
  byRS &= 3;
  switch ( byRS )
  {
    /******************* port A output/DDR read *******************/
  case PIA_DDRA:
    // read output register
    if ( OUTPUT_SELECTED(m_byCTLA) )
    {
      // combine input and output values
      retval = ( m_byOA & m_byDDRA ) | ( m_byIA & ~m_byDDRA );
      // IRQ flags implicitly cleared by a read
      CLEAR_IRQ1( m_byCTLA );
      CLEAR_IRQ1( m_byCTLB );
      UpdateInterrupts();
      // CA2 is configured as output and in read strobe mode
      if ( C2_OUTPUT(m_byCTLA) && C2_STROBE_MODE(m_byCTLA) )
      {
        // this will cause a transition low; call the output function if we're currently high
        if ( m_byOCA2 )
          PIA_W_CALLBACK( m_stOutCA2, 0 );
        m_byOCA2 = 0;

        // if the CA2 strobe is cleared by the E, reset it right away
        if ( STROBE_E_RESET( m_byCTLA ) )
        {
          PIA_W_CALLBACK( m_stOutCA2, 1 );
          m_byOCA2 = 1;
        }
      }
    }
    // read DDR register
    else
    {
      retval = m_byDDRA;
    }
    break;

    /******************* port B output/DDR read *******************/
  case PIA_DDRB:

    // read output register
    if ( OUTPUT_SELECTED( m_byCTLB ) )
    {
      // combine input and output values
      retval = ( m_byOB & m_byDDRB ) + ( m_byIB & ~m_byDDRB );

      // IRQ flags implicitly cleared by a read
      CLEAR_IRQ2( m_byCTLA );
      CLEAR_IRQ2( m_byCTLB );
      UpdateInterrupts();
    }
    /* read DDR register */
    else
    {
      retval = m_byDDRB;
    }
    break;

    /******************* port A control read *******************/
  case PIA_CTLA:
    // read control register
    retval = m_byCTLA;
    // when CA2 is an output, IRQA2 = 0, and is not affected by CA2 transitions.
    if ( C2_OUTPUT( m_byCTLA ) )
      retval &= ~PIA_IRQ2;
    break;

    /******************* port B control read *******************/
  case PIA_CTLB:
    retval = m_byCTLB;
    // when CB2 is an output, IRQB2 = 0, and is not affected by CB2 transitions.
    if ( C2_OUTPUT( m_byCTLB ) )
      retval &= ~PIA_IRQ2;
    break;

  }

  return retval;
}