Add "*" symbol for current address in inline assembler
This commit is contained in:
parent
5ca651bc36
commit
60165a7fc3
|
@ -480,7 +480,7 @@ void bm_polygon_nc_fill(Bitmap * bm, ClipRect * clip, int * px, int * py, char n
|
||||||
#define REG_D0 0x0a
|
#define REG_D0 0x0a
|
||||||
#define REG_D1 0x0b
|
#define REG_D1 0x0b
|
||||||
|
|
||||||
static void buildline(char ly, char lx, int dx, int dy, int stride, bool left, bool up)
|
static void buildline(char ly, char lx, int dx, int dy, int stride, bool left, bool up, char pattern, LineOp op)
|
||||||
{
|
{
|
||||||
char ip = 0;
|
char ip = 0;
|
||||||
|
|
||||||
|
@ -491,14 +491,50 @@ static void buildline(char ly, char lx, int dx, int dy, int stride, bool left, b
|
||||||
// set pixel
|
// set pixel
|
||||||
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_D0);
|
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_D0);
|
||||||
|
|
||||||
ip += asm_zp(BLIT_CODE + ip, ASM_ASL, REG_PAT);
|
switch (op)
|
||||||
ip += asm_rl(BLIT_CODE + ip, ASM_BCC, 6);
|
{
|
||||||
ip += asm_zp(BLIT_CODE + ip, ASM_INC, REG_PAT);
|
case LINOP_SET:
|
||||||
ip += asm_iy(BLIT_CODE + ip, ASM_ORA, REG_SP);
|
ip += asm_zp(BLIT_CODE + ip, ASM_ASL, REG_PAT);
|
||||||
ip += asm_rl(BLIT_CODE + ip, ASM_BNE, 4);
|
ip += asm_rl(BLIT_CODE + ip, ASM_BCC, 6);
|
||||||
ip += asm_im(BLIT_CODE + ip, ASM_EOR, 0xff);
|
ip += asm_zp(BLIT_CODE + ip, ASM_INC, REG_PAT);
|
||||||
ip += asm_iy(BLIT_CODE + ip, ASM_AND, REG_SP);
|
ip += asm_iy(BLIT_CODE + ip, ASM_ORA, REG_SP);
|
||||||
ip += asm_iy(BLIT_CODE + ip, ASM_STA, REG_SP);
|
ip += asm_rl(BLIT_CODE + ip, ASM_BNE, 4);
|
||||||
|
ip += asm_im(BLIT_CODE + ip, ASM_EOR, 0xff);
|
||||||
|
ip += asm_iy(BLIT_CODE + ip, ASM_AND, REG_SP);
|
||||||
|
ip += asm_iy(BLIT_CODE + ip, ASM_STA, REG_SP);
|
||||||
|
break;
|
||||||
|
case LINOP_OR:
|
||||||
|
if (pattern != 0xff)
|
||||||
|
{
|
||||||
|
ip += asm_zp(BLIT_CODE + ip, ASM_ASL, REG_PAT);
|
||||||
|
ip += asm_rl(BLIT_CODE + ip, ASM_BCC, 6);
|
||||||
|
ip += asm_zp(BLIT_CODE + ip, ASM_INC, REG_PAT);
|
||||||
|
}
|
||||||
|
ip += asm_iy(BLIT_CODE + ip, ASM_ORA, REG_SP);
|
||||||
|
ip += asm_iy(BLIT_CODE + ip, ASM_STA, REG_SP);
|
||||||
|
break;
|
||||||
|
case LINOP_XOR:
|
||||||
|
if (pattern != 0xff)
|
||||||
|
{
|
||||||
|
ip += asm_zp(BLIT_CODE + ip, ASM_ASL, REG_PAT);
|
||||||
|
ip += asm_rl(BLIT_CODE + ip, ASM_BCC, 6);
|
||||||
|
ip += asm_zp(BLIT_CODE + ip, ASM_INC, REG_PAT);
|
||||||
|
}
|
||||||
|
ip += asm_iy(BLIT_CODE + ip, ASM_EOR, REG_SP);
|
||||||
|
ip += asm_iy(BLIT_CODE + ip, ASM_STA, REG_SP);
|
||||||
|
break;
|
||||||
|
case LINOP_AND:
|
||||||
|
if (pattern != 0xff)
|
||||||
|
{
|
||||||
|
ip += asm_zp(BLIT_CODE + ip, ASM_ASL, REG_PAT);
|
||||||
|
ip += asm_rl(BLIT_CODE + ip, ASM_BCC, 8);
|
||||||
|
ip += asm_zp(BLIT_CODE + ip, ASM_INC, REG_PAT);
|
||||||
|
}
|
||||||
|
ip += asm_im(BLIT_CODE + ip, ASM_EOR, 0xff);
|
||||||
|
ip += asm_iy(BLIT_CODE + ip, ASM_AND, REG_SP);
|
||||||
|
ip += asm_iy(BLIT_CODE + ip, ASM_STA, REG_SP);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// m >= 0
|
// m >= 0
|
||||||
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_DP + 1);
|
ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_DP + 1);
|
||||||
|
@ -587,8 +623,21 @@ static inline void callline(byte * dst, byte bit, int m, char lh, char pattern)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void bmu_line(Bitmap * bm, int x0, int y0, int x1, int y1, char pattern)
|
void bmu_line(Bitmap * bm, int x0, int y0, int x1, int y1, char pattern, LineOp op)
|
||||||
{
|
{
|
||||||
|
if (pattern == 0x00)
|
||||||
|
{
|
||||||
|
if (op == LINOP_SET)
|
||||||
|
{
|
||||||
|
pattern = 0xff;
|
||||||
|
op = LINOP_AND;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (pattern == 0xff && op == LINOP_SET)
|
||||||
|
op = LINOP_OR;
|
||||||
|
|
||||||
int dx = x1 - x0, dy = y1 - y0;
|
int dx = x1 - x0, dy = y1 - y0;
|
||||||
byte quad = 0;
|
byte quad = 0;
|
||||||
if (dx < 0)
|
if (dx < 0)
|
||||||
|
@ -617,7 +666,7 @@ void bmu_line(Bitmap * bm, int x0, int y0, int x1, int y1, char pattern)
|
||||||
char ry = y0 & 7;
|
char ry = y0 & 7;
|
||||||
int stride = 8 * bm->cwidth;
|
int stride = 8 * bm->cwidth;
|
||||||
|
|
||||||
buildline(ry, (l + 1) & 0xff, dx, dy, (quad & 2) ? -stride : stride, quad & 1, quad & 2);
|
buildline(ry, (l + 1) & 0xff, dx, dy, (quad & 2) ? -stride : stride, quad & 1, quad & 2, pattern, op);
|
||||||
|
|
||||||
callline(dp, bit, m, l >> 8, pattern);
|
callline(dp, bit, m, l >> 8, pattern);
|
||||||
}
|
}
|
||||||
|
@ -627,7 +676,7 @@ static int muldiv(int x, int mul, int div)
|
||||||
return (int)((long)x * mul / div);
|
return (int)((long)x * mul / div);
|
||||||
}
|
}
|
||||||
|
|
||||||
void bm_line(Bitmap * bm, ClipRect * clip, int x0, int y0, int x1, int y1, char pattern)
|
void bm_line(Bitmap * bm, ClipRect * clip, int x0, int y0, int x1, int y1, char pattern, LineOp op)
|
||||||
{
|
{
|
||||||
int dx = x1 - x0, dy = y1 - y0;
|
int dx = x1 - x0, dy = y1 - y0;
|
||||||
|
|
||||||
|
@ -711,7 +760,7 @@ void bm_line(Bitmap * bm, ClipRect * clip, int x0, int y0, int x1, int y1, char
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bmu_line(bm, x0, y0, x1, y1, pattern);
|
bmu_line(bm, x0, y0, x1, y1, pattern, op);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void callddop(byte * src, byte * dst, byte pat)
|
static inline void callddop(byte * src, byte * dst, byte pat)
|
||||||
|
|
|
@ -48,6 +48,14 @@ enum BlitOp
|
||||||
BLTOP_PATTERN_AND_SRC = BLIT_SRC | BLIT_PATTERN | BLIT_AND
|
BLTOP_PATTERN_AND_SRC = BLIT_SRC | BLIT_PATTERN | BLIT_AND
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum LineOp
|
||||||
|
{
|
||||||
|
LINOP_SET,
|
||||||
|
LINOP_OR,
|
||||||
|
LINOP_AND,
|
||||||
|
LINOP_XOR
|
||||||
|
};
|
||||||
|
|
||||||
extern char NineShadesOfGrey[9][8];
|
extern char NineShadesOfGrey[9][8];
|
||||||
|
|
||||||
// Fast unsigned integer square root
|
// Fast unsigned integer square root
|
||||||
|
@ -102,10 +110,10 @@ inline bool bm_get(Bitmap * bm, int x, int y);
|
||||||
inline void bm_put(Bitmap * bm, int x, int y, bool c);
|
inline void bm_put(Bitmap * bm, int x, int y, bool c);
|
||||||
|
|
||||||
// Draw an unclipped line using an eight bit pattern
|
// Draw an unclipped line using an eight bit pattern
|
||||||
void bmu_line(Bitmap * bm, int x0, int y0, int x1, int y1, char pattern);
|
void bmu_line(Bitmap * bm, int x0, int y0, int x1, int y1, char pattern, LineOp op);
|
||||||
|
|
||||||
// Draw a clipped line using an eight bit pattern
|
// Draw a clipped line using an eight bit pattern
|
||||||
void bm_line(Bitmap * bm, ClipRect * clip, int x0, int y0, int x1, int y1, char pattern);
|
void bm_line(Bitmap * bm, ClipRect * clip, int x0, int y0, int x1, int y1, char pattern, LineOp op);
|
||||||
|
|
||||||
// Unclipped bit blit
|
// Unclipped bit blit
|
||||||
void bmu_bitblit(Bitmap * dbm, int dx, int dy, Bitmap * sbm, int sx, int sy, int w, int h, const char * pattern, BlitOp op);
|
void bmu_bitblit(Bitmap * dbm, int dx, int dy, Bitmap * sbm, int sx, int sy, int w, int h, const char * pattern, BlitOp op);
|
||||||
|
|
|
@ -546,7 +546,17 @@ void InterCodeGenerator::TranslateAssembler(InterCodeModule* mod, Expression* ex
|
||||||
if (!aexp)
|
if (!aexp)
|
||||||
mErrors->Error(cexp->mLocation, EERR_ASM_INVALD_OPERAND, "Missing assembler operand");
|
mErrors->Error(cexp->mLocation, EERR_ASM_INVALD_OPERAND, "Missing assembler operand");
|
||||||
else
|
else
|
||||||
d[offset] = aexp->mInteger - offset - 1;
|
{
|
||||||
|
if (aexp->mType == DT_LABEL_REF)
|
||||||
|
{
|
||||||
|
if (aexp->mBase->mBase)
|
||||||
|
d[offset] = aexp->mOffset + aexp->mBase->mInteger - offset - 1;
|
||||||
|
else
|
||||||
|
mErrors->Error(aexp->mLocation, EERR_ASM_INVALD_OPERAND, "Undefined immediate operand", aexp->mBase->mIdent->mString);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
d[offset] = aexp->mInteger - offset - 1;
|
||||||
|
}
|
||||||
offset++;
|
offset++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -11683,6 +11683,49 @@ bool NativeCodeBasicBlock::OptimizeInnerLoops(NativeCodeProcedure* proc)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool NativeCodeBasicBlock::OptimizeSelect(NativeCodeProcedure* proc)
|
||||||
|
{
|
||||||
|
bool changed = false;
|
||||||
|
|
||||||
|
if (!mVisited)
|
||||||
|
{
|
||||||
|
mVisited = true;
|
||||||
|
|
||||||
|
if (mFalseJump && mIns.Size() > 0 && mIns.Last().ChangesAccuAndFlag() &&
|
||||||
|
mTrueJump->mIns.Size() == 1 && mFalseJump->mIns.Size() == 1 &&
|
||||||
|
!mTrueJump->mFalseJump && !mFalseJump->mFalseJump && mTrueJump->mTrueJump == mFalseJump->mTrueJump &&
|
||||||
|
mTrueJump->mIns[0].mType == ASMIT_LDA && mTrueJump->mIns[0].mMode == ASMIM_IMMEDIATE &&
|
||||||
|
mFalseJump->mIns[0].mType == ASMIT_LDA && mFalseJump->mIns[0].mMode == ASMIM_IMMEDIATE)
|
||||||
|
{
|
||||||
|
if (mBranch == ASMIT_BNE || mBranch == ASMIT_BEQ)
|
||||||
|
{
|
||||||
|
char vt = mTrueJump->mIns[0].mAddress, vf = mFalseJump->mIns[0].mAddress;
|
||||||
|
mTrueJump = mTrueJump->mTrueJump;
|
||||||
|
mFalseJump = nullptr;
|
||||||
|
|
||||||
|
if (mBranch == ASMIT_BEQ)
|
||||||
|
{
|
||||||
|
char t = vt; vt = vf; vf = t;
|
||||||
|
}
|
||||||
|
|
||||||
|
mIns.Push(NativeCodeInstruction(ASMIT_CMP, ASMIM_IMMEDIATE, 1));
|
||||||
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, 0));
|
||||||
|
mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_IMMEDIATE, 0xff));
|
||||||
|
mIns.Push(NativeCodeInstruction(ASMIT_AND, ASMIM_IMMEDIATE, vt ^ vf));
|
||||||
|
mIns.Push(NativeCodeInstruction(ASMIT_EOR, ASMIM_IMMEDIATE, vt));
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mTrueJump && mTrueJump->OptimizeSelect(proc))
|
||||||
|
changed = true;
|
||||||
|
if (mFalseJump && mFalseJump->OptimizeSelect(proc))
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
// Size reduction violating various assumptions such as no branches in basic blocks
|
// Size reduction violating various assumptions such as no branches in basic blocks
|
||||||
// must be last step before actual assembly
|
// must be last step before actual assembly
|
||||||
|
|
||||||
|
@ -11931,6 +11974,33 @@ void NativeCodeBasicBlock::BlockSizeReduction(void)
|
||||||
j += 2;
|
j += 2;
|
||||||
i += 3;
|
i += 3;
|
||||||
}
|
}
|
||||||
|
else if (i + 5 < mIns.Size() &&
|
||||||
|
mIns[i + 0].mType == ASMIT_LDA &&
|
||||||
|
mIns[i + 1].mType == ASMIT_CMP && mIns[i + 1].mMode == ASMIM_IMMEDIATE && mIns[i + 1].mAddress == 0x01 &&
|
||||||
|
mIns[i + 2].mType == ASMIT_LDA && mIns[i + 2].mMode == ASMIM_IMMEDIATE && mIns[i + 2].mAddress == 0x00 &&
|
||||||
|
mIns[i + 3].mType == ASMIT_ADC && mIns[i + 3].mMode == ASMIM_IMMEDIATE && mIns[i + 3].mAddress == 0xff &&
|
||||||
|
mIns[i + 4].mType == ASMIT_AND && mIns[i + 4].mMode == ASMIM_IMMEDIATE &&
|
||||||
|
mIns[i + 5].mType == ASMIT_EOR && mIns[i + 5].mMode == ASMIM_IMMEDIATE)
|
||||||
|
{
|
||||||
|
char veq = mIns[i + 4].mAddress ^ mIns[i + 5].mAddress, vne = mIns[i + 5].mAddress;
|
||||||
|
|
||||||
|
mIns[j + 0] = mIns[i + 0];
|
||||||
|
mIns[j + 1].mType = ASMIT_BEQ; mIns[j + 1].mMode = ASMIM_RELATIVE; mIns[j + 1].mAddress = veq != 0 ? 4 : 2;
|
||||||
|
mIns[j + 2].mType = ASMIT_LDA; mIns[j + 2].mMode = ASMIM_IMMEDIATE; mIns[j + 2].mAddress = vne; mIns[j + 2].mFlags = 0;
|
||||||
|
j += 3;
|
||||||
|
if (veq != 0)
|
||||||
|
{
|
||||||
|
if (vne)
|
||||||
|
mIns[j + 0].mType = ASMIT_BNE;
|
||||||
|
else
|
||||||
|
mIns[j + 0].mType = ASMIT_BEQ;
|
||||||
|
mIns[j + 0].mMode = ASMIM_RELATIVE;
|
||||||
|
mIns[j + 0].mAddress = 2;
|
||||||
|
mIns[j + 1].mType = ASMIT_LDA; mIns[j + 1].mMode = ASMIM_IMMEDIATE; mIns[j + 1].mAddress = veq; mIns[j + 1].mFlags = 0;
|
||||||
|
j += 2;
|
||||||
|
}
|
||||||
|
i += 6;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
mIns[j++] = mIns[i++];
|
mIns[j++] = mIns[i++];
|
||||||
}
|
}
|
||||||
|
@ -12480,6 +12550,92 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
// move iny/dey/inx/dex down
|
||||||
|
|
||||||
|
for (int i = 0; i + 1 < mIns.Size(); i++)
|
||||||
|
{
|
||||||
|
if ((mIns[i].mType == ASMIT_INY || mIns[i].mType == ASMIT_DEY) && !mIns[i + 1].ChangesYReg() && !(mIns[i + 1].mLive & LIVE_CPU_REG_Z))
|
||||||
|
{
|
||||||
|
if (!mIns[i + 1].RequiresYReg())
|
||||||
|
{
|
||||||
|
NativeCodeInstruction pins = mIns[i];
|
||||||
|
mIns[i] = mIns[i + 1];
|
||||||
|
mIns[i + 1] = pins;
|
||||||
|
}
|
||||||
|
else if (mIns[i + 1].mMode == ASMIM_ABSOLUTE_Y)
|
||||||
|
{
|
||||||
|
if (mIns[i].mType == ASMIT_INY)
|
||||||
|
mIns[i + 1].mAddress++;
|
||||||
|
else
|
||||||
|
mIns[i + 1].mAddress--;
|
||||||
|
NativeCodeInstruction pins = mIns[i];
|
||||||
|
mIns[i] = mIns[i + 1];
|
||||||
|
mIns[i + 1] = pins;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ((mIns[i].mType == ASMIT_INX || mIns[i].mType == ASMIT_DEX) && !mIns[i + 1].ChangesXReg() && !(mIns[i + 1].mLive & LIVE_CPU_REG_Z))
|
||||||
|
{
|
||||||
|
if (!mIns[i + 1].RequiresXReg())
|
||||||
|
{
|
||||||
|
NativeCodeInstruction pins = mIns[i];
|
||||||
|
mIns[i] = mIns[i + 1];
|
||||||
|
mIns[i + 1] = pins;
|
||||||
|
}
|
||||||
|
else if (mIns[i + 1].mMode == ASMIM_ABSOLUTE_X)
|
||||||
|
{
|
||||||
|
if (mIns[i].mType == ASMIT_INX)
|
||||||
|
mIns[i + 1].mAddress++;
|
||||||
|
else
|
||||||
|
mIns[i + 1].mAddress--;
|
||||||
|
NativeCodeInstruction pins = mIns[i];
|
||||||
|
mIns[i] = mIns[i + 1];
|
||||||
|
mIns[i + 1] = pins;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if 1
|
||||||
|
// move tya/clc/adc/tay down
|
||||||
|
for (int i = 0; i + 5 < mIns.Size(); i++)
|
||||||
|
{
|
||||||
|
if (mIns[i + 0].mType == ASMIT_TYA && mIns[i + 1].mType == ASMIT_CLC && mIns[i + 2].mType == ASMIT_ADC && mIns[i + 2].mMode == ASMIM_IMMEDIATE && mIns[i + 3].mType == ASMIT_TAY && !(mIns[i + 3].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_C)))
|
||||||
|
{
|
||||||
|
if (mIns[i + 4].mType == ASMIT_LDA && (mIns[i + 4].mMode == ASMIM_IMMEDIATE || mIns[i + 4].mMode == ASMIM_IMMEDIATE_ADDRESS || mIns[i + 4].mMode == ASMIM_ZERO_PAGE) &&
|
||||||
|
mIns[i + 5].mType == ASMIT_STA && !(mIns[i + 5].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_Z)))
|
||||||
|
{
|
||||||
|
mIns[i + 4].mLive |= LIVE_CPU_REG_Y;
|
||||||
|
mIns[i + 5].mLive |= LIVE_CPU_REG_Y;
|
||||||
|
if (mIns[i + 5].mMode == ASMIM_ABSOLUTE_Y)
|
||||||
|
mIns[i + 5].mAddress += mIns[i + 2].mAddress;
|
||||||
|
|
||||||
|
mIns.Insert(i + 0, mIns[i + 4]); mIns.Remove(i + 5);
|
||||||
|
mIns.Insert(i + 1, mIns[i + 5]); mIns.Remove(i + 6);
|
||||||
|
}
|
||||||
|
#if 1
|
||||||
|
else if (i + 6 < mIns.Size() &&
|
||||||
|
mIns[i + 4].mType == ASMIT_LDA && (mIns[i + 4].mMode == ASMIM_IMMEDIATE || mIns[i + 4].mMode == ASMIM_IMMEDIATE_ADDRESS || mIns[i + 4].mMode == ASMIM_ZERO_PAGE) &&
|
||||||
|
mIns[i + 5].mType == ASMIT_STA &&
|
||||||
|
mIns[i + 6].mType == ASMIT_STA && !(mIns[i + 6].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_Z)))
|
||||||
|
{
|
||||||
|
mIns[i + 4].mLive |= LIVE_CPU_REG_Y;
|
||||||
|
mIns[i + 5].mLive |= LIVE_CPU_REG_Y;
|
||||||
|
mIns[i + 6].mLive |= LIVE_CPU_REG_Y;
|
||||||
|
if (mIns[i + 5].mMode == ASMIM_ABSOLUTE_Y)
|
||||||
|
mIns[i + 5].mAddress += mIns[i + 2].mAddress;
|
||||||
|
if (mIns[i + 6].mMode == ASMIM_ABSOLUTE_Y)
|
||||||
|
mIns[i + 6].mAddress += mIns[i + 2].mAddress;
|
||||||
|
|
||||||
|
mIns.Insert(i + 0, mIns[i + 4]); mIns.Remove(i + 5);
|
||||||
|
mIns.Insert(i + 1, mIns[i + 5]); mIns.Remove(i + 6);
|
||||||
|
mIns.Insert(i + 2, mIns[i + 6]); mIns.Remove(i + 7);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
|
|
||||||
// reverse "sta t,lda abs,clc,adc t" to "sta t,clc,adc abs,nop"
|
// reverse "sta t,lda abs,clc,adc t" to "sta t,clc,adc abs,nop"
|
||||||
|
@ -14438,6 +14594,83 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (i + 3 < mIns.Size())
|
||||||
|
{
|
||||||
|
if (
|
||||||
|
mIns[i + 0].mType == ASMIT_INY &&
|
||||||
|
mIns[i + 1].mType == ASMIT_TYA &&
|
||||||
|
mIns[i + 2].mType == ASMIT_CLC &&
|
||||||
|
mIns[i + 3].mType == ASMIT_ADC && mIns[i + 3].mMode == ASMIM_IMMEDIATE && !(mIns[i + 3].mLive & (LIVE_CPU_REG_Y | LIVE_CPU_REG_C)))
|
||||||
|
{
|
||||||
|
mIns[i + 0].mType = ASMIT_NOP;
|
||||||
|
mIns[i + 3].mAddress++;
|
||||||
|
progress = true;
|
||||||
|
}
|
||||||
|
else if (
|
||||||
|
mIns[i + 0].mType == ASMIT_CLC &&
|
||||||
|
mIns[i + 1].mType == ASMIT_ADC && mIns[i + 1].mMode == ASMIM_IMMEDIATE &&
|
||||||
|
mIns[i + 2].mType == ASMIT_TAY &&
|
||||||
|
mIns[i + 3].mType == ASMIT_INY && !(mIns[i + 3].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_C)))
|
||||||
|
{
|
||||||
|
mIns[i + 1].mAddress++;
|
||||||
|
mIns[i + 3].mType = ASMIT_NOP;
|
||||||
|
progress = true;
|
||||||
|
}
|
||||||
|
else if (
|
||||||
|
mIns[i + 0].mType == ASMIT_INX &&
|
||||||
|
mIns[i + 1].mType == ASMIT_TXA &&
|
||||||
|
mIns[i + 2].mType == ASMIT_CLC &&
|
||||||
|
mIns[i + 3].mType == ASMIT_ADC && mIns[i + 3].mMode == ASMIM_IMMEDIATE && !(mIns[i + 3].mLive & (LIVE_CPU_REG_X | LIVE_CPU_REG_C)))
|
||||||
|
{
|
||||||
|
mIns[i + 0].mType = ASMIT_NOP;
|
||||||
|
mIns[i + 3].mAddress++;
|
||||||
|
progress = true;
|
||||||
|
}
|
||||||
|
else if (
|
||||||
|
mIns[i + 0].mType == ASMIT_CLC &&
|
||||||
|
mIns[i + 1].mType == ASMIT_ADC && mIns[i + 1].mMode == ASMIM_IMMEDIATE &&
|
||||||
|
mIns[i + 2].mType == ASMIT_TAX &&
|
||||||
|
mIns[i + 3].mType == ASMIT_INX && !(mIns[i + 3].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_C)))
|
||||||
|
{
|
||||||
|
mIns[i + 1].mAddress++;
|
||||||
|
mIns[i + 3].mType = ASMIT_NOP;
|
||||||
|
progress = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#if 1
|
||||||
|
if (pass > 2 && i + 4 < mIns.Size())
|
||||||
|
{
|
||||||
|
if (
|
||||||
|
mIns[i + 0].mType == ASMIT_INY &&
|
||||||
|
mIns[i + 1].mType == ASMIT_INY &&
|
||||||
|
mIns[i + 2].mType == ASMIT_INY &&
|
||||||
|
mIns[i + 3].mType == ASMIT_INY &&
|
||||||
|
mIns[i + 4].mType == ASMIT_INY && !(mIns[i + 4].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_C)))
|
||||||
|
{
|
||||||
|
mIns[i + 0].mType = ASMIT_TYA; mIns[i + 0].mLive |= LIVE_CPU_REG_A;
|
||||||
|
mIns[i + 1].mType = ASMIT_CLC; mIns[i + 1].mLive |= LIVE_CPU_REG_A;
|
||||||
|
mIns[i + 2].mType = ASMIT_ADC; mIns[i + 2].mMode = ASMIM_IMMEDIATE; mIns[i + 2].mAddress = 5; mIns[i + 2].mLive |= LIVE_CPU_REG_A;
|
||||||
|
mIns[i + 3].mType = ASMIT_TAY;
|
||||||
|
mIns[i + 4].mType = ASMIT_NOP;
|
||||||
|
progress = true;
|
||||||
|
}
|
||||||
|
else if (
|
||||||
|
mIns[i + 0].mType == ASMIT_INX &&
|
||||||
|
mIns[i + 1].mType == ASMIT_INX &&
|
||||||
|
mIns[i + 2].mType == ASMIT_INX &&
|
||||||
|
mIns[i + 3].mType == ASMIT_INX &&
|
||||||
|
mIns[i + 4].mType == ASMIT_INX && !(mIns[i + 4].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_C)))
|
||||||
|
{
|
||||||
|
mIns[i + 0].mType = ASMIT_TXA; mIns[i + 0].mLive |= LIVE_CPU_REG_A;
|
||||||
|
mIns[i + 1].mType = ASMIT_CLC; mIns[i + 1].mLive |= LIVE_CPU_REG_A;
|
||||||
|
mIns[i + 2].mType = ASMIT_ADC; mIns[i + 2].mMode = ASMIM_IMMEDIATE; mIns[i + 2].mAddress = 5; mIns[i + 2].mLive |= LIVE_CPU_REG_A;
|
||||||
|
mIns[i + 3].mType = ASMIT_TAX;
|
||||||
|
mIns[i + 4].mType = ASMIT_NOP;
|
||||||
|
progress = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
if (i + 5 < mIns.Size())
|
if (i + 5 < mIns.Size())
|
||||||
{
|
{
|
||||||
if (
|
if (
|
||||||
|
@ -15602,6 +15835,12 @@ void NativeCodeProcedure::Optimize(void)
|
||||||
#endif
|
#endif
|
||||||
#if 1
|
#if 1
|
||||||
|
|
||||||
|
ResetVisited();
|
||||||
|
if (mEntryBlock->OptimizeSelect(this))
|
||||||
|
{
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (step > 0)
|
if (step > 0)
|
||||||
{
|
{
|
||||||
ResetVisited();
|
ResetVisited();
|
||||||
|
|
|
@ -151,6 +151,8 @@ public:
|
||||||
bool SimpleLoopReversal(NativeCodeProcedure* proc);
|
bool SimpleLoopReversal(NativeCodeProcedure* proc);
|
||||||
bool OptimizeInnerLoop(NativeCodeProcedure* proc, NativeCodeBasicBlock* head, NativeCodeBasicBlock* tail, GrowingArray<NativeCodeBasicBlock*>& blocks);
|
bool OptimizeInnerLoop(NativeCodeProcedure* proc, NativeCodeBasicBlock* head, NativeCodeBasicBlock* tail, GrowingArray<NativeCodeBasicBlock*>& blocks);
|
||||||
|
|
||||||
|
bool OptimizeSelect(NativeCodeProcedure* proc);
|
||||||
|
|
||||||
NativeCodeBasicBlock* FindTailBlock(NativeCodeBasicBlock* head);
|
NativeCodeBasicBlock* FindTailBlock(NativeCodeBasicBlock* head);
|
||||||
bool OptimizeInnerLoops(NativeCodeProcedure* proc);
|
bool OptimizeInnerLoops(NativeCodeProcedure* proc);
|
||||||
void CollectInnerLoop(NativeCodeBasicBlock* head, GrowingArray<NativeCodeBasicBlock*>& lblocks);
|
void CollectInnerLoop(NativeCodeBasicBlock* head, GrowingArray<NativeCodeBasicBlock*>& lblocks);
|
||||||
|
|
|
@ -2194,7 +2194,7 @@ Expression* Parser::ParseSwitchStatement(void)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Expression* Parser::ParseAssemblerBaseOperand(void)
|
Expression* Parser::ParseAssemblerBaseOperand(Declaration* pcasm, int pcoffset)
|
||||||
{
|
{
|
||||||
Expression* exp = nullptr;
|
Expression* exp = nullptr;
|
||||||
Declaration* dec;
|
Declaration* dec;
|
||||||
|
@ -2203,7 +2203,7 @@ Expression* Parser::ParseAssemblerBaseOperand(void)
|
||||||
{
|
{
|
||||||
case TK_SUB:
|
case TK_SUB:
|
||||||
mScanner->NextToken();
|
mScanner->NextToken();
|
||||||
exp = ParseAssemblerBaseOperand();
|
exp = ParseAssemblerBaseOperand(pcasm, pcoffset);
|
||||||
if (exp->mType == EX_CONSTANT && exp->mDecValue->mType == DT_CONST_INTEGER)
|
if (exp->mType == EX_CONSTANT && exp->mDecValue->mType == DT_CONST_INTEGER)
|
||||||
{
|
{
|
||||||
dec = new Declaration(mScanner->mLocation, DT_CONST_INTEGER);
|
dec = new Declaration(mScanner->mLocation, DT_CONST_INTEGER);
|
||||||
|
@ -2220,6 +2220,16 @@ Expression* Parser::ParseAssemblerBaseOperand(void)
|
||||||
mErrors->Error(exp->mLocation, EERR_INCOMPATIBLE_OPERATOR, "Cannot negate expression");
|
mErrors->Error(exp->mLocation, EERR_INCOMPATIBLE_OPERATOR, "Cannot negate expression");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case TK_MUL:
|
||||||
|
mScanner->NextToken();
|
||||||
|
exp = new Expression(mScanner->mLocation, EX_CONSTANT);
|
||||||
|
dec = new Declaration(mScanner->mLocation, DT_LABEL);
|
||||||
|
exp->mDecType = TheUnsignedIntTypeDeclaration;
|
||||||
|
exp->mDecValue = dec;
|
||||||
|
dec->mInteger = pcoffset;
|
||||||
|
dec->mBase = pcasm;
|
||||||
|
break;
|
||||||
|
|
||||||
case TK_INTEGER:
|
case TK_INTEGER:
|
||||||
dec = new Declaration(mScanner->mLocation, DT_CONST_INTEGER);
|
dec = new Declaration(mScanner->mLocation, DT_CONST_INTEGER);
|
||||||
dec->mInteger = mScanner->mTokenInteger;
|
dec->mInteger = mScanner->mTokenInteger;
|
||||||
|
@ -2329,31 +2339,31 @@ Expression* Parser::ParseAssemblerBaseOperand(void)
|
||||||
return exp;
|
return exp;
|
||||||
}
|
}
|
||||||
|
|
||||||
Expression* Parser::ParseAssemblerMulOperand(void)
|
Expression* Parser::ParseAssemblerMulOperand(Declaration* pcasm, int pcoffset)
|
||||||
{
|
{
|
||||||
Expression* exp = ParseAssemblerBaseOperand();
|
Expression* exp = ParseAssemblerBaseOperand(pcasm, pcoffset);
|
||||||
while (mScanner->mToken == TK_MUL || mScanner->mToken == TK_DIV || mScanner->mToken == TK_MOD)
|
while (mScanner->mToken == TK_MUL || mScanner->mToken == TK_DIV || mScanner->mToken == TK_MOD)
|
||||||
{
|
{
|
||||||
Expression* nexp = new Expression(mScanner->mLocation, EX_BINARY);
|
Expression* nexp = new Expression(mScanner->mLocation, EX_BINARY);
|
||||||
nexp->mToken = mScanner->mToken;
|
nexp->mToken = mScanner->mToken;
|
||||||
nexp->mLeft = exp;
|
nexp->mLeft = exp;
|
||||||
mScanner->NextToken();
|
mScanner->NextToken();
|
||||||
nexp->mRight = ParseAssemblerBaseOperand();
|
nexp->mRight = ParseAssemblerBaseOperand(pcasm, pcoffset);
|
||||||
exp = nexp->ConstantFold(mErrors);
|
exp = nexp->ConstantFold(mErrors);
|
||||||
}
|
}
|
||||||
return exp;
|
return exp;
|
||||||
}
|
}
|
||||||
|
|
||||||
Expression* Parser::ParseAssemblerAddOperand(void)
|
Expression* Parser::ParseAssemblerAddOperand(Declaration* pcasm, int pcoffset)
|
||||||
{
|
{
|
||||||
Expression* exp = ParseAssemblerMulOperand();
|
Expression* exp = ParseAssemblerMulOperand(pcasm, pcoffset);
|
||||||
while (mScanner->mToken == TK_ADD || mScanner->mToken == TK_SUB)
|
while (mScanner->mToken == TK_ADD || mScanner->mToken == TK_SUB)
|
||||||
{
|
{
|
||||||
Expression* nexp = new Expression(mScanner->mLocation, EX_BINARY);
|
Expression* nexp = new Expression(mScanner->mLocation, EX_BINARY);
|
||||||
nexp->mToken = mScanner->mToken;
|
nexp->mToken = mScanner->mToken;
|
||||||
nexp->mLeft = exp;
|
nexp->mLeft = exp;
|
||||||
mScanner->NextToken();
|
mScanner->NextToken();
|
||||||
nexp->mRight = ParseAssemblerMulOperand();
|
nexp->mRight = ParseAssemblerMulOperand(pcasm, pcoffset);
|
||||||
if (!nexp->mLeft->mDecValue || !nexp->mRight->mDecValue)
|
if (!nexp->mLeft->mDecValue || !nexp->mRight->mDecValue)
|
||||||
{
|
{
|
||||||
mErrors->Error(mScanner->mLocation, EERR_INCOMPATIBLE_OPERATOR, "Invalid assembler operand");
|
mErrors->Error(mScanner->mLocation, EERR_INCOMPATIBLE_OPERATOR, "Invalid assembler operand");
|
||||||
|
@ -2403,12 +2413,12 @@ Expression* Parser::ParseAssemblerAddOperand(void)
|
||||||
return exp;
|
return exp;
|
||||||
}
|
}
|
||||||
|
|
||||||
Expression* Parser::ParseAssemblerOperand(void)
|
Expression* Parser::ParseAssemblerOperand(Declaration* pcasm, int pcoffset)
|
||||||
{
|
{
|
||||||
if (mScanner->mToken == TK_LESS_THAN)
|
if (mScanner->mToken == TK_LESS_THAN)
|
||||||
{
|
{
|
||||||
mScanner->NextToken();
|
mScanner->NextToken();
|
||||||
Expression* exp = ParseAssemblerOperand();
|
Expression* exp = ParseAssemblerOperand(pcasm, pcoffset);
|
||||||
|
|
||||||
if (exp->mType == EX_CONSTANT)
|
if (exp->mType == EX_CONSTANT)
|
||||||
{
|
{
|
||||||
|
@ -2478,7 +2488,7 @@ Expression* Parser::ParseAssemblerOperand(void)
|
||||||
else if (mScanner->mToken == TK_GREATER_THAN)
|
else if (mScanner->mToken == TK_GREATER_THAN)
|
||||||
{
|
{
|
||||||
mScanner->NextToken();
|
mScanner->NextToken();
|
||||||
Expression* exp = ParseAssemblerOperand();
|
Expression* exp = ParseAssemblerOperand(pcasm, pcoffset);
|
||||||
|
|
||||||
if (exp->mType == EX_CONSTANT)
|
if (exp->mType == EX_CONSTANT)
|
||||||
{
|
{
|
||||||
|
@ -2546,7 +2556,7 @@ Expression* Parser::ParseAssemblerOperand(void)
|
||||||
return exp;
|
return exp;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return ParseAssemblerAddOperand();
|
return ParseAssemblerAddOperand(pcasm, pcoffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Parser::AddAssemblerRegister(const Ident* ident, int value)
|
void Parser::AddAssemblerRegister(const Ident* ident, int value)
|
||||||
|
@ -2648,12 +2658,12 @@ Expression* Parser::ParseAssembler(void)
|
||||||
{
|
{
|
||||||
ilast->mAsmInsMode = ASMIM_IMMEDIATE;
|
ilast->mAsmInsMode = ASMIM_IMMEDIATE;
|
||||||
mScanner->NextToken();
|
mScanner->NextToken();
|
||||||
ilast->mLeft = ParseAssemblerOperand();
|
ilast->mLeft = ParseAssemblerOperand(vdasm, offset);
|
||||||
}
|
}
|
||||||
else if (mScanner->mToken == TK_OPEN_PARENTHESIS)
|
else if (mScanner->mToken == TK_OPEN_PARENTHESIS)
|
||||||
{
|
{
|
||||||
mScanner->NextToken();
|
mScanner->NextToken();
|
||||||
ilast->mLeft = ParseAssemblerOperand();
|
ilast->mLeft = ParseAssemblerOperand(vdasm, offset);
|
||||||
if (mScanner->mToken == TK_COMMA)
|
if (mScanner->mToken == TK_COMMA)
|
||||||
{
|
{
|
||||||
mScanner->NextToken();
|
mScanner->NextToken();
|
||||||
|
@ -2693,7 +2703,7 @@ Expression* Parser::ParseAssembler(void)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ilast->mLeft = ParseAssemblerOperand();
|
ilast->mLeft = ParseAssemblerOperand(vdasm, offset);
|
||||||
if (mScanner->mToken == TK_COMMA)
|
if (mScanner->mToken == TK_COMMA)
|
||||||
{
|
{
|
||||||
mScanner->NextToken();
|
mScanner->NextToken();
|
||||||
|
@ -2960,7 +2970,7 @@ void Parser::ParsePragma(void)
|
||||||
{
|
{
|
||||||
mScanner->NextToken();
|
mScanner->NextToken();
|
||||||
ConsumeToken(TK_OPEN_PARENTHESIS);
|
ConsumeToken(TK_OPEN_PARENTHESIS);
|
||||||
Expression* exp = ParseAssemblerOperand();
|
Expression* exp = ParseAssemblerOperand(nullptr, 0);
|
||||||
|
|
||||||
ConsumeToken(TK_COMMA);
|
ConsumeToken(TK_COMMA);
|
||||||
if (mScanner->mToken == TK_IDENT)
|
if (mScanner->mToken == TK_IDENT)
|
||||||
|
|
|
@ -41,10 +41,10 @@ protected:
|
||||||
Expression* ParseFunction(Declaration* dec);
|
Expression* ParseFunction(Declaration* dec);
|
||||||
Expression* ParseAssembler(void);
|
Expression* ParseAssembler(void);
|
||||||
|
|
||||||
Expression* ParseAssemblerBaseOperand(void);
|
Expression* ParseAssemblerBaseOperand(Declaration* pcasm, int pcoffset);
|
||||||
Expression* ParseAssemblerMulOperand(void);
|
Expression* ParseAssemblerMulOperand(Declaration* pcasm, int pcoffset);
|
||||||
Expression* ParseAssemblerAddOperand(void);
|
Expression* ParseAssemblerAddOperand(Declaration* pcasm, int pcoffset);
|
||||||
Expression* ParseAssemblerOperand(void);
|
Expression* ParseAssemblerOperand(Declaration * pcasm, int pcoffset);
|
||||||
|
|
||||||
void AddAssemblerRegister(const Ident* ident, int value);
|
void AddAssemblerRegister(const Ident* ident, int value);
|
||||||
|
|
||||||
|
|
|
@ -73,7 +73,7 @@ int main(int argc, const char** argv)
|
||||||
|
|
||||||
#else
|
#else
|
||||||
strcpy(strProductName, "oscar64");
|
strcpy(strProductName, "oscar64");
|
||||||
strcpy(strProductVersion, "1.3.72");
|
strcpy(strProductVersion, "1.3.73");
|
||||||
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
uint32_t length = sizeof(basePath);
|
uint32_t length = sizeof(basePath);
|
||||||
|
|
|
@ -25,8 +25,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_NEUTRAL
|
||||||
//
|
//
|
||||||
|
|
||||||
VS_VERSION_INFO VERSIONINFO
|
VS_VERSION_INFO VERSIONINFO
|
||||||
FILEVERSION 1,3,72,0
|
FILEVERSION 1,3,73,0
|
||||||
PRODUCTVERSION 1,3,72,0
|
PRODUCTVERSION 1,3,73,0
|
||||||
FILEFLAGSMASK 0x3fL
|
FILEFLAGSMASK 0x3fL
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
FILEFLAGS 0x1L
|
FILEFLAGS 0x1L
|
||||||
|
@ -43,12 +43,12 @@ BEGIN
|
||||||
BEGIN
|
BEGIN
|
||||||
VALUE "CompanyName", "oscar64"
|
VALUE "CompanyName", "oscar64"
|
||||||
VALUE "FileDescription", "oscar64 compiler"
|
VALUE "FileDescription", "oscar64 compiler"
|
||||||
VALUE "FileVersion", "1.3.72.0"
|
VALUE "FileVersion", "1.3.73.0"
|
||||||
VALUE "InternalName", "oscar64.exe"
|
VALUE "InternalName", "oscar64.exe"
|
||||||
VALUE "LegalCopyright", "Copyright (C) 2021"
|
VALUE "LegalCopyright", "Copyright (C) 2021"
|
||||||
VALUE "OriginalFilename", "oscar64.exe"
|
VALUE "OriginalFilename", "oscar64.exe"
|
||||||
VALUE "ProductName", "oscar64"
|
VALUE "ProductName", "oscar64"
|
||||||
VALUE "ProductVersion", "1.3.72.0"
|
VALUE "ProductVersion", "1.3.73.0"
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
BLOCK "VarFileInfo"
|
BLOCK "VarFileInfo"
|
||||||
|
|
|
@ -3414,15 +3414,15 @@
|
||||||
{
|
{
|
||||||
"Name" = "8:Microsoft Visual Studio"
|
"Name" = "8:Microsoft Visual Studio"
|
||||||
"ProductName" = "8:oscar64"
|
"ProductName" = "8:oscar64"
|
||||||
"ProductCode" = "8:{07197B62-14CB-4607-AF17-B93D06B4E603}"
|
"ProductCode" = "8:{A53359B5-4B83-418F-BE3F-60133D152224}"
|
||||||
"PackageCode" = "8:{05C9040B-AB11-4EEF-B99C-0BC6CAB578AC}"
|
"PackageCode" = "8:{5B0C1429-92B6-4506-ABF5-36A623D4C056}"
|
||||||
"UpgradeCode" = "8:{9AB61EFF-ACAC-4079-9950-8D96615CD4EF}"
|
"UpgradeCode" = "8:{9AB61EFF-ACAC-4079-9950-8D96615CD4EF}"
|
||||||
"AspNetVersion" = "8:2.0.50727.0"
|
"AspNetVersion" = "8:2.0.50727.0"
|
||||||
"RestartWWWService" = "11:FALSE"
|
"RestartWWWService" = "11:FALSE"
|
||||||
"RemovePreviousVersions" = "11:TRUE"
|
"RemovePreviousVersions" = "11:TRUE"
|
||||||
"DetectNewerInstalledVersion" = "11:TRUE"
|
"DetectNewerInstalledVersion" = "11:TRUE"
|
||||||
"InstallAllUsers" = "11:FALSE"
|
"InstallAllUsers" = "11:FALSE"
|
||||||
"ProductVersion" = "8:1.3.72"
|
"ProductVersion" = "8:1.3.73"
|
||||||
"Manufacturer" = "8:oscar64"
|
"Manufacturer" = "8:oscar64"
|
||||||
"ARPHELPTELEPHONE" = "8:"
|
"ARPHELPTELEPHONE" = "8:"
|
||||||
"ARPHELPLINK" = "8:"
|
"ARPHELPLINK" = "8:"
|
||||||
|
|
|
@ -207,23 +207,23 @@ int main(void)
|
||||||
|
|
||||||
bm_line(&Screen, &SRect,
|
bm_line(&Screen, &SRect,
|
||||||
p[iy + 0][ix + 0].x, p[iy + 0][ix + 0].y,
|
p[iy + 0][ix + 0].x, p[iy + 0][ix + 0].y,
|
||||||
p[iy + 0][ix + 1].x, p[iy + 0][ix + 1].y, patt);
|
p[iy + 0][ix + 1].x, p[iy + 0][ix + 1].y, patt, LINOP_SET);
|
||||||
|
|
||||||
bm_line(&Screen, &SRect,
|
bm_line(&Screen, &SRect,
|
||||||
p[iy + 1][ix + 0].x, p[iy + 1][ix + 0].y,
|
p[iy + 1][ix + 0].x, p[iy + 1][ix + 0].y,
|
||||||
p[iy + 1][ix + 1].x, p[iy + 1][ix + 1].y, patt);
|
p[iy + 1][ix + 1].x, p[iy + 1][ix + 1].y, patt, LINOP_SET);
|
||||||
|
|
||||||
bm_line(&Screen, &SRect,
|
bm_line(&Screen, &SRect,
|
||||||
p[iy + 0][ix + 0].x, p[iy + 0][ix + 0].y,
|
p[iy + 0][ix + 0].x, p[iy + 0][ix + 0].y,
|
||||||
p[iy + 1][ix + 0].x, p[iy + 1][ix + 0].y, patt);
|
p[iy + 1][ix + 0].x, p[iy + 1][ix + 0].y, patt, LINOP_SET);
|
||||||
|
|
||||||
bm_line(&Screen, &SRect,
|
bm_line(&Screen, &SRect,
|
||||||
p[iy + 0][ix + 1].x, p[iy + 0][ix + 1].y,
|
p[iy + 0][ix + 1].x, p[iy + 0][ix + 1].y,
|
||||||
p[iy + 1][ix + 1].x, p[iy + 1][ix + 1].y, patt);
|
p[iy + 1][ix + 1].x, p[iy + 1][ix + 1].y, patt, LINOP_SET);
|
||||||
}
|
}
|
||||||
|
|
||||||
mmap_set(MMAP_NO_BASIC);
|
mmap_set(MMAP_NO_BASIC);
|
||||||
// getch();
|
getch();
|
||||||
|
|
||||||
restore();
|
restore();
|
||||||
|
|
||||||
|
|
|
@ -40,10 +40,10 @@ void draw(ClipRect * cr, byte pattern)
|
||||||
{
|
{
|
||||||
for(int i=0; i<40; i ++)
|
for(int i=0; i<40; i ++)
|
||||||
{
|
{
|
||||||
bm_line(&Screen, cr, 8 * i, 0, 319, 5 * i, pattern);
|
bm_line(&Screen, cr, 8 * i, 0, 319, 5 * i, pattern, LINOP_SET);
|
||||||
bm_line(&Screen, cr, 319, 5 * i, 319 - 8 * i, 199, pattern);
|
bm_line(&Screen, cr, 319, 5 * i, 319 - 8 * i, 199, pattern, LINOP_SET);
|
||||||
bm_line(&Screen, cr, 319 - 8 * i, 199, 0, 199 - 5 * i, pattern);
|
bm_line(&Screen, cr, 319 - 8 * i, 199, 0, 199 - 5 * i, pattern, LINOP_SET);
|
||||||
bm_line(&Screen, cr, 0, 199 - 5 * i, 8 * i, 0, pattern);
|
bm_line(&Screen, cr, 0, 199 - 5 * i, 8 * i, 0, pattern, LINOP_SET);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -74,7 +74,7 @@ int main(void)
|
||||||
for(int j=0; j<10; j++)
|
for(int j=0; j<10; j++)
|
||||||
{
|
{
|
||||||
int k = (j + 1) % 10;
|
int k = (j + 1) % 10;
|
||||||
bm_line(&Screen, &cr, rpx[j], rpy[j], rpx[k], rpy[k], 0xff);
|
bm_line(&Screen, &cr, rpx[j], rpy[j], rpx[k], rpy[k], 0xff, LINOP_SET);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Binary file not shown.
Loading…
Reference in New Issue