Add __export, __native and __interrupt storage class specifiers
This commit is contained in:
parent
94532fe038
commit
5c8b1c6daf
34
README.md
34
README.md
|
@ -43,7 +43,6 @@ There are still several open areas, but most targets have been reached. The cur
|
|||
|
||||
### Optimizing
|
||||
|
||||
* Complex loop optimization
|
||||
* Auto variables placed on fixed stack for known call sequence
|
||||
|
||||
### Intermediate code generation
|
||||
|
@ -118,6 +117,30 @@ A section of the file can be selected by providing a limit and or an offset into
|
|||
|
||||
The compiler can be provided with additional information using the built in function __assume(cond). This can be useful to mark unreachable code using __assume(false) for e.g. the default of a switch statement. Another good option is to limit the value range of arguments to allow the compiler using byte operations without the need for integer promotion.
|
||||
|
||||
### Marking functions as native
|
||||
|
||||
Routines can be marked to be compiled to 6502 machine code with the native pragma:
|
||||
|
||||
void Plot(int x, int y)
|
||||
{
|
||||
(*Bitmap)[y >> 3][x >> 3][y & 7] |= 0x80 >> (x & 7);
|
||||
}
|
||||
|
||||
#pragma native(Plot)
|
||||
|
||||
Or alternatively with a __native storage class specifier
|
||||
|
||||
__native void Plot(int x, int y)
|
||||
{
|
||||
(*Bitmap)[y >> 3][x >> 3][y & 7] |= 0x80 >> (x & 7);
|
||||
}
|
||||
|
||||
### Linker control
|
||||
|
||||
The linker includes only objects that are referenced, starting by the startup code into main() and so on.
|
||||
|
||||
If you need to have a function or variable present regardless, you can specify it with the __export storage class specifier or use the #pragma reference(name) pragma.
|
||||
|
||||
|
||||
## Inline Assembler
|
||||
|
||||
|
@ -263,15 +286,6 @@ The intermediate code generator assumes a large number of registers so the zero
|
|||
* **0x43-0x52** caller saved registers
|
||||
* **0x53-0x8f** callee saved registers
|
||||
|
||||
Routines can be marked to be compiled to 6502 machine code with the native pragma:
|
||||
|
||||
void Plot(int x, int y)
|
||||
{
|
||||
(*Bitmap)[y >> 3][x >> 3][y & 7] |= 0x80 >> (x & 7);
|
||||
}
|
||||
|
||||
#pragma native(Plot)
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include <c64/vic.h>
|
||||
#include <c64/cia.h>
|
||||
#include <c64/asm6502.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
volatile char npos = 1, tpos = 0;
|
||||
|
||||
|
@ -176,40 +177,32 @@ void rirq_build(RIRQCode * ic, byte size)
|
|||
asm_ab(ic->code + 4, ASM_CPX, 0xd012);
|
||||
asm_rl(ic->code + 7, ASM_BCS, -5);
|
||||
asm_ab(ic->code + 9, ASM_STY, 0x0000);
|
||||
/*
|
||||
ic->code[0] = 0xa0; // ldy #
|
||||
ic->code[2] = 0xa9; // lda #
|
||||
ic->code[4] = 0xec; // cpx
|
||||
ic->code[5] = 0x12;
|
||||
ic->code[6] = 0xd0;
|
||||
ic->code[7] = 0xb0; // bcs
|
||||
ic->code[8] = -5;
|
||||
ic->code[9] = 0x8c; // sty
|
||||
*/
|
||||
|
||||
if (size == 1)
|
||||
{
|
||||
asm_np(ic->code + 12, ASM_RTS);
|
||||
//ic->code[12] = 0x60; // rts
|
||||
}
|
||||
else
|
||||
{
|
||||
asm_ab(ic->code + 12, ASM_STA, 0x0000);
|
||||
// ic->code[12] = 0x8d; // sty
|
||||
|
||||
byte p = 15;
|
||||
for(byte i=2; i<size; i++)
|
||||
{
|
||||
p += asm_im(ic->code + p, ASM_LDA, 0x00);
|
||||
p += asm_ab(ic->code + p, ASM_STA, 0x0000);
|
||||
//ic->code[p] = 0xa9; // lda #
|
||||
//ic->code[p + 2] = 0x8d; // sta
|
||||
//p += 5;
|
||||
}
|
||||
asm_np(ic->code + p, ASM_RTS);
|
||||
//ic->code[p] = 0x60;
|
||||
}
|
||||
}
|
||||
|
||||
RIRQCode * rirq_alloc(byte size)
|
||||
{
|
||||
RIRQCode * ic = (RIRQCode *)malloc(1 + RIRQ_SIZE + 5 * size);
|
||||
rirq_build(ic, size);
|
||||
return ic;
|
||||
}
|
||||
|
||||
#pragma native(rirq_build)
|
||||
|
||||
void rirq_set(byte n, byte row, RIRQCode * write)
|
||||
|
@ -220,8 +213,15 @@ void rirq_set(byte n, byte row, RIRQCode * write)
|
|||
rasterIRQRows[n] = row;
|
||||
}
|
||||
|
||||
static const byte irqai[6] = {RIRQ_ADDR_0, RIRQ_ADDR_1, RIRQ_ADDR_2, RIRQ_ADDR_3, RIRQ_ADDR_4};
|
||||
static const byte irqdi[6] = {RIRQ_DATA_0, RIRQ_DATA_1, RIRQ_DATA_2, RIRQ_DATA_3, RIRQ_DATA_4};
|
||||
static const byte irqai[16] = {
|
||||
RIRQ_ADDR_0, RIRQ_ADDR_1, RIRQ_ADDR_2, RIRQ_ADDR_3, RIRQ_ADDR_4, RIRQ_ADDR_5, RIRQ_ADDR_6, RIRQ_ADDR_7,
|
||||
RIRQ_ADDR_8, RIRQ_ADDR_9, RIRQ_ADDR_10, RIRQ_ADDR_11, RIRQ_ADDR_12, RIRQ_ADDR_13, RIRQ_ADDR_14, RIRQ_ADDR_15
|
||||
};
|
||||
|
||||
static const byte irqdi[16] = {
|
||||
RIRQ_DATA_0, RIRQ_DATA_1, RIRQ_DATA_2, RIRQ_DATA_3, RIRQ_DATA_4, RIRQ_DATA_5, RIRQ_DATA_6, RIRQ_DATA_7,
|
||||
RIRQ_DATA_8, RIRQ_DATA_9, RIRQ_DATA_10, RIRQ_DATA_11, RIRQ_DATA_12, RIRQ_DATA_13, RIRQ_DATA_14, RIRQ_DATA_15
|
||||
};
|
||||
|
||||
void rirq_addr(RIRQCode * ic, byte n, void * addr)
|
||||
{
|
||||
|
|
|
@ -23,7 +23,40 @@ enum RIRQCodeIndex
|
|||
RIRQ_DATA_4 = 26,
|
||||
RIRQ_ADDR_4 = 28,
|
||||
|
||||
RIRQ_SIZE = 31
|
||||
RIRQ_SIZE = 31,
|
||||
|
||||
RIRQ_DATA_5 = 31,
|
||||
RIRQ_ADDR_5 = 33,
|
||||
|
||||
RIRQ_DATA_6 = 36,
|
||||
RIRQ_ADDR_6 = 38,
|
||||
|
||||
RIRQ_DATA_7 = 41,
|
||||
RIRQ_ADDR_7 = 43,
|
||||
|
||||
RIRQ_DATA_8 = 46,
|
||||
RIRQ_ADDR_8 = 48,
|
||||
|
||||
RIRQ_DATA_9 = 51,
|
||||
RIRQ_ADDR_9 = 53,
|
||||
|
||||
RIRQ_DATA_10 = 56,
|
||||
RIRQ_ADDR_10 = 58,
|
||||
|
||||
RIRQ_DATA_11 = 61,
|
||||
RIRQ_ADDR_11 = 63,
|
||||
|
||||
RIRQ_DATA_12 = 66,
|
||||
RIRQ_ADDR_12 = 68,
|
||||
|
||||
RIRQ_DATA_13 = 71,
|
||||
RIRQ_ADDR_13 = 73,
|
||||
|
||||
RIRQ_DATA_14 = 76,
|
||||
RIRQ_ADDR_14 = 78,
|
||||
|
||||
RIRQ_DATA_15 = 81,
|
||||
RIRQ_ADDR_15 = 88,
|
||||
};
|
||||
|
||||
// One raster interrupt operation, handles up to five writes
|
||||
|
@ -34,9 +67,12 @@ typedef struct RIRQCode
|
|||
byte code[RIRQ_SIZE];
|
||||
} RIRQCode;
|
||||
|
||||
// Build one raster IRQ operation of the given size (wait + #ops)
|
||||
// Build one raster IRQ operation of the given size (wait + #ops) for up to 5 instructions
|
||||
void rirq_build(RIRQCode * ic, byte size);
|
||||
|
||||
// Allocate one raster IRQ operation of the given size (wait + #ops)
|
||||
RIRQCode * rirq_alloc(byte size);
|
||||
|
||||
// Add a write command to a raster IRQ
|
||||
inline void rirq_write(RIRQCode * ic, byte n, void * addr, byte data);
|
||||
|
||||
|
|
|
@ -66,14 +66,16 @@ static const uint32 DTF_FASTCALL = 0x00004000;
|
|||
static const uint32 DTF_INLINE = 0x00008000;
|
||||
static const uint32 DTF_ANALYZED = 0x00010000;
|
||||
static const uint32 DTF_REQUEST_INLINE = 0x00020000;
|
||||
static const uint32 DTF_INTERRUPT = 0x00040000;
|
||||
static const uint32 DTF_EXPORT = 0x00080000;
|
||||
|
||||
static const uint32 DTF_FUNC_VARIABLE = 0x00040000;
|
||||
static const uint32 DTF_FUNC_ASSEMBLER = 0x00080000;
|
||||
static const uint32 DTF_FUNC_RECURSIVE = 0x00100000;
|
||||
static const uint32 DTF_FUNC_ANALYZING = 0x00200000;
|
||||
static const uint32 DTF_FUNC_CONSTEXPR = 0x00400000;
|
||||
static const uint32 DTF_FUNC_VARIABLE = 0x00100000;
|
||||
static const uint32 DTF_FUNC_ASSEMBLER = 0x00200000;
|
||||
static const uint32 DTF_FUNC_RECURSIVE = 0x00400000;
|
||||
static const uint32 DTF_FUNC_ANALYZING = 0x00800000;
|
||||
static const uint32 DTF_FUNC_CONSTEXPR = 0x01000000;
|
||||
|
||||
static const uint32 DTF_VAR_ALIASING = 0x00800000;
|
||||
static const uint32 DTF_VAR_ALIASING = 0x02000000;
|
||||
|
||||
|
||||
class Declaration;
|
||||
|
|
|
@ -54,6 +54,7 @@ enum ErrorID
|
|||
ERRR_PREPROCESSOR,
|
||||
ERRR_INVALID_CASE,
|
||||
ERRR_INSUFFICIENT_MEMORY,
|
||||
ERRR_INTERRUPT_TO_COMPLEX,
|
||||
|
||||
EERR_INVALID_PREPROCESSOR,
|
||||
};
|
||||
|
|
|
@ -8022,7 +8022,7 @@ InterCodeProcedure::InterCodeProcedure(InterCodeModule * mod, const Location & l
|
|||
mRenameTable(-1), mRenameUnionTable(-1), mGlobalRenameTable(-1),
|
||||
mValueForwardingTable(nullptr), mLocalVars(nullptr), mParamVars(nullptr), mModule(mod),
|
||||
mIdent(ident), mLinkerObject(linkerObject),
|
||||
mNativeProcedure(false), mLeafProcedure(false), mCallsFunctionPointer(false), mCalledFunctions(nullptr), mFastCallProcedure(false)
|
||||
mNativeProcedure(false), mLeafProcedure(false), mCallsFunctionPointer(false), mCalledFunctions(nullptr), mFastCallProcedure(false), mInterrupt(false)
|
||||
{
|
||||
mID = mModule->mProcedures.Size();
|
||||
mModule->mProcedures.Push(this);
|
||||
|
@ -8729,6 +8729,8 @@ void InterCodeProcedure::Close(void)
|
|||
BuildLoopPrefix();
|
||||
DisassembleDebug("added dominators");
|
||||
|
||||
BuildDataFlowSets();
|
||||
|
||||
ResetVisited();
|
||||
mEntryBlock->SingleBlockLoopOptimisation(mParamAliasedSet);
|
||||
|
||||
|
|
|
@ -476,7 +476,7 @@ public:
|
|||
GrowingTypeArray mTemporaries;
|
||||
GrowingIntArray mTempOffset, mTempSizes;
|
||||
int mTempSize, mCommonFrameSize, mCallerSavedTemps;
|
||||
bool mLeafProcedure, mNativeProcedure, mCallsFunctionPointer, mHasDynamicStack, mHasInlineAssembler, mCallsByteCode, mFastCallProcedure;
|
||||
bool mLeafProcedure, mNativeProcedure, mCallsFunctionPointer, mHasDynamicStack, mHasInlineAssembler, mCallsByteCode, mFastCallProcedure, mInterrupt;
|
||||
GrowingInterCodeProcedurePtrArray mCalledFunctions;
|
||||
|
||||
InterCodeModule * mModule;
|
||||
|
|
|
@ -3363,6 +3363,9 @@ InterCodeProcedure* InterCodeGenerator::TranslateProcedure(InterCodeModule * mod
|
|||
if (dec->mFlags & DTF_NATIVE)
|
||||
proc->mNativeProcedure = true;
|
||||
|
||||
if (dec->mFlags & DTF_INTERRUPT)
|
||||
proc->mInterrupt = true;
|
||||
|
||||
if (dec->mBase->mFlags & DTF_FASTCALL)
|
||||
{
|
||||
proc->mFastCallProcedure = true;
|
||||
|
|
|
@ -33,6 +33,34 @@ enum LinkerSectionType
|
|||
LST_STACK
|
||||
};
|
||||
|
||||
struct ZeroPageSet
|
||||
{
|
||||
ZeroPageSet(void)
|
||||
{
|
||||
for (int i = 0; i < 8; i++)
|
||||
mBits[i] = 0;
|
||||
}
|
||||
|
||||
uint32 mBits[8];
|
||||
|
||||
void operator += (int n)
|
||||
{
|
||||
mBits[n >> 5] |= 1 << (n & 31);
|
||||
}
|
||||
|
||||
bool operator[] (int n) const
|
||||
{
|
||||
return (mBits[n >> 5] & (1 << (n & 31))) != 0;
|
||||
}
|
||||
|
||||
ZeroPageSet& operator |= (const ZeroPageSet& set)
|
||||
{
|
||||
for (int i = 0; i < 8; i++)
|
||||
mBits[i] |= set.mBits[i];
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
class LinkerObject;
|
||||
class LinkerSection;
|
||||
|
||||
|
@ -110,6 +138,7 @@ public:
|
|||
uint32 mFlags;
|
||||
uint8 mTemporaries[16], mTempSizes[16];
|
||||
int mNumTemporaries;
|
||||
ZeroPageSet mZeroPageSet;
|
||||
|
||||
LinkerObject(void);
|
||||
~LinkerObject(void);
|
||||
|
|
|
@ -8430,6 +8430,50 @@ void NativeCodeBasicBlock::FindZeroPageAlias(const NumberSet& statics, NumberSet
|
|||
}
|
||||
}
|
||||
|
||||
void NativeCodeBasicBlock::CollectZeroPageSet(ZeroPageSet& locals, ZeroPageSet& global)
|
||||
{
|
||||
if (!mVisited)
|
||||
{
|
||||
mVisited = true;
|
||||
|
||||
for (int i = 0; i < mIns.Size(); i++)
|
||||
{
|
||||
switch (mIns[i].mMode)
|
||||
{
|
||||
case ASMIM_ZERO_PAGE:
|
||||
if (mIns[i].ChangesAddress())
|
||||
locals += mIns[i].mAddress;
|
||||
break;
|
||||
case ASMIM_ABSOLUTE:
|
||||
if (mIns[i].mType == ASMIT_JSR)
|
||||
{
|
||||
if (mIns[i].mFlags & NCIF_RUNTIME)
|
||||
{
|
||||
for (int j = 0; j < 4; j++)
|
||||
{
|
||||
locals += BC_REG_ACCU + j;
|
||||
locals += BC_REG_WORK + j;
|
||||
}
|
||||
}
|
||||
|
||||
if (mIns[i].mLinkerObject)
|
||||
{
|
||||
LinkerObject* lo = mIns[i].mLinkerObject;
|
||||
|
||||
global |= lo->mZeroPageSet;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (mTrueJump)
|
||||
mTrueJump->CollectZeroPageSet(locals, global);
|
||||
if (mFalseJump)
|
||||
mFalseJump->CollectZeroPageSet(locals, global);
|
||||
}
|
||||
}
|
||||
|
||||
void NativeCodeBasicBlock::CollectZeroPageUsage(NumberSet& used, NumberSet &modified, NumberSet& pairs)
|
||||
{
|
||||
if (!mVisited)
|
||||
|
@ -8451,14 +8495,28 @@ void NativeCodeBasicBlock::CollectZeroPageUsage(NumberSet& used, NumberSet &modi
|
|||
pairs += mIns[i].mAddress;
|
||||
break;
|
||||
case ASMIM_ABSOLUTE:
|
||||
if (mIns[i].mType == ASMIT_JSR && mIns[i].mLinkerObject)
|
||||
if (mIns[i].mType == ASMIT_JSR)
|
||||
{
|
||||
LinkerObject* lo = mIns[i].mLinkerObject;
|
||||
|
||||
for (int i = 0; i < lo->mNumTemporaries; i++)
|
||||
if (mIns[i].mFlags & NCIF_RUNTIME)
|
||||
{
|
||||
for (int j = 0; j < lo->mTempSizes[i]; j++)
|
||||
used += lo->mTemporaries[i] + j;
|
||||
for (int j = 0; j < 4; j++)
|
||||
{
|
||||
used += BC_REG_ACCU + j;
|
||||
used += BC_REG_WORK + j;
|
||||
modified += BC_REG_ACCU + j;
|
||||
modified += BC_REG_WORK + j;
|
||||
}
|
||||
}
|
||||
|
||||
if (mIns[i].mLinkerObject)
|
||||
{
|
||||
LinkerObject* lo = mIns[i].mLinkerObject;
|
||||
|
||||
for (int i = 0; i < lo->mNumTemporaries; i++)
|
||||
{
|
||||
for (int j = 0; j < lo->mTempSizes[i]; j++)
|
||||
used += lo->mTemporaries[i] + j;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -13728,7 +13786,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass)
|
|||
{
|
||||
int yoffset = mIns[i + 0].mAddress;
|
||||
|
||||
if (breg == mIns[i + 2].mAddress)
|
||||
if (breg == mIns[i + 2].mAddress || ireg == mIns[i + 2].mAddress)
|
||||
{
|
||||
mIns[apos + 3].mType = ASMIT_NOP; mIns[apos + 3].mMode = ASMIM_IMPLIED;
|
||||
mIns[apos + 6].mType = ASMIT_NOP; mIns[apos + 6].mMode = ASMIM_IMPLIED;
|
||||
|
@ -14067,7 +14125,8 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass)
|
|||
if (mIns[i + 2].mAddress == 2)
|
||||
mIns[i + 2].mType = ASMIT_INX;
|
||||
else
|
||||
mIns[i + 3].mType = ASMIT_NOP;
|
||||
mIns[i + 2].mType = ASMIT_NOP;
|
||||
mIns[i + 2].mMode = ASMIM_IMPLIED;
|
||||
mIns[i + 3].mType = ASMIT_STX;
|
||||
progress = true;
|
||||
}
|
||||
|
@ -14083,7 +14142,8 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass)
|
|||
if (mIns[i + 2].mAddress == 2)
|
||||
mIns[i + 2].mType = ASMIT_DEX;
|
||||
else
|
||||
mIns[i + 3].mType = ASMIT_NOP;
|
||||
mIns[i + 2].mType = ASMIT_NOP;
|
||||
mIns[i + 2].mMode = ASMIM_IMPLIED;
|
||||
mIns[i + 3].mType = ASMIT_STX;
|
||||
progress = true;
|
||||
}
|
||||
|
@ -14099,7 +14159,8 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass)
|
|||
if (mIns[i + 2].mAddress == 2)
|
||||
mIns[i + 2].mType = ASMIT_INY;
|
||||
else
|
||||
mIns[i + 3].mType = ASMIT_NOP;
|
||||
mIns[i + 2].mType = ASMIT_NOP;
|
||||
mIns[i + 2].mMode = ASMIM_IMPLIED;
|
||||
mIns[i + 3].mType = ASMIT_STY;
|
||||
progress = true;
|
||||
}
|
||||
|
@ -14115,7 +14176,8 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass)
|
|||
if (mIns[i + 2].mAddress == 2)
|
||||
mIns[i + 2].mType = ASMIT_DEY;
|
||||
else
|
||||
mIns[i + 3].mType = ASMIT_NOP;
|
||||
mIns[i + 2].mType = ASMIT_NOP;
|
||||
mIns[i + 2].mMode = ASMIM_IMPLIED;
|
||||
mIns[i + 3].mType = ASMIT_STY;
|
||||
progress = true;
|
||||
}
|
||||
|
@ -15054,163 +15116,224 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
|
|||
|
||||
bool ignoreExpandCommonFrame = false;
|
||||
|
||||
if (mNoFrame)
|
||||
if (mInterProc->mInterrupt)
|
||||
{
|
||||
if (mStackExpand > 0)
|
||||
if (!mNoFrame || mStackExpand > 0 || commonFrameSize > 0)
|
||||
mGenerator->mErrors->Error(mInterProc->mLocation, ERRR_INTERRUPT_TO_COMPLEX, "Function to complex for interrupt");
|
||||
|
||||
ZeroPageSet zpLocal, zpGlobal;
|
||||
ResetVisited();
|
||||
mEntryBlock->CollectZeroPageSet(zpLocal, zpGlobal);
|
||||
zpLocal |= zpGlobal;
|
||||
|
||||
for (int i = 2; i < 256; i++)
|
||||
{
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_SEC, ASMIM_IMPLIED));
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK));
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_SBC, ASMIM_IMMEDIATE, (mStackExpand + commonFrameSize) & 0xff));
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_STACK));
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_BCS, ASMIM_RELATIVE, 2));
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_DEC, ASMIM_ZERO_PAGE, BC_REG_STACK + 1));
|
||||
ignoreExpandCommonFrame = true;
|
||||
|
||||
if (tempSave)
|
||||
if (zpLocal[i])
|
||||
{
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, commonFrameSize + tempSave - 1));
|
||||
if (tempSave == 1)
|
||||
{
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP_SAVED));
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, BC_REG_STACK));
|
||||
}
|
||||
else if (tempSave == 2)
|
||||
{
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP_SAVED + 1));
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, BC_REG_STACK));
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_DEY, ASMIM_IMPLIED));
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP_SAVED));
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, BC_REG_STACK));
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, i));
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_PHA));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else if (commonFrameSize > 0)
|
||||
{
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDX, ASMIM_IMMEDIATE, tempSave - 1));
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE_X, BC_REG_TMP_SAVED));
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, BC_REG_STACK));
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_DEY, ASMIM_IMPLIED));
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_DEX, ASMIM_IMPLIED));
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_BPL, ASMIM_RELATIVE, -8));
|
||||
}
|
||||
else
|
||||
{
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE_Y, BC_REG_TMP_SAVED));
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, BC_REG_STACK));
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_DEY, ASMIM_IMPLIED));
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_BPL, ASMIM_RELATIVE, -8));
|
||||
}
|
||||
for (int i = 255; i >= 2; i--)
|
||||
{
|
||||
if (zpLocal[i])
|
||||
{
|
||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_PLA));
|
||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, i));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_SEC, ASMIM_IMPLIED));
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK));
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_SBC, ASMIM_IMMEDIATE, mStackExpand & 0xff));
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_STACK));
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK + 1));
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_SBC, ASMIM_IMMEDIATE, (mStackExpand >> 8) & 0xff));
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_STACK + 1));
|
||||
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, tempSave));
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_LOCALS));
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, BC_REG_STACK));
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED));
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_LOCALS + 1));
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, BC_REG_STACK));
|
||||
|
||||
if (tempSave)
|
||||
if (mNoFrame)
|
||||
{
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_DEY, ASMIM_IMPLIED));
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_DEY, ASMIM_IMPLIED));
|
||||
if (mStackExpand > 0)
|
||||
{
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_SEC, ASMIM_IMPLIED));
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK));
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_SBC, ASMIM_IMMEDIATE, (mStackExpand + commonFrameSize) & 0xff));
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_STACK));
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_BCS, ASMIM_RELATIVE, 2));
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_DEC, ASMIM_ZERO_PAGE, BC_REG_STACK + 1));
|
||||
ignoreExpandCommonFrame = true;
|
||||
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE_Y, BC_REG_TMP_SAVED));
|
||||
if (tempSave)
|
||||
{
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, commonFrameSize + tempSave - 1));
|
||||
if (tempSave == 1)
|
||||
{
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP_SAVED));
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, BC_REG_STACK));
|
||||
}
|
||||
else if (tempSave == 2)
|
||||
{
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP_SAVED + 1));
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, BC_REG_STACK));
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_DEY, ASMIM_IMPLIED));
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP_SAVED));
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, BC_REG_STACK));
|
||||
|
||||
}
|
||||
else if (commonFrameSize > 0)
|
||||
{
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDX, ASMIM_IMMEDIATE, tempSave - 1));
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE_X, BC_REG_TMP_SAVED));
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, BC_REG_STACK));
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_DEY, ASMIM_IMPLIED));
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_DEX, ASMIM_IMPLIED));
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_BPL, ASMIM_RELATIVE, -8));
|
||||
}
|
||||
else
|
||||
{
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE_Y, BC_REG_TMP_SAVED));
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, BC_REG_STACK));
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_DEY, ASMIM_IMPLIED));
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_BPL, ASMIM_RELATIVE, -8));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_SEC, ASMIM_IMPLIED));
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK));
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_SBC, ASMIM_IMMEDIATE, mStackExpand & 0xff));
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_STACK));
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK + 1));
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_SBC, ASMIM_IMMEDIATE, (mStackExpand >> 8) & 0xff));
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_STACK + 1));
|
||||
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, tempSave));
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_LOCALS));
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, BC_REG_STACK));
|
||||
if (tempSave > 1)
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED));
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_LOCALS + 1));
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, BC_REG_STACK));
|
||||
|
||||
if (tempSave)
|
||||
{
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_DEY, ASMIM_IMPLIED));
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_BPL, ASMIM_RELATIVE, -8));
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_DEY, ASMIM_IMPLIED));
|
||||
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE_Y, BC_REG_TMP_SAVED));
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, BC_REG_STACK));
|
||||
if (tempSave > 1)
|
||||
{
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_DEY, ASMIM_IMPLIED));
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_BPL, ASMIM_RELATIVE, -8));
|
||||
}
|
||||
}
|
||||
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_CLC, ASMIM_IMPLIED));
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK));
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_IMMEDIATE, frameSpace + 2));
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_LOCALS));
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK + 1));
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_IMMEDIATE, 0));
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_LOCALS + 1));
|
||||
}
|
||||
|
||||
if (!proc->mLeafProcedure && commonFrameSize > 0 && !ignoreExpandCommonFrame)
|
||||
{
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_SEC, ASMIM_IMPLIED));
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK));
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_SBC, ASMIM_IMMEDIATE, commonFrameSize & 0xff));
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_STACK));
|
||||
if (commonFrameSize >= 256)
|
||||
{
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK + 1));
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_SBC, ASMIM_IMMEDIATE, (commonFrameSize >> 8) & 0xff));
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_STACK + 1));
|
||||
}
|
||||
else
|
||||
{
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_BCS, ASMIM_RELATIVE, 2));
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_DEC, ASMIM_ZERO_PAGE, BC_REG_STACK + 1));
|
||||
}
|
||||
|
||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_CLC, ASMIM_IMPLIED));
|
||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK));
|
||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_IMMEDIATE, commonFrameSize & 0xff));
|
||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_STACK));
|
||||
if (commonFrameSize >= 256)
|
||||
{
|
||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK + 1));
|
||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_IMMEDIATE, (commonFrameSize >> 8) & 0xff));
|
||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_STACK + 1));
|
||||
}
|
||||
else
|
||||
{
|
||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_BCC, ASMIM_RELATIVE, 2));
|
||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_INC, ASMIM_ZERO_PAGE, BC_REG_STACK + 1));
|
||||
}
|
||||
}
|
||||
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_CLC, ASMIM_IMPLIED));
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK));
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_IMMEDIATE, frameSpace + 2));
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_LOCALS));
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK + 1));
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_IMMEDIATE, 0));
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_LOCALS + 1));
|
||||
}
|
||||
|
||||
if (!proc->mLeafProcedure && commonFrameSize > 0 && !ignoreExpandCommonFrame)
|
||||
{
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_SEC, ASMIM_IMPLIED));
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK));
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_SBC, ASMIM_IMMEDIATE, commonFrameSize & 0xff));
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_STACK));
|
||||
if (commonFrameSize >= 256)
|
||||
if (mNoFrame)
|
||||
{
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK + 1));
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_SBC, ASMIM_IMMEDIATE, (commonFrameSize >> 8) & 0xff));
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_STACK + 1));
|
||||
if (mStackExpand > 0)
|
||||
{
|
||||
if (tempSave)
|
||||
{
|
||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, commonFrameSize + tempSave - 1));
|
||||
if (tempSave == 1)
|
||||
{
|
||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, BC_REG_STACK));
|
||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP_SAVED));
|
||||
}
|
||||
else if (tempSave == 2)
|
||||
{
|
||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, BC_REG_STACK));
|
||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP_SAVED + 1));
|
||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_DEY, ASMIM_IMPLIED));
|
||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, BC_REG_STACK));
|
||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP_SAVED));
|
||||
|
||||
}
|
||||
else if (commonFrameSize > 0)
|
||||
{
|
||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDX, ASMIM_IMMEDIATE, tempSave - 1));
|
||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, BC_REG_STACK));
|
||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE_X, BC_REG_TMP_SAVED));
|
||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_DEY, ASMIM_IMPLIED));
|
||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_DEX, ASMIM_IMPLIED));
|
||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_BPL, ASMIM_RELATIVE, -8));
|
||||
}
|
||||
else
|
||||
{
|
||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, BC_REG_STACK));
|
||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE_Y, BC_REG_TMP_SAVED));
|
||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_DEY, ASMIM_IMPLIED));
|
||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_BPL, ASMIM_RELATIVE, -8));
|
||||
}
|
||||
}
|
||||
|
||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_CLC, ASMIM_IMPLIED));
|
||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK));
|
||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_IMMEDIATE, (mStackExpand + commonFrameSize) & 0xff));
|
||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_STACK));
|
||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_BCC, ASMIM_RELATIVE, 2));
|
||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_INC, ASMIM_ZERO_PAGE, BC_REG_STACK + 1));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_BCS, ASMIM_RELATIVE, 2));
|
||||
mEntryBlock->mIns.Push(NativeCodeInstruction(ASMIT_DEC, ASMIM_ZERO_PAGE, BC_REG_STACK + 1));
|
||||
}
|
||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, tempSave));
|
||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, BC_REG_STACK));
|
||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_LOCALS));
|
||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED));
|
||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, BC_REG_STACK));
|
||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_LOCALS + 1));
|
||||
|
||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_CLC, ASMIM_IMPLIED));
|
||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK));
|
||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_IMMEDIATE, commonFrameSize & 0xff));
|
||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_STACK));
|
||||
if (commonFrameSize >= 256)
|
||||
{
|
||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK + 1));
|
||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_IMMEDIATE, (commonFrameSize >> 8) & 0xff));
|
||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_STACK + 1));
|
||||
}
|
||||
else
|
||||
{
|
||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_BCC, ASMIM_RELATIVE, 2));
|
||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_INC, ASMIM_ZERO_PAGE, BC_REG_STACK + 1));
|
||||
}
|
||||
}
|
||||
|
||||
if (mNoFrame)
|
||||
{
|
||||
if (mStackExpand > 0)
|
||||
{
|
||||
if (tempSave)
|
||||
{
|
||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, commonFrameSize + tempSave - 1));
|
||||
if (tempSave == 1)
|
||||
{
|
||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, BC_REG_STACK));
|
||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP_SAVED));
|
||||
}
|
||||
else if (tempSave == 2)
|
||||
{
|
||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, BC_REG_STACK));
|
||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP_SAVED + 1));
|
||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_DEY, ASMIM_IMPLIED));
|
||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, BC_REG_STACK));
|
||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP_SAVED));
|
||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_DEY, ASMIM_IMPLIED));
|
||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_DEY, ASMIM_IMPLIED));
|
||||
|
||||
}
|
||||
else if (commonFrameSize > 0)
|
||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, BC_REG_STACK));
|
||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE_Y, BC_REG_TMP_SAVED));
|
||||
if (tempSave > 1)
|
||||
{
|
||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDX, ASMIM_IMMEDIATE, tempSave - 1));
|
||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, BC_REG_STACK));
|
||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE_X, BC_REG_TMP_SAVED));
|
||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_DEY, ASMIM_IMPLIED));
|
||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_DEX, ASMIM_IMPLIED));
|
||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_BPL, ASMIM_RELATIVE, -8));
|
||||
}
|
||||
else
|
||||
{
|
||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, BC_REG_STACK));
|
||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE_Y, BC_REG_TMP_SAVED));
|
||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_DEY, ASMIM_IMPLIED));
|
||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_BPL, ASMIM_RELATIVE, -8));
|
||||
}
|
||||
|
@ -15218,43 +15341,20 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
|
|||
|
||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_CLC, ASMIM_IMPLIED));
|
||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK));
|
||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_IMMEDIATE, (mStackExpand + commonFrameSize) & 0xff));
|
||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_IMMEDIATE, mStackExpand & 0xff));
|
||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_STACK));
|
||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_BCC, ASMIM_RELATIVE, 2));
|
||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_INC, ASMIM_ZERO_PAGE, BC_REG_STACK + 1));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, tempSave));
|
||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, BC_REG_STACK));
|
||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_LOCALS));
|
||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED));
|
||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, BC_REG_STACK));
|
||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_LOCALS + 1));
|
||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK + 1));
|
||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_IMMEDIATE, (mStackExpand >> 8) & 0xff));
|
||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_STACK + 1));
|
||||
|
||||
if (tempSave)
|
||||
{
|
||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_DEY, ASMIM_IMPLIED));
|
||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_DEY, ASMIM_IMPLIED));
|
||||
|
||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, BC_REG_STACK));
|
||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE_Y, BC_REG_TMP_SAVED));
|
||||
if (tempSave > 1)
|
||||
{
|
||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_DEY, ASMIM_IMPLIED));
|
||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_BPL, ASMIM_RELATIVE, -8));
|
||||
}
|
||||
}
|
||||
|
||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_CLC, ASMIM_IMPLIED));
|
||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK));
|
||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_IMMEDIATE, mStackExpand & 0xff));
|
||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_STACK));
|
||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK + 1));
|
||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_IMMEDIATE, (mStackExpand >> 8) & 0xff));
|
||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_STACK + 1));
|
||||
ZeroPageSet zpLocal, zpGlobal;
|
||||
ResetVisited();
|
||||
mEntryBlock->CollectZeroPageSet(zpLocal, zpGlobal);
|
||||
zpLocal |= zpGlobal;
|
||||
|
||||
proc->mLinkerObject->mZeroPageSet = zpLocal;
|
||||
}
|
||||
|
||||
mExitBlock->mIns.Push(NativeCodeInstruction(ASMIT_RTS, ASMIM_IMPLIED));
|
||||
|
|
|
@ -243,6 +243,7 @@ public:
|
|||
void BuildEntryDataSet(const NativeRegisterDataSet& set);
|
||||
bool ApplyEntryDataSet(void);
|
||||
|
||||
void CollectZeroPageSet(ZeroPageSet& locals, ZeroPageSet& global);
|
||||
void CollectZeroPageUsage(NumberSet& used, NumberSet& modified, NumberSet& pairs);
|
||||
void FindZeroPageAlias(const NumberSet& statics, NumberSet& invalid, uint8* alias, int accu);
|
||||
bool RemapZeroPage(const uint8* remap);
|
||||
|
|
|
@ -376,10 +376,21 @@ Declaration* Parser::ParsePostfixDeclaration(void)
|
|||
Declaration* ndec = new Declaration(mScanner->mLocation, DT_TYPE_POINTER);
|
||||
ndec->mSize = 2;
|
||||
ndec->mFlags |= DTF_DEFINED;
|
||||
if (mScanner->mToken == TK_CONST)
|
||||
|
||||
for (;;)
|
||||
{
|
||||
ndec->mFlags |= DTF_CONST;
|
||||
mScanner->NextToken();
|
||||
if (mScanner->mToken == TK_CONST)
|
||||
{
|
||||
ndec->mFlags |= DTF_CONST;
|
||||
mScanner->NextToken();
|
||||
}
|
||||
else if (mScanner->mToken == TK_VOLATILE)
|
||||
{
|
||||
ndec->mFlags |= DTF_VOLATILE;
|
||||
mScanner->NextToken();
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
Declaration* dec = ParsePostfixDeclaration();
|
||||
|
@ -605,6 +616,7 @@ Declaration * Parser::CopyConstantInitializer(int offset, Declaration* dtype, Ex
|
|||
ndec->mValue = exp;
|
||||
ndec->mBase = dtype;
|
||||
dec = ndec;
|
||||
dec->mOffset = offset;
|
||||
}
|
||||
else
|
||||
mErrors->Error(exp->mLocation, EERR_CONSTANT_INITIALIZER, "Incompatible constant initializer");
|
||||
|
@ -886,22 +898,45 @@ Declaration* Parser::ParseDeclaration(bool variable)
|
|||
}
|
||||
else
|
||||
{
|
||||
if (mScanner->mToken == TK_STATIC)
|
||||
for (;;)
|
||||
{
|
||||
storageFlags |= DTF_STATIC;
|
||||
mScanner->NextToken();
|
||||
}
|
||||
|
||||
if (mScanner->mToken == TK_EXTERN)
|
||||
{
|
||||
storageFlags |= DTF_EXTERN;
|
||||
mScanner->NextToken();
|
||||
}
|
||||
|
||||
if (mScanner->mToken == TK_INLINE)
|
||||
{
|
||||
storageFlags |= DTF_REQUEST_INLINE;
|
||||
mScanner->NextToken();
|
||||
if (mScanner->mToken == TK_STATIC)
|
||||
{
|
||||
storageFlags |= DTF_STATIC;
|
||||
mScanner->NextToken();
|
||||
}
|
||||
else if (mScanner->mToken == TK_EXTERN)
|
||||
{
|
||||
storageFlags |= DTF_EXTERN;
|
||||
mScanner->NextToken();
|
||||
}
|
||||
else if (mScanner->mToken == TK_INLINE)
|
||||
{
|
||||
storageFlags |= DTF_REQUEST_INLINE;
|
||||
mScanner->NextToken();
|
||||
}
|
||||
else if (mScanner->mToken == TK_EXPORT)
|
||||
{
|
||||
storageFlags |= DTF_EXPORT;
|
||||
mScanner->NextToken();
|
||||
}
|
||||
else if (mScanner->mToken == TK_FASTCALL)
|
||||
{
|
||||
storageFlags |= DTF_FASTCALL;
|
||||
mScanner->NextToken();
|
||||
}
|
||||
else if (mScanner->mToken == TK_NATIVE)
|
||||
{
|
||||
storageFlags |= DTF_NATIVE;
|
||||
mScanner->NextToken();
|
||||
}
|
||||
else if (mScanner->mToken == TK_INTERRUPT)
|
||||
{
|
||||
storageFlags |= DTF_INTERRUPT | DTF_NATIVE;
|
||||
mScanner->NextToken();
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1057,6 +1092,11 @@ Declaration* Parser::ParseDeclaration(bool variable)
|
|||
ndec->mSection = mDataSection;
|
||||
ndec->mSize = ndec->mBase->mSize;
|
||||
}
|
||||
|
||||
if (storageFlags & DTF_EXPORT)
|
||||
{
|
||||
mCompilationUnits->AddReferenced(ndec);
|
||||
}
|
||||
}
|
||||
|
||||
if (mScanner->mToken == TK_COMMA)
|
||||
|
|
|
@ -50,6 +50,10 @@ const char* TokenNames[] =
|
|||
"'__assume'",
|
||||
|
||||
"__asm",
|
||||
"__interrupt",
|
||||
"__native",
|
||||
"__fastcall",
|
||||
"__export",
|
||||
|
||||
"number",
|
||||
"char",
|
||||
|
@ -1257,6 +1261,14 @@ void Scanner::NextRawToken(void)
|
|||
mToken = TK_ASM;
|
||||
else if (!strcmp(tkident, "__assume"))
|
||||
mToken = TK_ASSUME;
|
||||
else if (!strcmp(tkident, "__interrupt"))
|
||||
mToken = TK_INTERRUPT;
|
||||
else if (!strcmp(tkident, "__native"))
|
||||
mToken = TK_NATIVE;
|
||||
else if (!strcmp(tkident, "__fastcall"))
|
||||
mToken = TK_FASTCALL;
|
||||
else if (!strcmp(tkident, "__export"))
|
||||
mToken = TK_EXPORT;
|
||||
else
|
||||
{
|
||||
mToken = TK_IDENT;
|
||||
|
|
|
@ -48,6 +48,10 @@ enum Token
|
|||
TK_ASSUME,
|
||||
|
||||
TK_ASM,
|
||||
TK_INTERRUPT,
|
||||
TK_NATIVE,
|
||||
TK_FASTCALL,
|
||||
TK_EXPORT,
|
||||
|
||||
TK_NUMBER,
|
||||
TK_CHARACTER,
|
||||
|
|
|
@ -73,7 +73,7 @@ int main(int argc, const char** argv)
|
|||
|
||||
#else
|
||||
strcpy(strProductName, "oscar64");
|
||||
strcpy(strProductVersion, "1.2.67");
|
||||
strcpy(strProductVersion, "1.2.68");
|
||||
|
||||
#ifdef __APPLE__
|
||||
uint32_t length = sizeof(basePath);
|
||||
|
|
|
@ -25,8 +25,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_NEUTRAL
|
|||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 1,2,67,0
|
||||
PRODUCTVERSION 1,2,67,0
|
||||
FILEVERSION 1,2,68,0
|
||||
PRODUCTVERSION 1,2,68,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
|
@ -43,12 +43,12 @@ BEGIN
|
|||
BEGIN
|
||||
VALUE "CompanyName", "oscar64"
|
||||
VALUE "FileDescription", "oscar64 compiler"
|
||||
VALUE "FileVersion", "1.2.67.0"
|
||||
VALUE "FileVersion", "1.2.68.0"
|
||||
VALUE "InternalName", "oscar64.exe"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2021"
|
||||
VALUE "OriginalFilename", "oscar64.exe"
|
||||
VALUE "ProductName", "oscar64"
|
||||
VALUE "ProductVersion", "1.2.67.0"
|
||||
VALUE "ProductVersion", "1.2.68.0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
|
Binary file not shown.
|
@ -1,3 +1,4 @@
|
|||
#!/bin/sh
|
||||
../../bin/oscar64 joycontrol.c
|
||||
../../bin/oscar64 multiplexer.c -n
|
||||
../../bin/oscar64 creditroll.c -n
|
||||
|
|
|
@ -0,0 +1,233 @@
|
|||
#include <c64/vic.h>
|
||||
#include <c64/rasterirq.h>
|
||||
#include <c64/sprites.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define Screen ((char *)0x400)
|
||||
|
||||
// make space until 0x2000 for code and data
|
||||
|
||||
#pragma region( lower, 0x0a00, 0x2000, , , {code, data} )
|
||||
|
||||
// then space for our sprite data
|
||||
|
||||
#pragma section( spriteset, 0)
|
||||
|
||||
#pragma region( spriteset, 0x2000, 0x2c00, , , {spriteset} )
|
||||
|
||||
|
||||
// everything beyond will be code, data, bss and heap to the end
|
||||
|
||||
#pragma region( main, 0x2c00, 0xa000, , , {code, data, bss, heap, stack} )
|
||||
|
||||
|
||||
// spriteset at fixed location
|
||||
|
||||
#pragma data(spriteset)
|
||||
|
||||
char spriteset[64 * 48] = {0};
|
||||
|
||||
#pragma data(data)
|
||||
|
||||
char charset[32 * 8] = {
|
||||
#embed "../resources/scifiglyph.bin"
|
||||
}
|
||||
|
||||
|
||||
const char * scrolltext[] = {
|
||||
|
||||
|
||||
"This sample uses",
|
||||
"six sprites",
|
||||
"multiplexed six",
|
||||
"times to provide",
|
||||
"twelve lines of",
|
||||
"text with eighteen",
|
||||
"characters each",
|
||||
"",
|
||||
"each character is",
|
||||
"extracted from a",
|
||||
"custom font into a",
|
||||
"new sprite and the",
|
||||
"sprites are then",
|
||||
"moved up the",
|
||||
"screen",
|
||||
"",
|
||||
"interrupts are",
|
||||
"used to switch the",
|
||||
"sprite vertical",
|
||||
"position and",
|
||||
"graphics",
|
||||
"data every two",
|
||||
"character lines"
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
};
|
||||
|
||||
|
||||
RIRQCode * spmux[6], final;
|
||||
|
||||
void readline(char * dp, char n)
|
||||
{
|
||||
const char * sp = scrolltext[n];
|
||||
|
||||
char s = 0;
|
||||
while (sp[s])
|
||||
s++;
|
||||
|
||||
char l = (18 - s) >> 1;
|
||||
char i = 0;
|
||||
while (i < l)
|
||||
dp[i++] = ' ';
|
||||
|
||||
s = 0;
|
||||
while (sp[s])
|
||||
{
|
||||
dp[i++] = sp[s];
|
||||
s++;
|
||||
}
|
||||
|
||||
while (i < 18)
|
||||
dp[i++] = ' ';
|
||||
}
|
||||
|
||||
void expandline(const char * line, char sppos, char ty)
|
||||
{
|
||||
char * dp = spriteset + 64 * sppos + 3 * ty;
|
||||
|
||||
char xl = 0;
|
||||
for(char x=0; x<6; x++)
|
||||
{
|
||||
const char * sp = charset + 8 * (line[x] & 0x1f);
|
||||
|
||||
dp[ 0] = sp[0]; dp[ 3] = sp[1]; dp[ 6] = sp[2]; dp[ 9] = sp[3];
|
||||
dp[12] = sp[4]; dp[15] = sp[5]; dp[18] = sp[6]; dp[21] = sp[7];
|
||||
|
||||
dp++;
|
||||
xl++;
|
||||
if (xl == 3)
|
||||
{
|
||||
dp += 61;
|
||||
xl = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
rirq_init(true);
|
||||
spr_init(Screen);
|
||||
|
||||
int oy = 0;
|
||||
char sy = 128;
|
||||
|
||||
for(int i=0; i<5; i++)
|
||||
{
|
||||
spmux[i] = rirq_alloc(12);
|
||||
for(int x=0; x<6; x++)
|
||||
{
|
||||
rirq_write(spmux[i], 2 * x + 0, &vic.spr_pos[x].y, 48 * (i + 1) + oy);
|
||||
rirq_write(spmux[i], 2 * x + 1, Screen + 0x3f8 + x, sy + 1 + i);
|
||||
}
|
||||
rirq_set(i, 48 * i + 46 + oy, spmux[i]);
|
||||
}
|
||||
|
||||
rirq_build(&final, 0);
|
||||
rirq_set(5, 250, &final);
|
||||
rirq_sort();
|
||||
|
||||
rirq_start();
|
||||
|
||||
for(int x=0; x<6; x++)
|
||||
{
|
||||
spr_set(x, true, 40 + 48 * x, oy, 128, 1, false, true, true);
|
||||
}
|
||||
|
||||
char line[20];
|
||||
char lpos = 0;
|
||||
|
||||
for(;;)
|
||||
{
|
||||
rirq_wait();
|
||||
|
||||
oy--;
|
||||
if (oy < 0)
|
||||
{
|
||||
oy += 48;
|
||||
sy += 6;
|
||||
if (sy == 128 + 36)
|
||||
sy = 128;
|
||||
}
|
||||
|
||||
for(char i=0; i<5; i++)
|
||||
{
|
||||
int ty = 48 * i + 46 + oy;
|
||||
if (ty < 250)
|
||||
rirq_move(i, ty);
|
||||
else
|
||||
rirq_clear(i);
|
||||
}
|
||||
rirq_sort();
|
||||
|
||||
char sty = sy;
|
||||
for(int x=0; x<6; x++)
|
||||
{
|
||||
spr_move(x, 40 + 48 * x, oy);
|
||||
spr_image(x, sty);
|
||||
sty ++;
|
||||
}
|
||||
|
||||
|
||||
for(char i=0; i<5; i++)
|
||||
{
|
||||
if (sty == 128 + 36)
|
||||
sty = 128;
|
||||
|
||||
char py = 48 * (i + 1) + oy;
|
||||
for(char x=0; x<6; x++)
|
||||
{
|
||||
rirq_data(spmux[i], 2 * x + 0, py);
|
||||
rirq_data(spmux[i], 2 * x + 1, sty);
|
||||
sty ++;
|
||||
}
|
||||
}
|
||||
rirq_sort();
|
||||
|
||||
vic.color_border++;
|
||||
|
||||
switch (oy)
|
||||
{
|
||||
case 46:
|
||||
case 42:
|
||||
readline(line, lpos);
|
||||
lpos++;
|
||||
if (lpos == 28)
|
||||
lpos = 0;
|
||||
break;
|
||||
case 45:
|
||||
expandline(line + 0, sty - 6 - 128, 0);
|
||||
break;
|
||||
case 44:
|
||||
expandline(line + 6, sty - 4 - 128, 0);
|
||||
break;
|
||||
case 43:
|
||||
expandline(line + 12, sty - 2 - 128, 0);
|
||||
break;
|
||||
|
||||
case 41:
|
||||
expandline(line + 0, sty - 6 - 128, 12);
|
||||
break;
|
||||
case 40:
|
||||
expandline(line + 6, sty - 4 - 128, 12);
|
||||
break;
|
||||
case 39:
|
||||
expandline(line + 12, sty - 2 - 128, 12);
|
||||
break;
|
||||
}
|
||||
vic.color_border--;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,2 +1,3 @@
|
|||
call ..\..\bin\oscar64 joycontrol.c
|
||||
call ..\..\bin\oscar64 multiplexer.c -n
|
||||
call ..\..\bin\oscar64 creditroll.c -n
|
||||
|
|
Loading…
Reference in New Issue