예제 #1
0
void C6821::SetCA1(BYTE byData)
{
  byData = byData ? 1 : 0;

  // the new state has caused a transition
  if ( m_byCA1 ^ byData )
  {
    // handle the active transition
    if ( ( byData && C1_LOW_TO_HIGH( m_byCTLA ) ) ||
      ( !byData && C1_HIGH_TO_LOW( m_byCTLA ) ) )
    {
      // mark the IRQ
      SET_IRQ1(m_byCTLA);

      // update externals
      UpdateInterrupts();

      // CA2 is configured as output and in read strobe mode and cleared by a CA1 transition
      if ( C2_OUTPUT( m_byCTLA ) && C2_STROBE_MODE( m_byCTLA ) && STROBE_C1_RESET( m_byCTLA ) )
      {
        // call the CA2 output function
        if ( !m_byOCA2 )
          PIA_W_CALLBACK( m_stOutCA2, 1 );

        // clear CA2
        m_byOCA2 = 1;
      }
    }
  }

  // set the new value for CA1
  m_byCA1 = byData;
}
예제 #2
0
void pia_set_input_cb1 (int which, int data)
{
	struct pia6821 *p = pia + which;

	/* limit the data to 0 or 1 */
	data = data ? 1 : 0;

	/* the new state has caused a transition */
	if (p->in_cb1 ^ data)
	{
		/* handle the active transition */
		if ((data && C1_LOW_TO_HIGH (p->ctl_b)) || (!data && C1_HIGH_TO_LOW (p->ctl_b)))
		{
			/* mark the IRQ */
			p->irq_b1 = 1;

			/* call the IRQ function if enabled */
			if (IRQ1_ENABLED (p->ctl_b))
				if (p->irq_b_func) p->irq_b_func ();

			/* CB2 is configured as output and in write strobe mode and cleared by a CA1 transition */
			if (C2_OUTPUT (p->ctl_b) && C2_STROBE_MODE (p->ctl_b) && STROBE_C1_RESET (p->ctl_b))
			{
				/* the IRQ1 flag must have also been cleared */
				if (!p->irq_b1)
				{
					/* call the CB2 output function */
					if (!p->out_cb2)
						if (p->out_cb2_func) p->out_cb2_func (0, 1);

					/* clear CB2 */
					p->out_cb2 = 1;
				}
			}
		}
	}

	/* set the new value for CB1 */
	p->in_cb1 = data;
}
예제 #3
0
파일: 6821pia.c 프로젝트: Ilgrim/MAMEHub
UINT8 pia6821_device::port_b_r()
{
	UINT8 ret = get_in_b_value();

	// This read will implicitly clear the IRQ B1 flag.  If CB2 is in write-strobe
	// mode with CB1 restore, and a CB1 active transition set the flag,
	// clearing it will cause CB2 to go high again.  Note that this is different
	// from what happens with port A.
	if(m_irq_b1 && C2_STROBE_MODE(m_ctl_b) && STROBE_C1_RESET(m_ctl_b))
	{
		set_out_cb2(TRUE);
	}

	// IRQ flags implicitly cleared by a read
	m_irq_b1 = FALSE;
	m_irq_b2 = FALSE;
	update_interrupts();

	LOG(("PIA #%s: port B read = %02X\n", tag(), ret));

	return ret;
}
예제 #4
0
static UINT8 port_b_r(const device_config *device)
{
	pia6821_state *p = get_token(device);

	UINT8 ret = get_in_b_value(device);

	/* This read will implicitly clear the IRQ B1 flag.  If CB2 is in write-strobe
       mode with CB1 restore, and a CB1 active transition set the flag,
       clearing it will cause CB2 to go high again.  Note that this is different
       from what happens with port A. */
	if (p->irq_b1 && C2_STROBE_MODE(p->ctl_b) && STROBE_C1_RESET(p->ctl_b))
		set_out_cb2(device, TRUE);

	/* IRQ flags implicitly cleared by a read */
	p->irq_b1 = FALSE;
	p->irq_b2 = FALSE;
	update_interrupts(device);

	LOG(("PIA #%s: port B read = %02X\n", device->tag, ret));

	return ret;
}
예제 #5
0
void pia_set_input_ca1(int which, int data)
{
	struct pia6821 *p = pia + which;

	/* limit the data to 0 or 1 */
	data = data ? 1 : 0;

	/* the new state has caused a transition */
	if (p->in_ca1 ^ data)
	{
		/* handle the active transition */
		if ((data && C1_LOW_TO_HIGH(p->ctl_a)) || (!data && C1_HIGH_TO_LOW(p->ctl_a)))
		{
			/* mark the IRQ */
			p->irq_a1 = 1;

			/* update externals */
			update_6821_interrupts(p);

			/* CA2 is configured as output and in read strobe mode and cleared by a CA1 transition */
			if (C2_OUTPUT(p->ctl_a) && C2_STROBE_MODE(p->ctl_a) && STROBE_C1_RESET(p->ctl_a))
			{
				/* call the CA2 output function */
				if (!p->out_ca2)
					if (p->intf->out_ca2_func) p->intf->out_ca2_func(0, 1);

				/* clear CA2 */
				p->out_ca2 = 1;
			}
		}
	}

	/* set the new value for CA1 */
	p->in_ca1 = data;
	p->in_set |= PIA_IN_SET_CA1;
}
예제 #6
0
int pia_read(int which, int offset)
{
	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);

				/* This read will implicitly clear the IRQ B1 flag.  If CB2 is in write-strobe
                   output mode with CB1 restore, and a CB1 active transition set the flag,
                   clearing it will cause CB2 to go high again.  Note that this is different
                   from what happens with port A. */
				if (p->irq_b1 && C2_OUTPUT(p->ctl_b) && C2_STROBE_MODE(p->ctl_b) && STROBE_C1_RESET(p->ctl_b))
				{
					/* call the CB2 output function */
					if (!p->out_cb2)
						if (p->intf->out_cb2_func) p->intf->out_cb2_func(0, 1);

					/* clear CB2 */
					p->out_cb2 = 1;
				}

				/* 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;
}