📄 tms34010.c
字号:
{
/* ~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 + -