diff --git a/include/gfx/bitmap.c b/include/gfx/bitmap.c index c47219b..0c854bc 100644 --- a/include/gfx/bitmap.c +++ b/include/gfx/bitmap.c @@ -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_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; @@ -491,14 +491,50 @@ static void buildline(char ly, char lx, int dx, int dy, int stride, bool left, b // set pixel ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_D0); - 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_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); + switch (op) + { + case LINOP_SET: + 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_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 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; byte quad = 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; 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); } @@ -627,7 +676,7 @@ static int muldiv(int x, int mul, int 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; @@ -711,7 +760,7 @@ void bm_line(Bitmap * bm, ClipRect * clip, int x0, int y0, int x1, int y1, char 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) diff --git a/include/gfx/bitmap.h b/include/gfx/bitmap.h index 5b09256..fe182bc 100644 --- a/include/gfx/bitmap.h +++ b/include/gfx/bitmap.h @@ -48,6 +48,14 @@ enum BlitOp 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]; // 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); // 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 -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 void bmu_bitblit(Bitmap * dbm, int dx, int dy, Bitmap * sbm, int sx, int sy, int w, int h, const char * pattern, BlitOp op); diff --git a/oscar64/InterCodeGenerator.cpp b/oscar64/InterCodeGenerator.cpp index 83dca55..8f548d9 100644 --- a/oscar64/InterCodeGenerator.cpp +++ b/oscar64/InterCodeGenerator.cpp @@ -545,8 +545,18 @@ void InterCodeGenerator::TranslateAssembler(InterCodeModule* mod, Expression* ex case ASMIM_RELATIVE: if (!aexp) mErrors->Error(cexp->mLocation, EERR_ASM_INVALD_OPERAND, "Missing assembler operand"); - else - d[offset] = aexp->mInteger - offset - 1; + else + { + 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++; break; } diff --git a/oscar64/NativeCodeGenerator.cpp b/oscar64/NativeCodeGenerator.cpp index 15f7c7d..6f38db5 100644 --- a/oscar64/NativeCodeGenerator.cpp +++ b/oscar64/NativeCodeGenerator.cpp @@ -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 // must be last step before actual assembly @@ -11931,6 +11974,33 @@ void NativeCodeBasicBlock::BlockSizeReduction(void) j += 2; 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 mIns[j++] = mIns[i++]; } @@ -12480,6 +12550,92 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass) #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 // 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 } + + 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 ( @@ -15602,6 +15835,12 @@ void NativeCodeProcedure::Optimize(void) #endif #if 1 + ResetVisited(); + if (mEntryBlock->OptimizeSelect(this)) + { + changed = true; + } + if (step > 0) { ResetVisited(); diff --git a/oscar64/NativeCodeGenerator.h b/oscar64/NativeCodeGenerator.h index 944ad47..28d3142 100644 --- a/oscar64/NativeCodeGenerator.h +++ b/oscar64/NativeCodeGenerator.h @@ -151,6 +151,8 @@ public: bool SimpleLoopReversal(NativeCodeProcedure* proc); bool OptimizeInnerLoop(NativeCodeProcedure* proc, NativeCodeBasicBlock* head, NativeCodeBasicBlock* tail, GrowingArray& blocks); + bool OptimizeSelect(NativeCodeProcedure* proc); + NativeCodeBasicBlock* FindTailBlock(NativeCodeBasicBlock* head); bool OptimizeInnerLoops(NativeCodeProcedure* proc); void CollectInnerLoop(NativeCodeBasicBlock* head, GrowingArray& lblocks); diff --git a/oscar64/Parser.cpp b/oscar64/Parser.cpp index fb963d4..ae645fa 100644 --- a/oscar64/Parser.cpp +++ b/oscar64/Parser.cpp @@ -2194,7 +2194,7 @@ Expression* Parser::ParseSwitchStatement(void) -Expression* Parser::ParseAssemblerBaseOperand(void) +Expression* Parser::ParseAssemblerBaseOperand(Declaration* pcasm, int pcoffset) { Expression* exp = nullptr; Declaration* dec; @@ -2203,7 +2203,7 @@ Expression* Parser::ParseAssemblerBaseOperand(void) { case TK_SUB: mScanner->NextToken(); - exp = ParseAssemblerBaseOperand(); + exp = ParseAssemblerBaseOperand(pcasm, pcoffset); if (exp->mType == EX_CONSTANT && exp->mDecValue->mType == 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"); 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: dec = new Declaration(mScanner->mLocation, DT_CONST_INTEGER); dec->mInteger = mScanner->mTokenInteger; @@ -2329,31 +2339,31 @@ Expression* Parser::ParseAssemblerBaseOperand(void) 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) { Expression* nexp = new Expression(mScanner->mLocation, EX_BINARY); nexp->mToken = mScanner->mToken; nexp->mLeft = exp; mScanner->NextToken(); - nexp->mRight = ParseAssemblerBaseOperand(); + nexp->mRight = ParseAssemblerBaseOperand(pcasm, pcoffset); exp = nexp->ConstantFold(mErrors); } 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) { Expression* nexp = new Expression(mScanner->mLocation, EX_BINARY); nexp->mToken = mScanner->mToken; nexp->mLeft = exp; mScanner->NextToken(); - nexp->mRight = ParseAssemblerMulOperand(); + nexp->mRight = ParseAssemblerMulOperand(pcasm, pcoffset); if (!nexp->mLeft->mDecValue || !nexp->mRight->mDecValue) { mErrors->Error(mScanner->mLocation, EERR_INCOMPATIBLE_OPERATOR, "Invalid assembler operand"); @@ -2403,12 +2413,12 @@ Expression* Parser::ParseAssemblerAddOperand(void) return exp; } -Expression* Parser::ParseAssemblerOperand(void) +Expression* Parser::ParseAssemblerOperand(Declaration* pcasm, int pcoffset) { if (mScanner->mToken == TK_LESS_THAN) { mScanner->NextToken(); - Expression* exp = ParseAssemblerOperand(); + Expression* exp = ParseAssemblerOperand(pcasm, pcoffset); if (exp->mType == EX_CONSTANT) { @@ -2478,7 +2488,7 @@ Expression* Parser::ParseAssemblerOperand(void) else if (mScanner->mToken == TK_GREATER_THAN) { mScanner->NextToken(); - Expression* exp = ParseAssemblerOperand(); + Expression* exp = ParseAssemblerOperand(pcasm, pcoffset); if (exp->mType == EX_CONSTANT) { @@ -2546,7 +2556,7 @@ Expression* Parser::ParseAssemblerOperand(void) return exp; } else - return ParseAssemblerAddOperand(); + return ParseAssemblerAddOperand(pcasm, pcoffset); } void Parser::AddAssemblerRegister(const Ident* ident, int value) @@ -2648,12 +2658,12 @@ Expression* Parser::ParseAssembler(void) { ilast->mAsmInsMode = ASMIM_IMMEDIATE; mScanner->NextToken(); - ilast->mLeft = ParseAssemblerOperand(); + ilast->mLeft = ParseAssemblerOperand(vdasm, offset); } else if (mScanner->mToken == TK_OPEN_PARENTHESIS) { mScanner->NextToken(); - ilast->mLeft = ParseAssemblerOperand(); + ilast->mLeft = ParseAssemblerOperand(vdasm, offset); if (mScanner->mToken == TK_COMMA) { mScanner->NextToken(); @@ -2693,7 +2703,7 @@ Expression* Parser::ParseAssembler(void) } else { - ilast->mLeft = ParseAssemblerOperand(); + ilast->mLeft = ParseAssemblerOperand(vdasm, offset); if (mScanner->mToken == TK_COMMA) { mScanner->NextToken(); @@ -2960,7 +2970,7 @@ void Parser::ParsePragma(void) { mScanner->NextToken(); ConsumeToken(TK_OPEN_PARENTHESIS); - Expression* exp = ParseAssemblerOperand(); + Expression* exp = ParseAssemblerOperand(nullptr, 0); ConsumeToken(TK_COMMA); if (mScanner->mToken == TK_IDENT) diff --git a/oscar64/Parser.h b/oscar64/Parser.h index 8c782ed..55ec388 100644 --- a/oscar64/Parser.h +++ b/oscar64/Parser.h @@ -41,10 +41,10 @@ protected: Expression* ParseFunction(Declaration* dec); Expression* ParseAssembler(void); - Expression* ParseAssemblerBaseOperand(void); - Expression* ParseAssemblerMulOperand(void); - Expression* ParseAssemblerAddOperand(void); - Expression* ParseAssemblerOperand(void); + Expression* ParseAssemblerBaseOperand(Declaration* pcasm, int pcoffset); + Expression* ParseAssemblerMulOperand(Declaration* pcasm, int pcoffset); + Expression* ParseAssemblerAddOperand(Declaration* pcasm, int pcoffset); + Expression* ParseAssemblerOperand(Declaration * pcasm, int pcoffset); void AddAssemblerRegister(const Ident* ident, int value); diff --git a/oscar64/oscar64.cpp b/oscar64/oscar64.cpp index cfca492..97aa698 100644 --- a/oscar64/oscar64.cpp +++ b/oscar64/oscar64.cpp @@ -73,7 +73,7 @@ int main(int argc, const char** argv) #else strcpy(strProductName, "oscar64"); - strcpy(strProductVersion, "1.3.72"); + strcpy(strProductVersion, "1.3.73"); #ifdef __APPLE__ uint32_t length = sizeof(basePath); diff --git a/oscar64/oscar64.rc b/oscar64/oscar64.rc index 6409718..1b349ed 100644 --- a/oscar64/oscar64.rc +++ b/oscar64/oscar64.rc @@ -25,8 +25,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_NEUTRAL // VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,3,72,0 - PRODUCTVERSION 1,3,72,0 + FILEVERSION 1,3,73,0 + PRODUCTVERSION 1,3,73,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -43,12 +43,12 @@ BEGIN BEGIN VALUE "CompanyName", "oscar64" VALUE "FileDescription", "oscar64 compiler" - VALUE "FileVersion", "1.3.72.0" + VALUE "FileVersion", "1.3.73.0" VALUE "InternalName", "oscar64.exe" VALUE "LegalCopyright", "Copyright (C) 2021" VALUE "OriginalFilename", "oscar64.exe" VALUE "ProductName", "oscar64" - VALUE "ProductVersion", "1.3.72.0" + VALUE "ProductVersion", "1.3.73.0" END END BLOCK "VarFileInfo" diff --git a/oscar64setup/oscar64setup.vdproj b/oscar64setup/oscar64setup.vdproj index 63333d2..c51e43b 100644 --- a/oscar64setup/oscar64setup.vdproj +++ b/oscar64setup/oscar64setup.vdproj @@ -3414,15 +3414,15 @@ { "Name" = "8:Microsoft Visual Studio" "ProductName" = "8:oscar64" - "ProductCode" = "8:{07197B62-14CB-4607-AF17-B93D06B4E603}" - "PackageCode" = "8:{05C9040B-AB11-4EEF-B99C-0BC6CAB578AC}" + "ProductCode" = "8:{A53359B5-4B83-418F-BE3F-60133D152224}" + "PackageCode" = "8:{5B0C1429-92B6-4506-ABF5-36A623D4C056}" "UpgradeCode" = "8:{9AB61EFF-ACAC-4079-9950-8D96615CD4EF}" "AspNetVersion" = "8:2.0.50727.0" "RestartWWWService" = "11:FALSE" "RemovePreviousVersions" = "11:TRUE" "DetectNewerInstalledVersion" = "11:TRUE" "InstallAllUsers" = "11:FALSE" - "ProductVersion" = "8:1.3.72" + "ProductVersion" = "8:1.3.73" "Manufacturer" = "8:oscar64" "ARPHELPTELEPHONE" = "8:" "ARPHELPLINK" = "8:" diff --git a/samples/hires/func3d.c b/samples/hires/func3d.c index bceeec5..fdb8b04 100644 --- a/samples/hires/func3d.c +++ b/samples/hires/func3d.c @@ -207,23 +207,23 @@ int main(void) bm_line(&Screen, &SRect, 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, 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, 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, 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); -// getch(); + getch(); restore(); diff --git a/samples/hires/lines.c b/samples/hires/lines.c index f6f5d6f..3a93443 100644 --- a/samples/hires/lines.c +++ b/samples/hires/lines.c @@ -40,10 +40,10 @@ void draw(ClipRect * cr, byte pattern) { for(int i=0; i<40; i ++) { - bm_line(&Screen, cr, 8 * i, 0, 319, 5 * i, pattern); - bm_line(&Screen, cr, 319, 5 * i, 319 - 8 * i, 199, pattern); - bm_line(&Screen, cr, 319 - 8 * i, 199, 0, 199 - 5 * i, pattern); - bm_line(&Screen, cr, 0, 199 - 5 * i, 8 * i, 0, 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, LINOP_SET); + 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, LINOP_SET); } } diff --git a/samples/hires/polygon.c b/samples/hires/polygon.c index 46a301c..60edf3a 100644 --- a/samples/hires/polygon.c +++ b/samples/hires/polygon.c @@ -74,7 +74,7 @@ int main(void) for(int j=0; j<10; j++) { 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); } } diff --git a/samples/memmap/easyflash.crt b/samples/memmap/easyflash.crt index 3b06a79..01f49e7 100644 Binary files a/samples/memmap/easyflash.crt and b/samples/memmap/easyflash.crt differ