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)
|
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)
|
if (channels[chn].state == SIDFX_IDLE)
|
||||||
channels[chn].state = SIDFX_READY;
|
channels[chn].state = SIDFX_READY;
|
||||||
|
@ -38,6 +40,7 @@ void sidfx_play(byte chn, SIDFX * fx, byte cnt)
|
||||||
channels[chn].com = fx;
|
channels[chn].com = fx;
|
||||||
channels[chn].cnt = cnt - 1;
|
channels[chn].cnt = cnt - 1;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void sidfx_stop(byte chn)
|
void sidfx_stop(byte chn)
|
||||||
{
|
{
|
||||||
|
|
|
@ -9,6 +9,7 @@ struct SIDFX
|
||||||
byte ctrl, attdec, susrel;
|
byte ctrl, attdec, susrel;
|
||||||
int dfreq, dpwm;
|
int dfreq, dpwm;
|
||||||
byte time1, time0;
|
byte time1, time0;
|
||||||
|
byte priority;
|
||||||
};
|
};
|
||||||
|
|
||||||
void sidfx_init(void);
|
void sidfx_init(void);
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
volatile char npos = 1, tpos = 0;
|
volatile char npos = 1, tpos = 0;
|
||||||
|
volatile byte rirq_count;
|
||||||
|
|
||||||
byte rasterIRQRows[NUM_IRQS];
|
byte rasterIRQRows[NUM_IRQS];
|
||||||
byte rasterIRQIndex[NUM_IRQS];
|
byte rasterIRQIndex[NUM_IRQS];
|
||||||
|
@ -62,6 +63,7 @@ w1:
|
||||||
e2:
|
e2:
|
||||||
ldx npos
|
ldx npos
|
||||||
stx tpos
|
stx tpos
|
||||||
|
inc rirq_count
|
||||||
|
|
||||||
bit $d011
|
bit $d011
|
||||||
bmi e1
|
bmi e1
|
||||||
|
@ -135,6 +137,7 @@ w1:
|
||||||
e2:
|
e2:
|
||||||
ldx npos
|
ldx npos
|
||||||
stx tpos
|
stx tpos
|
||||||
|
inc rirq_count
|
||||||
|
|
||||||
bit $d011
|
bit $d011
|
||||||
bmi e1
|
bmi e1
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
#define NUM_IRQS 16
|
#define NUM_IRQS 16
|
||||||
|
|
||||||
|
extern volatile byte rirq_count;
|
||||||
|
|
||||||
enum RIRQCodeIndex
|
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;
|
static int GlobalValueNumber = 0;
|
||||||
|
|
||||||
NativeRegisterData::NativeRegisterData(void)
|
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++;
|
mValue = GlobalValueNumber++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NativeRegisterData::ResetMask(void)
|
||||||
|
{
|
||||||
|
mMask = 0;
|
||||||
|
}
|
||||||
|
|
||||||
bool NativeRegisterData::SameData(const NativeRegisterData& d) const
|
bool NativeRegisterData::SameData(const NativeRegisterData& d) const
|
||||||
{
|
{
|
||||||
if (mMode != d.mMode)
|
if (mMode != d.mMode)
|
||||||
|
@ -56,6 +61,14 @@ void NativeRegisterDataSet::Reset(void)
|
||||||
mRegs[i].Reset();
|
mRegs[i].Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NativeRegisterDataSet::ResetMask(void)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < NUM_REGS; i++)
|
||||||
|
mRegs[i].ResetMask();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void NativeRegisterDataSet::ResetZeroPage(int addr)
|
void NativeRegisterDataSet::ResetZeroPage(int addr)
|
||||||
{
|
{
|
||||||
mRegs[addr].Reset();
|
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)
|
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 NativeCodeInstruction::ValueForwarding(NativeRegisterDataSet& data, AsmInsType& carryop, bool initial, bool final)
|
||||||
{
|
{
|
||||||
bool changed = false;
|
bool changed = false;
|
||||||
|
@ -10107,7 +10432,14 @@ bool NativeCodeBasicBlock::ForwardAccuAddSub(void)
|
||||||
for (int j = apred; j < i; j++)
|
for (int j = apred; j < i; j++)
|
||||||
mIns[j].mLive |= LIVE_CPU_REG_A;
|
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;
|
mIns[i].mType = ASMIT_NOP; mIns[i].mMode = ASMIM_IMPLIED;
|
||||||
|
}
|
||||||
changed = true;
|
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))
|
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))
|
if (mTrueJump && mTrueJump->ExpandADCToBranch(proc))
|
||||||
changed = true;
|
changed = true;
|
||||||
if (mFalseJump && mFalseJump->ExpandADCToBranch(proc))
|
if (mFalseJump && mFalseJump->ExpandADCToBranch(proc))
|
||||||
|
@ -12783,10 +13175,12 @@ bool NativeCodeBasicBlock::JoinTAXARange(int from, int to)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int live = mIns[to].mLive;
|
||||||
mIns.Remove(to);
|
mIns.Remove(to);
|
||||||
for (int i = start; i < from; i++)
|
for (int i = start; i < from; i++)
|
||||||
{
|
{
|
||||||
mIns.Insert(to, mIns[start]);
|
mIns.Insert(to, mIns[start]);
|
||||||
|
mIns[to].mLive |= live;
|
||||||
mIns.Remove(start);
|
mIns.Remove(start);
|
||||||
}
|
}
|
||||||
mIns.Remove(start);
|
mIns.Remove(start);
|
||||||
|
@ -12804,10 +13198,12 @@ bool NativeCodeBasicBlock::JoinTAXARange(int from, int to)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int live = mIns[to].mLive;
|
||||||
mIns.Remove(to);
|
mIns.Remove(to);
|
||||||
for (int i = start; i < from; i++)
|
for (int i = start; i < from; i++)
|
||||||
{
|
{
|
||||||
mIns.Insert(to, mIns[start]);
|
mIns.Insert(to, mIns[start]);
|
||||||
|
mIns[to].mLive |= live;
|
||||||
mIns.Remove(start);
|
mIns.Remove(start);
|
||||||
}
|
}
|
||||||
mIns.Remove(start);
|
mIns.Remove(start);
|
||||||
|
@ -12829,10 +13225,12 @@ bool NativeCodeBasicBlock::JoinTAXARange(int from, int to)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int live = mIns[to].mLive;
|
||||||
mIns.Remove(to);
|
mIns.Remove(to);
|
||||||
for (int i = start; i < from; i++)
|
for (int i = start; i < from; i++)
|
||||||
{
|
{
|
||||||
mIns.Insert(to, mIns[start]);
|
mIns.Insert(to, mIns[start]);
|
||||||
|
mIns[to].mLive |= live;
|
||||||
mIns.Remove(start);
|
mIns.Remove(start);
|
||||||
}
|
}
|
||||||
mIns.Remove(start);
|
mIns.Remove(start);
|
||||||
|
@ -12857,16 +13255,22 @@ bool NativeCodeBasicBlock::JoinTAXARange(int from, int to)
|
||||||
|
|
||||||
start--;
|
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)
|
if (mIns[to].mLive & LIVE_CPU_REG_Y)
|
||||||
{
|
{
|
||||||
for (int i = start; i < from; i++)
|
for (int i = start; i < from; i++)
|
||||||
mIns[i].mLive |= LIVE_CPU_REG_Y;
|
mIns[i].mLive |= LIVE_CPU_REG_Y;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int live = mIns[to].mLive;
|
||||||
mIns.Remove(to);
|
mIns.Remove(to);
|
||||||
for (int i = start; i < from; i++)
|
for (int i = start; i < from; i++)
|
||||||
{
|
{
|
||||||
mIns.Insert(to, mIns[start]);
|
mIns.Insert(to, mIns[start]);
|
||||||
|
mIns[to].mLive |= live;
|
||||||
mIns.Remove(start);
|
mIns.Remove(start);
|
||||||
}
|
}
|
||||||
mIns.Remove(start);
|
mIns.Remove(start);
|
||||||
|
@ -13552,6 +13956,63 @@ bool NativeCodeBasicBlock::MoveIndirectLoadStoreDown(int at)
|
||||||
return false;
|
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)
|
bool NativeCodeBasicBlock::MoveIndirectLoadStoreUp(int at)
|
||||||
{
|
{
|
||||||
int j = at - 1;
|
int j = at - 1;
|
||||||
|
@ -14394,6 +14855,60 @@ bool NativeCodeBasicBlock::MoveCLCLoadAddZPStoreDown(int at)
|
||||||
return false;
|
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 NativeCodeBasicBlock::ValueForwarding(const NativeRegisterDataSet& data, bool global, bool final)
|
||||||
{
|
{
|
||||||
bool changed = false;
|
bool changed = false;
|
||||||
|
@ -14509,10 +15024,14 @@ bool NativeCodeBasicBlock::ValueForwarding(const NativeRegisterDataSet& data, bo
|
||||||
if (mNDataSet.mRegs[CPU_REG_C].mMode == NRDM_IMMEDIATE)
|
if (mNDataSet.mRegs[CPU_REG_C].mMode == NRDM_IMMEDIATE)
|
||||||
{
|
{
|
||||||
mBranch = ASMIT_JMP;
|
mBranch = ASMIT_JMP;
|
||||||
|
mTrueJump->mNumEntries--;
|
||||||
if (!mNDataSet.mRegs[CPU_REG_C].mValue)
|
if (!mNDataSet.mRegs[CPU_REG_C].mValue)
|
||||||
mTrueJump = fork->mFalseJump;
|
mTrueJump = fork->mFalseJump;
|
||||||
else
|
else
|
||||||
mTrueJump = fork->mTrueJump;
|
mTrueJump = fork->mTrueJump;
|
||||||
|
mTrueJump->mNumEntries++;
|
||||||
|
if (mFalseJump)
|
||||||
|
mFalseJump->mNumEntries--;
|
||||||
mFalseJump = nullptr;
|
mFalseJump = nullptr;
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
|
@ -14521,10 +15040,14 @@ bool NativeCodeBasicBlock::ValueForwarding(const NativeRegisterDataSet& data, bo
|
||||||
if (mNDataSet.mRegs[CPU_REG_C].mMode == NRDM_IMMEDIATE)
|
if (mNDataSet.mRegs[CPU_REG_C].mMode == NRDM_IMMEDIATE)
|
||||||
{
|
{
|
||||||
mBranch = ASMIT_JMP;
|
mBranch = ASMIT_JMP;
|
||||||
|
mTrueJump->mNumEntries--;
|
||||||
if (mNDataSet.mRegs[CPU_REG_C].mValue)
|
if (mNDataSet.mRegs[CPU_REG_C].mValue)
|
||||||
mTrueJump = fork->mFalseJump;
|
mTrueJump = fork->mFalseJump;
|
||||||
else
|
else
|
||||||
mTrueJump = fork->mTrueJump;
|
mTrueJump = fork->mTrueJump;
|
||||||
|
mTrueJump->mNumEntries++;
|
||||||
|
if (mFalseJump)
|
||||||
|
mFalseJump->mNumEntries--;
|
||||||
mFalseJump = nullptr;
|
mFalseJump = nullptr;
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
|
@ -14533,10 +15056,14 @@ bool NativeCodeBasicBlock::ValueForwarding(const NativeRegisterDataSet& data, bo
|
||||||
if (mNDataSet.mRegs[CPU_REG_Z].mMode == NRDM_IMMEDIATE)
|
if (mNDataSet.mRegs[CPU_REG_Z].mMode == NRDM_IMMEDIATE)
|
||||||
{
|
{
|
||||||
mBranch = ASMIT_JMP;
|
mBranch = ASMIT_JMP;
|
||||||
|
mTrueJump->mNumEntries--;
|
||||||
if (!mNDataSet.mRegs[CPU_REG_Z].mValue)
|
if (!mNDataSet.mRegs[CPU_REG_Z].mValue)
|
||||||
mTrueJump = fork->mFalseJump;
|
mTrueJump = fork->mFalseJump;
|
||||||
else
|
else
|
||||||
mTrueJump = fork->mTrueJump;
|
mTrueJump = fork->mTrueJump;
|
||||||
|
mTrueJump->mNumEntries++;
|
||||||
|
if (mFalseJump)
|
||||||
|
mFalseJump->mNumEntries--;
|
||||||
mFalseJump = nullptr;
|
mFalseJump = nullptr;
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
|
@ -14562,10 +15089,14 @@ bool NativeCodeBasicBlock::ValueForwarding(const NativeRegisterDataSet& data, bo
|
||||||
if (mNDataSet.mRegs[CPU_REG_Z].mMode == NRDM_IMMEDIATE)
|
if (mNDataSet.mRegs[CPU_REG_Z].mMode == NRDM_IMMEDIATE)
|
||||||
{
|
{
|
||||||
mBranch = ASMIT_JMP;
|
mBranch = ASMIT_JMP;
|
||||||
|
mTrueJump->mNumEntries--;
|
||||||
if (mNDataSet.mRegs[CPU_REG_Z].mValue)
|
if (mNDataSet.mRegs[CPU_REG_Z].mValue)
|
||||||
mTrueJump = fork->mFalseJump;
|
mTrueJump = fork->mFalseJump;
|
||||||
else
|
else
|
||||||
mTrueJump = fork->mTrueJump;
|
mTrueJump = fork->mTrueJump;
|
||||||
|
mTrueJump->mNumEntries++;
|
||||||
|
if (mFalseJump)
|
||||||
|
mFalseJump->mNumEntries--;
|
||||||
mFalseJump = nullptr;
|
mFalseJump = nullptr;
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
|
@ -14574,10 +15105,14 @@ bool NativeCodeBasicBlock::ValueForwarding(const NativeRegisterDataSet& data, bo
|
||||||
if (mNDataSet.mRegs[CPU_REG_Z].mMode == NRDM_IMMEDIATE)
|
if (mNDataSet.mRegs[CPU_REG_Z].mMode == NRDM_IMMEDIATE)
|
||||||
{
|
{
|
||||||
mBranch = ASMIT_JMP;
|
mBranch = ASMIT_JMP;
|
||||||
|
mTrueJump->mNumEntries--;
|
||||||
if ((mNDataSet.mRegs[CPU_REG_Z].mValue & 0x80))
|
if ((mNDataSet.mRegs[CPU_REG_Z].mValue & 0x80))
|
||||||
mTrueJump = fork->mFalseJump;
|
mTrueJump = fork->mFalseJump;
|
||||||
else
|
else
|
||||||
mTrueJump = fork->mTrueJump;
|
mTrueJump = fork->mTrueJump;
|
||||||
|
mTrueJump->mNumEntries++;
|
||||||
|
if (mFalseJump)
|
||||||
|
mFalseJump->mNumEntries--;
|
||||||
mFalseJump = nullptr;
|
mFalseJump = nullptr;
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
|
@ -14586,10 +15121,14 @@ bool NativeCodeBasicBlock::ValueForwarding(const NativeRegisterDataSet& data, bo
|
||||||
if (mNDataSet.mRegs[CPU_REG_Z].mMode == NRDM_IMMEDIATE)
|
if (mNDataSet.mRegs[CPU_REG_Z].mMode == NRDM_IMMEDIATE)
|
||||||
{
|
{
|
||||||
mBranch = ASMIT_JMP;
|
mBranch = ASMIT_JMP;
|
||||||
|
mTrueJump->mNumEntries--;
|
||||||
if (!(mNDataSet.mRegs[CPU_REG_Z].mValue & 0x80))
|
if (!(mNDataSet.mRegs[CPU_REG_Z].mValue & 0x80))
|
||||||
mTrueJump = fork->mFalseJump;
|
mTrueJump = fork->mFalseJump;
|
||||||
else
|
else
|
||||||
mTrueJump = fork->mTrueJump;
|
mTrueJump = fork->mTrueJump;
|
||||||
|
mTrueJump->mNumEntries++;
|
||||||
|
if (mFalseJump)
|
||||||
|
mFalseJump->mNumEntries--;
|
||||||
mFalseJump = nullptr;
|
mFalseJump = nullptr;
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
|
@ -17490,6 +18029,22 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
|
||||||
|
|
||||||
#endif
|
#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
|
#if 1
|
||||||
// move load - store abs up to initial store
|
// 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
|
// Replace (a & 0x80) != 0 with bpl/bmi
|
||||||
int sz = mIns.Size();
|
int sz = mIns.Size();
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
if (sz > 1 &&
|
if (sz > 1 &&
|
||||||
mIns[sz - 2].ChangesAccuAndFlag() &&
|
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 + 0].mType = ASMIT_NOP; mIns[i + 0].mMode = ASMIM_IMPLIED;
|
||||||
mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].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 + 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;
|
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 + 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 + 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 + 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 + 3].mType = ASMIT_TAY;
|
||||||
mIns[i + 4].mType = ASMIT_NOP;
|
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 + 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 + 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 + 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 + 3].mType = ASMIT_TAX;
|
||||||
mIns[i + 4].mType = ASMIT_NOP;
|
mIns[i + 4].mType = ASMIT_NOP;
|
||||||
|
@ -21069,6 +21636,47 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
|
||||||
|
|
||||||
#endif
|
#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
|
#endif
|
||||||
#if 1
|
#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))
|
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);
|
mEntryBlock->BuildDominatorTree(nullptr);
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
if (step > 3)
|
||||||
|
{
|
||||||
|
NativeRegisterDataSet data;
|
||||||
|
|
||||||
|
bool bchanged;
|
||||||
|
do {
|
||||||
|
ResetVisited();
|
||||||
|
bchanged = mEntryBlock->BitFieldForwarding(data);
|
||||||
|
} while (bchanged);
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
|
@ -22116,6 +22738,7 @@ void NativeCodeProcedure::Optimize(void)
|
||||||
|
|
||||||
} while (changed);
|
} while (changed);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
ResetVisited();
|
ResetVisited();
|
||||||
if (mEntryBlock->PeepHoleOptimizer(this, step))
|
if (mEntryBlock->PeepHoleOptimizer(this, step))
|
||||||
|
@ -22298,10 +22921,14 @@ void NativeCodeProcedure::Optimize(void)
|
||||||
if (mEntryBlock->ForwardAccuAddSub())
|
if (mEntryBlock->ForwardAccuAddSub())
|
||||||
changed = true;
|
changed = true;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
#if 1
|
||||||
ResetVisited();
|
ResetVisited();
|
||||||
if (mEntryBlock->ForwardZpYIndex(step >= 4))
|
if (mEntryBlock->ForwardZpYIndex(step >= 4))
|
||||||
changed = true;
|
changed = true;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if 1
|
||||||
ResetVisited();
|
ResetVisited();
|
||||||
if (mEntryBlock->ForwardZpXIndex(step >= 4))
|
if (mEntryBlock->ForwardZpXIndex(step >= 4))
|
||||||
changed = true;
|
changed = true;
|
||||||
|
@ -22596,6 +23223,13 @@ void NativeCodeProcedure::CompileInterBlock(InterCodeProcedure* iproc, InterCode
|
||||||
block->LoadEffectiveAddress(iproc, iblock->mInstructions[i + 1], nullptr, ins, false);
|
block->LoadEffectiveAddress(iproc, iblock->mInstructions[i + 1], nullptr, ins, false);
|
||||||
i++;
|
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
|
else
|
||||||
block->UnaryOperator(iproc, this, ins);
|
block->UnaryOperator(iproc, this, ins);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -20,13 +20,14 @@ enum NativeRegisterDataMode
|
||||||
struct NativeRegisterData
|
struct NativeRegisterData
|
||||||
{
|
{
|
||||||
NativeRegisterDataMode mMode;
|
NativeRegisterDataMode mMode;
|
||||||
int mValue;
|
int mValue, mMask;
|
||||||
uint32 mFlags;
|
uint32 mFlags;
|
||||||
LinkerObject * mLinkerObject;
|
LinkerObject * mLinkerObject;
|
||||||
|
|
||||||
NativeRegisterData(void);
|
NativeRegisterData(void);
|
||||||
|
|
||||||
void Reset(void);
|
void Reset(void);
|
||||||
|
void ResetMask(void);
|
||||||
|
|
||||||
bool SameData(const NativeRegisterData& d) const;
|
bool SameData(const NativeRegisterData& d) const;
|
||||||
};
|
};
|
||||||
|
@ -36,10 +37,13 @@ struct NativeRegisterDataSet
|
||||||
NativeRegisterData mRegs[261];
|
NativeRegisterData mRegs[261];
|
||||||
|
|
||||||
void Reset(void);
|
void Reset(void);
|
||||||
|
void ResetMask(void);
|
||||||
|
|
||||||
void ResetZeroPage(int addr);
|
void ResetZeroPage(int addr);
|
||||||
void ResetAbsolute(LinkerObject * linkerObject, int addr);
|
void ResetAbsolute(LinkerObject * linkerObject, int addr);
|
||||||
void ResetIndirect(void);
|
void ResetIndirect(void);
|
||||||
void Intersect(const NativeRegisterDataSet& set);
|
void Intersect(const NativeRegisterDataSet& set);
|
||||||
|
void IntersectMask(const NativeRegisterDataSet& set);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -76,6 +80,7 @@ public:
|
||||||
void Assemble(NativeCodeBasicBlock* block);
|
void Assemble(NativeCodeBasicBlock* block);
|
||||||
void FilterRegUsage(NumberSet& requiredTemps, NumberSet& providedTemps);
|
void FilterRegUsage(NumberSet& requiredTemps, NumberSet& providedTemps);
|
||||||
bool IsUsedResultInstructions(NumberSet& requiredTemps);
|
bool IsUsedResultInstructions(NumberSet& requiredTemps);
|
||||||
|
bool BitFieldForwarding(NativeRegisterDataSet& data, AsmInsType& carryop);
|
||||||
bool ValueForwarding(NativeRegisterDataSet& data, AsmInsType & carryop, bool initial, bool final);
|
bool ValueForwarding(NativeRegisterDataSet& data, AsmInsType & carryop, bool initial, bool final);
|
||||||
|
|
||||||
void Simulate(NativeRegisterDataSet& data);
|
void Simulate(NativeRegisterDataSet& data);
|
||||||
|
@ -241,6 +246,7 @@ public:
|
||||||
bool MoveIndirectLoadStoreUp(int at);
|
bool MoveIndirectLoadStoreUp(int at);
|
||||||
bool MoveAbsoluteLoadStoreUp(int at);
|
bool MoveAbsoluteLoadStoreUp(int at);
|
||||||
bool MoveLoadStoreOutOfXYRangeUp(int at);
|
bool MoveLoadStoreOutOfXYRangeUp(int at);
|
||||||
|
bool MoveLoadIndirectTempStoreUp(int at);
|
||||||
|
|
||||||
bool MoveLoadAddImmStoreAbsXUp(int at);
|
bool MoveLoadAddImmStoreAbsXUp(int at);
|
||||||
bool MoveStaTaxLdaStaDown(int at);
|
bool MoveStaTaxLdaStaDown(int at);
|
||||||
|
@ -289,6 +295,7 @@ public:
|
||||||
bool ReverseReplaceTAX(int at);
|
bool ReverseReplaceTAX(int at);
|
||||||
|
|
||||||
bool ValueForwarding(const NativeRegisterDataSet& data, bool global, bool final);
|
bool ValueForwarding(const NativeRegisterDataSet& data, bool global, bool final);
|
||||||
|
bool BitFieldForwarding(const NativeRegisterDataSet& data);
|
||||||
|
|
||||||
void CollectEntryBlocks(NativeCodeBasicBlock* block);
|
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)
|
bool SourceFile::ReadLineRLE(char* line)
|
||||||
{
|
{
|
||||||
assert(mFill >= 0 && mFill < 256);
|
assert(mFill >= 0 && mFill < 256);
|
||||||
|
@ -171,6 +261,10 @@ bool SourceFile::ReadLine(char* line)
|
||||||
if (ReadLineRLE(line))
|
if (ReadLineRLE(line))
|
||||||
return true;
|
return true;
|
||||||
break;
|
break;
|
||||||
|
case SFM_BINARY_LZO:
|
||||||
|
if (ReadLineLZO(line))
|
||||||
|
return true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(mFile);
|
fclose(mFile);
|
||||||
|
@ -233,6 +327,7 @@ bool SourceFile::Open(const char* name, const char* path, SourceFileMode mode)
|
||||||
mMode = mode;
|
mMode = mode;
|
||||||
mLimit = 0x10000;
|
mLimit = 0x10000;
|
||||||
mFill = 0;
|
mFill = 0;
|
||||||
|
mPos = 0;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,8 @@ enum SourceFileMode
|
||||||
{
|
{
|
||||||
SFM_TEXT,
|
SFM_TEXT,
|
||||||
SFM_BINARY,
|
SFM_BINARY,
|
||||||
SFM_BINARY_RLE
|
SFM_BINARY_RLE,
|
||||||
|
SFM_BINARY_LZO
|
||||||
};
|
};
|
||||||
class SourceFile
|
class SourceFile
|
||||||
{
|
{
|
||||||
|
@ -31,12 +32,13 @@ public:
|
||||||
SourceFileMode mMode;
|
SourceFileMode mMode;
|
||||||
int mLimit;
|
int mLimit;
|
||||||
|
|
||||||
char mBuffer[256];
|
char mBuffer[512];
|
||||||
int mFill;
|
int mFill, mPos;
|
||||||
|
|
||||||
bool ReadLine(char* line);
|
bool ReadLine(char* line);
|
||||||
|
|
||||||
bool ReadLineRLE(char* line);
|
bool ReadLineRLE(char* line);
|
||||||
|
bool ReadLineLZO(char* line);
|
||||||
|
|
||||||
SourceFile(void);
|
SourceFile(void);
|
||||||
~SourceFile(void);
|
~SourceFile(void);
|
||||||
|
|
|
@ -656,6 +656,8 @@ void Scanner::NextToken(void)
|
||||||
{
|
{
|
||||||
if (!strcmp(mTokenIdent->mString, "rle"))
|
if (!strcmp(mTokenIdent->mString, "rle"))
|
||||||
mode = SFM_BINARY_RLE;
|
mode = SFM_BINARY_RLE;
|
||||||
|
else if (!strcmp(mTokenIdent->mString, "lzo"))
|
||||||
|
mode = SFM_BINARY_LZO;
|
||||||
else
|
else
|
||||||
mErrors->Error(mLocation, EERR_FILE_NOT_FOUND, "Invalid embed compression mode", mTokenIdent);
|
mErrors->Error(mLocation, EERR_FILE_NOT_FOUND, "Invalid embed compression mode", mTokenIdent);
|
||||||
|
|
||||||
|
|
|
@ -73,7 +73,7 @@ int main2(int argc, const char** argv)
|
||||||
|
|
||||||
#else
|
#else
|
||||||
strcpy(strProductName, "oscar64");
|
strcpy(strProductName, "oscar64");
|
||||||
strcpy(strProductVersion, "1.5.121");
|
strcpy(strProductVersion, "1.6.123");
|
||||||
|
|
||||||
#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,5,121,0
|
FILEVERSION 1,6,123,0
|
||||||
PRODUCTVERSION 1,5,121,0
|
PRODUCTVERSION 1,6,123,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.5.121.0"
|
VALUE "FileVersion", "1.6.123.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.5.121.0"
|
VALUE "ProductVersion", "1.6.123.0"
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
BLOCK "VarFileInfo"
|
BLOCK "VarFileInfo"
|
||||||
|
|
|
@ -130,6 +130,12 @@
|
||||||
}
|
}
|
||||||
"Entry"
|
"Entry"
|
||||||
{
|
{
|
||||||
|
"MsmKey" = "8:_24F2466589154E2DAA108C2EDB3BB432"
|
||||||
|
"OwnerKey" = "8:_UNDEFINED"
|
||||||
|
"MsmSig" = "8:_UNDEFINED"
|
||||||
|
}
|
||||||
|
"Entry"
|
||||||
|
{
|
||||||
"MsmKey" = "8:_29ED5D9B606D45DA80CFF329A7643DC8"
|
"MsmKey" = "8:_29ED5D9B606D45DA80CFF329A7643DC8"
|
||||||
"OwnerKey" = "8:_UNDEFINED"
|
"OwnerKey" = "8:_UNDEFINED"
|
||||||
"MsmSig" = "8:_UNDEFINED"
|
"MsmSig" = "8:_UNDEFINED"
|
||||||
|
@ -274,6 +280,12 @@
|
||||||
}
|
}
|
||||||
"Entry"
|
"Entry"
|
||||||
{
|
{
|
||||||
|
"MsmKey" = "8:_557F7BC3AD794C4A93D5DFDA00024E1B"
|
||||||
|
"OwnerKey" = "8:_UNDEFINED"
|
||||||
|
"MsmSig" = "8:_UNDEFINED"
|
||||||
|
}
|
||||||
|
"Entry"
|
||||||
|
{
|
||||||
"MsmKey" = "8:_5832EB4DC2134FF0BB7872666547CA0B"
|
"MsmKey" = "8:_5832EB4DC2134FF0BB7872666547CA0B"
|
||||||
"OwnerKey" = "8:_UNDEFINED"
|
"OwnerKey" = "8:_UNDEFINED"
|
||||||
"MsmSig" = "8:_UNDEFINED"
|
"MsmSig" = "8:_UNDEFINED"
|
||||||
|
@ -664,6 +676,12 @@
|
||||||
}
|
}
|
||||||
"Entry"
|
"Entry"
|
||||||
{
|
{
|
||||||
|
"MsmKey" = "8:_CA8FE59769D748A5BF04ABC3F9154DBA"
|
||||||
|
"OwnerKey" = "8:_UNDEFINED"
|
||||||
|
"MsmSig" = "8:_UNDEFINED"
|
||||||
|
}
|
||||||
|
"Entry"
|
||||||
|
{
|
||||||
"MsmKey" = "8:_CC473A7B399D4B31A9DC8C94F7771EF7"
|
"MsmKey" = "8:_CC473A7B399D4B31A9DC8C94F7771EF7"
|
||||||
"OwnerKey" = "8:_UNDEFINED"
|
"OwnerKey" = "8:_UNDEFINED"
|
||||||
"MsmSig" = "8:_UNDEFINED"
|
"MsmSig" = "8:_UNDEFINED"
|
||||||
|
@ -1327,6 +1345,26 @@
|
||||||
"IsDependency" = "11:FALSE"
|
"IsDependency" = "11:FALSE"
|
||||||
"IsolateTo" = "8:"
|
"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"
|
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_29ED5D9B606D45DA80CFF329A7643DC8"
|
||||||
{
|
{
|
||||||
"SourcePath" = "8:..\\samples\\kernalio\\diskdir.c"
|
"SourcePath" = "8:..\\samples\\kernalio\\diskdir.c"
|
||||||
|
@ -1807,6 +1845,26 @@
|
||||||
"IsDependency" = "11:FALSE"
|
"IsDependency" = "11:FALSE"
|
||||||
"IsolateTo" = "8:"
|
"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"
|
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_5832EB4DC2134FF0BB7872666547CA0B"
|
||||||
{
|
{
|
||||||
"SourcePath" = "8:..\\samples\\sprites\\make.bat"
|
"SourcePath" = "8:..\\samples\\sprites\\make.bat"
|
||||||
|
@ -3107,6 +3165,26 @@
|
||||||
"IsDependency" = "11:FALSE"
|
"IsDependency" = "11:FALSE"
|
||||||
"IsolateTo" = "8:"
|
"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"
|
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_CC473A7B399D4B31A9DC8C94F7771EF7"
|
||||||
{
|
{
|
||||||
"SourcePath" = "8:..\\samples\\memmap\\charsethi.c"
|
"SourcePath" = "8:..\\samples\\memmap\\charsethi.c"
|
||||||
|
@ -4023,15 +4101,15 @@
|
||||||
{
|
{
|
||||||
"Name" = "8:Microsoft Visual Studio"
|
"Name" = "8:Microsoft Visual Studio"
|
||||||
"ProductName" = "8:oscar64"
|
"ProductName" = "8:oscar64"
|
||||||
"ProductCode" = "8:{9712E64F-8FDC-4FD2-BE20-8889E458BC89}"
|
"ProductCode" = "8:{F66E2274-2B16-49B2-950F-83A3DC2EEA9D}"
|
||||||
"PackageCode" = "8:{63C93E1F-200E-43F4-8A18-C9A7743F2543}"
|
"PackageCode" = "8:{4F43842C-6F90-403A-8CE1-352F775F975F}"
|
||||||
"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.5.121"
|
"ProductVersion" = "8:1.6.123"
|
||||||
"Manufacturer" = "8:oscar64"
|
"Manufacturer" = "8:oscar64"
|
||||||
"ARPHELPTELEPHONE" = "8:"
|
"ARPHELPTELEPHONE" = "8:"
|
||||||
"ARPHELPLINK" = "8:"
|
"ARPHELPLINK" = "8:"
|
||||||
|
@ -4545,7 +4623,7 @@
|
||||||
{
|
{
|
||||||
"{5259A561-127C-4D43-A0A1-72F10C7B3BF8}:_FB2E467BC172457785F4279BB0BFE8B6"
|
"{5259A561-127C-4D43-A0A1-72F10C7B3BF8}:_FB2E467BC172457785F4279BB0BFE8B6"
|
||||||
{
|
{
|
||||||
"SourcePath" = "8:..\\Debug\\oscar64.exe"
|
"SourcePath" = "8:..\\Release\\oscar64.exe"
|
||||||
"TargetName" = "8:"
|
"TargetName" = "8:"
|
||||||
"Tag" = "8:"
|
"Tag" = "8:"
|
||||||
"Folder" = "8:_607E75AF0E2A4CB9908C4C39DF8FE6E4"
|
"Folder" = "8:_607E75AF0E2A4CB9908C4C39DF8FE6E4"
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
../../bin/oscar64 charsetlo.c
|
../../bin/oscar64 charsetlo.c
|
||||||
../../bin/oscar64 charsethi.c
|
../../bin/oscar64 charsethi.c
|
||||||
../../bin/oscar64 charsetcopy.c
|
../../bin/oscar64 charsetcopy.c
|
||||||
|
../../bin/oscar64 charsetexpand.c
|
||||||
../../bin/oscar64 easyflash.c -n -tf=crt
|
../../bin/oscar64 easyflash.c -n -tf=crt
|
||||||
../../bin/oscar64 easyflashreloc.c -n -tf=crt
|
../../bin/oscar64 easyflashreloc.c -n -tf=crt
|
||||||
../../bin/oscar64 easyflashshared.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 charsetlo.c
|
||||||
call ..\..\bin\oscar64 charsethi.c
|
call ..\..\bin\oscar64 charsethi.c
|
||||||
call ..\..\bin\oscar64 charsetcopy.c
|
call ..\..\bin\oscar64 charsetcopy.c
|
||||||
|
call ..\..\bin\oscar64 charsetexpand.c
|
||||||
call ..\..\bin\oscar64 easyflash.c -n -tf=crt
|
call ..\..\bin\oscar64 easyflash.c -n -tf=crt
|
||||||
call ..\..\bin\oscar64 easyflashreloc.c -n -tf=crt
|
call ..\..\bin\oscar64 easyflashreloc.c -n -tf=crt
|
||||||
call ..\..\bin\oscar64 easyflashshared.c -n -tf=crt
|
call ..\..\bin\oscar64 easyflashshared.c -n -tf=crt
|
||||||
|
|
Loading…
Reference in New Issue