Add iecbus library
This commit is contained in:
parent
e6b46a3acf
commit
cdbb24b6b2
|
@ -63,7 +63,7 @@ The compiler can also be built using MSVC or GCC. A visual studio project and a
|
||||||
|
|
||||||
The compiler is command line driven, and creates an executable .prg file.
|
The compiler is command line driven, and creates an executable .prg file.
|
||||||
|
|
||||||
oscar64 {-i=includePath} [-o=output.prg] [-rt=runtime.c] [-tf=format] [-e] [-n] [-dSYMBOL[=value]] {source.c}
|
oscar64 {-i=includePath} [-o=output.prg] [-rt=runtime.c] [-tf=format] [-tm=machine] [-e] [-n] [-dSYMBOL[=value]] {source.c}
|
||||||
|
|
||||||
* -v : verbose output for diagnostics
|
* -v : verbose output for diagnostics
|
||||||
* -v2 : more verbose output
|
* -v2 : more verbose output
|
||||||
|
|
|
@ -0,0 +1,238 @@
|
||||||
|
#include "iecbus.h"
|
||||||
|
#include <c64/cia.h>
|
||||||
|
#include <c64/vic.h>
|
||||||
|
|
||||||
|
IEC_STATUS iec_status;
|
||||||
|
|
||||||
|
#define CIA2B_ATNOUT 0x08
|
||||||
|
#define CIA2B_CLKOUT 0x10
|
||||||
|
#define CIA2B_DATAOUT 0x20
|
||||||
|
|
||||||
|
#define CIA2B_CLKIN 0x40
|
||||||
|
#define CIA2B_DATAIN 0x80
|
||||||
|
|
||||||
|
#pragma optimize(push)
|
||||||
|
#pragma optimize(1)
|
||||||
|
|
||||||
|
static void delay(char n)
|
||||||
|
{
|
||||||
|
while (n)
|
||||||
|
{
|
||||||
|
__asm {
|
||||||
|
nop
|
||||||
|
}
|
||||||
|
n--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void data_low(void)
|
||||||
|
{
|
||||||
|
cia2.pra &= ~CIA2B_DATAOUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void data_high(void)
|
||||||
|
{
|
||||||
|
cia2.pra |= CIA2B_DATAOUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void clock_low(void)
|
||||||
|
{
|
||||||
|
cia2.pra &= ~CIA2B_CLKOUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void cdata_low(void)
|
||||||
|
{
|
||||||
|
cia2.pra &= ~(CIA2B_CLKOUT | CIA2B_DATAOUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void clock_high(void)
|
||||||
|
{
|
||||||
|
cia2.pra |= CIA2B_CLKOUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void atn_low(void)
|
||||||
|
{
|
||||||
|
cia2.pra &= ~CIA2B_ATNOUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void atn_high(void)
|
||||||
|
{
|
||||||
|
cia2.pra |= CIA2B_ATNOUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool data_check(void)
|
||||||
|
{
|
||||||
|
char cnt = 100;
|
||||||
|
while (cnt > 0 && (cia2.pra & CIA2B_DATAIN))
|
||||||
|
cnt--;
|
||||||
|
|
||||||
|
if (cnt)
|
||||||
|
return true;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
iec_status = IEC_TIMEOUT;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool iec_eoi(void)
|
||||||
|
{
|
||||||
|
cdata_low();
|
||||||
|
|
||||||
|
while (!(cia2.pra & CIA2B_DATAIN))
|
||||||
|
;
|
||||||
|
delay(50);
|
||||||
|
|
||||||
|
return data_check();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool iec_write(char b)
|
||||||
|
{
|
||||||
|
cdata_low();
|
||||||
|
|
||||||
|
while (!(cia2.pra & CIA2B_DATAIN))
|
||||||
|
;
|
||||||
|
|
||||||
|
for(char i=0; i<8; i++)
|
||||||
|
{
|
||||||
|
clock_high();
|
||||||
|
if (b & 1)
|
||||||
|
data_low();
|
||||||
|
else
|
||||||
|
data_high();
|
||||||
|
clock_low();
|
||||||
|
b >>= 1;
|
||||||
|
__asm
|
||||||
|
{
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
data_low();
|
||||||
|
clock_high();
|
||||||
|
|
||||||
|
return data_check();
|
||||||
|
}
|
||||||
|
|
||||||
|
char iec_read(void)
|
||||||
|
{
|
||||||
|
while (!(cia2.pra & CIA2B_CLKIN))
|
||||||
|
;
|
||||||
|
|
||||||
|
data_low();
|
||||||
|
|
||||||
|
char cnt = 100;
|
||||||
|
while (cnt > 0 && (cia2.pra & CIA2B_CLKIN))
|
||||||
|
cnt--;
|
||||||
|
|
||||||
|
if (cnt == 0)
|
||||||
|
{
|
||||||
|
iec_status = IEC_EOF;
|
||||||
|
data_high();
|
||||||
|
__asm
|
||||||
|
{
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
}
|
||||||
|
data_low();
|
||||||
|
|
||||||
|
cnt = 200;
|
||||||
|
while (cnt > 0 && (cia2.pra & CIA2B_CLKIN))
|
||||||
|
cnt--;
|
||||||
|
|
||||||
|
if (cnt == 0)
|
||||||
|
{
|
||||||
|
iec_status = IEC_TIMEOUT;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
char b = 0;
|
||||||
|
for(char i=0; i<8; i++)
|
||||||
|
{
|
||||||
|
char c;
|
||||||
|
while (!((c = cia2.pra) & CIA2B_CLKIN))
|
||||||
|
;
|
||||||
|
|
||||||
|
b >>= 1;
|
||||||
|
b |= c & 0x80;
|
||||||
|
|
||||||
|
while (cia2.pra & CIA2B_CLKIN)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
data_high();
|
||||||
|
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
void iec_atn(char dev, char sec)
|
||||||
|
{
|
||||||
|
atn_high();
|
||||||
|
clock_high();
|
||||||
|
|
||||||
|
delay(100);
|
||||||
|
|
||||||
|
iec_write(dev);
|
||||||
|
if (sec != 0xff)
|
||||||
|
iec_write(sec);
|
||||||
|
|
||||||
|
data_high();
|
||||||
|
atn_low();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void iec_talk(char dev, char sec)
|
||||||
|
{
|
||||||
|
iec_status = IEC_OK;
|
||||||
|
|
||||||
|
iec_atn(dev | 0x40, sec);
|
||||||
|
clock_low();
|
||||||
|
}
|
||||||
|
|
||||||
|
void iec_untalk(void)
|
||||||
|
{
|
||||||
|
iec_atn(0x5f, 0xff);
|
||||||
|
}
|
||||||
|
|
||||||
|
void iec_listen(char dev, char sec)
|
||||||
|
{
|
||||||
|
iec_status = IEC_OK;
|
||||||
|
|
||||||
|
iec_atn(dev | 0x20, sec);
|
||||||
|
}
|
||||||
|
|
||||||
|
void iec_unlisten(void)
|
||||||
|
{
|
||||||
|
iec_atn(0x3f, 0xff);
|
||||||
|
}
|
||||||
|
|
||||||
|
void iec_open(char dev, char sec, const char * fname)
|
||||||
|
{
|
||||||
|
iec_status = IEC_OK;
|
||||||
|
|
||||||
|
iec_atn(dev | 0x20, sec | 0xf0);
|
||||||
|
char i = 0;
|
||||||
|
while (fname[i])
|
||||||
|
{
|
||||||
|
if (!fname[i + 1])
|
||||||
|
iec_eoi();
|
||||||
|
iec_write(fname[i]);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
iec_unlisten();
|
||||||
|
}
|
||||||
|
|
||||||
|
void iec_close(char dev, char sec)
|
||||||
|
{
|
||||||
|
iec_atn(dev | 0x20, sec | 0xe0);
|
||||||
|
iec_unlisten();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#pragma optimize(pop)
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
#ifndef C64_IECBUS_H
|
||||||
|
#define C64_IECBUS_H
|
||||||
|
|
||||||
|
enum IEC_STATUS
|
||||||
|
{
|
||||||
|
IEC_OK = 0x00,
|
||||||
|
IEC_EOF = 0x01,
|
||||||
|
|
||||||
|
IEC_ERROR = 0x80,
|
||||||
|
IEC_TIMEOUT
|
||||||
|
};
|
||||||
|
|
||||||
|
extern IEC_STATUS iec_status;
|
||||||
|
|
||||||
|
bool iec_eoi(void);
|
||||||
|
|
||||||
|
bool iec_write(char b);
|
||||||
|
|
||||||
|
char iec_read(void);
|
||||||
|
|
||||||
|
void iec_atn(char dev, char sec);
|
||||||
|
|
||||||
|
void iec_talk(char dev, char sec);
|
||||||
|
|
||||||
|
void iec_untalk(void);
|
||||||
|
|
||||||
|
void iec_listen(char dev, char sec);
|
||||||
|
|
||||||
|
void iec_unlisten(void);
|
||||||
|
|
||||||
|
void iec_open(char dev, char sec, const char * fname);
|
||||||
|
|
||||||
|
void iec_close(char dev, char sec);
|
||||||
|
|
||||||
|
#pragma compile("iecbus.c")
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
#ifndef NES_MMC1_H
|
#ifndef NES_MMC1_H
|
||||||
#define NES_MMC1_H
|
#define NES_MMC1_H
|
||||||
|
|
||||||
|
|
||||||
#include <c64/types.h>
|
#include <c64/types.h>
|
||||||
|
|
||||||
enum MMC1Mirror
|
enum MMC1Mirror
|
||||||
|
|
|
@ -19226,14 +19226,14 @@ bool NativeCodeBasicBlock::JoinTailCodeSequences(NativeCodeProcedure* proc, bool
|
||||||
int ns = mIns.Size();
|
int ns = mIns.Size();
|
||||||
if ((mIns[ns - 2].mType == ASMIT_INY || mIns[ns - 2].mType == ASMIT_DEY) && mIns[ns - 1].mType == ASMIT_TYA)
|
if ((mIns[ns - 2].mType == ASMIT_INY || mIns[ns - 2].mType == ASMIT_DEY) && mIns[ns - 1].mType == ASMIT_TYA)
|
||||||
{
|
{
|
||||||
if (mBranch == ASMIT_BEQ && !mFalseJump->mEntryRequiredRegs[CPU_REG_A])
|
if (mBranch == ASMIT_BEQ && !mFalseJump->mEntryRequiredRegs[CPU_REG_A] && mTrueJump->mNumEntries == 1)
|
||||||
{
|
{
|
||||||
mTrueJump->mIns.Insert(0, NativeCodeInstruction(mIns[ns - 1].mIns, ASMIT_LDA, ASMIM_IMMEDIATE, 0));
|
mTrueJump->mIns.Insert(0, NativeCodeInstruction(mIns[ns - 1].mIns, ASMIT_LDA, ASMIM_IMMEDIATE, 0));
|
||||||
mIns[ns - 1].mType = ASMIT_NOP;
|
mIns[ns - 1].mType = ASMIT_NOP;
|
||||||
mIns[ns - 2].mLive |= LIVE_CPU_REG_Z;
|
mIns[ns - 2].mLive |= LIVE_CPU_REG_Z;
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
else if (mBranch == ASMIT_BNE && !mTrueJump->mEntryRequiredRegs[CPU_REG_A])
|
else if (mBranch == ASMIT_BNE && !mTrueJump->mEntryRequiredRegs[CPU_REG_A] && mFalseJump->mNumEntries == 1)
|
||||||
{
|
{
|
||||||
mFalseJump->mIns.Insert(0, NativeCodeInstruction(mIns[ns - 1].mIns, ASMIT_LDA, ASMIM_IMMEDIATE, 0));
|
mFalseJump->mIns.Insert(0, NativeCodeInstruction(mIns[ns - 1].mIns, ASMIT_LDA, ASMIM_IMMEDIATE, 0));
|
||||||
mIns[ns - 1].mType = ASMIT_NOP;
|
mIns[ns - 1].mType = ASMIT_NOP;
|
||||||
|
@ -19243,14 +19243,14 @@ bool NativeCodeBasicBlock::JoinTailCodeSequences(NativeCodeProcedure* proc, bool
|
||||||
}
|
}
|
||||||
else if ((mIns[ns - 2].mType == ASMIT_INX || mIns[ns - 2].mType == ASMIT_DEX) && mIns[ns - 1].mType == ASMIT_TXA)
|
else if ((mIns[ns - 2].mType == ASMIT_INX || mIns[ns - 2].mType == ASMIT_DEX) && mIns[ns - 1].mType == ASMIT_TXA)
|
||||||
{
|
{
|
||||||
if (mBranch == ASMIT_BEQ && !mFalseJump->mEntryRequiredRegs[CPU_REG_A])
|
if (mBranch == ASMIT_BEQ && !mFalseJump->mEntryRequiredRegs[CPU_REG_A] && mTrueJump->mNumEntries == 1)
|
||||||
{
|
{
|
||||||
mTrueJump->mIns.Insert(0, NativeCodeInstruction(mIns[ns - 1].mIns, ASMIT_LDA, ASMIM_IMMEDIATE, 0));
|
mTrueJump->mIns.Insert(0, NativeCodeInstruction(mIns[ns - 1].mIns, ASMIT_LDA, ASMIM_IMMEDIATE, 0));
|
||||||
mIns[ns - 1].mType = ASMIT_NOP;
|
mIns[ns - 1].mType = ASMIT_NOP;
|
||||||
mIns[ns - 2].mLive |= LIVE_CPU_REG_Z;
|
mIns[ns - 2].mLive |= LIVE_CPU_REG_Z;
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
else if (mBranch == ASMIT_BNE && !mTrueJump->mEntryRequiredRegs[CPU_REG_A])
|
else if (mBranch == ASMIT_BNE && !mTrueJump->mEntryRequiredRegs[CPU_REG_A] && mFalseJump->mNumEntries == 1)
|
||||||
{
|
{
|
||||||
mFalseJump->mIns.Insert(0, NativeCodeInstruction(mIns[ns - 1].mIns, ASMIT_LDA, ASMIM_IMMEDIATE, 0));
|
mFalseJump->mIns.Insert(0, NativeCodeInstruction(mIns[ns - 1].mIns, ASMIT_LDA, ASMIM_IMMEDIATE, 0));
|
||||||
mIns[ns - 1].mType = ASMIT_NOP;
|
mIns[ns - 1].mType = ASMIT_NOP;
|
||||||
|
@ -19283,6 +19283,37 @@ bool NativeCodeBasicBlock::JoinTailCodeSequences(NativeCodeProcedure* proc, bool
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
if (mIns.Size() >= 2 && mNumEntries == 1)
|
||||||
|
{
|
||||||
|
if (mIns[0].mType == ASMIT_TYA && mIns[1].IsShift() && mIns[1].mMode == ASMIM_IMPLIED)
|
||||||
|
{
|
||||||
|
NativeCodeBasicBlock* block = mEntryBlocks[0];
|
||||||
|
int ns = block->mIns.Size();
|
||||||
|
if (ns >= 2 && block->mIns[ns - 2].mType == ASMIT_TAY && block->mIns[ns - 1].IsSame(mIns[1]))
|
||||||
|
{
|
||||||
|
mIns[0].mType = ASMIT_NOP; mIns[0].mMode = ASMIM_IMPLIED;
|
||||||
|
mIns[1].mType = ASMIT_NOP; mIns[1].mMode = ASMIM_IMPLIED;
|
||||||
|
block->mIns[ns - 1].mLive |= LIVE_CPU_REG_A | LIVE_CPU_REG_C;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (mIns.Size() >= 1 && mNumEntries == 1)
|
||||||
|
{
|
||||||
|
if (mIns[0].IsShift() && mIns[0].mMode == ASMIM_ZERO_PAGE && !(mIns[0].mLive & LIVE_MEM))
|
||||||
|
{
|
||||||
|
NativeCodeBasicBlock* block = mEntryBlocks[0];
|
||||||
|
int ns = block->mIns.Size();
|
||||||
|
if (ns >= 2 &&
|
||||||
|
block->mIns[ns - 2].mType == ASMIT_STA && block->mIns[ns - 2].SameEffectiveAddress(mIns[0]) &&
|
||||||
|
block->mIns[ns - 1].mType == mIns[0].mType && block->mIns[ns - 1].mMode == ASMIM_IMPLIED && !(mIns[0].mLive & LIVE_MEM))
|
||||||
|
{
|
||||||
|
mIns[0].mType = ASMIT_NOP; mIns[0].mMode = ASMIM_IMPLIED;
|
||||||
|
block->mIns[ns - 1].mLive |= LIVE_CPU_REG_A | LIVE_CPU_REG_C;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
#if 1
|
#if 1
|
||||||
if (mIns.Size() >= 2)
|
if (mIns.Size() >= 2)
|
||||||
{
|
{
|
||||||
|
@ -20300,6 +20331,47 @@ bool NativeCodeBasicBlock::FoldLoopEntry(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!changed && mTrueJump && mFalseJump && mIns.Size() >= 2)
|
||||||
|
{
|
||||||
|
int sz = mIns.Size();
|
||||||
|
|
||||||
|
if (mIns[sz - 2].mType == ASMIT_LDA && ((mIns[sz - 1].mType == ASMIT_AND && mIns[sz - 1].mMode == ASMIM_IMMEDIATE) || (mIns[sz - 1].IsShift() && mIns[sz - 1].mMode == ASMIM_IMPLIED)))
|
||||||
|
{
|
||||||
|
if (mTrueJump->mIns.Size() == 2 && mTrueJump != this)
|
||||||
|
{
|
||||||
|
if (mTrueJump->mIns[0].IsSame(mIns[sz - 2]) && mTrueJump->mIns[1].IsSame(mIns[sz - 1]))
|
||||||
|
{
|
||||||
|
if (mBranch == mTrueJump->mBranch && mFalseJump == mTrueJump->mFalseJump && mTrueJump == mTrueJump->mTrueJump ||
|
||||||
|
mBranch == InvertBranchCondition(mTrueJump->mBranch) && mFalseJump == mTrueJump->mTrueJump && mTrueJump == mTrueJump->mFalseJump)
|
||||||
|
{
|
||||||
|
mIns[sz - 1].mType = ASMIT_NOP; mIns[sz - 1].mMode = ASMIM_IMPLIED;
|
||||||
|
mIns[sz - 2].mType = ASMIT_NOP; mIns[sz - 2].mMode = ASMIM_IMPLIED;
|
||||||
|
mBranch = ASMIT_JMP;
|
||||||
|
mFalseJump->RemEntryBlock(this);
|
||||||
|
mFalseJump = nullptr;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!changed && mFalseJump->mIns.Size() == 2 && mFalseJump != this)
|
||||||
|
{
|
||||||
|
if (mFalseJump->mIns[0].IsSame(mIns[sz - 2]) && mFalseJump->mIns[1].IsSame(mIns[sz - 1]))
|
||||||
|
{
|
||||||
|
if (mBranch == mFalseJump->mBranch && mFalseJump == mFalseJump->mFalseJump && mFalseJump == mTrueJump->mTrueJump ||
|
||||||
|
mBranch == InvertBranchCondition(mFalseJump->mBranch) && mFalseJump == mFalseJump->mTrueJump && mTrueJump == mFalseJump->mFalseJump)
|
||||||
|
{
|
||||||
|
mIns[sz - 1].mType = ASMIT_NOP;
|
||||||
|
mIns[sz - 1].mMode = ASMIM_IMPLIED;
|
||||||
|
mBranch = ASMIT_JMP;
|
||||||
|
mTrueJump->RemEntryBlock(this);
|
||||||
|
mTrueJump = mFalseJump;
|
||||||
|
mFalseJump = nullptr;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (mTrueJump && mTrueJump->FoldLoopEntry())
|
if (mTrueJump && mTrueJump->FoldLoopEntry())
|
||||||
changed = true;
|
changed = true;
|
||||||
|
@ -33930,6 +34002,17 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
|
||||||
mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED;
|
mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED;
|
||||||
progress = true;
|
progress = true;
|
||||||
}
|
}
|
||||||
|
#if 1
|
||||||
|
else if (
|
||||||
|
mIns[i + 0].mType == ASMIT_STX && mIns[i + 0].mMode == ASMIM_ZERO_PAGE &&
|
||||||
|
mIns[i + 1].IsShift() && mIns[i + 1].mMode == ASMIM_ZERO_PAGE && mIns[i + 1].mAddress == mIns[i + 0].mAddress && !(mIns[i + 1].mLive & (LIVE_CPU_REG_A | LIVE_MEM)))
|
||||||
|
{
|
||||||
|
mIns[i + 0].mType = ASMIT_TXA; mIns[i + 0].mMode = ASMIM_IMPLIED; mIns[i + 0].mLive |= LIVE_CPU_REG_A;
|
||||||
|
mIns[i + 1].mMode = ASMIM_IMPLIED;
|
||||||
|
progress = true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
else if (
|
else if (
|
||||||
mIns[i + 0].mType == ASMIT_LDA && mIns[i + 0].mMode == ASMIM_IMMEDIATE &&
|
mIns[i + 0].mType == ASMIT_LDA && mIns[i + 0].mMode == ASMIM_IMMEDIATE &&
|
||||||
|
@ -35476,6 +35559,16 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
|
||||||
|
|
||||||
progress = true;
|
progress = true;
|
||||||
}
|
}
|
||||||
|
else if (
|
||||||
|
mIns[i + 0].mType == ASMIT_LDA &&
|
||||||
|
mIns[i + 1].IsShift() && mIns[i + 1].mMode == ASMIM_IMPLIED &&
|
||||||
|
mIns[i + 2].mType == mIns[i + 1].mType && mIns[i + 2].SameEffectiveAddress(mIns[i + 0]) &&
|
||||||
|
mIns[i + 3].mType == ASMIT_STA && mIns[i + 3].SameEffectiveAddress(mIns[i + 0]))
|
||||||
|
{
|
||||||
|
mIns[i + 2].mType = ASMIT_NOP; mIns[i + 2].mMode = ASMIM_IMPLIED;
|
||||||
|
mIns[i + 1].mLive |= LIVE_CPU_REG_C;
|
||||||
|
progress = true;
|
||||||
|
}
|
||||||
else if (
|
else if (
|
||||||
mIns[i + 0].mType == ASMIT_STA && mIns[i + 0].mMode == ASMIM_ZERO_PAGE &&
|
mIns[i + 0].mType == ASMIT_STA && mIns[i + 0].mMode == ASMIM_ZERO_PAGE &&
|
||||||
mIns[i + 2].mType == ASMIT_LDX && mIns[i + 2].mMode == ASMIM_ZERO_PAGE && mIns[i + 2].mAddress == mIns[i + 0].mAddress &&
|
mIns[i + 2].mType == ASMIT_LDX && mIns[i + 2].mMode == ASMIM_ZERO_PAGE && mIns[i + 2].mAddress == mIns[i + 0].mAddress &&
|
||||||
|
@ -36807,6 +36900,22 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
|
||||||
progress = true;
|
progress = true;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#if 1
|
||||||
|
else if (
|
||||||
|
mIns[i + 0].mType == ASMIT_AND && mIns[i + 0].mMode == ASMIM_IMMEDIATE && mIns[i + 0].mAddress == 0x80 &&
|
||||||
|
mIns[i + 1].mType == ASMIT_STA && mIns[i + 1].mMode == ASMIM_ZERO_PAGE &&
|
||||||
|
mIns[i + 2].mType == ASMIT_LDA && mIns[i + 2].mMode == ASMIM_ZERO_PAGE && mIns[i + 2].mAddress != mIns[i + 1].mAddress &&
|
||||||
|
mIns[i + 3].mType == ASMIT_LSR && mIns[i + 3].mMode == ASMIM_IMPLIED &&
|
||||||
|
mIns[i + 4].mType == ASMIT_ORA && mIns[i + 4].mMode == ASMIM_ZERO_PAGE && mIns[i + 4].mAddress == mIns[i + 1].mAddress && !(mIns[i + 4].mLive & (LIVE_CPU_REG_C | LIVE_MEM)))
|
||||||
|
{
|
||||||
|
mIns[i + 0].mType = ASMIT_ASL; mIns[i + 0].mMode = ASMIM_IMPLIED; mIns[i + 0].mLive |= LIVE_CPU_REG_C;
|
||||||
|
mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED;
|
||||||
|
mIns[i + 2].mLive |= LIVE_CPU_REG_C;
|
||||||
|
mIns[i + 3].mType = ASMIT_ROR;
|
||||||
|
mIns[i + 4].mType = ASMIT_NOP; mIns[i + 4].mMode = ASMIM_IMPLIED;
|
||||||
|
progress = true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
#if 0
|
#if 0
|
||||||
else if (
|
else if (
|
||||||
mIns[i + 0].mType == ASMIT_LDY && mIns[i + 0].mMode == ASMIM_ZERO_PAGE &&
|
mIns[i + 0].mType == ASMIT_LDY && mIns[i + 0].mMode == ASMIM_ZERO_PAGE &&
|
||||||
|
@ -38139,6 +38248,19 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
|
||||||
|
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
|
else if (pass >= 7 && sz >= 1 &&
|
||||||
|
mIns[sz - 1].mType == ASMIT_AND && mIns[sz - 1].mMode == ASMIM_IMMEDIATE && mIns[sz - 1].mAddress == 0x40 && !(mIns[sz - 1].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_C)) &&
|
||||||
|
(mBranch == ASMIT_BEQ || mBranch == ASMIT_BNE) && !mExitRequiredRegs[CPU_REG_Z])
|
||||||
|
{
|
||||||
|
mIns[sz - 1].mType = ASMIT_ASL; mIns[sz - 1].mMode = ASMIM_IMPLIED;
|
||||||
|
|
||||||
|
if (mBranch == ASMIT_BEQ)
|
||||||
|
mBranch = ASMIT_BPL;
|
||||||
|
else
|
||||||
|
mBranch = ASMIT_BMI;
|
||||||
|
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (sz == 1 && mBranch == ASMIT_BNE && mTrueJump == this)
|
if (sz == 1 && mBranch == ASMIT_BNE && mTrueJump == this)
|
||||||
{
|
{
|
||||||
|
@ -38946,7 +39068,7 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
|
||||||
{
|
{
|
||||||
mInterProc = proc;
|
mInterProc = proc;
|
||||||
|
|
||||||
CheckFunc = !strcmp(mInterProc->mIdent->mString, "fill_screen");
|
CheckFunc = !strcmp(mInterProc->mIdent->mString, "iec_read");
|
||||||
|
|
||||||
int nblocks = proc->mBlocks.Size();
|
int nblocks = proc->mBlocks.Size();
|
||||||
tblocks = new NativeCodeBasicBlock * [nblocks];
|
tblocks = new NativeCodeBasicBlock * [nblocks];
|
||||||
|
@ -39596,7 +39718,6 @@ void NativeCodeProcedure::Optimize(void)
|
||||||
mEntryBlock->ReplaceFinalZeroPageUse(this);
|
mEntryBlock->ReplaceFinalZeroPageUse(this);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int t = 0;
|
int t = 0;
|
||||||
#if 1
|
#if 1
|
||||||
do
|
do
|
||||||
|
@ -39785,8 +39906,6 @@ void NativeCodeProcedure::Optimize(void)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#if _DEBUG
|
#if _DEBUG
|
||||||
ResetVisited();
|
ResetVisited();
|
||||||
mEntryBlock->CheckBlocks(true);
|
mEntryBlock->CheckBlocks(true);
|
||||||
|
@ -40174,8 +40293,10 @@ void NativeCodeProcedure::Optimize(void)
|
||||||
else
|
else
|
||||||
cnt++;
|
cnt++;
|
||||||
|
|
||||||
|
|
||||||
} while (changed);
|
} while (changed);
|
||||||
|
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
ResetVisited();
|
ResetVisited();
|
||||||
mEntryBlock->ReduceLocalYPressure();
|
mEntryBlock->ReduceLocalYPressure();
|
||||||
|
|
|
@ -3988,7 +3988,6 @@ void Parser::ParsePragma(void)
|
||||||
}
|
}
|
||||||
else if (ConsumeIdentIf("optimize"))
|
else if (ConsumeIdentIf("optimize"))
|
||||||
{
|
{
|
||||||
mScanner->NextToken();
|
|
||||||
ConsumeToken(TK_OPEN_PARENTHESIS);
|
ConsumeToken(TK_OPEN_PARENTHESIS);
|
||||||
if (!ConsumeTokenIf(TK_CLOSE_PARENTHESIS))
|
if (!ConsumeTokenIf(TK_CLOSE_PARENTHESIS))
|
||||||
{
|
{
|
||||||
|
@ -4026,6 +4025,7 @@ void Parser::ParsePragma(void)
|
||||||
default:
|
default:
|
||||||
mErrors->Error(mScanner->mLocation, ERRR_INVALID_NUMBER, "Invalid number");
|
mErrors->Error(mScanner->mLocation, ERRR_INVALID_NUMBER, "Invalid number");
|
||||||
}
|
}
|
||||||
|
mScanner->NextToken();
|
||||||
}
|
}
|
||||||
else if (ConsumeIdentIf("asm"))
|
else if (ConsumeIdentIf("asm"))
|
||||||
mCompilerOptions |= COPT_OPTIMIZE_ASSEMBLER;
|
mCompilerOptions |= COPT_OPTIMIZE_ASSEMBLER;
|
||||||
|
|
Loading…
Reference in New Issue