diff --git a/include/c64/vic.h b/include/c64/vic.h index 8224119..5a8197c 100644 --- a/include/c64/vic.h +++ b/include/c64/vic.h @@ -44,32 +44,32 @@ struct VIC { struct XY { - byte x, y; + volatile byte x, y; } spr_pos[8]; byte spr_msbx; volatile byte ctrl1; volatile byte raster; - byte lpx, lpy; - byte spr_enable; - byte ctrl2; - byte spr_expand_y; - byte memptr; - byte intr_ctrl; - byte intr_enable; - byte spr_priority; - byte spr_multi; - byte spr_expand_x; - byte spr_sprcol; - byte spr_backcol; - byte color_border; - byte color_back; - byte color_back1; - byte color_back2; - byte color_back3; - byte spr_mcolor0; - byte spr_mcolor1; - byte spr_color[8]; + volatile byte lpx, lpy; + volatile byte spr_enable; + volatile byte ctrl2; + volatile byte spr_expand_y; + volatile byte memptr; + volatile byte intr_ctrl; + volatile byte intr_enable; + volatile byte spr_priority; + volatile byte spr_multi; + volatile byte spr_expand_x; + volatile byte spr_sprcol; + volatile byte spr_backcol; + volatile byte color_border; + volatile byte color_back; + volatile byte color_back1; + volatile byte color_back2; + volatile byte color_back3; + volatile byte spr_mcolor0; + volatile byte spr_mcolor1; + volatile byte spr_color[8]; }; diff --git a/oscar64/InterCode.cpp b/oscar64/InterCode.cpp index 342cb57..21b7842 100644 --- a/oscar64/InterCode.cpp +++ b/oscar64/InterCode.cpp @@ -670,6 +670,15 @@ static bool StoreAliasing(const InterInstruction * lins, const InterInstruction* else if (lmem == IM_GLOBAL) return staticVars[lvindex]->mAliased; } + else if (MemRange(sins, tvalue, smem, svindex, soffset, ssize)) + { + if (smem == IM_LOCAL) + return aliasedLocals[svindex]; + else if (smem == IM_PARAM || smem == IM_FPARAM) + return aliasedParams[svindex]; + else if (smem == IM_GLOBAL) + return staticVars[svindex]->mAliased; + } return true; } @@ -5695,6 +5704,8 @@ static bool MatchingMem(const InterOperand& op1, const InterOperand& op2) return op1.mIntConst < op2.mIntConst + op2.mOperandSize && op2.mIntConst < op1.mIntConst + op1.mOperandSize; else return false; + case IM_INDIRECT: + return true; default: return false; } @@ -5725,6 +5736,8 @@ static bool SameMem(const InterOperand& op1, const InterOperand& op2) return true; case IM_GLOBAL: return op1.mLinkerObject == op2.mLinkerObject; + case IM_INDIRECT: + default: return false; } @@ -9104,7 +9117,7 @@ void InterCodeProcedure::Disassemble(FILE* file) void InterCodeProcedure::Disassemble(const char* name, bool dumpSets) { -#if 0 +#if 1 #ifdef _WIN32 FILE* file; static bool initial = true; diff --git a/oscar64/InterCodeGenerator.cpp b/oscar64/InterCodeGenerator.cpp index c67fe39..ceb65dd 100644 --- a/oscar64/InterCodeGenerator.cpp +++ b/oscar64/InterCodeGenerator.cpp @@ -1149,6 +1149,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* ins->mSrc[1].mType = IT_POINTER; ins->mSrc[1].mTemp = vl.mTemp; ins->mSrc[1].mOperandSize = vl.mType->mSize; + ins->mVolatile = vl.mType->mFlags & DTF_VOLATILE; block->Append(ins); } } @@ -1575,6 +1576,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* sins->mSrc[1].mType = IT_POINTER; sins->mSrc[1].mTemp = vl.mTemp; sins->mSrc[1].mOperandSize = vl.mType->mSize; + sins->mVolatile = vl.mType->mFlags & DTF_VOLATILE; block->Append(sins); return ExValue(vdl.mType, ains->mDst.mTemp); @@ -1634,6 +1636,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* sins->mSrc[1].mType = IT_POINTER; sins->mSrc[1].mTemp = vl.mTemp; sins->mSrc[1].mOperandSize = vl.mType->mSize; + sins->mVolatile = vl.mType->mFlags & DTF_VOLATILE; block->Append(sins); return ExValue(vdl.mType, vdl.mTemp); diff --git a/oscar64/NativeCodeGenerator.cpp b/oscar64/NativeCodeGenerator.cpp index d4d6b9b..49f4f4c 100644 --- a/oscar64/NativeCodeGenerator.cpp +++ b/oscar64/NativeCodeGenerator.cpp @@ -13545,6 +13545,23 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass) mIns[i + 0].mType = ASMIT_SEC; progress = true; } + else if ( + mIns[i + 0].mType == ASMIT_CLC && + mIns[i + 1].mType == ASMIT_LDA && mIns[i + 1].mMode == ASMIM_IMMEDIATE && mIns[i + 1].mAddress == 0 && + mIns[i + 2].mType == ASMIT_ADC) + { + mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED; + mIns[i + 2].mType = ASMIT_LDA; + progress = true; + } + else if ( + mIns[i + 0].mType == ASMIT_CLC && + mIns[i + 1].mType == ASMIT_LDA && + mIns[i + 2].mType == ASMIT_ADC && mIns[i + 2].mMode == ASMIM_IMMEDIATE && mIns[i + 2].mAddress == 0) + { + mIns[i + 2].mType = ASMIT_NOP; mIns[i + 2].mMode = ASMIM_IMPLIED; + progress = true; + } else if ( mIns[i + 0].mType == ASMIT_LDA && (mIns[i + 0].mMode == ASMIM_IMMEDIATE || mIns[i + 0].mMode == ASMIM_IMMEDIATE_ADDRESS || mIns[i + 0].mMode == ASMIM_ZERO_PAGE) && mIns[i + 1].mType == ASMIT_CLC && @@ -13628,7 +13645,17 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass) progress = true; } else if ( - mIns[i + 0].mType == ASMIT_STA && + mIns[i + 0].mType == ASMIT_SBC && mIns[i + 0].mMode == ASMIM_IMMEDIATE && + mIns[i + 1].mType == ASMIT_SEC && + mIns[i + 2].mType == ASMIT_SBC && mIns[i + 2].mMode == ASMIM_IMMEDIATE && !(mIns[i + 2].mLive & LIVE_CPU_REG_C)) + { + mIns[i + 0].mAddress += mIns[i + 2].mAddress; + mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED; + mIns[i + 2].mType = ASMIT_NOP; mIns[i + 2].mMode = ASMIM_IMPLIED; + progress = true; + } + else if ( + mIns[i + 0].mType == ASMIT_STA && !(mIns[i + 0].mFlags & NCIF_VOLATILE) && mIns[i + 2].mType == ASMIT_STA && mIns[i + 0].SameEffectiveAddress(mIns[i + 2]) && !mIns[i + 1].ChangesAddress() && !mIns[i + 1].ChangesGlobalMemory() && !mIns[i + 1].ChangesYReg() && !mIns[i + 1].ChangesXReg()) diff --git a/oscar64setup/oscar64setup.vdproj b/oscar64setup/oscar64setup.vdproj index 4812413..fe631b6 100644 --- a/oscar64setup/oscar64setup.vdproj +++ b/oscar64setup/oscar64setup.vdproj @@ -496,6 +496,12 @@ } "Entry" { + "MsmKey" = "8:_C4B1FC7B672E4E538E92FD06D90AE808" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { "MsmKey" = "8:_C6B8A6C354494A50BBFD7EE6B2FB39B6" "OwnerKey" = "8:_UNDEFINED" "MsmSig" = "8:_UNDEFINED" @@ -2355,6 +2361,26 @@ "IsDependency" = "11:FALSE" "IsolateTo" = "8:" } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_C4B1FC7B672E4E538E92FD06D90AE808" + { + "SourcePath" = "8:..\\samples\\sprites\\creditroll.c" + "TargetName" = "8:creditroll.c" + "Tag" = "8:" + "Folder" = "8:_A891BBCA276B4516852A6BFD884353E3" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_C6B8A6C354494A50BBFD7EE6B2FB39B6" { "SourcePath" = "8:..\\samples\\scrolling\\bigfont.c" @@ -3169,15 +3195,15 @@ { "Name" = "8:Microsoft Visual Studio" "ProductName" = "8:oscar64" - "ProductCode" = "8:{118A6EF7-D160-4A3E-AECC-5B0D9AA16099}" - "PackageCode" = "8:{8B7C9187-A38D-43DB-B458-3E80FDB17616}" + "ProductCode" = "8:{57F0583C-4EF1-449B-8D24-9A0A3FBCE308}" + "PackageCode" = "8:{A44F1E87-7AF4-42BD-989E-8DD388A05570}" "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.2.67" + "ProductVersion" = "8:1.2.68" "Manufacturer" = "8:oscar64" "ARPHELPTELEPHONE" = "8:" "ARPHELPLINK" = "8:" diff --git a/samples/sprites/creditroll.c b/samples/sprites/creditroll.c index 470d9a4..4afa82a 100644 --- a/samples/sprites/creditroll.c +++ b/samples/sprites/creditroll.c @@ -69,44 +69,58 @@ const char * scrolltext[] = { RIRQCode * spmux[6], final; +// Expand a line of source text into buffer centered + void readline(char * dp, char n) { const char * sp = scrolltext[n]; - + + // Count number of characters + char s = 0; while (sp[s]) s++; + // Left padding + char l = (18 - s) >> 1; char i = 0; while (i < l) dp[i++] = ' '; + // Text in center s = 0; while (sp[s]) - { - dp[i++] = sp[s]; - s++; - } + dp[i++] = sp[s++]; + // Right padding while (i < 18) dp[i++] = ' '; } +// Expand six characters into sprite + void expandline(const char * line, char sppos, char ty) { + // Target position for first character char * dp = spriteset + 64 * sppos + 3 * ty; + char xl = 0; for(char x=0; x<6; x++) { + // Source character data const char * sp = charset + 8 * (line[x] & 0x1f); + // Copy eight rows dp[ 0] = sp[0]; dp[ 3] = sp[1]; dp[ 6] = sp[2]; dp[ 9] = sp[3]; dp[12] = sp[4]; dp[15] = sp[5]; dp[18] = sp[6]; dp[21] = sp[7]; + // Next character dp++; xl++; + + // Advance to next sprite if (xl == 3) { dp += 61; @@ -120,83 +134,112 @@ int main(void) rirq_init(true); spr_init(Screen); - int oy = 0; + // Vertical pixel offset + sbyte oy = 0; + + // Index of top left sprite char sy = 128; - for(int i=0; i<5; i++) + // Loop over five rows of virtual sprites + for(char i=0; i<5; i++) { - spmux[i] = rirq_alloc(12); - for(int x=0; x<6; x++) + // Allocate large rirq command with 12 writes + RIRQCode * sp = rirq_alloc(12); + spmux[i] = sp; + + // Six sprites per row + for(char x=0; x<6; x++) { - rirq_write(spmux[i], 2 * x + 0, &vic.spr_pos[x].y, 48 * (i + 1) + oy); - rirq_write(spmux[i], 2 * x + 1, Screen + 0x3f8 + x, sy + 1 + i); + // Vertical sprite position + rirq_write(sp, 2 * x + 0, &vic.spr_pos[x].y, 48 * (i + 1) + oy); + + // Sprite graphic + rirq_write(sp, 2 * x + 1, Screen + 0x3f8 + x, sy + 1 + i); } + + // Place in list rirq_set(i, 48 * i + 46 + oy, spmux[i]); } + // Final irq at bottom of screen rirq_build(&final, 0); rirq_set(5, 250, &final); - rirq_sort(); + // Placing top sprites + for(int x=0; x<6; x++) + spr_set(x, true, 40 + 48 * x, oy, 128, 1, false, true, true); + + // Initial sort and start of processing + rirq_sort(); rirq_start(); - for(int x=0; x<6; x++) - { - spr_set(x, true, 40 + 48 * x, oy, 128, 1, false, true, true); - } - + // Buffer for single line char line[20]; + + // Index into text to scroll char lpos = 0; for(;;) { + // Wait for end of irq list rirq_wait(); + // Advance one pixel line oy--; if (oy < 0) { + // Advance one row of sprites oy += 48; - sy += 6; + sy += 6; if (sy == 128 + 36) sy = 128; } + // Update interrupt position for(char i=0; i<5; i++) { int ty = 48 * i + 46 + oy; + + // No interrupts below screen bottom if (ty < 250) rirq_move(i, ty); else rirq_clear(i); } + + // Sort list rirq_sort(); + // Reset row of top level sprites char sty = sy; for(int x=0; x<6; x++) - { + { spr_move(x, 40 + 48 * x, oy); spr_image(x, sty); sty ++; } - + // Update write data in interrupt list for(char i=0; i<5; i++) { + RIRQCode * sp = spmux[i]; + + // Check sprite rotation if (sty == 128 + 36) sty = 128; + // Update vertical position and sprite data char py = 48 * (i + 1) + oy; for(char x=0; x<6; x++) { - rirq_data(spmux[i], 2 * x + 0, py); - rirq_data(spmux[i], 2 * x + 1, sty); + rirq_data(sp, 2 * x + 0, py); + rirq_data(sp, 2 * x + 1, sty); sty ++; } } - rirq_sort(); - - vic.color_border++; + // Expand next line of text into bottom row of + // sprites while invisible switch (oy) { case 46: @@ -226,7 +269,6 @@ int main(void) expandline(line + 12, sty - 2 - 128, 12); break; } - vic.color_border--; } return 0;