⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 z80fmly.c

📁 这个是延伸mame的在wince平台下的游戏模拟器的代码
💻 C
📖 第 1 页 / 共 2 页
字号:

	/* see if the trigger value has changed */
	if (data != ctc->extclk[ch])
	{
		ctc->extclk[ch] = data;

		/* see if this is the active edge of the trigger */
		if (((mode & EDGE) == EDGE_RISING && data) || ((mode & EDGE) == EDGE_FALLING && !data))
		{
			/* if we're waiting for a trigger, start the timer */
			if ((mode & WAITING_FOR_TRIG) && (mode & MODE) == MODE_TIMER)
			{
				double clock = ((mode & PRESCALER) == PRESCALER_16) ? ctc->invclock16 : ctc->invclock256;

				if (ctc->timer[ch])
					timer_remove (ctc->timer[ch]);
				if (!(ctc->notimer & (1<<ch)))
					ctc->timer[ch] = timer_pulse (clock * (double)ctc->tconst[ch], (which << 2) + ch, z80ctc_timercallback);
			}

			/* we're no longer waiting */
			ctc->mode[ch] &= ~WAITING_FOR_TRIG;

			/* if we're clocking externally, decrement the count */
			if ((mode & MODE) == MODE_COUNTER)
			{
				ctc->down[ch]--;

				/* if we hit zero, do the same thing as for a timer interrupt */
				if (!ctc->down[ch])
					z80ctc_timercallback ((which << 2) + ch);
			}
		}
	}
}

void z80ctc_0_trg0_w (int offset, int data) { z80ctc_trg_w (0, 0, offset, data); }
void z80ctc_0_trg1_w (int offset, int data) { z80ctc_trg_w (0, 1, offset, data); }
void z80ctc_0_trg2_w (int offset, int data) { z80ctc_trg_w (0, 2, offset, data); }
void z80ctc_0_trg3_w (int offset, int data) { z80ctc_trg_w (0, 3, offset, data); }
void z80ctc_1_trg0_w (int offset, int data) { z80ctc_trg_w (1, 0, offset, data); }
void z80ctc_1_trg1_w (int offset, int data) { z80ctc_trg_w (1, 1, offset, data); }
void z80ctc_1_trg2_w (int offset, int data) { z80ctc_trg_w (1, 2, offset, data); }
void z80ctc_1_trg3_w (int offset, int data) { z80ctc_trg_w (1, 3, offset, data); }


/*---------------------- Z80 PIO ---------------------------------*/

/* starforce emurate Z80PIO subset */
/* ch.A mode 1 input handshake mode from sound command */
/* ch.b not use */


#define PIO_MODE0 0x00		/* output mode */
#define PIO_MODE1 0x01		/* input  mode */
#define PIO_MODE2 0x02		/* i/o    mode */
#define PIO_MODE3 0x03		/* bit    mode */
/* pio controll port operation (bit 0-3) */
#define PIO_OP_MODE 0x0f	/* mode select        */
#define PIO_OP_INTC 0x07	/* interrupt controll */
#define PIO_OP_INTE 0x03	/* interrupt enable   */
#define PIO_OP_INTE 0x03	/* interrupt enable   */
/* pio interrupt controll nit */
#define PIO_INT_ENABLE 0x80  /* ENABLE : 0=disable , 1=enable */
#define PIO_INT_AND    0x40  /* LOGIC  : 0=OR      , 1=AND    */
#define PIO_INT_HIGH   0x20  /* LEVEL  : 0=low     , 1=high   */
#define PIO_INT_MASK   0x10  /* MASK   : 0=off     , 1=on     */

typedef struct
{
	int vector[2];                        /* interrupt vector               */
	void (*intr)(int which);              /* interrupt callbacks            */
	void (*rdyr[2])(int data);            /* RDY active callback            */
	int mode[2];                          /* mode 00=in,01=out,02=i/o,03=bit*/
	int enable[2];                        /* interrupt enable               */
	int mask[2];                          /* mask folowers                  */
	int dir[2];                           /* direction (bit mode)           */
	int rdy[2];                           /* ready pin level                */
	int in[2];                            /* input port data                */
	int out[2];                           /* output port                    */
	int int_state[2];                     /* interrupt status (daisy chain) */
} z80pio;

static z80pio pios[MAX_PIO];

/* initialize pio emurator */
void z80pio_init (z80pio_interface *intf)
{
	int i;

	memset (pios, 0, sizeof (pios));

	for (i = 0; i < intf->num; i++)
	{
		pios[i].intr = intf->intr[i];
		pios[i].rdyr[0] = intf->rdyA[i];
		pios[i].rdyr[1] = intf->rdyB[i];
		z80pio_reset (i);
	}
}

static void z80pio_interrupt_check( z80pio *pio )
{
	int state;

	if( pio->int_state[1] & Z80_INT_IEO ) state  = Z80_INT_IEO;
	else                                  state  = pio->int_state[1];
	if( pio->int_state[0] & Z80_INT_IEO ) state  = Z80_INT_IEO;
	else                                  state |= pio->int_state[0];
	/* change daisy chain status */
	if (pio->intr) (*pio->intr)(state);
}

static void z80pio_check_irq( z80pio *pio , int ch )
{
	int irq = 0;
	int data;
	int old_state;

	if( pio->enable[ch] & PIO_INT_ENABLE )
	{
		if( pio->mode[ch] == PIO_MODE3 )
		{
			data  =  pio->in[ch] & pio->dir[ch]; /* input data only */
			data &= ~pio->mask[ch];              /* mask follow     */
			if( !(pio->enable[ch]&PIO_INT_HIGH) )/* active level    */
				data ^= pio->mask[ch];             /* active low  */
			if( pio->enable[ch]&PIO_INT_AND )    /* logic      */
			     { if( data == pio->mask[ch] ) irq = 1; }
			else { if( data == 0             ) irq = 1; }
			/* if portB , portA mode 2 check */
			if( ch && (pio->mode[0]==PIO_MODE2) )
			{
				if( pio->rdy[ch] == 0 ) irq = 1;
			}
		}
		else if( pio->rdy[ch] == 0 ) irq = 1;
	}
	old_state = pio->int_state[ch];
	if( irq ) pio->int_state[ch] |=  Z80_INT_REQ;
	else      pio->int_state[ch] &= ~Z80_INT_REQ;

	if( old_state != pio->int_state[ch] )
		z80pio_interrupt_check( pio );
}

void z80pio_reset (int which)
{
	z80pio *pio = pios + which;
	int i;

	for( i = 0 ; i <= 1 ; i++){
		pio->mask[i]   = 0xff;	/* mask all on */
		pio->enable[i] = 0x00;	/* disable     */
		pio->mode[i]   = 0x01;	/* mode input  */
		pio->dir[i]    = 0x01;	/* dir  input  */
		pio->rdy[i]    = 0x00;	/* RDY = low   */
		pio->out[i]    = 0x00;	/* outdata = 0 */
		pio->int_state[i] = 0;
	}
	z80pio_interrupt_check( pio );
}

/* pio data register write */
void z80pio_d_w( int which , int ch , int data )
{
	z80pio *pio = pios + which;
	if( ch ) ch = 1;

	pio->out[ch] = data;	/* latch out data */
	switch( pio->mode[ch] ){
	case PIO_MODE0:			/* mode 0 output */
	case PIO_MODE2:			/* mode 2 i/o */
		pio->rdy[ch] = 1;	/* ready = H */
		z80pio_check_irq( pio , ch );
		return;
	case PIO_MODE1:			/* mode 1 intput */
	case PIO_MODE3:			/* mode 0 bit */
		return;
	default:
		return;
	}
}

/* pio controll register write */
void z80pio_c_w( int which , int ch , int data )
{
	z80pio *pio = pios + which;
	if( ch ) ch = 1;

	/* load direction phase ? */
	if( pio->mode[ch] == 0x13 ){
		pio->dir[ch] = data;
		pio->mode[ch] = 0x03;
		return;
	}
	/* load mask folows phase ? */
	if( pio->enable[ch] & PIO_INT_MASK ){	/* load mask folows */
		pio->mask[ch] = data;
		pio->enable[ch] &= ~PIO_INT_MASK;
		return;
	}
	switch( data & 0x0f ){
	case PIO_OP_MODE:	/* mode select 0=out,1=in,2=i/o,3=bit */
		pio->mode[ch] = (data >> 6 );
		if( pio->mode[ch] == 0x03 ) pio->mode[ch] = 0x13;
		break;
	case PIO_OP_INTC:		/* interrupt control */
		pio->enable[ch] = data & 0xf0;
		pio->mask[ch]   = 0x00;
		/* when interrupt enable , set vector request flag */
		break;
	case PIO_OP_INTE:		/* interrupt enable controll */
		pio->enable[ch] &= ~PIO_INT_ENABLE;
		pio->enable[ch] |= (data & PIO_INT_ENABLE);
		break;
	default:
			if( !(data&1) )
			{
				pio->vector[ch] = data;
			}
	}
	/* interrupt check */
	z80pio_check_irq( pio , ch );
}

/* pio controll register read */
int z80pio_c_r( int which , int ch )
{
	if( ch ) ch = 1;

	return 0;
}

/* pio data register read */
int z80pio_d_r( int which , int ch )
{
	z80pio *pio = pios + which;
	if( ch ) ch = 1;

	switch( pio->mode[ch] ){
	case PIO_MODE0:			/* mode 0 output */
		return pio->out[ch];
	case PIO_MODE1:			/* mode 1 intput */
		pio->rdy[ch] = 1;	/* ready = H */
		z80pio_check_irq( pio , ch );
		return pio->in[ch];
	case PIO_MODE2:			/* mode 2 i/o */
		pio->rdy[1] = 1;	/* brdy = H */
		z80pio_check_irq( pio , ch );
		return pio->in[ch];
	case PIO_MODE3:			/* mode 3 bit */
		return (pio->in[ch]&pio->dir[ch])|(pio->out[ch]&~pio->dir[ch]);
	}
	return 0;
}

int z80pio_interrupt( int which )
{
	z80pio *pio = pios + which;
	int ch = 0;

	/* port A */
	if( pio->int_state[0] == Z80_INT_REQ )
	{
		pio->int_state[0] |= Z80_INT_IEO;
	} if( pio->int_state[0] == 0 )
	{
		/* port B */
		ch = 1;
		if( pio->int_state[1] == Z80_INT_REQ )
		{
			pio->int_state[1] |= Z80_INT_IEO;
		}
		else
		{
			ch = 0;
		}
	}
	z80pio_interrupt_check( pio );
	return pio->vector[ch];
}

void z80pio_reti( int which )
{
	z80pio *pio = pios + which;

	if( pio->int_state[0] & Z80_INT_IEO )
	{
		pio->int_state[0] &= ~Z80_INT_IEO;
	} else if( pio->int_state[1] & Z80_INT_IEO )
	{
		pio->int_state[1] &= ~Z80_INT_IEO;
	}
	/* set next interrupt stattus */
	z80pio_interrupt_check( pio );
}

/* z80pio port write */
void z80pio_p_w( int which , int ch , int data )
{
	z80pio *pio = pios + which;

	if( ch ) ch = 1;

	pio->in[ch]  = data;
	switch( pio->mode[ch] ){
	case PIO_MODE0:
		break;
	case PIO_MODE2:	/* only port A */
		ch = 1;		/* handshake and IRQ is use portB */
	case PIO_MODE1:
		pio->rdy[ch] = 0;
		z80pio_check_irq( pio , ch );
		break;
	case PIO_MODE3:
		/* irq check */
		z80pio_check_irq( pio , ch );
		break;
	}
}

/* z80pio port read */
int z80pio_p_r( int which , int ch )
{
	z80pio *pio = pios + which;

	if( ch ) ch = 1;

	switch( pio->mode[ch] ){
	case PIO_MODE2:		/* port A only */
	case PIO_MODE0:
		pio->rdy[ch] = 0;
		z80pio_check_irq( pio , ch );
		break;
	case PIO_MODE1:
		break;
	case PIO_MODE3:
		/*     input bits                , output bits                */
		return (pio->in[ch]&pio->dir[ch])|(pio->out[ch]&~pio->dir[ch]);
	}
	return pio->out[ch];
}

/* for mame interface */

void z80pio_0_reset (void) { z80pio_reset (0); }

void z80pio_0_w(int offset , int data)
{
	if(offset&1) z80pio_c_w(0,(offset/2)&1,data);
	else         z80pio_d_w(0,(offset/2)&1,data);
}

int  z80pio_0_r(int offset)
{
	return (offset&1) ? z80pio_c_r(0,(offset/2)&1) : z80pio_d_r(0,(offset/2)&1);
}

void z80pioA_0_p_w(int offset , int data) { z80pio_p_w(0,0,data);   }
void z80pioB_0_p_w(int offset , int data) { z80pio_p_w(0,1,data);   }
int  z80pioA_0_p_r(int offset )           { return z80pio_p_r(0,0); }
int  z80pioB_0_p_r(int offset )           { return z80pio_p_r(0,1); }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -