Exemple #1
0
void C6821::set_input_cb2(int data)
{
	/* limit the data to 0 or 1 */
	data = data ? 1 : 0;

	/* CB2 is in input mode */
	if((ControlB & CTRL_C2_OUTPUT) == 0)
	{
		/* the new state has caused a transition */
		if (InputCB2 ^ data)
		{
			/* handle the active transition */
			if ((data && (ControlB & 2)) || (!data && (ControlB & 2) == 0))
			{
				/* mark the IRQ */
				IRQB2 = 1;

				/* update externals */
				update_6821_interrupts();
			}
		}
	}

	/* set the new value for CA2 */
	InputCB2 = data;
//	p->in_set |= PIA_IN_SET_CB2;
}
Exemple #2
0
void pia_set_input_cb2(int which, int data)
{
	struct pia6821 *p = pia + which;

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

	/* CB2 is in input mode */
	if (C2_INPUT(p->ctl_b))
	{
		/* the new state has caused a transition */
		if (p->in_cb2 ^ data)
		{
			/* handle the active transition */
			if ((data && C2_LOW_TO_HIGH(p->ctl_b)) || (!data && C2_HIGH_TO_LOW(p->ctl_b)))
			{
				/* mark the IRQ */
				p->irq_b2 = 1;

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

	/* set the new value for CA2 */
	p->in_cb2 = data;
	p->in_set |= PIA_IN_SET_CB2;
}
Exemple #3
0
void pia_set_input_cb1(int which, int data)
{
	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;

			/* update externals */
			update_6821_interrupts(p);

			/* If CB2 is configured as a write-strobe output which is reset by a CB1
               transition, this reset will only happen when a read from port B implicitly
               clears the IRQ B1 flag.  So we handle the CB2 reset there.  Note that this
               is different from what happens with port A. */
		}
	}

	/* set the new value for CB1 */
	p->in_cb1 = data;
	p->in_set |= PIA_IN_SET_CB1;
}
Exemple #4
0
void C6821::set_input_cb1(int data)
{
	/* limit the data to 0 or 1 */
	data = data ? 1 : 0;

	/* the new state has caused a transition */
	if (InputCB1 ^ data)
	{
		/* handle the active transition */
		if ((data && (ControlB & 2)) || (!data && (ControlB & 2) == 0))
		{
			/* mark the IRQ */
			IRQB1 = 1;

			/* update externals */
			update_6821_interrupts();

			/* If CB2 is configured as a write-strobe output which is reset by a CB1
               transition, this reset will only happen when a read from port B implicitly
               clears the IRQ B1 flag.  So we handle the CB2 reset there.  Note that this
               is different from what happens with port A. */
		}
	}

	/* set the new value for CB1 */
	InputCB1 = data;
//	p->in_set |= PIA_IN_SET_CB1;
}
Exemple #5
0
static void pia_postload(int which)
{
	struct pia6821 *p = pia + which;
	update_6821_interrupts(p);
	if (p->intf->out_a_func && p->ddr_a) p->intf->out_a_func(0, p->out_a & p->ddr_a);
	if (p->intf->out_b_func && p->ddr_b) p->intf->out_b_func(0, p->out_b & p->ddr_b);
	if (p->intf->out_ca2_func) p->intf->out_ca2_func(0, p->out_ca2);
	if (p->intf->out_cb2_func) p->intf->out_cb2_func(0, p->out_cb2);
}
Exemple #6
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;

			/* update externals */
			update_6821_interrupts(p);

			/* 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->intf->out_cb2_func) p->intf->out_cb2_func(0, 1);

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

	/* set the new value for CB1 */
	p->in_cb1 = data;
	p->in_set |= PIA_IN_SET_CB1;
}
Exemple #7
0
void pia_set_input_ca1(int which, int data)
{
	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;
}
Exemple #8
0
void C6821::set_input_ca1(int data)
{
	/* limit the data to 0 or 1 */
	data = data ? 1 : 0;

	/* the new state has caused a transition */
	if(InputCA1 ^ data)
	{

		/* handle the active transition */
		if ((data && (ControlA & 2)) || (!data && (ControlA & 2) == 0))
		{
			/* mark the IRQ */
			IRQA1 = 1;

			/* update externals */
			update_6821_interrupts();

			/* CA2 is configured as output and in read strobe mode and cleared by a CA1 transition */
			if(ControlA & CTRL_C2_OUTPUT && 
				(ControlA & CTRL_C2_SETMODE) == 0 && 
				(ControlA & CTRL_STROBE_E_RESET) == 0)
			{
				/* call the CA2 output function */
				if (OutputCA2 == 0 && OutputCA2Func) OutputCA2Func(user,1);

				/* clear CA2 */
				OutputCA2 = 1;
			}
		}
	}

	/* set the new value for CA1 */
	InputCA1 = data;
//	p->in_set |= PIA_IN_SET_CA1;
}
Exemple #9
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;
	}
}
Exemple #10
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;
}
Exemple #11
0
void C6821::Write(int reg,u8 data)
{
switch(reg)
	{
	case c6821_ddra:
		if(ControlA & CTRL_OUTPUT)
			{
			OutputA = data;
			if(OutputAFunc && DataA)
				OutputAFunc(user,OutputA & DataA);
			}
		else
			{
			if(DataA != data)
				{
				DataA = data;
				if(OutputAFunc && DataA)
					OutputAFunc(user,OutputA & DataA);
				}
			}
		break;
	case c6821_ctrla:
		data &= 0x3F;
		if(data & CTRL_C2_OUTPUT)
			{
			u8 t;

			if(data & CTRL_C2_SETMODE)
				{
				if((data & 8) == 0)
					t = 0;
				else
					t = 1;
				}
			else
				t = 1;
			if((ControlA & CTRL_C2_OUTPUT) == 0 ||
				((ControlA & CTRL_C2_OUTPUT) && (OutputCA2 ^ t)))
				{
				if(OutputCA2Func)
					OutputCA2Func(user,t);
				}
			OutputCA2 = t;
			}
		ControlA = data;
		update_6821_interrupts();
		break;
	case c6821_ddrb:
		if(ControlB & CTRL_OUTPUT)
			{
			OutputB = data;
			if(OutputBFunc && DataB)
				OutputBFunc(user,OutputB & DataB);
			if(ControlB & CTRL_C2_OUTPUT && (ControlB & CTRL_C2_SETMODE) == 0)
				{
				if(OutputCB2 && OutputCB2Func)
					OutputCB2Func(user,0);
				OutputCB2 = 0;
				if(ControlB & CTRL_STROBE_E_RESET)
					{
					if(OutputCB2Func)
						OutputCB2Func(user,1);
					OutputCB2 = 1;
					}
				}
			}
		else
			{
			if(DataB != data)
				{
				DataB = data;
				if(OutputBFunc && DataB)
					OutputBFunc(user,OutputB & DataB);
				}
			}
		break;
	case c6821_ctrlb:
		data &= 0x3F;
		if(data & CTRL_C2_OUTPUT)
			{
			u8 t;

			if(data & CTRL_C2_SETMODE)
				{
				if((data & 8) == 0)
					t = 0;
				else
					t = 1;
				}
			else
				t = 1;
			if((ControlB & CTRL_C2_OUTPUT) == 0 ||
				((ControlB & CTRL_C2_OUTPUT) && (OutputCB2 ^ t)))
				{
				if(OutputCB2Func)
					OutputCB2Func(user,t);
				}
			OutputCB2 = t;
			}
		ControlB = data;
		update_6821_interrupts();
		break;
	}
}
Exemple #12
0
u8 C6821::Read(int reg)
{
u8 ret;

switch(reg)
	{
	case c6821_ddra:
		if(ControlA & CTRL_OUTPUT)				//output selected
			{
			if(InputAFunc)							//function specified to get input data?
				InputA = InputAFunc(user);
			ret = OutputA & DataA;				//combine input and output data
			ret |= InputA & ~DataA;
			IRQA1 = 0;								//clear irq data
			IRQA2 = 0;
			update_6821_interrupts();
			if(ControlA & CTRL_C2_OUTPUT &&	//ca2 is output and strobe is on
				(ControlA & CTRL_C2_SETMODE) == 0)
				{
				if(OutputCA2 && OutputCA2Func)//if output ca2 specified
					OutputCA2Func(user,0);		//send low signal
				OutputCA2 = 0;
				if(ControlA & CTRL_STROBE_E_RESET)
					{
					if(OutputCA2Func)				//if output ca2 specified
						OutputCA2Func(user,1);	//send high signal
					OutputCA2 = 1;
					}
				}
			}
		else											//input selected, read data register
			ret = DataA;
		return(ret);
	case c6821_ctrla:
		if(InputCA1Func)
			set_input_ca1(InputCA1Func(user));
		if(InputCA2Func)
			set_input_ca2(InputCA2Func(user));
		ret = ControlA;
		if(IRQA1)
			ret |= 0x80;
		if(IRQA2 && (ControlA & CTRL_C2_OUTPUT) == 0)
			ret |= 0x40;
		return(ret);
	case c6821_ddrb:
		if(ControlB & CTRL_OUTPUT)				//output selected
			{
			if(InputBFunc)							//function specified to get input data?
				InputB = InputBFunc(user);
			ret = OutputB & DataB;				//combine input and output data
			ret |= InputB & ~DataB;
			if(IRQB1 && 
				ControlB & CTRL_C2_OUTPUT && 
				(ControlB & CTRL_C2_SETMODE) == 0 &&
				(ControlB & CTRL_STROBE_E_RESET) == 0)
				{
				if(OutputCB2 == 0 && OutputCB2Func)
					OutputCB2Func(user,1);		//send high signal
				OutputCB2 = 1;
				}
			IRQB1 = 0;								//clear irq data
			IRQB2 = 0;
			update_6821_interrupts();
			}
		else											//input selected, read data register
			ret = DataB;
		return(ret);
	case c6821_ctrlb:
		if(InputCB1Func)
			set_input_cb1(InputCB1Func(user));
		if(InputCB2Func)
			set_input_cb2(InputCB2Func(user));
		ret = ControlB;
		if(IRQB1)
			ret |= 0x80;
		if(IRQB2 && (ControlB & CTRL_C2_OUTPUT) == 0)
			ret |= 0x40;
		return(ret);
	}
return(0);
}