Add lz compression for embedded assets
This commit is contained in:
parent
62d08e139b
commit
ea1fa189b2
|
@ -29,6 +29,8 @@ void sidfx_init(void)
|
|||
}
|
||||
|
||||
void sidfx_play(byte chn, SIDFX * fx, byte cnt)
|
||||
{
|
||||
if (!channels[chn].com || channels[chn].com->priority <= fx->priority)
|
||||
{
|
||||
if (channels[chn].state == SIDFX_IDLE)
|
||||
channels[chn].state = SIDFX_READY;
|
||||
|
@ -38,6 +40,7 @@ void sidfx_play(byte chn, SIDFX * fx, byte cnt)
|
|||
channels[chn].com = fx;
|
||||
channels[chn].cnt = cnt - 1;
|
||||
}
|
||||
}
|
||||
|
||||
void sidfx_stop(byte chn)
|
||||
{
|
||||
|
|
|
@ -9,6 +9,7 @@ struct SIDFX
|
|||
byte ctrl, attdec, susrel;
|
||||
int dfreq, dpwm;
|
||||
byte time1, time0;
|
||||
byte priority;
|
||||
};
|
||||
|
||||
void sidfx_init(void);
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include <stdlib.h>
|
||||
|
||||
volatile char npos = 1, tpos = 0;
|
||||
volatile byte rirq_count;
|
||||
|
||||
byte rasterIRQRows[NUM_IRQS];
|
||||
byte rasterIRQIndex[NUM_IRQS];
|
||||
|
@ -62,6 +63,7 @@ w1:
|
|||
e2:
|
||||
ldx npos
|
||||
stx tpos
|
||||
inc rirq_count
|
||||
|
||||
bit $d011
|
||||
bmi e1
|
||||
|
@ -135,6 +137,7 @@ w1:
|
|||
e2:
|
||||
ldx npos
|
||||
stx tpos
|
||||
inc rirq_count
|
||||
|
||||
bit $d011
|
||||
bmi e1
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
#define NUM_IRQS 16
|
||||
|
||||
extern volatile byte rirq_count;
|
||||
|
||||
enum RIRQCodeIndex
|
||||
{
|
||||
|
|
|
@ -0,0 +1,88 @@
|
|||
#include "oscar.h"
|
||||
|
||||
const char * oscar_expand_lzo(char * dp, const char * sp)
|
||||
{
|
||||
char cmd = sp[0];
|
||||
do
|
||||
{
|
||||
const char * cp;
|
||||
|
||||
if (cmd & 0x80)
|
||||
{
|
||||
cp = dp - sp[1];
|
||||
cmd &= 0x7f;
|
||||
sp += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
sp += 1;
|
||||
cp = sp;
|
||||
sp += cmd;
|
||||
}
|
||||
|
||||
char n = 0x00;
|
||||
do {
|
||||
dp[n] = cp[n];
|
||||
n++;
|
||||
} while (n != cmd);
|
||||
dp += cmd;
|
||||
|
||||
cmd = sp[0];
|
||||
} while (cmd);
|
||||
|
||||
return sp + 1;
|
||||
}
|
||||
|
||||
const char * oscar_expand_rle(char * dp, const char * sp)
|
||||
{
|
||||
char cmd = sp[0];
|
||||
|
||||
do
|
||||
{
|
||||
if (cmd & 0x80)
|
||||
{
|
||||
char rep = (cmd & 0x70) >> 4;
|
||||
char c = sp[1];
|
||||
for(signed char i=rep; i>=0; i--)
|
||||
dp[i] = c;
|
||||
|
||||
rep++;
|
||||
sp += 2;
|
||||
dp += rep;
|
||||
|
||||
cmd &= 0x0f;
|
||||
for(signed char i=cmd; i>=0; i--)
|
||||
dp[i] = sp[i];
|
||||
|
||||
cmd++;
|
||||
sp += cmd;
|
||||
dp += cmd;
|
||||
}
|
||||
else if (cmd & 0x40)
|
||||
{
|
||||
cmd &= 0x3f;
|
||||
sp ++;
|
||||
for(signed char i=cmd; i>=0; i--)
|
||||
dp[i] = sp[i];
|
||||
|
||||
cmd++;
|
||||
sp += cmd;
|
||||
dp += cmd;
|
||||
}
|
||||
else
|
||||
{
|
||||
char c = sp[1];
|
||||
for(signed char i=cmd; i>=0; i--)
|
||||
dp[i] = c;
|
||||
|
||||
cmd++;
|
||||
sp += 2;
|
||||
dp += cmd;
|
||||
}
|
||||
|
||||
cmd = sp[0];
|
||||
|
||||
} while (cmd)
|
||||
|
||||
return sp + 1;
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
#ifndef OSCAR_H
|
||||
#define OSCAR_H
|
||||
|
||||
|
||||
__native const char * oscar_expand_lzo(char * dp, const char * sp);
|
||||
|
||||
__native const char * oscar_expand_rle(char * dp, const char * sp);
|
||||
|
||||
|
||||
#pragma compile("oscar.c")
|
||||
|
||||
#endif
|
|
@ -21,7 +21,7 @@ static const uint32 LIVE_ALL = 0x000000ff;
|
|||
static int GlobalValueNumber = 0;
|
||||
|
||||
NativeRegisterData::NativeRegisterData(void)
|
||||
: mMode(NRDM_UNKNOWN), mValue(GlobalValueNumber++)
|
||||
: mMode(NRDM_UNKNOWN), mValue(GlobalValueNumber++), mMask(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
@ -32,6 +32,11 @@ void NativeRegisterData::Reset(void)
|
|||
mValue = GlobalValueNumber++;
|
||||
}
|
||||
|
||||
void NativeRegisterData::ResetMask(void)
|
||||
{
|
||||
mMask = 0;
|
||||
}
|
||||
|
||||
bool NativeRegisterData::SameData(const NativeRegisterData& d) const
|
||||
{
|
||||
if (mMode != d.mMode)
|
||||
|
@ -56,6 +61,14 @@ void NativeRegisterDataSet::Reset(void)
|
|||
mRegs[i].Reset();
|
||||
}
|
||||
|
||||
void NativeRegisterDataSet::ResetMask(void)
|
||||
{
|
||||
for (int i = 0; i < NUM_REGS; i++)
|
||||
mRegs[i].ResetMask();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void NativeRegisterDataSet::ResetZeroPage(int addr)
|
||||
{
|
||||
mRegs[addr].Reset();
|
||||
|
@ -85,6 +98,15 @@ void NativeRegisterDataSet::ResetIndirect(void)
|
|||
}
|
||||
|
||||
|
||||
void NativeRegisterDataSet::IntersectMask(const NativeRegisterDataSet& set)
|
||||
{
|
||||
for (int i = 0; i < NUM_REGS; i++)
|
||||
{
|
||||
mRegs[i].mMask &= set.mRegs[i].mMask & ~(mRegs[i].mValue ^ set.mRegs[i].mValue);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void NativeRegisterDataSet::Intersect(const NativeRegisterDataSet& set)
|
||||
{
|
||||
|
||||
|
@ -1787,6 +1809,309 @@ void NativeCodeInstruction::Simulate(NativeRegisterDataSet& data)
|
|||
}
|
||||
}
|
||||
|
||||
bool NativeCodeInstruction::BitFieldForwarding(NativeRegisterDataSet& data, AsmInsType& carryop)
|
||||
{
|
||||
bool changed = false;
|
||||
|
||||
int iaddr = -1;
|
||||
|
||||
if (mMode == ASMIM_IMPLIED)
|
||||
iaddr = CPU_REG_A;
|
||||
else if (mMode == ASMIM_ZERO_PAGE)
|
||||
iaddr = mAddress;
|
||||
|
||||
switch (mType)
|
||||
{
|
||||
case ASMIT_JSR:
|
||||
data.ResetMask();
|
||||
break;
|
||||
case ASMIT_CLC:
|
||||
data.mRegs[CPU_REG_C].mMask = 1;
|
||||
data.mRegs[CPU_REG_C].mValue = 0;
|
||||
break;
|
||||
case ASMIT_SEC:
|
||||
data.mRegs[CPU_REG_C].mMask = 1;
|
||||
data.mRegs[CPU_REG_C].mValue = 1;
|
||||
break;
|
||||
|
||||
case ASMIT_CMP:
|
||||
case ASMIT_CPX:
|
||||
case ASMIT_CPY:
|
||||
data.mRegs[CPU_REG_C].mMask = 0;
|
||||
break;
|
||||
|
||||
case ASMIT_ADC:
|
||||
case ASMIT_SBC:
|
||||
data.mRegs[CPU_REG_C].mMask = 0;
|
||||
data.mRegs[CPU_REG_A].mMask = 0;
|
||||
break;
|
||||
|
||||
case ASMIT_LDA:
|
||||
if (mMode == ASMIM_ZERO_PAGE)
|
||||
{
|
||||
data.mRegs[CPU_REG_A].mMask = data.mRegs[mAddress].mMask;
|
||||
data.mRegs[CPU_REG_A].mValue = data.mRegs[mAddress].mValue;
|
||||
|
||||
if (data.mRegs[CPU_REG_A].mMask == 0xff)
|
||||
{
|
||||
mType = ASMIT_LDA;
|
||||
mMode = ASMIM_IMMEDIATE;
|
||||
mAddress = data.mRegs[CPU_REG_A].mValue;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
else if (mMode == ASMIM_IMMEDIATE)
|
||||
{
|
||||
data.mRegs[CPU_REG_A].mMask = 0xff;
|
||||
data.mRegs[CPU_REG_A].mValue = mAddress & 0xff;
|
||||
}
|
||||
else
|
||||
data.mRegs[CPU_REG_A].mMask = 0;
|
||||
break;
|
||||
case ASMIT_STA:
|
||||
if (mMode == ASMIM_ZERO_PAGE)
|
||||
{
|
||||
data.mRegs[mAddress].mMask = data.mRegs[CPU_REG_A].mMask;
|
||||
data.mRegs[mAddress].mValue = data.mRegs[CPU_REG_A].mValue;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case ASMIT_AND:
|
||||
if (mMode == ASMIM_ZERO_PAGE)
|
||||
{
|
||||
int zeros =
|
||||
(data.mRegs[mAddress].mMask & ~data.mRegs[mAddress].mValue) |
|
||||
(data.mRegs[CPU_REG_A].mMask & ~data.mRegs[CPU_REG_A].mValue);
|
||||
|
||||
int ones =
|
||||
(data.mRegs[mAddress].mMask & data.mRegs[mAddress].mValue) &
|
||||
(data.mRegs[CPU_REG_A].mMask & data.mRegs[CPU_REG_A].mValue);
|
||||
|
||||
data.mRegs[CPU_REG_A].mMask = ones | zeros;
|
||||
data.mRegs[CPU_REG_A].mValue = ones;
|
||||
|
||||
if (data.mRegs[CPU_REG_A].mMask == 0xff)
|
||||
{
|
||||
mType = ASMIT_LDA;
|
||||
mMode = ASMIM_IMMEDIATE;
|
||||
mAddress = data.mRegs[CPU_REG_A].mValue;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
else if (mMode == ASMIM_IMMEDIATE)
|
||||
{
|
||||
int zeros = ~mAddress | (data.mRegs[CPU_REG_A].mMask & ~data.mRegs[CPU_REG_A].mValue);
|
||||
|
||||
int ones = mAddress & (data.mRegs[CPU_REG_A].mMask & data.mRegs[CPU_REG_A].mValue);
|
||||
|
||||
data.mRegs[CPU_REG_A].mMask = ones | zeros;
|
||||
data.mRegs[CPU_REG_A].mValue = ones;
|
||||
|
||||
if (data.mRegs[CPU_REG_A].mMask == 0xff)
|
||||
{
|
||||
mType = ASMIT_LDA;
|
||||
mMode = ASMIM_IMMEDIATE;
|
||||
mAddress = data.mRegs[CPU_REG_A].mValue;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
data.mRegs[CPU_REG_A].mMask &= ~data.mRegs[CPU_REG_A].mValue;
|
||||
break;
|
||||
|
||||
case ASMIT_ORA:
|
||||
if (mMode == ASMIM_ZERO_PAGE)
|
||||
{
|
||||
int ones =
|
||||
(data.mRegs[mAddress].mMask & data.mRegs[mAddress].mValue) |
|
||||
(data.mRegs[CPU_REG_A].mMask & data.mRegs[CPU_REG_A].mValue);
|
||||
|
||||
int zeros =
|
||||
(data.mRegs[mAddress].mMask & ~data.mRegs[mAddress].mValue) &
|
||||
(data.mRegs[CPU_REG_A].mMask & ~data.mRegs[CPU_REG_A].mValue);
|
||||
|
||||
data.mRegs[CPU_REG_A].mMask = ones | zeros;
|
||||
data.mRegs[CPU_REG_A].mValue = ones;
|
||||
|
||||
if (data.mRegs[CPU_REG_A].mMask == 0xff)
|
||||
{
|
||||
mType = ASMIT_LDA;
|
||||
mMode = ASMIM_IMMEDIATE;
|
||||
mAddress = data.mRegs[CPU_REG_A].mValue;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
else if (mMode == ASMIM_IMMEDIATE)
|
||||
{
|
||||
int ones = mAddress | (data.mRegs[CPU_REG_A].mMask & data.mRegs[CPU_REG_A].mValue);
|
||||
|
||||
int zeros = ~ mAddress & (data.mRegs[CPU_REG_A].mMask & ~data.mRegs[CPU_REG_A].mValue);
|
||||
|
||||
data.mRegs[CPU_REG_A].mMask = ones | zeros;
|
||||
data.mRegs[CPU_REG_A].mValue = ones;
|
||||
|
||||
if (data.mRegs[CPU_REG_A].mMask == 0xff)
|
||||
{
|
||||
mType = ASMIT_LDA;
|
||||
mMode = ASMIM_IMMEDIATE;
|
||||
mAddress = data.mRegs[CPU_REG_A].mValue;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
data.mRegs[CPU_REG_A].mMask &= data.mRegs[CPU_REG_A].mValue;
|
||||
break;
|
||||
|
||||
case ASMIT_EOR:
|
||||
data.mRegs[CPU_REG_A].mMask = 0;
|
||||
break;
|
||||
|
||||
case ASMIT_TXA:
|
||||
case ASMIT_TYA:
|
||||
data.mRegs[CPU_REG_A].mMask = 0;
|
||||
break;
|
||||
|
||||
case ASMIT_INC:
|
||||
case ASMIT_DEC:
|
||||
case ASMIT_STX:
|
||||
case ASMIT_STY:
|
||||
if (mMode == ASMIM_ZERO_PAGE)
|
||||
data.mRegs[mAddress].mMask = 0;
|
||||
break;
|
||||
|
||||
case ASMIT_ASL:
|
||||
if (iaddr >= 0)
|
||||
{
|
||||
int mask = data.mRegs[iaddr].mMask, value = data.mRegs[iaddr].mValue;
|
||||
|
||||
data.mRegs[iaddr].mMask = ((mask << 1) & 0xff) | 0x01;
|
||||
data.mRegs[iaddr].mValue = ((value << 1) & 0xff);
|
||||
|
||||
if (mask & 0x80)
|
||||
{
|
||||
data.mRegs[CPU_REG_C].mMask = 1;
|
||||
data.mRegs[CPU_REG_C].mValue = value >> 7;
|
||||
}
|
||||
else
|
||||
data.mRegs[CPU_REG_C].mMask = 0;
|
||||
|
||||
if (mMode == ASMIM_IMPLIED && data.mRegs[CPU_REG_A].mMask == 0xff && data.mRegs[CPU_REG_C].mMask)
|
||||
{
|
||||
carryop = data.mRegs[CPU_REG_C].mValue ? ASMIT_SEC : ASMIT_CLC;
|
||||
mType = ASMIT_LDA;
|
||||
mMode = ASMIM_IMMEDIATE;
|
||||
mAddress = data.mRegs[CPU_REG_A].mValue;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
data.mRegs[CPU_REG_C].mMask = 0;
|
||||
break;
|
||||
|
||||
case ASMIT_LSR:
|
||||
if (iaddr >= 0)
|
||||
{
|
||||
int mask = data.mRegs[iaddr].mMask, value = data.mRegs[iaddr].mValue;
|
||||
|
||||
data.mRegs[iaddr].mMask = ((mask >> 1) & 0xff) | 0x80;
|
||||
data.mRegs[iaddr].mValue = ((value >> 1) & 0x7f);
|
||||
|
||||
if (mask & 0x01)
|
||||
{
|
||||
data.mRegs[CPU_REG_C].mMask = 1;
|
||||
data.mRegs[CPU_REG_C].mValue = value & 1;
|
||||
}
|
||||
else
|
||||
data.mRegs[CPU_REG_C].mMask = 0;
|
||||
|
||||
if (mMode == ASMIM_IMPLIED && data.mRegs[CPU_REG_A].mMask == 0xff && data.mRegs[CPU_REG_C].mMask)
|
||||
{
|
||||
carryop = data.mRegs[CPU_REG_C].mValue ? ASMIT_SEC : ASMIT_CLC;
|
||||
mType = ASMIT_LDA;
|
||||
mMode = ASMIM_IMMEDIATE;
|
||||
mAddress = data.mRegs[CPU_REG_A].mValue;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
data.mRegs[CPU_REG_C].mMask = 0;
|
||||
break;
|
||||
|
||||
case ASMIT_ROL:
|
||||
if (iaddr >= 0)
|
||||
{
|
||||
int mask = data.mRegs[iaddr].mMask, value = data.mRegs[iaddr].mValue;
|
||||
|
||||
data.mRegs[iaddr].mMask = (mask << 1) & 0xff;
|
||||
data.mRegs[iaddr].mValue = (value << 1) & 0xff;
|
||||
|
||||
if (data.mRegs[CPU_REG_C].mMask & 1)
|
||||
{
|
||||
data.mRegs[iaddr].mMask |= 1;
|
||||
data.mRegs[iaddr].mValue |= data.mRegs[CPU_REG_C].mValue & 1;
|
||||
}
|
||||
|
||||
if (mask & 0x80)
|
||||
{
|
||||
data.mRegs[CPU_REG_C].mMask = 1;
|
||||
data.mRegs[CPU_REG_C].mValue = value >> 7;
|
||||
}
|
||||
else
|
||||
data.mRegs[CPU_REG_C].mMask = 0;
|
||||
|
||||
if (mMode == ASMIM_IMPLIED && data.mRegs[CPU_REG_A].mMask == 0xff && data.mRegs[CPU_REG_C].mMask)
|
||||
{
|
||||
carryop = data.mRegs[CPU_REG_C].mValue ? ASMIT_SEC : ASMIT_CLC;
|
||||
mType = ASMIT_LDA;
|
||||
mMode = ASMIM_IMMEDIATE;
|
||||
mAddress = data.mRegs[CPU_REG_A].mValue;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
data.mRegs[CPU_REG_C].mMask = 0;
|
||||
break;
|
||||
|
||||
case ASMIT_ROR:
|
||||
if (iaddr >= 0)
|
||||
{
|
||||
int mask = data.mRegs[iaddr].mMask, value = data.mRegs[iaddr].mValue;
|
||||
|
||||
data.mRegs[iaddr].mMask = (mask >> 1) & 0xff;
|
||||
data.mRegs[iaddr].mValue = (value >> 1) & 0x7f;
|
||||
|
||||
if (data.mRegs[CPU_REG_C].mMask & 1)
|
||||
{
|
||||
data.mRegs[iaddr].mMask |= 0x80;
|
||||
data.mRegs[iaddr].mValue |= (data.mRegs[CPU_REG_C].mValue << 7) & 0x80;
|
||||
}
|
||||
|
||||
if (mask & 0x01)
|
||||
{
|
||||
data.mRegs[CPU_REG_C].mMask = 1;
|
||||
data.mRegs[CPU_REG_C].mValue = value & 1;
|
||||
}
|
||||
else
|
||||
data.mRegs[CPU_REG_C].mMask = 0;
|
||||
|
||||
if (mMode == ASMIM_IMPLIED && data.mRegs[CPU_REG_A].mMask == 0xff && data.mRegs[CPU_REG_C].mMask)
|
||||
{
|
||||
carryop = data.mRegs[CPU_REG_C].mValue ? ASMIT_SEC : ASMIT_CLC;
|
||||
mType = ASMIT_LDA;
|
||||
mMode = ASMIM_IMMEDIATE;
|
||||
mAddress = data.mRegs[CPU_REG_A].mValue;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
data.mRegs[CPU_REG_C].mMask = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
bool NativeCodeInstruction::ValueForwarding(NativeRegisterDataSet& data, AsmInsType& carryop, bool initial, bool final)
|
||||
{
|
||||
bool changed = false;
|
||||
|
@ -10107,7 +10432,14 @@ bool NativeCodeBasicBlock::ForwardAccuAddSub(void)
|
|||
for (int j = apred; j < i; j++)
|
||||
mIns[j].mLive |= LIVE_CPU_REG_A;
|
||||
|
||||
if (mIns[i].mLive & LIVE_CPU_REG_Z)
|
||||
{
|
||||
mIns[i].mType = ASMIT_ORA; mIns[i].mMode = ASMIM_IMMEDIATE; mIns[i].mAddress = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
mIns[i].mType = ASMIT_NOP; mIns[i].mMode = ASMIM_IMPLIED;
|
||||
}
|
||||
changed = true;
|
||||
}
|
||||
else if (i + 2 < mIns.Size() && mIns[i + 1].mType == ASMIT_CLC && mIns[i + 2].mType == ASMIT_ADC && mIns[i + 2].mMode == ASMIM_IMMEDIATE && !(mIns[i + 2].mLive & LIVE_CPU_REG_C))
|
||||
|
@ -11031,6 +11363,66 @@ bool NativeCodeBasicBlock::ExpandADCToBranch(NativeCodeProcedure* proc)
|
|||
|
||||
}
|
||||
|
||||
#if 1
|
||||
if (mIns.Size() >= 1 && mFalseJump)
|
||||
{
|
||||
int sz = mIns.Size();
|
||||
|
||||
if (mIns[sz - 1].mType == ASMIT_CMP || mIns[sz - 1].mType == ASMIT_CPX || mIns[sz - 1].mType == ASMIT_CPY)
|
||||
{
|
||||
if (mBranch == ASMIT_BEQ)
|
||||
{
|
||||
if (mFalseJump->mNumEntries == 1 && mTrueJump->mNumEntries == 2 && mFalseJump->mIns.Size() == 0)
|
||||
{
|
||||
if (mFalseJump->mBranch == ASMIT_BCC)
|
||||
{
|
||||
if (mFalseJump->mFalseJump == mTrueJump)
|
||||
{
|
||||
mBranch = ASMIT_BCS;
|
||||
mFalseJump = mFalseJump->mFalseJump;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
else if (mFalseJump->mBranch == ASMIT_BCS)
|
||||
{
|
||||
if (mFalseJump->mTrueJump == mTrueJump)
|
||||
{
|
||||
mBranch = ASMIT_BCS;
|
||||
mFalseJump = mFalseJump->mTrueJump;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (mBranch == ASMIT_BNE)
|
||||
{
|
||||
if (mTrueJump->mNumEntries == 1 && mFalseJump->mNumEntries == 2 && mTrueJump->mIns.Size() == 0)
|
||||
{
|
||||
if (mTrueJump->mBranch == ASMIT_BCC)
|
||||
{
|
||||
if (mTrueJump->mFalseJump == mFalseJump)
|
||||
{
|
||||
mBranch = ASMIT_BCC;
|
||||
mTrueJump = mTrueJump->mTrueJump;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
else if (mTrueJump->mBranch == ASMIT_BCS)
|
||||
{
|
||||
if (mTrueJump->mTrueJump == mFalseJump)
|
||||
{
|
||||
mBranch = ASMIT_BCC;
|
||||
mTrueJump = mTrueJump->mFalseJump;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
if (mTrueJump && mTrueJump->ExpandADCToBranch(proc))
|
||||
changed = true;
|
||||
if (mFalseJump && mFalseJump->ExpandADCToBranch(proc))
|
||||
|
@ -12783,10 +13175,12 @@ bool NativeCodeBasicBlock::JoinTAXARange(int from, int to)
|
|||
return false;
|
||||
}
|
||||
|
||||
int live = mIns[to].mLive;
|
||||
mIns.Remove(to);
|
||||
for (int i = start; i < from; i++)
|
||||
{
|
||||
mIns.Insert(to, mIns[start]);
|
||||
mIns[to].mLive |= live;
|
||||
mIns.Remove(start);
|
||||
}
|
||||
mIns.Remove(start);
|
||||
|
@ -12804,10 +13198,12 @@ bool NativeCodeBasicBlock::JoinTAXARange(int from, int to)
|
|||
return false;
|
||||
}
|
||||
|
||||
int live = mIns[to].mLive;
|
||||
mIns.Remove(to);
|
||||
for (int i = start; i < from; i++)
|
||||
{
|
||||
mIns.Insert(to, mIns[start]);
|
||||
mIns[to].mLive |= live;
|
||||
mIns.Remove(start);
|
||||
}
|
||||
mIns.Remove(start);
|
||||
|
@ -12829,10 +13225,12 @@ bool NativeCodeBasicBlock::JoinTAXARange(int from, int to)
|
|||
return false;
|
||||
}
|
||||
|
||||
int live = mIns[to].mLive;
|
||||
mIns.Remove(to);
|
||||
for (int i = start; i < from; i++)
|
||||
{
|
||||
mIns.Insert(to, mIns[start]);
|
||||
mIns[to].mLive |= live;
|
||||
mIns.Remove(start);
|
||||
}
|
||||
mIns.Remove(start);
|
||||
|
@ -12857,16 +13255,22 @@ bool NativeCodeBasicBlock::JoinTAXARange(int from, int to)
|
|||
|
||||
start--;
|
||||
|
||||
int plive = mIns[start].mLive;
|
||||
for (int i = from; i < to; i++)
|
||||
mIns[i].mLive |= plive;
|
||||
|
||||
if (mIns[to].mLive & LIVE_CPU_REG_Y)
|
||||
{
|
||||
for (int i = start; i < from; i++)
|
||||
mIns[i].mLive |= LIVE_CPU_REG_Y;
|
||||
}
|
||||
|
||||
int live = mIns[to].mLive;
|
||||
mIns.Remove(to);
|
||||
for (int i = start; i < from; i++)
|
||||
{
|
||||
mIns.Insert(to, mIns[start]);
|
||||
mIns[to].mLive |= live;
|
||||
mIns.Remove(start);
|
||||
}
|
||||
mIns.Remove(start);
|
||||
|
@ -13552,6 +13956,63 @@ bool NativeCodeBasicBlock::MoveIndirectLoadStoreDown(int at)
|
|||
return false;
|
||||
}
|
||||
|
||||
bool NativeCodeBasicBlock::MoveLoadIndirectTempStoreUp(int at)
|
||||
{
|
||||
// ldy #imm
|
||||
// lda (t0), y
|
||||
// sta t1
|
||||
|
||||
int j = at - 1;
|
||||
while (j >= 3)
|
||||
{
|
||||
if (mIns[j].mType == ASMIT_STA && mIns[j].mMode == ASMIM_ZERO_PAGE && (mIns[j].mAddress == mIns[at + 1].mAddress || mIns[j].mAddress == mIns[at + 1].mAddress + 1))
|
||||
{
|
||||
if (mIns[j - 3].mType == ASMIT_LDA && mIns[j - 3].mMode == ASMIM_ZERO_PAGE &&
|
||||
mIns[j - 2].mType == ASMIT_STA && mIns[j - 2].mMode == ASMIM_ZERO_PAGE &&
|
||||
mIns[j - 1].mType == ASMIT_LDA && mIns[j - 1].mMode == ASMIM_ZERO_PAGE &&
|
||||
mIns[j - 0].mType == ASMIT_STA && mIns[j - 0].mMode == ASMIM_ZERO_PAGE)
|
||||
{
|
||||
if (mIns[j - 2].mAddress == mIns[at + 1].mAddress &&
|
||||
mIns[j - 0].mAddress == mIns[at + 1].mAddress + 1 &&
|
||||
mIns[j - 1].mAddress == mIns[j - 3].mAddress + 1)
|
||||
{
|
||||
mIns[at + 1].mLive |= mIns[j].mLive;
|
||||
mIns[at + 2].mLive |= mIns[j].mLive;
|
||||
mIns[at + 3].mLive |= mIns[j].mLive;
|
||||
|
||||
mIns[at + 1].mAddress = mIns[j - 3].mAddress;
|
||||
mIns[at + 1].mLive |= LIVE_MEM;
|
||||
|
||||
mIns.Insert(j + 1, mIns[at + 2]);
|
||||
mIns.Insert(j + 1, mIns[at + 2]);
|
||||
mIns.Insert(j + 1, mIns[at + 2]);
|
||||
|
||||
mIns.Remove(at + 3);
|
||||
mIns.Remove(at + 3);
|
||||
mIns.Remove(at + 3);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mIns[j].ReferencesYReg())
|
||||
return false;
|
||||
if (mIns[j].ChangesZeroPage(mIns[at + 1].mAddress))
|
||||
return false;
|
||||
if (mIns[j].ChangesZeroPage(mIns[at + 1].mAddress + 1))
|
||||
return false;
|
||||
if (mIns[j].ReferencesZeroPage(mIns[at + 2].mAddress))
|
||||
return false;
|
||||
|
||||
j--;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NativeCodeBasicBlock::MoveIndirectLoadStoreUp(int at)
|
||||
{
|
||||
int j = at - 1;
|
||||
|
@ -14394,6 +14855,60 @@ bool NativeCodeBasicBlock::MoveCLCLoadAddZPStoreDown(int at)
|
|||
return false;
|
||||
}
|
||||
|
||||
bool NativeCodeBasicBlock::BitFieldForwarding(const NativeRegisterDataSet& data)
|
||||
{
|
||||
bool changed = false;
|
||||
|
||||
if (!mVisited)
|
||||
{
|
||||
mNDataSet = data;
|
||||
|
||||
if (mLoopHead)
|
||||
{
|
||||
mNDataSet.ResetMask();
|
||||
}
|
||||
else if (mNumEntries > 0)
|
||||
{
|
||||
if (mNumEntered > 0)
|
||||
mNDataSet.IntersectMask(mDataSet);
|
||||
|
||||
mNumEntered++;
|
||||
|
||||
if (mNumEntered < mNumEntries)
|
||||
{
|
||||
mDataSet = mNDataSet;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
mVisited = true;
|
||||
|
||||
for (int i = 0; i < mIns.Size(); i++)
|
||||
{
|
||||
AsmInsType carryop = ASMIT_NOP;
|
||||
|
||||
if (mIns[i].BitFieldForwarding(mNDataSet, carryop))
|
||||
changed = true;
|
||||
if (carryop != ASMIT_NOP)
|
||||
mIns.Insert(i + 1, NativeCodeInstruction(carryop));
|
||||
}
|
||||
|
||||
|
||||
if (mFalseJump)
|
||||
{
|
||||
mFDataSet = mNDataSet;
|
||||
|
||||
}
|
||||
|
||||
if (this->mTrueJump && this->mTrueJump->BitFieldForwarding(mNDataSet))
|
||||
changed = true;
|
||||
if (this->mFalseJump && this->mFalseJump->BitFieldForwarding(mFDataSet))
|
||||
changed = true;
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
bool NativeCodeBasicBlock::ValueForwarding(const NativeRegisterDataSet& data, bool global, bool final)
|
||||
{
|
||||
bool changed = false;
|
||||
|
@ -14509,10 +15024,14 @@ bool NativeCodeBasicBlock::ValueForwarding(const NativeRegisterDataSet& data, bo
|
|||
if (mNDataSet.mRegs[CPU_REG_C].mMode == NRDM_IMMEDIATE)
|
||||
{
|
||||
mBranch = ASMIT_JMP;
|
||||
mTrueJump->mNumEntries--;
|
||||
if (!mNDataSet.mRegs[CPU_REG_C].mValue)
|
||||
mTrueJump = fork->mFalseJump;
|
||||
else
|
||||
mTrueJump = fork->mTrueJump;
|
||||
mTrueJump->mNumEntries++;
|
||||
if (mFalseJump)
|
||||
mFalseJump->mNumEntries--;
|
||||
mFalseJump = nullptr;
|
||||
changed = true;
|
||||
}
|
||||
|
@ -14521,10 +15040,14 @@ bool NativeCodeBasicBlock::ValueForwarding(const NativeRegisterDataSet& data, bo
|
|||
if (mNDataSet.mRegs[CPU_REG_C].mMode == NRDM_IMMEDIATE)
|
||||
{
|
||||
mBranch = ASMIT_JMP;
|
||||
mTrueJump->mNumEntries--;
|
||||
if (mNDataSet.mRegs[CPU_REG_C].mValue)
|
||||
mTrueJump = fork->mFalseJump;
|
||||
else
|
||||
mTrueJump = fork->mTrueJump;
|
||||
mTrueJump->mNumEntries++;
|
||||
if (mFalseJump)
|
||||
mFalseJump->mNumEntries--;
|
||||
mFalseJump = nullptr;
|
||||
changed = true;
|
||||
}
|
||||
|
@ -14533,10 +15056,14 @@ bool NativeCodeBasicBlock::ValueForwarding(const NativeRegisterDataSet& data, bo
|
|||
if (mNDataSet.mRegs[CPU_REG_Z].mMode == NRDM_IMMEDIATE)
|
||||
{
|
||||
mBranch = ASMIT_JMP;
|
||||
mTrueJump->mNumEntries--;
|
||||
if (!mNDataSet.mRegs[CPU_REG_Z].mValue)
|
||||
mTrueJump = fork->mFalseJump;
|
||||
else
|
||||
mTrueJump = fork->mTrueJump;
|
||||
mTrueJump->mNumEntries++;
|
||||
if (mFalseJump)
|
||||
mFalseJump->mNumEntries--;
|
||||
mFalseJump = nullptr;
|
||||
changed = true;
|
||||
}
|
||||
|
@ -14562,10 +15089,14 @@ bool NativeCodeBasicBlock::ValueForwarding(const NativeRegisterDataSet& data, bo
|
|||
if (mNDataSet.mRegs[CPU_REG_Z].mMode == NRDM_IMMEDIATE)
|
||||
{
|
||||
mBranch = ASMIT_JMP;
|
||||
mTrueJump->mNumEntries--;
|
||||
if (mNDataSet.mRegs[CPU_REG_Z].mValue)
|
||||
mTrueJump = fork->mFalseJump;
|
||||
else
|
||||
mTrueJump = fork->mTrueJump;
|
||||
mTrueJump->mNumEntries++;
|
||||
if (mFalseJump)
|
||||
mFalseJump->mNumEntries--;
|
||||
mFalseJump = nullptr;
|
||||
changed = true;
|
||||
}
|
||||
|
@ -14574,10 +15105,14 @@ bool NativeCodeBasicBlock::ValueForwarding(const NativeRegisterDataSet& data, bo
|
|||
if (mNDataSet.mRegs[CPU_REG_Z].mMode == NRDM_IMMEDIATE)
|
||||
{
|
||||
mBranch = ASMIT_JMP;
|
||||
mTrueJump->mNumEntries--;
|
||||
if ((mNDataSet.mRegs[CPU_REG_Z].mValue & 0x80))
|
||||
mTrueJump = fork->mFalseJump;
|
||||
else
|
||||
mTrueJump = fork->mTrueJump;
|
||||
mTrueJump->mNumEntries++;
|
||||
if (mFalseJump)
|
||||
mFalseJump->mNumEntries--;
|
||||
mFalseJump = nullptr;
|
||||
changed = true;
|
||||
}
|
||||
|
@ -14586,10 +15121,14 @@ bool NativeCodeBasicBlock::ValueForwarding(const NativeRegisterDataSet& data, bo
|
|||
if (mNDataSet.mRegs[CPU_REG_Z].mMode == NRDM_IMMEDIATE)
|
||||
{
|
||||
mBranch = ASMIT_JMP;
|
||||
mTrueJump->mNumEntries--;
|
||||
if (!(mNDataSet.mRegs[CPU_REG_Z].mValue & 0x80))
|
||||
mTrueJump = fork->mFalseJump;
|
||||
else
|
||||
mTrueJump = fork->mTrueJump;
|
||||
mTrueJump->mNumEntries++;
|
||||
if (mFalseJump)
|
||||
mFalseJump->mNumEntries--;
|
||||
mFalseJump = nullptr;
|
||||
changed = true;
|
||||
}
|
||||
|
@ -17490,6 +18029,22 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
|
|||
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
// move load (),y store zp up to potential user
|
||||
for (int i = 4; i + 2 < mIns.Size(); i++)
|
||||
{
|
||||
if (mIns[i + 0].mType == ASMIT_LDY && mIns[i + 0].mMode == ASMIM_IMMEDIATE &&
|
||||
mIns[i + 1].mType == ASMIT_LDA && mIns[i + 1].mMode == ASMIM_INDIRECT_Y && !(mIns[i + 1].mLive & LIVE_MEM) &&
|
||||
mIns[i + 2].mType == ASMIT_STA && mIns[i + 2].mMode == ASMIM_ZERO_PAGE && !(mIns[i + 2].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_Z | LIVE_CPU_REG_Y)))
|
||||
{
|
||||
if (MoveLoadIndirectTempStoreUp(i))
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
CheckLive();
|
||||
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
// move load - store abs up to initial store
|
||||
//
|
||||
|
@ -18065,6 +18620,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
|
|||
|
||||
// Replace (a & 0x80) != 0 with bpl/bmi
|
||||
int sz = mIns.Size();
|
||||
|
||||
#if 1
|
||||
if (sz > 1 &&
|
||||
mIns[sz - 2].ChangesAccuAndFlag() &&
|
||||
|
@ -19994,7 +20550,18 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
|
|||
mIns[i + 0].mType = ASMIT_NOP; mIns[i + 0].mMode = ASMIM_IMPLIED;
|
||||
mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED;
|
||||
mIns[i + 3].mType = ASMIT_LDA; mIns[i + 3].mLive |= LIVE_CPU_REG_C;
|
||||
mIns[i + 4].mType = ASMIT_SBC;
|
||||
mIns[i + 4].mType = ASMIT_SBC; mIns[i + 4].mLive |= LIVE_CPU_REG_C;
|
||||
|
||||
if (mIns[i + 4].RequiresYReg())
|
||||
{
|
||||
mIns[i + 2].mLive |= LIVE_CPU_REG_Y;
|
||||
mIns[i + 3].mLive |= LIVE_CPU_REG_Y;
|
||||
}
|
||||
if (mIns[i + 4].RequiresXReg())
|
||||
{
|
||||
mIns[i + 2].mLive |= LIVE_CPU_REG_X;
|
||||
mIns[i + 3].mLive |= LIVE_CPU_REG_X;
|
||||
}
|
||||
|
||||
progress = true;
|
||||
}
|
||||
|
@ -20731,7 +21298,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
|
|||
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 + 1].mType = ASMIT_CLC; mIns[i + 1].mLive |= LIVE_CPU_REG_A | LIVE_CPU_REG_C;
|
||||
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;
|
||||
|
@ -20745,7 +21312,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
|
|||
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 + 1].mType = ASMIT_CLC; mIns[i + 1].mLive |= LIVE_CPU_REG_A | LIVE_CPU_REG_C;
|
||||
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;
|
||||
|
@ -21069,6 +21636,47 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
|
|||
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
if (i + 13 < mIns.Size())
|
||||
{
|
||||
if (mIns[i + 2].mType == ASMIT_ADC && mIns[i + 2].mMode == ASMIM_IMMEDIATE && mIns[i + 2].mAddress == 1)
|
||||
{
|
||||
printf("CHECK\n");
|
||||
}
|
||||
|
||||
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 == 1 &&
|
||||
mIns[i + 3].mType == ASMIT_STA && mIns[i + 3].mMode == ASMIM_ZERO_PAGE &&
|
||||
mIns[i + 4].mType == ASMIT_LDA &&
|
||||
mIns[i + 5].mType == ASMIT_ADC && mIns[i + 5].mMode == ASMIM_IMMEDIATE && mIns[i + 5].mAddress == 0 &&
|
||||
mIns[i + 6].mType == ASMIT_STA && mIns[i + 6].mMode == ASMIM_ZERO_PAGE &&
|
||||
|
||||
mIns[i + 7].mType == ASMIT_CLC &&
|
||||
mIns[i + 8].mType == ASMIT_LDA && mIns[i + 8].mMode == ASMIM_ZERO_PAGE && mIns[i + 8].mAddress == mIns[i + 3].mAddress && !(mIns[i + 8].mLive & LIVE_MEM) &&
|
||||
mIns[i + 9].mType == ASMIT_ADC &&
|
||||
mIns[i + 10].mType == ASMIT_STA &&
|
||||
mIns[i + 11].mType == ASMIT_LDA && mIns[i + 11].mMode == ASMIM_ZERO_PAGE && mIns[i + 11].mAddress == mIns[i + 6].mAddress && !(mIns[i + 11].mLive & LIVE_MEM) &&
|
||||
mIns[i + 12].mType == ASMIT_ADC &&
|
||||
mIns[i + 12].mType == ASMIT_STA)
|
||||
{
|
||||
mIns[i + 7].CopyMode(mIns[i + 0]);
|
||||
mIns[i + 11].CopyMode(mIns[i + 4]);
|
||||
mIns[i + 8].mType = ASMIT_SEC;
|
||||
|
||||
for (int j = 0; j < 7; j++)
|
||||
{
|
||||
mIns[i + j].mType = ASMIT_NOP;
|
||||
mIns[i + j].mMode = ASMIM_IMPLIED;
|
||||
mIns[i + j + 7].mLive |= mIns[i + 0].mLive;
|
||||
}
|
||||
|
||||
progress = true;
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#if 1
|
||||
if (pass > 1 && mIns[i].mMode == ASMIM_IMMEDIATE_ADDRESS && mIns[i].mLinkerObject && (mIns[i].mFlags & NCIF_LOWER) && !(mIns[i].mAddress & 0xff) && !(mIns[i].mLinkerObject->mAlignment & 0xff))
|
||||
|
@ -22102,6 +22710,20 @@ void NativeCodeProcedure::Optimize(void)
|
|||
|
||||
mEntryBlock->BuildDominatorTree(nullptr);
|
||||
|
||||
#if 1
|
||||
if (step > 3)
|
||||
{
|
||||
NativeRegisterDataSet data;
|
||||
|
||||
bool bchanged;
|
||||
do {
|
||||
ResetVisited();
|
||||
bchanged = mEntryBlock->BitFieldForwarding(data);
|
||||
} while (bchanged);
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
do
|
||||
{
|
||||
|
@ -22116,6 +22738,7 @@ void NativeCodeProcedure::Optimize(void)
|
|||
|
||||
} while (changed);
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
ResetVisited();
|
||||
if (mEntryBlock->PeepHoleOptimizer(this, step))
|
||||
|
@ -22298,10 +22921,14 @@ void NativeCodeProcedure::Optimize(void)
|
|||
if (mEntryBlock->ForwardAccuAddSub())
|
||||
changed = true;
|
||||
|
||||
#endif
|
||||
#if 1
|
||||
ResetVisited();
|
||||
if (mEntryBlock->ForwardZpYIndex(step >= 4))
|
||||
changed = true;
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
ResetVisited();
|
||||
if (mEntryBlock->ForwardZpXIndex(step >= 4))
|
||||
changed = true;
|
||||
|
@ -22596,6 +23223,13 @@ void NativeCodeProcedure::CompileInterBlock(InterCodeProcedure* iproc, InterCode
|
|||
block->LoadEffectiveAddress(iproc, iblock->mInstructions[i + 1], nullptr, ins, false);
|
||||
i++;
|
||||
}
|
||||
else if (i + 2 < iblock->mInstructions.Size() && ins->mOperator == IA_NEG &&
|
||||
iblock->mInstructions[i + 2]->mCode == IC_LEA && iblock->mInstructions[i + 2]->mSrc[0].mTemp == ins->mDst.mTemp && iblock->mInstructions[i + 2]->mSrc[0].mFinal &&
|
||||
iblock->mInstructions[i + 1]->mCode == IC_LOAD && iblock->mInstructions[i + 2]->mSrc[1].mTemp == iblock->mInstructions[i + 1]->mDst.mTemp && iblock->mInstructions[i + 2]->mSrc[1].mFinal)
|
||||
{
|
||||
block->LoadEffectiveAddress(iproc, iblock->mInstructions[i + 2], iblock->mInstructions[i + 1], ins, false);
|
||||
i+=2;
|
||||
}
|
||||
else
|
||||
block->UnaryOperator(iproc, this, ins);
|
||||
break;
|
||||
|
|
|
@ -20,13 +20,14 @@ enum NativeRegisterDataMode
|
|||
struct NativeRegisterData
|
||||
{
|
||||
NativeRegisterDataMode mMode;
|
||||
int mValue;
|
||||
int mValue, mMask;
|
||||
uint32 mFlags;
|
||||
LinkerObject * mLinkerObject;
|
||||
|
||||
NativeRegisterData(void);
|
||||
|
||||
void Reset(void);
|
||||
void ResetMask(void);
|
||||
|
||||
bool SameData(const NativeRegisterData& d) const;
|
||||
};
|
||||
|
@ -36,10 +37,13 @@ struct NativeRegisterDataSet
|
|||
NativeRegisterData mRegs[261];
|
||||
|
||||
void Reset(void);
|
||||
void ResetMask(void);
|
||||
|
||||
void ResetZeroPage(int addr);
|
||||
void ResetAbsolute(LinkerObject * linkerObject, int addr);
|
||||
void ResetIndirect(void);
|
||||
void Intersect(const NativeRegisterDataSet& set);
|
||||
void IntersectMask(const NativeRegisterDataSet& set);
|
||||
};
|
||||
|
||||
|
||||
|
@ -76,6 +80,7 @@ public:
|
|||
void Assemble(NativeCodeBasicBlock* block);
|
||||
void FilterRegUsage(NumberSet& requiredTemps, NumberSet& providedTemps);
|
||||
bool IsUsedResultInstructions(NumberSet& requiredTemps);
|
||||
bool BitFieldForwarding(NativeRegisterDataSet& data, AsmInsType& carryop);
|
||||
bool ValueForwarding(NativeRegisterDataSet& data, AsmInsType & carryop, bool initial, bool final);
|
||||
|
||||
void Simulate(NativeRegisterDataSet& data);
|
||||
|
@ -241,6 +246,7 @@ public:
|
|||
bool MoveIndirectLoadStoreUp(int at);
|
||||
bool MoveAbsoluteLoadStoreUp(int at);
|
||||
bool MoveLoadStoreOutOfXYRangeUp(int at);
|
||||
bool MoveLoadIndirectTempStoreUp(int at);
|
||||
|
||||
bool MoveLoadAddImmStoreAbsXUp(int at);
|
||||
bool MoveStaTaxLdaStaDown(int at);
|
||||
|
@ -289,6 +295,7 @@ public:
|
|||
bool ReverseReplaceTAX(int at);
|
||||
|
||||
bool ValueForwarding(const NativeRegisterDataSet& data, bool global, bool final);
|
||||
bool BitFieldForwarding(const NativeRegisterDataSet& data);
|
||||
|
||||
void CollectEntryBlocks(NativeCodeBasicBlock* block);
|
||||
|
||||
|
|
|
@ -20,6 +20,96 @@ SourcePath::~SourcePath(void)
|
|||
|
||||
}
|
||||
|
||||
bool SourceFile::ReadLineLZO(char* line)
|
||||
{
|
||||
if (mPos > 256)
|
||||
{
|
||||
memmove(mBuffer, mBuffer + mPos - 256, mFill + 256 - mPos);
|
||||
mFill -= mPos - 256;
|
||||
mPos = 256;
|
||||
}
|
||||
|
||||
assert(mFill >= 0 && mFill - mPos < 384 && mPos <= mFill);
|
||||
|
||||
int c;
|
||||
while (mLimit && mFill < 384 && (c = fgetc(mFile)) >= 0)
|
||||
{
|
||||
mLimit--;
|
||||
mBuffer[mFill++] = c;
|
||||
}
|
||||
|
||||
if (mPos < mFill)
|
||||
{
|
||||
int pi = 0;
|
||||
while (pi < 127 && mPos < mFill)
|
||||
{
|
||||
int bi = pi, bj = 0;
|
||||
for (int i = 1; i < mPos; i++)
|
||||
{
|
||||
int j = 0;
|
||||
while (j < 127 && mPos + j < mFill && mBuffer[mPos - i + j] == mBuffer[mPos + j])
|
||||
j++;
|
||||
|
||||
if (j > bj)
|
||||
{
|
||||
bi = i;
|
||||
bj = j;
|
||||
}
|
||||
}
|
||||
|
||||
if (bj >= 4)
|
||||
{
|
||||
if (pi > 0)
|
||||
{
|
||||
sprintf_s(line, 1024, "0x%02x, ", pi);
|
||||
|
||||
for (int i = 0; i < pi; i++)
|
||||
{
|
||||
char buffer[16];
|
||||
sprintf_s(buffer, 16, "0x%02x, ", (unsigned char)mBuffer[mPos - pi + i]);
|
||||
|
||||
strcat_s(line, 1024, buffer);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf_s(line, 1024, "0x%02x, 0x%02x, ", 128 + bj, bi);
|
||||
mPos += bj;
|
||||
|
||||
if (mFill == mPos)
|
||||
strcat_s(line, 1024, "0x00, ");
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mPos++;
|
||||
pi++;
|
||||
}
|
||||
}
|
||||
|
||||
sprintf_s(line, 1024, "0x%02x, ", pi);
|
||||
|
||||
for (int i = 0; i < pi; i++)
|
||||
{
|
||||
char buffer[16];
|
||||
sprintf_s(buffer, 16, "0x%02x, ", (unsigned char)mBuffer[mPos - pi + i]);
|
||||
|
||||
strcat_s(line, 1024, buffer);
|
||||
}
|
||||
|
||||
if (mFill == mPos)
|
||||
strcat_s(line, 1024, "0x00, ");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SourceFile::ReadLineRLE(char* line)
|
||||
{
|
||||
assert(mFill >= 0 && mFill < 256);
|
||||
|
@ -171,6 +261,10 @@ bool SourceFile::ReadLine(char* line)
|
|||
if (ReadLineRLE(line))
|
||||
return true;
|
||||
break;
|
||||
case SFM_BINARY_LZO:
|
||||
if (ReadLineLZO(line))
|
||||
return true;
|
||||
break;
|
||||
}
|
||||
|
||||
fclose(mFile);
|
||||
|
@ -233,6 +327,7 @@ bool SourceFile::Open(const char* name, const char* path, SourceFileMode mode)
|
|||
mMode = mode;
|
||||
mLimit = 0x10000;
|
||||
mFill = 0;
|
||||
mPos = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -18,7 +18,8 @@ enum SourceFileMode
|
|||
{
|
||||
SFM_TEXT,
|
||||
SFM_BINARY,
|
||||
SFM_BINARY_RLE
|
||||
SFM_BINARY_RLE,
|
||||
SFM_BINARY_LZO
|
||||
};
|
||||
class SourceFile
|
||||
{
|
||||
|
@ -31,12 +32,13 @@ public:
|
|||
SourceFileMode mMode;
|
||||
int mLimit;
|
||||
|
||||
char mBuffer[256];
|
||||
int mFill;
|
||||
char mBuffer[512];
|
||||
int mFill, mPos;
|
||||
|
||||
bool ReadLine(char* line);
|
||||
|
||||
bool ReadLineRLE(char* line);
|
||||
bool ReadLineLZO(char* line);
|
||||
|
||||
SourceFile(void);
|
||||
~SourceFile(void);
|
||||
|
|
|
@ -656,6 +656,8 @@ void Scanner::NextToken(void)
|
|||
{
|
||||
if (!strcmp(mTokenIdent->mString, "rle"))
|
||||
mode = SFM_BINARY_RLE;
|
||||
else if (!strcmp(mTokenIdent->mString, "lzo"))
|
||||
mode = SFM_BINARY_LZO;
|
||||
else
|
||||
mErrors->Error(mLocation, EERR_FILE_NOT_FOUND, "Invalid embed compression mode", mTokenIdent);
|
||||
|
||||
|
|
|
@ -73,7 +73,7 @@ int main2(int argc, const char** argv)
|
|||
|
||||
#else
|
||||
strcpy(strProductName, "oscar64");
|
||||
strcpy(strProductVersion, "1.5.121");
|
||||
strcpy(strProductVersion, "1.6.123");
|
||||
|
||||
#ifdef __APPLE__
|
||||
uint32_t length = sizeof(basePath);
|
||||
|
|
|
@ -25,8 +25,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_NEUTRAL
|
|||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 1,5,121,0
|
||||
PRODUCTVERSION 1,5,121,0
|
||||
FILEVERSION 1,6,123,0
|
||||
PRODUCTVERSION 1,6,123,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
|
@ -43,12 +43,12 @@ BEGIN
|
|||
BEGIN
|
||||
VALUE "CompanyName", "oscar64"
|
||||
VALUE "FileDescription", "oscar64 compiler"
|
||||
VALUE "FileVersion", "1.5.121.0"
|
||||
VALUE "FileVersion", "1.6.123.0"
|
||||
VALUE "InternalName", "oscar64.exe"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2021"
|
||||
VALUE "OriginalFilename", "oscar64.exe"
|
||||
VALUE "ProductName", "oscar64"
|
||||
VALUE "ProductVersion", "1.5.121.0"
|
||||
VALUE "ProductVersion", "1.6.123.0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
|
|
@ -130,6 +130,12 @@
|
|||
}
|
||||
"Entry"
|
||||
{
|
||||
"MsmKey" = "8:_24F2466589154E2DAA108C2EDB3BB432"
|
||||
"OwnerKey" = "8:_UNDEFINED"
|
||||
"MsmSig" = "8:_UNDEFINED"
|
||||
}
|
||||
"Entry"
|
||||
{
|
||||
"MsmKey" = "8:_29ED5D9B606D45DA80CFF329A7643DC8"
|
||||
"OwnerKey" = "8:_UNDEFINED"
|
||||
"MsmSig" = "8:_UNDEFINED"
|
||||
|
@ -274,6 +280,12 @@
|
|||
}
|
||||
"Entry"
|
||||
{
|
||||
"MsmKey" = "8:_557F7BC3AD794C4A93D5DFDA00024E1B"
|
||||
"OwnerKey" = "8:_UNDEFINED"
|
||||
"MsmSig" = "8:_UNDEFINED"
|
||||
}
|
||||
"Entry"
|
||||
{
|
||||
"MsmKey" = "8:_5832EB4DC2134FF0BB7872666547CA0B"
|
||||
"OwnerKey" = "8:_UNDEFINED"
|
||||
"MsmSig" = "8:_UNDEFINED"
|
||||
|
@ -664,6 +676,12 @@
|
|||
}
|
||||
"Entry"
|
||||
{
|
||||
"MsmKey" = "8:_CA8FE59769D748A5BF04ABC3F9154DBA"
|
||||
"OwnerKey" = "8:_UNDEFINED"
|
||||
"MsmSig" = "8:_UNDEFINED"
|
||||
}
|
||||
"Entry"
|
||||
{
|
||||
"MsmKey" = "8:_CC473A7B399D4B31A9DC8C94F7771EF7"
|
||||
"OwnerKey" = "8:_UNDEFINED"
|
||||
"MsmSig" = "8:_UNDEFINED"
|
||||
|
@ -1327,6 +1345,26 @@
|
|||
"IsDependency" = "11:FALSE"
|
||||
"IsolateTo" = "8:"
|
||||
}
|
||||
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_24F2466589154E2DAA108C2EDB3BB432"
|
||||
{
|
||||
"SourcePath" = "8:..\\include\\oscar.c"
|
||||
"TargetName" = "8:oscar.c"
|
||||
"Tag" = "8:"
|
||||
"Folder" = "8:_7C0D28C244F14A21B5F72213BBE59B6F"
|
||||
"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}:_29ED5D9B606D45DA80CFF329A7643DC8"
|
||||
{
|
||||
"SourcePath" = "8:..\\samples\\kernalio\\diskdir.c"
|
||||
|
@ -1807,6 +1845,26 @@
|
|||
"IsDependency" = "11:FALSE"
|
||||
"IsolateTo" = "8:"
|
||||
}
|
||||
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_557F7BC3AD794C4A93D5DFDA00024E1B"
|
||||
{
|
||||
"SourcePath" = "8:..\\samples\\memmap\\charsetexpand.c"
|
||||
"TargetName" = "8:charsetexpand.c"
|
||||
"Tag" = "8:"
|
||||
"Folder" = "8:_A62A71A6A08941C5964B90112D87731F"
|
||||
"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}:_5832EB4DC2134FF0BB7872666547CA0B"
|
||||
{
|
||||
"SourcePath" = "8:..\\samples\\sprites\\make.bat"
|
||||
|
@ -3107,6 +3165,26 @@
|
|||
"IsDependency" = "11:FALSE"
|
||||
"IsolateTo" = "8:"
|
||||
}
|
||||
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_CA8FE59769D748A5BF04ABC3F9154DBA"
|
||||
{
|
||||
"SourcePath" = "8:..\\include\\oscar.h"
|
||||
"TargetName" = "8:oscar.h"
|
||||
"Tag" = "8:"
|
||||
"Folder" = "8:_7C0D28C244F14A21B5F72213BBE59B6F"
|
||||
"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}:_CC473A7B399D4B31A9DC8C94F7771EF7"
|
||||
{
|
||||
"SourcePath" = "8:..\\samples\\memmap\\charsethi.c"
|
||||
|
@ -4023,15 +4101,15 @@
|
|||
{
|
||||
"Name" = "8:Microsoft Visual Studio"
|
||||
"ProductName" = "8:oscar64"
|
||||
"ProductCode" = "8:{9712E64F-8FDC-4FD2-BE20-8889E458BC89}"
|
||||
"PackageCode" = "8:{63C93E1F-200E-43F4-8A18-C9A7743F2543}"
|
||||
"ProductCode" = "8:{F66E2274-2B16-49B2-950F-83A3DC2EEA9D}"
|
||||
"PackageCode" = "8:{4F43842C-6F90-403A-8CE1-352F775F975F}"
|
||||
"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.5.121"
|
||||
"ProductVersion" = "8:1.6.123"
|
||||
"Manufacturer" = "8:oscar64"
|
||||
"ARPHELPTELEPHONE" = "8:"
|
||||
"ARPHELPLINK" = "8:"
|
||||
|
@ -4545,7 +4623,7 @@
|
|||
{
|
||||
"{5259A561-127C-4D43-A0A1-72F10C7B3BF8}:_FB2E467BC172457785F4279BB0BFE8B6"
|
||||
{
|
||||
"SourcePath" = "8:..\\Debug\\oscar64.exe"
|
||||
"SourcePath" = "8:..\\Release\\oscar64.exe"
|
||||
"TargetName" = "8:"
|
||||
"Tag" = "8:"
|
||||
"Folder" = "8:_607E75AF0E2A4CB9908C4C39DF8FE6E4"
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
../../bin/oscar64 charsetlo.c
|
||||
../../bin/oscar64 charsethi.c
|
||||
../../bin/oscar64 charsetcopy.c
|
||||
../../bin/oscar64 charsetexpand.c
|
||||
../../bin/oscar64 easyflash.c -n -tf=crt
|
||||
../../bin/oscar64 easyflashreloc.c -n -tf=crt
|
||||
../../bin/oscar64 easyflashshared.c -n -tf=crt
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
#include <c64/vic.h>
|
||||
#include <c64/memmap.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <oscar.h>
|
||||
|
||||
// make space until 0xcc00 by extending the default region
|
||||
|
||||
#pragma region( main, 0x0a00, 0xcc00, , , {code, data, bss, heap, stack} )
|
||||
|
||||
// space for our custom charset from c000 to c800, will be copied to
|
||||
// 0xd000 during startup to free space for stack and heap
|
||||
|
||||
#pragma section( charset, 0)
|
||||
|
||||
#pragma region( charset, 0xc000, 0xc800, , , {charset} )
|
||||
|
||||
// set initialized data segment to charset section
|
||||
|
||||
#pragma data(charset)
|
||||
|
||||
// lz compressed data
|
||||
char charset[] = {
|
||||
#embed 2048 0 lzo "../resources/charset.bin"
|
||||
}
|
||||
|
||||
// back to normal
|
||||
|
||||
#pragma data(data)
|
||||
|
||||
// pointers to charset and screen in memory
|
||||
|
||||
#define Screen ((char *)0xcc00)
|
||||
#define Charset ((char *)0xd000)
|
||||
|
||||
int main(void)
|
||||
{
|
||||
// Install the trampoline
|
||||
mmap_trampoline();
|
||||
|
||||
// make all of RAM visibile to the CPU
|
||||
mmap_set(MMAP_RAM);
|
||||
|
||||
// expand the font
|
||||
oscar_expand_lzo(Charset, charset);
|
||||
|
||||
// make lower part of RAM visible to CPU
|
||||
mmap_set(MMAP_NO_BASIC);
|
||||
|
||||
// map the vic to the new charset
|
||||
|
||||
vic_setmode(VICM_TEXT, Screen, Charset)
|
||||
|
||||
for(int i=0; i<1000; i++)
|
||||
Screen[i] = (char)i;
|
||||
|
||||
// wait for keypress
|
||||
|
||||
getchar();
|
||||
|
||||
// restore VIC
|
||||
|
||||
vic_setmode(VICM_TEXT, (char *)0x0400, (char *)0x1000)
|
||||
|
||||
// restore basic ROM
|
||||
mmap_set(MMAP_ROM);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -3,6 +3,7 @@ call ..\..\bin\oscar64 allmem.c
|
|||
call ..\..\bin\oscar64 charsetlo.c
|
||||
call ..\..\bin\oscar64 charsethi.c
|
||||
call ..\..\bin\oscar64 charsetcopy.c
|
||||
call ..\..\bin\oscar64 charsetexpand.c
|
||||
call ..\..\bin\oscar64 easyflash.c -n -tf=crt
|
||||
call ..\..\bin\oscar64 easyflashreloc.c -n -tf=crt
|
||||
call ..\..\bin\oscar64 easyflashshared.c -n -tf=crt
|
||||
|
|
Loading…
Reference in New Issue