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

📄 tms34010.c

📁 这个是延伸mame的在wince平台下的游戏模拟器的代码
💻 C
📖 第 1 页 / 共 2 页
字号:
{
	/*  ~S -> D */
	return ~newpix;
}
static INT32 raster_op_16(INT32 newpix, INT32 oldpix)
{
	/*  S + D -> D */
	return newpix + oldpix;
}
static INT32 raster_op_17(INT32 newpix, INT32 oldpix)
{
	/*  S + D -> D with Saturation*/
	INT32 max = (UINT32)0xffffffff>>(32-IOREG(REG_PSIZE));
	INT32 res = newpix + oldpix;
	return (res > max) ? max : res;
}
static INT32 raster_op_18(INT32 newpix, INT32 oldpix)
{
	/*  D - S -> D */
	return oldpix - newpix;
}
static INT32 raster_op_19(INT32 newpix, INT32 oldpix)
{
	/*  D - S -> D with Saturation */
	INT32 res = oldpix - newpix;
	return (res < 0) ? 0 : res;
}
static INT32 raster_op_20(INT32 newpix, INT32 oldpix)
{
	/*  MAX(S,D) -> D */
	return ((oldpix > newpix) ? oldpix : newpix);
}
static INT32 raster_op_21(INT32 newpix, INT32 oldpix)
{
	/*  MIN(S,D) -> D */
	return ((oldpix > newpix) ? newpix : oldpix);
}


/****************************************************************************/
/* Set all registers to given values                                        */
/****************************************************************************/
void TMS34010_SetRegs(TMS34010_Regs *Regs)
{
	state = *Regs;
	change_pc29(PC)
}

/****************************************************************************/
/* Get all registers in given buffer                                        */
/****************************************************************************/
void TMS34010_GetRegs(TMS34010_Regs *Regs)
{
	*Regs = state;
}

/****************************************************************************/
/* Return program counter                                                   */
/****************************************************************************/
unsigned TMS34010_GetPC(void)
{
	return PC;
}


TMS34010_Regs* TMS34010_GetState(void)
{
	return &state;
}


void TMS34010_Reset(void)
{
	int i;

	memset (&state, 0, sizeof (state));
	state.lastpixaddr = INVALID_PIX_ADDRESS;
	for (i = 0; i < MAX_CPU; i ++)
	{
		TMS34010_timer[i] = 0;
	}

	PC = RLONG(0xffffffe0);
	change_pc29(PC)
	RESET_ST();

	state.shiftreg = malloc(SHIFTREG_SIZE);

	/* The slave CPU starts out halted */
	if (cpu_getactivecpu() == CPU_SLAVE)
	{
		IOREG(REG_HSTCTLH) = 0x8000;
		cpu_halt(cpu_getactivecpu(), 0);
	}

	if (stackbase[cpu_getactivecpu()] == 0)
	{
		/* */
	}

	state.stackbase = stackbase[cpu_getactivecpu()] - stackoffs[cpu_getactivecpu()];

	state.to_shiftreg   = to_shiftreg  [cpu_getactivecpu()];		
	state.from_shiftreg = from_shiftreg[cpu_getactivecpu()];		
}


void TMS34010_Cause_Interrupt(int type)
{
	/* NONE = 0 */
	IOREG(REG_INTPEND) |= type;
}


void TMS34010_Clear_Pending_Interrupts(void)
{
	/* This doesn't apply */
}


/* Generate interrupts */
static void Interrupt(void)
{
	int take=0;

	if (IOREG(REG_INTPEND) & TMS34010_NMI)
	{
		IOREG(REG_INTPEND) &= ~TMS34010_NMI;

		if (!(IOREG(REG_HSTCTLH) & 0x0200))  
		{
			PUSH(PC);
			PUSH(GET_ST());					
		}
		RESET_ST();
		PC = RLONG(0xfffffee0);
        change_pc29(PC);
	}
	else
	{
		if ((IOREG(REG_INTPEND) & TMS34010_HI) &&
			(IOREG(REG_INTENB)  & TMS34010_HI))
		{
			take = 0xfffffec0;		
		}
		else
		if ((IOREG(REG_INTPEND) & TMS34010_DI) &&
			(IOREG(REG_INTENB)  & TMS34010_DI))
		{
			take = 0xfffffea0;
		}
		else
		if ((IOREG(REG_INTPEND) & TMS34010_WV) &&
			(IOREG(REG_INTENB)  & TMS34010_WV))
		{
			take = 0xfffffe80;		
		}
		else
		if ((IOREG(REG_INTPEND) & TMS34010_INT1) &&
			(IOREG(REG_INTENB)  & TMS34010_INT1))
		{
			take = 0xffffffc0;		
		}
		else
		if ((IOREG(REG_INTPEND) & TMS34010_INT2) &&
			(IOREG(REG_INTENB)  & TMS34010_INT2))
		{
			take = 0xffffffa0;		
		}

		if (take)
		{
			PUSH(PC);
			PUSH(GET_ST());
			RESET_ST();
			PC = RLONG(take);
			change_pc29(PC);
		}
	}
}


#ifdef MAME_DEBUG
extern int mame_debug;
#endif

/* execute instructions on this CPU until icount expires */
int TMS34010_Execute(int cycles)
{
	/* Get out if CPU is halted. Absolutely no interrupts must be taken!!! */
	if (IOREG(REG_HSTCTLH) & 0x8000)
	{
		return cycles;		
	}

	TMS34010_ICount = cycles;
	change_pc29(PC)
	do
	{
		/* Quickly reject the cases when there are no pending interrupts
		   or they are disabled (as in an interrupt service routine) */
		if (IOREG(REG_INTPEND))
		{
			if ((IE_FLAG || (IOREG(REG_INTPEND) & TMS34010_NMI)))
			{
				Interrupt();			
			}
		}

		#ifdef	MAME_DEBUG
		if (mame_debug) { state.st = GET_ST(); MAME_Debug(); }
		#endif
		state.op = ROPCODE ();
		(*opcode_table[state.op >> 4])();

		#ifdef	MAME_DEBUG
		if (mame_debug) { state.st = GET_ST(); MAME_Debug(); }
		#endif
		state.op = ROPCODE ();
		(*opcode_table[state.op >> 4])();

		#ifdef	MAME_DEBUG
		if (mame_debug) { state.st = GET_ST(); MAME_Debug(); }
		#endif
		state.op = ROPCODE ();
		(*opcode_table[state.op >> 4])();

		#ifdef	MAME_DEBUG
		if (mame_debug) { state.st = GET_ST(); MAME_Debug(); }
		#endif
		state.op = ROPCODE ();
		(*opcode_table[state.op >> 4])();

		TMS34010_ICount -= 4 * TMS34010_AVGCYCLES;

	} while (TMS34010_ICount > 0);

	return cycles - TMS34010_ICount;
}


static UINT32 (*pixel_write_ops[4][5])(UINT32, UINT32)	=
{
	{write_pixel_1,     write_pixel_2,     write_pixel_4,     write_pixel_8,     write_pixel_16},
	{write_pixel_r_1,   write_pixel_r_2,   write_pixel_r_4,   write_pixel_r_8,   write_pixel_r_16},
	{write_pixel_t_1,   write_pixel_t_2,   write_pixel_t_4,   write_pixel_t_8,   write_pixel_t_16},
	{write_pixel_r_t_1, write_pixel_r_t_2, write_pixel_r_t_4, write_pixel_r_t_8, write_pixel_r_t_16}
};

static UINT32 (*pixel_read_ops[5])(UINT32 address) =
{
	read_pixel_1, read_pixel_2, read_pixel_4, read_pixel_8, read_pixel_16
};


static void set_pixel_function(void)
{
	UINT32 i1,i2;

	if (IOREG(REG_DPYCTL) & 0x0800)
	{
		/* Shift Register Transfer */
		state.pixel_write = write_pixel_shiftreg;
		state.pixel_read  = read_pixel_shiftreg;
		return;
	}

	switch (IOREG(REG_PSIZE))
	{
	default:
	case 0x01: i2 = 0; break;
	case 0x02: i2 = 1; break;
	case 0x04: i2 = 2; break;
	case 0x08: i2 = 3; break;
	case 0x10: i2 = 4; break;
	}

	if (state.transparency)
	{
		if (state.raster_op)
		{
			i1 = 3;			
		}
		else
		{
			i1 = 2;
		}
	}
	else
	{
		if (state.raster_op)
		{
			i1 = 1;			
		}
		else
		{
			i1 = 0;
		}		
	}

	state.pixel_write = pixel_write_ops[i1][i2];
	state.pixel_read  = pixel_read_ops [i2];
}


static INT32 (*raster_ops[32]) (INT32 newpix, INT32 oldpix) =
{
	           0, raster_op_1 , raster_op_2 , raster_op_3,
	raster_op_4 , raster_op_5 , raster_op_6 , raster_op_7,
	raster_op_8 , raster_op_9 , raster_op_10, raster_op_11,
	raster_op_12, raster_op_13, raster_op_14, raster_op_15,
	raster_op_16, raster_op_17, raster_op_18, raster_op_19,
	raster_op_20, raster_op_21,            0,            0,
	           0,            0,            0,            0,
	           0,            0,            0,            0,
};

static void set_raster_op(void)
{
	state.raster_op = raster_ops[(IOREG(REG_CONTROL) >> 10) & 0x1f];
}

void TMS34010_io_register_w(int reg, int data)
{
	int cpu;
							
	/* Set register */
	reg >>= 1;
	IOREG(reg) = data;		

	switch (reg)
	{
	case REG_DPYINT:
		/* Set display interrupt timer */
		cpu = cpu_getactivecpu();
		if (TMS34010_timer[cpu])
		{
			timer_remove(TMS34010_timer[cpu]);		
		}
		TMS34010_timer[cpu] = timer_set(cpu_getscanlinetime(data), cpu, TMS34010_io_intcallback);	
		break;

	case REG_CONTROL:
		state.transparency = data & 0x20;
		state.window_checking = (data >> 6) & 0x03;
		set_raster_op();
		set_pixel_function();
		break;

	case REG_PSIZE:
		set_pixel_function();

		switch (data)
		{
		default:
		case 0x01: state.xytolshiftcount2 = 0; break;
		case 0x02: state.xytolshiftcount2 = 1; break;
		case 0x04: state.xytolshiftcount2 = 2; break;
		case 0x08: state.xytolshiftcount2 = 3; break;
		case 0x10: state.xytolshiftcount2 = 4; break;
		}
		break;

	case REG_PMASK:
		break;

	case REG_DPYCTL:
		set_pixel_function();
		break;

	case REG_HSTCTLH:
		if (data & 0x8000)
		{
			/* CPU is halting itself, stop execution right away */
			TMS34010_ICount = 0;
		}
		cpu_halt(cpu_getactivecpu(), !(data & 0x8000));

		if (data & 0x0100)
		{
			/* NMI issued */
			cpu_cause_interrupt(cpu_getactivecpu(), TMS34010_NMI);
		}
		break;

	case REG_CONVDP:
		state.xytolshiftcount1 = ~data & 0x0f;
		break;
	}

}

int TMS34010_io_register_r(int reg)
{
	reg >>=1;
	switch (reg)
	{
	case REG_VCOUNT:
		return cpu_getscanline();

	case REG_HCOUNT:
		return cpu_gethorzbeampos();
	}

	return IOREG(reg);
}

#define FINDCONTEXT(cpu, context)       \
	if (cpu_is_saving_context(cpu))     \
	{                                   \
		context = cpu_getcontext(cpu);  \
	}                                   \
	else                                \
	{                                   \
		context = &state;               \
	}                                   \


void TMS34010_set_stack_base(int cpu, UINT8* stackbase_p, UINT32 stackoffs_p)
{
	stackbase[cpu] = stackbase_p;		
	stackoffs[cpu] = stackoffs_p;			
}

void TMS34010_set_shiftreg_functions(int cpu,
									 void (*to_shiftreg_p  )(UINT32, UINT16*),
									 void (*from_shiftreg_p)(UINT32, UINT16*))
{
	to_shiftreg  [cpu] = to_shiftreg_p;		
	from_shiftreg[cpu] = from_shiftreg_p;		
}

int TMS34010_io_display_blanked(int cpu)
{
	TMS34010_Regs* context;
	FINDCONTEXT(cpu, context);
	return (!(context->IOregs[REG_DPYCTL] & 0x8000));
}

int TMS34010_get_DPYSTRT(int cpu)
{
	TMS34010_Regs* context;
	FINDCONTEXT(cpu, context);
	return context->IOregs[REG_DPYSTRT];
}

static void TMS34010_io_intcallback(int param)
{
	/* Reset timer for next frame */
	double interval = TIME_IN_HZ (Machine->drv->frames_per_second);
	TMS34010_timer[param] = timer_set(interval, param, TMS34010_io_intcallback);	
	cpu_cause_interrupt(param, TMS34010_DI);
}


void TMS34010_State_Save(int cpunum, void *f)
{
	TMS34010_Regs* context;
	FINDCONTEXT(cpunum, context);
	osd_fwrite(f,context,sizeof(state));
	osd_fwrite(f,&TMS34010_ICount,sizeof(TMS34010_ICount));
	osd_fwrite(f,state.shiftreg,sizeof(SHIFTREG_SIZE));
}

void TMS34010_State_Load(int cpunum, void *f)
{
	/* Don't reload the following */
	unsigned short* shiftreg_save = state.shiftreg;
	void (*to_shiftreg_save)  (UINT32, UINT16*) = state.to_shiftreg;
	void (*from_shiftreg_save)(UINT32, UINT16*) = state.from_shiftreg;

	TMS34010_Regs* context;
	FINDCONTEXT(cpunum, context);

	osd_fread(f,context,sizeof(state));
	osd_fread(f,&TMS34010_ICount,sizeof(TMS34010_ICount));
	change_pc29(PC);
	SET_FW();
	TMS34010_io_register_w(REG_DPYINT<<1,IOREG(REG_DPYINT));
	set_raster_op();
	set_pixel_function();

	state.shiftreg      = shiftreg_save;
	state.to_shiftreg   = to_shiftreg_save;
	state.from_shiftreg = from_shiftreg_save;

	osd_fread(f,state.shiftreg,sizeof(SHIFTREG_SIZE));
}


/* Host interface */
static TMS34010_Regs* slavecontext;			

void TMS34010_HSTADRL_w (int offset, int data)
{
	slavecontext = cpu_getcontext(CPU_SLAVE);

    SLAVE_IOREG(REG_HSTADRL) = data & 0xfff0;
}

void TMS34010_HSTADRH_w (int offset, int data)
{
	slavecontext = cpu_getcontext(CPU_SLAVE);

    SLAVE_IOREG(REG_HSTADRH) = data;
}

void TMS34010_HSTDATA_w (int offset, int data)
{
	unsigned int addr;

	memorycontextswap (CPU_SLAVE);				
												
	addr = (SLAVE_IOREG(REG_HSTADRH) << 16) | SLAVE_IOREG(REG_HSTADRL);

    TMS34010_WRMEM_WORD(TOBYTE(addr), data);

	/* Postincrement? */
	if (SLAVE_IOREG(REG_HSTCTLH) & 0x0800)
	{
		addr += 0x10;
		SLAVE_IOREG(REG_HSTADRH) = addr >> 16;
		SLAVE_IOREG(REG_HSTADRL) = (UINT16)addr;
	}
												
	memorycontextswap (CPU_MASTER);				
	change_pc29(PC);							
}

int  TMS34010_HSTDATA_r (int offset)
{
	unsigned int addr;
	int data;									
												
	memorycontextswap (CPU_SLAVE);				
												
	addr = (SLAVE_IOREG(REG_HSTADRH) << 16) | SLAVE_IOREG(REG_HSTADRL);

	/* Preincrement? */
	if (SLAVE_IOREG(REG_HSTCTLH) & 0x1000)
	{
		addr += 0x10;
		SLAVE_IOREG(REG_HSTADRH) = addr >> 16;
		SLAVE_IOREG(REG_HSTADRL) = (UINT16)addr;
	}
	
    data = TMS34010_RDMEM_WORD(TOBYTE(addr));
												
	memorycontextswap (CPU_MASTER);				
	change_pc29(PC);							
	 											
	return data;
}

void TMS34010_HSTCTLH_w (int offset, int data)
{
	slavecontext = cpu_getcontext(CPU_SLAVE);

    SLAVE_IOREG(REG_HSTCTLH) = data;

	cpu_halt(CPU_SLAVE, !(data & 0x8000));

	if (data & 0x0100)
	{
		/* Issue NMI */
		cpu_cause_interrupt(CPU_SLAVE, TMS34010_NMI);
	}
}

⌨️ 快捷键说明

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