📄 34010ops.c
字号:
/*** TMS34010: Portable TMS34010 emulator ************************************
Copyright (C) Alex Pasadyn/Zsolt Vasvari 1998
Opcodes
Most of the opcodes were painfully tested to produce the fastest
possible code on DJGPP. If you make any changes, please test for
performace. Even a trivial change such as reordering a couple of
lines can have a change in performance.
Most games seem to be especially sensitive to the XY instructions,
such as ADDXY and SUBXY.
*****************************************************************************/
/* clears flags */
#define CLR_V (V_FLAG = 0)
#define ZEXTEND(val,width) if (width) (val) &= ((UINT32)0xffffffff>>(32-(width)))
#define SEXTEND(val,width) if (width) \
{ \
(val) &= ((UINT32)0xffffffff>>(32-(width))); \
(val) |= (((val)&(1<<((width)-1)))?((0xffffffff)<<(width)):0); \
}
#define SET_Z(val) (NOTZ_FLAG = (val))
#define SET_N(val) (N_FLAG = SIGN(val))
#define SET_NZ(val) {SET_Z(val); SET_N(NOTZ_FLAG);}
#define SET_V_SUB(a,b,r) (V_FLAG = SIGN( ((a)^(b))&((a)^(r))))
#define SET_V_ADD(a,b,r) (V_FLAG = SIGN(~((a)^(b))&((a)^(r))))
#define SET_C_SUB(a,b) (C_FLAG = (((UINT32) (b)) >((UINT32)(a))))
#define SET_C_ADD(a,b) (C_FLAG = (((UINT32)(~(a)))<((UINT32)(b))))
#define SET_NZV_SUB(a,b,r) {SET_NZ(r);SET_V_SUB(a,b,r);}
#define SET_NZCV_SUB(a,b,r) {SET_NZV_SUB(a,b,r);SET_C_SUB(a,b);}
#define SET_NZCV_ADD(a,b,r) {SET_NZ(r);SET_V_ADD(a,b,r);SET_C_ADD(a,b);}
/* XY manipulation macros */
#define GET_X(val) ((INT16) (val))
#define GET_Y(val) ((INT16)((val) >> 16))
#define COMBINE_XY(x,y) (((UINT32)((UINT16)(x))) | (((UINT16)(y)) << 16))
#define XYTOL(val) ((((INT32)((UINT16)GET_Y(val)) <<state.xytolshiftcount1) | \
(((INT32)((UINT16)GET_X(val)))<<state.xytolshiftcount2)) + OFFSET)
static void unimpl(void)
{
PUSH(PC);
PUSH(GET_ST());
RESET_ST();
PC = RLONG(0xfffffc20);
}
/* Graphics Instructions */
static void adjust_xy_to_window(void)
{
/* Window clipping mode 3 */
INT16 sx, sy, ex, ey;
INT16 wsx,wsy,wex,wey;
INT16 csx,csy,cex,cey;
sx = GET_X(DADDR);
sy = GET_Y(DADDR);
ex = sx + GET_X(DYDX);
ey = sy + GET_Y(DYDX);
wsx = GET_X(WSTART);
wsy = GET_Y(WSTART);
wex = GET_X(WEND) + 1;
wey = GET_Y(WEND) + 1;
csx = (sx >= wsx) ? sx : wsx;
csy = (sy >= wsy) ? sy : wsy;
cex = (ex <= wex) ? ex : wex;
cey = (ey <= wey) ? ey : wey;
DADDR = COMBINE_XY(csx, csy);
DYDX = COMBINE_XY(cex - csx, cey - csy);
}
static void pixblt_b_l(void)
{
UINT32 boundary;
if (!P_FLAG)
{
P_FLAG = 1;
BREG(10<<4) = (UINT16)GET_X(DYDX);
BREG(11<<4) = (UINT16)GET_Y(DYDX);
BREG(12<<4) = DADDR;
BREG(13<<4) = SADDR;
}
do {
boundary = WPIXEL(DADDR, (rfield_z_01(SADDR) ? COLOR1 : COLOR0));
if (--BREG(10<<4))
{
DADDR += IOREG(REG_PSIZE);
SADDR++;
}
else
{
if (!--BREG(11<<4))
{
FINISH_PIX_OP;
return;
}
BREG(10<<4) = GET_X(DYDX);
DADDR = BREG(12<<4) = BREG(12<<4) + DPTCH;
SADDR = BREG(13<<4) = BREG(13<<4) + SPTCH;
}
}
while (!boundary);
PC -= 0x10;
}
static void pixblt_b_xy(void)
{
UINT32 boundary;
INT16 x,y;
if (!P_FLAG)
{
P_FLAG = 1;
BREG(10<<4) = (UINT16)GET_X(DYDX);
BREG(11<<4) = (UINT16)GET_Y(DYDX);
BREG(12<<4) = DADDR;
BREG(13<<4) = SADDR;
}
do {
boundary = WPIXEL(XYTOL(DADDR), (rfield_z_01(SADDR) ? COLOR1 : COLOR0));
if (--BREG(10<<4))
{
x = GET_X(DADDR) + 1;
y = GET_Y(DADDR);
DADDR = COMBINE_XY(x,y);
SADDR++;
}
else
{
if (!--BREG(11<<4))
{
FINISH_PIX_OP;
return;
}
BREG(10<<4) = GET_X(DYDX);
x = GET_X(BREG(12<<4));
y = GET_Y(BREG(12<<4)) + 1;
DADDR = BREG(12<<4) = COMBINE_XY(x,y);
SADDR = BREG(13<<4) = BREG(13<<4) + SPTCH;
}
}
while (!boundary);
PC -= 0x10;
}
static void pixblt_l_l(void)
{
UINT32 boundary;
if (!P_FLAG)
{
P_FLAG = 1;
BREG(14<<4) = IOREG(REG_PSIZE);
if (PBH)
{
BREG(14<<4) = -BREG(14<<4);
DADDR += BREG(14<<4);
SADDR += BREG(14<<4);
}
BREG(10<<4) = (UINT16)GET_X(DYDX);
BREG(11<<4) = (UINT16)GET_Y(DYDX);
BREG(12<<4) = DADDR;
BREG(13<<4) = SADDR;
}
do {
boundary = WPIXEL(DADDR,RPIXEL(SADDR));
if (--BREG(10<<4))
{
DADDR += BREG(14<<4);
SADDR += BREG(14<<4);
}
else
{
if (!--BREG(11<<4))
{
FINISH_PIX_OP;
return;
}
BREG(10<<4) = GET_X(DYDX);
if (PBV)
{
DADDR = BREG(12<<4) = BREG(12<<4) - DPTCH;
SADDR = BREG(13<<4) = BREG(13<<4) - SPTCH;
}
else
{
DADDR = BREG(12<<4) = BREG(12<<4) + DPTCH;
SADDR = BREG(13<<4) = BREG(13<<4) + SPTCH;
}
}
}
while (!boundary);
PC -= 0x10;
}
static void pixblt_l_xy(void)
{
UINT32 boundary;
INT16 x,y;
if (!P_FLAG)
{
P_FLAG = 1;
BREG(10<<4) = (UINT16)GET_X(DYDX);
BREG(11<<4) = (UINT16)GET_Y(DYDX);
BREG(12<<4) = DADDR;
BREG(13<<4) = SADDR;
}
do {
boundary = WPIXEL(XYTOL(DADDR),RPIXEL(SADDR));
if (--BREG(10<<4))
{
x = GET_X(DADDR) + 1;
y = GET_Y(DADDR);
DADDR = COMBINE_XY(x,y);
SADDR += IOREG(REG_PSIZE);
}
else
{
if (!--BREG(11<<4))
{
FINISH_PIX_OP;
return;
}
BREG(10<<4) = GET_X(DYDX);
x = GET_X(BREG(12<<4));
y = GET_Y(BREG(12<<4)) + 1;
DADDR = BREG(12<<4) = COMBINE_XY(x,y);
SADDR = BREG(13<<4) = BREG(13<<4) + SPTCH;
}
}
while (!boundary);
PC -= 0x10;
}
static void pixblt_xy_l(void)
{
UINT32 boundary;
INT16 x,y;
if (!P_FLAG)
{
P_FLAG = 1;
BREG(10<<4) = (UINT16)GET_X(DYDX);
BREG(11<<4) = (UINT16)GET_Y(DYDX);
BREG(12<<4) = DADDR;
BREG(13<<4) = SADDR;
}
do {
boundary = WPIXEL(DADDR,RPIXEL(XYTOL(SADDR)));
if (--BREG(10<<4))
{
DADDR += IOREG(REG_PSIZE);
x = GET_X(SADDR) + 1;
y = GET_Y(SADDR);
SADDR = COMBINE_XY(x,y);
}
else
{
if (!--BREG(11<<4))
{
FINISH_PIX_OP;
return;
}
BREG(10<<4) = GET_X(DYDX);
DADDR = BREG(12<<4) = BREG(12<<4) + DPTCH;
x = GET_X(BREG(13<<4));
y = GET_Y(BREG(13<<4)) + 1;
SADDR = BREG(13<<4) = COMBINE_XY(x,y);
}
}
while (!boundary);
PC -= 0x10;
}
static void pixblt_xy_xy(void)
{
UINT32 boundary;
INT16 x,y;
if (!P_FLAG)
{
P_FLAG = 1;
BREG(10<<4) = (UINT16)GET_X(DYDX);
BREG(11<<4) = (UINT16)GET_Y(DYDX);
BREG(12<<4) = DADDR;
BREG(13<<4) = SADDR;
}
do {
boundary = WPIXEL(XYTOL(DADDR),RPIXEL(XYTOL(SADDR)));
if (--BREG(10<<4))
{
x = GET_X(DADDR) + 1;
y = GET_Y(DADDR);
DADDR = COMBINE_XY(x,y);
x = GET_X(SADDR) + 1;
y = GET_Y(SADDR);
SADDR = COMBINE_XY(x,y);
}
else
{
if (!--BREG(11<<4))
{
FINISH_PIX_OP;
return;
}
BREG(10<<4) = GET_X(DYDX);
x = GET_X(BREG(12<<4));
y = GET_Y(BREG(12<<4)) + 1;
DADDR = BREG(12<<4) = COMBINE_XY(x,y);
x = GET_X(BREG(13<<4));
y = GET_Y(BREG(13<<4)) + 1;
SADDR = BREG(13<<4) = COMBINE_XY(x,y);
}
}
while (!boundary);
PC -= 0x10;
}
static void fill_l(void)
{
UINT32 boundary;
if (!P_FLAG)
{
P_FLAG = 1;
BREG(10<<4) = (UINT16)GET_X(DYDX);
BREG(11<<4) = (UINT16)GET_Y(DYDX);
BREG(12<<4) = DADDR;
}
do {
boundary = WPIXEL(DADDR,COLOR1);
if (--BREG(10<<4))
{
DADDR += IOREG(REG_PSIZE);
}
else
{
if (!--BREG(11<<4))
{
FINISH_PIX_OP;
return;
}
BREG(10<<4) = GET_X(DYDX);
DADDR = BREG(12<<4) = BREG(12<<4) + DPTCH;
}
}
while (!boundary);
PC -= 0x10;
}
static void fill_xy(void)
{
UINT32 boundary;
INT16 x,y;
if (!P_FLAG)
{
switch (state.window_checking)
{
case 0: break;
case 3: adjust_xy_to_window(); break;
default:
break;
}
BREG(10<<4) = (UINT16)GET_X(DYDX);
BREG(11<<4) = (UINT16)GET_Y(DYDX);
BREG(12<<4) = DADDR;
if ((INT16)BREG(10<<4)<=0 ||
(INT16)BREG(11<<4)<=0)
{
return;
}
P_FLAG = 1;
}
do {
boundary = WPIXEL(XYTOL(DADDR),COLOR1);
if (--BREG(10<<4))
{
x = GET_X(DADDR) + 1;
y = GET_Y(DADDR);
DADDR = COMBINE_XY(x,y);
}
else
{
if (!--BREG(11<<4))
{
FINISH_PIX_OP;
return;
}
BREG(10<<4) = GET_X(DYDX);
x = GET_X(BREG(12<<4));
y = GET_Y(BREG(12<<4)) + 1;
DADDR = BREG(12<<4) = COMBINE_XY(x,y);
}
}
while (!boundary);
PC -= 0x10;
}
static void line(void)
{
UINT32 algorithm = state.op & 0x80;
P_FLAG = 1;
if (COUNT > 0)
{
INT16 x1,x2,y1,y2,newx,newy;
COUNT--;
WPIXEL(XYTOL(DADDR),COLOR1);
if (( algorithm && SADDR > 0 ) ||
(!algorithm && SADDR >= 0))
{
SADDR += GET_Y(DYDX)*2 - GET_X(DYDX)*2;
x1 = GET_X(INC1);
y1 = GET_Y(INC1);
}
else
{
SADDR += GET_Y(DYDX)*2;
x1 = GET_X(INC2);
y1 = GET_Y(INC2);
}
x2 = GET_X(DADDR);
y2 = GET_Y(DADDR);
newx = x1+x2;
newy = y1+y2;
DADDR = COMBINE_XY(newx,newy);
PC -= 0x10;
return;
}
FINISH_PIX_OP;
}
#define ADD_XY(R) \
{ \
INT32 *rs = &R##REG(R##SRCREG); \
INT32 *rd = &R##REG(R##DSTREG); \
INT16 x1 = GET_X(*rd); \
INT16 x2 = GET_X(*rs); \
INT16 y1 = GET_Y(*rd); \
INT16 y2 = GET_Y(*rs); \
INT16 newx = x1+x2; \
INT16 newy = y1+y2; \
N_FLAG = !newx; \
V_FLAG = (newx & 0x8000); \
NOTZ_FLAG = newy; \
C_FLAG = (newy & 0x8000); \
*rd = COMBINE_XY(newx,newy); \
}
static void add_xy_a(void) { ADD_XY(A); }
static void add_xy_b(void) { ADD_XY(B); }
#define SUB_XY(R) \
{ \
INT32 *rs = &R##REG(R##SRCREG); \
INT32 *rd = &R##REG(R##DSTREG); \
INT16 x1 = GET_X(*rd); \
INT16 x2 = GET_X(*rs); \
INT16 y1 = GET_Y(*rd); \
INT16 y2 = GET_Y(*rs); \
INT16 newx = x1-x2; \
INT16 newy = y1-y2; \
*rd = COMBINE_XY(newx,newy); \
N_FLAG = (x2 == x1); \
C_FLAG = (y2 > y1); \
NOTZ_FLAG = (y2 != y1); \
V_FLAG = (x2 > x1); \
}
static void sub_xy_a(void) { SUB_XY(A); }
static void sub_xy_b(void) { SUB_XY(B); }
#define CMP_XY(R) \
{ \
INT16 x1 = GET_X(R##REG(R##DSTREG)); \
INT16 y1 = GET_Y(R##REG(R##DSTREG)); \
INT16 x2 = GET_X(R##REG(R##SRCREG)); \
INT16 y2 = GET_Y(R##REG(R##SRCREG)); \
INT16 newx = x1-x2; \
INT16 newy = y1-y2; \
N_FLAG = !newx; \
NOTZ_FLAG = newy; \
V_FLAG = (newx & 0x8000); \
C_FLAG = (newy & 0x8000); \
}
static void cmp_xy_a(void) { CMP_XY(A); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -