Add sprite multiplexer
This commit is contained in:
parent
80fea25916
commit
1fcc39acd5
|
@ -307,12 +307,11 @@ void rirq_sort(void)
|
|||
{
|
||||
byte ri = rasterIRQIndex[i];
|
||||
byte rr = rasterIRQRows[ri];
|
||||
byte j = i, rj = rasterIRQIndex[j - 1];
|
||||
while (j > 0 && rr < rasterIRQRows[rj])
|
||||
byte j = i, rj;
|
||||
while (j > 0 && rr < rasterIRQRows[(rj = rasterIRQIndex[j - 1])])
|
||||
{
|
||||
rasterIRQIndex[j] = rj;
|
||||
j--;
|
||||
rj = rasterIRQIndex[j - 1]
|
||||
}
|
||||
rasterIRQIndex[j] = ri;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,228 @@
|
|||
#include "sprites.h"
|
||||
#include "rasterirq.h"
|
||||
|
||||
static char * vspriteScreen;
|
||||
|
||||
|
||||
void spr_init(char * screen)
|
||||
{
|
||||
vspriteScreen = screen + 0x3f8;
|
||||
}
|
||||
|
||||
|
||||
void spr_set(char sp, bool show, int xpos, int ypos, char image, char color, bool multi, bool xexpand, bool yexpand)
|
||||
{
|
||||
char m = 1 << sp;
|
||||
|
||||
if (show)
|
||||
vic.spr_enable |= m;
|
||||
else
|
||||
vic.spr_enable &= ~m;
|
||||
|
||||
if (multi)
|
||||
vic.spr_multi |= m;
|
||||
else
|
||||
vic.spr_multi &= ~m;
|
||||
|
||||
if (xexpand)
|
||||
vic.spr_expand_x |= m;
|
||||
else
|
||||
vic.spr_expand_x &= ~m;
|
||||
|
||||
if (yexpand)
|
||||
vic.spr_expand_y |= m;
|
||||
else
|
||||
vic.spr_expand_y &= ~m;
|
||||
|
||||
vic.spr_pos[sp].y = ypos;
|
||||
vic.spr_pos[sp].x = xpos & 0xff;
|
||||
if (xpos & 0x100)
|
||||
vic.spr_msbx |= m;
|
||||
else
|
||||
vic.spr_msbx &= ~m;
|
||||
|
||||
vspriteScreen[sp] = image;
|
||||
vic.spr_color[sp] = color;
|
||||
}
|
||||
|
||||
void spr_show(char sp, bool show)
|
||||
{
|
||||
if (show)
|
||||
vic.spr_enable |= 1 << sp;
|
||||
else
|
||||
vic.spr_enable &= ~(1 << sp);
|
||||
}
|
||||
|
||||
void spr_move(char sp, int xpos, int ypos)
|
||||
{
|
||||
vic.spr_pos[sp].y = ypos;
|
||||
vic.spr_pos[sp].x = xpos & 0xff;
|
||||
if (xpos & 0x100)
|
||||
vic.spr_msbx |= 1 << sp;
|
||||
else
|
||||
vic.spr_msbx &= ~(1 << sp);
|
||||
}
|
||||
|
||||
void spr_image(char sp, char image)
|
||||
{
|
||||
vspriteScreen[sp] = image;
|
||||
}
|
||||
|
||||
void spr_color(char sp, char color)
|
||||
{
|
||||
vic.spr_color[sp] = color;
|
||||
}
|
||||
|
||||
|
||||
#define NUM_SPRITES 16
|
||||
|
||||
static char vspriteYLow[NUM_SPRITES], vspriteXLow[NUM_SPRITES], vspriteXHigh[NUM_SPRITES];
|
||||
static char vspriteImage[NUM_SPRITES], vspriteColor[NUM_SPRITES];
|
||||
|
||||
static char spriteOrder[16], spriteYPos[17];
|
||||
|
||||
static RIRQCode spirq[8], synch;
|
||||
|
||||
|
||||
void vspr_init(char * screen)
|
||||
{
|
||||
vspriteScreen = screen + 0x3f8;
|
||||
|
||||
vic.spr_expand_x = 0;
|
||||
vic.spr_expand_y = 0;
|
||||
vic.spr_enable = 0xff;
|
||||
|
||||
for(int i=0; i<8; i++)
|
||||
{
|
||||
rirq_build(spirq + i, 5);
|
||||
rirq_write(spirq + i, 0, &vic.spr_color[i], 0);
|
||||
rirq_write(spirq + i, 1, &vic.spr_pos[i].x, 0);
|
||||
rirq_write(spirq + i, 2, &vic.spr_pos[i].y, 0);
|
||||
rirq_write(spirq + i, 3, &vspriteScreen[i], 0);
|
||||
rirq_write(spirq + i, 4, &vic.spr_msbx, 0);
|
||||
rirq_set(i, 80 + 8 * i, spirq + i);
|
||||
}
|
||||
|
||||
rirq_build(&synch, 0);
|
||||
rirq_set(8, 250, &synch);
|
||||
|
||||
for(int i=0; i<16; i++)
|
||||
{
|
||||
spriteOrder[i] = i;
|
||||
vspriteYLow[i] = 0xff;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma native(vspr_init)
|
||||
|
||||
void vspr_set(char sp, int xpos, int ypos, char image, char color)
|
||||
{
|
||||
vspriteYLow[sp] = (char)ypos;
|
||||
vspriteXLow[sp] = (char)xpos;
|
||||
vspriteXHigh[sp] = (char)(xpos >> 8);
|
||||
vspriteImage[sp] = image;
|
||||
vspriteColor[sp] = color;
|
||||
if ((ypos & 0xff00 ) || (xpos & 0xfe00))
|
||||
vspriteYLow[sp] = 0xff;
|
||||
}
|
||||
|
||||
#pragma native(vspr_set)
|
||||
|
||||
void vspr_move(char sp, int xpos, int ypos)
|
||||
{
|
||||
char yp = (char)ypos;
|
||||
if ((ypos & 0xff00 ) || (xpos & 0xfe00))
|
||||
yp = 0xff;
|
||||
|
||||
vspriteYLow[sp] = yp;
|
||||
vspriteXLow[sp] = (char)xpos;
|
||||
vspriteXHigh[sp] = (char)(xpos >> 8);
|
||||
}
|
||||
|
||||
void vspr_image(char sp, char image)
|
||||
{
|
||||
vspriteImage[sp] = image;
|
||||
}
|
||||
|
||||
void vspr_color(char sp, char color)
|
||||
{
|
||||
vspriteColor[sp] = color;
|
||||
}
|
||||
|
||||
void vspr_hide(char sp)
|
||||
{
|
||||
vspriteYLow[sp] = 0xff;
|
||||
}
|
||||
|
||||
void vspr_sort(void)
|
||||
{
|
||||
spriteYPos[1] = vspriteYLow[spriteOrder[0]];
|
||||
|
||||
for(char i = 1; i<16; i++)
|
||||
{
|
||||
byte ri = spriteOrder[i];
|
||||
byte rr = vspriteYLow[ri];
|
||||
byte j = i, rj = spriteYPos[j];
|
||||
while (rr < rj)
|
||||
{
|
||||
spriteYPos[j + 1] = rj;
|
||||
spriteOrder[j] = spriteOrder[j - 1];
|
||||
rj = spriteYPos[j - 1];
|
||||
j--;
|
||||
}
|
||||
spriteOrder[j] = ri;
|
||||
spriteYPos[j + 1] = rr;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma native(vspr_sort)
|
||||
|
||||
void vspr_update(void)
|
||||
{
|
||||
char xymask = 0;
|
||||
char * vsprs = vspriteScreen;
|
||||
|
||||
for(char ui=0; ui<8; ui++)
|
||||
{
|
||||
byte ri = spriteOrder[ui];
|
||||
|
||||
vic.spr_color[ui] = vspriteColor[ri];
|
||||
vsprs[ui] = vspriteImage[ri];
|
||||
xymask = ((unsigned)xymask | (vspriteXHigh[ri] << 8)) >> 1;
|
||||
vic.spr_pos[ui].x = vspriteXLow[ri];
|
||||
vic.spr_pos[ui].y = vspriteYLow[ri];
|
||||
}
|
||||
|
||||
vic.spr_msbx = xymask;
|
||||
|
||||
if (spriteYPos[8] < 230)
|
||||
{
|
||||
char m = 1;
|
||||
for(char ti=0; ti<8; ti++)
|
||||
{
|
||||
|
||||
byte ri = spriteOrder[ti + 8];
|
||||
|
||||
xymask |= m;
|
||||
if (!vspriteXHigh[ri])
|
||||
xymask ^= m;
|
||||
|
||||
rirq_data(spirq + ti, 0, vspriteColor[ri]);
|
||||
rirq_data(spirq + ti, 1, vspriteXLow[ri]);
|
||||
rirq_data(spirq + ti, 2, vspriteYLow[ri]);
|
||||
rirq_data(spirq + ti, 3, vspriteImage[ri]);
|
||||
|
||||
rirq_data(spirq + ti, 4, xymask);
|
||||
rirq_move(ti, spriteYPos[ti + 1] + 21);
|
||||
|
||||
m <<= 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(char ti=0; ti<8; ti++)
|
||||
rirq_clear(ti);
|
||||
}
|
||||
}
|
||||
|
||||
#pragma native(vspr_update)
|
|
@ -0,0 +1,40 @@
|
|||
#ifndef SPRITES_H
|
||||
#define SPRITES_H
|
||||
|
||||
#include "vic.h"
|
||||
|
||||
|
||||
void spr_init(char * screen);
|
||||
|
||||
void spr_set(char sp, bool show, int xpos, int ypos, char image, char color, bool multi, bool xexpand, bool yexpand);
|
||||
|
||||
inline void spr_show(char sp, bool show);
|
||||
|
||||
inline void spr_move(char sp, int xpos, int ypos);
|
||||
|
||||
inline void spr_image(char sp, char image);
|
||||
|
||||
inline void spr_color(char sp, char color);
|
||||
|
||||
|
||||
void vspr_init(char * screen);
|
||||
|
||||
|
||||
void vspr_set(char sp, int xpos, int ypos, char image, char color);
|
||||
|
||||
inline void vspr_move(char sp, int xpos, int ypos);
|
||||
|
||||
inline void vspr_image(char sp, char image);
|
||||
|
||||
inline void vspr_color(char sp, char color);
|
||||
|
||||
inline void vspr_hide(char sp);
|
||||
|
||||
void vspr_sort(void);
|
||||
|
||||
void vspr_update(void);
|
||||
|
||||
|
||||
#pragma compile("sprites.c")
|
||||
|
||||
#endif
|
|
@ -45,3 +45,37 @@ void vic_setmode(VicMode mode, char * text, char * font)
|
|||
cia2.pra = (cia2.pra & 0xfc) | (((unsigned)text >> 14) ^ 0x03);
|
||||
vic.memptr = (((unsigned)text >> 6) & 0xf0) | (((unsigned)font >> 10) & 0x0e);
|
||||
}
|
||||
|
||||
void waitBottom(void)
|
||||
{
|
||||
while (!(vic.ctrl1 & VIC_CTRL1_RST8))
|
||||
;
|
||||
}
|
||||
|
||||
void waitTop(void)
|
||||
{
|
||||
while ((vic.ctrl1 & VIC_CTRL1_RST8))
|
||||
;
|
||||
}
|
||||
|
||||
void vic_waitFrame(void)
|
||||
{
|
||||
while ((vic.ctrl1 & VIC_CTRL1_RST8))
|
||||
;
|
||||
while (!(vic.ctrl1 & VIC_CTRL1_RST8))
|
||||
;
|
||||
}
|
||||
|
||||
void vic_waitLine(int line)
|
||||
{
|
||||
char upper = (char)(line >> 1) & VIC_CTRL1_RST8;
|
||||
char lower = (char)line;
|
||||
|
||||
do
|
||||
{
|
||||
while (vic.raster != lower)
|
||||
;
|
||||
} while ((vic.ctrl1 & VIC_CTRL1_RST8) != upper);
|
||||
}
|
||||
|
||||
#pragma native(vic_waitLine)
|
||||
|
|
|
@ -88,6 +88,13 @@ void vic_setmode(VicMode mode, char * text, char * font);
|
|||
|
||||
inline void vic_sprxy(byte s, int x, int y);
|
||||
|
||||
inline void vic_waitBottom(void);
|
||||
|
||||
inline void vic_waitTop(void);
|
||||
|
||||
inline void vic_waitFrame(void);
|
||||
|
||||
inline void vic_waitLine(int line);
|
||||
|
||||
#define vic (*((struct VIC *)0xd000))
|
||||
|
||||
|
|
|
@ -2676,7 +2676,7 @@ static void OptimizeAddress(InterInstruction * ins, const GrowingInstructionPtrA
|
|||
{
|
||||
ins->mSrc[offset].mIntConst = 0;
|
||||
|
||||
if (ins->mSrc[offset].mTemp >= 0 && tvalue[ins->mSrc[offset].mTemp])
|
||||
while (ins->mSrc[offset].mTemp >= 0 && tvalue[ins->mSrc[offset].mTemp])
|
||||
{
|
||||
InterInstruction* ains = tvalue[ins->mSrc[offset].mTemp];
|
||||
|
||||
|
@ -2705,6 +2705,8 @@ static void OptimizeAddress(InterInstruction * ins, const GrowingInstructionPtrA
|
|||
ins->mSrc[offset].mIntConst = ains->mSrc[1].mIntConst;
|
||||
ins->mSrc[offset].mTemp = ains->mSrc[0].mTemp;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -598,6 +598,31 @@ bool NativeCodeInstruction::RequiresXReg(void) const
|
|||
}
|
||||
|
||||
|
||||
void NativeCodeInstruction::ReplaceYRegWithXReg(void)
|
||||
{
|
||||
switch (mType)
|
||||
{
|
||||
case ASMIT_LDY:
|
||||
mType = ASMIT_LDX;
|
||||
break;
|
||||
case ASMIT_STY:
|
||||
mType = ASMIT_STX;
|
||||
break;
|
||||
case ASMIT_CPY:
|
||||
mType = ASMIT_CPX;
|
||||
break;
|
||||
case ASMIT_TYA:
|
||||
mType = ASMIT_TXA;
|
||||
break;
|
||||
case ASMIT_TAY:
|
||||
mType = ASMIT_TAX;
|
||||
break;
|
||||
}
|
||||
|
||||
if (mMode == ASMIM_ABSOLUTE_Y)
|
||||
mMode = ASMIM_ABSOLUTE_X;
|
||||
}
|
||||
|
||||
bool NativeCodeInstruction::ChangesYReg(void) const
|
||||
{
|
||||
return mType == ASMIT_TAY || mType == ASMIT_LDY || mType == ASMIT_INY || mType == ASMIT_DEY || mType == ASMIT_JSR;
|
||||
|
@ -4670,6 +4695,36 @@ void NativeCodeBasicBlock::ShiftRegisterLeft(InterCodeProcedure* proc, int reg,
|
|||
}
|
||||
}
|
||||
|
||||
void NativeCodeBasicBlock::ShiftRegisterLeftByte(InterCodeProcedure* proc, int reg, int shift)
|
||||
{
|
||||
if (shift == 0)
|
||||
{
|
||||
|
||||
}
|
||||
else if (shift == 1)
|
||||
{
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_ASL, ASMIM_ZERO_PAGE, reg));
|
||||
}
|
||||
else if (shift >= 6)
|
||||
{
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, reg));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_LSR, ASMIM_IMPLIED));
|
||||
for (int i = shift; i < 8; i++)
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_ROR, ASMIM_IMPLIED));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_AND, ASMIM_IMMEDIATE, (0xff << shift) & 0xff));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg));
|
||||
}
|
||||
else
|
||||
{
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, reg));
|
||||
for (int i = 0; i < shift; i++)
|
||||
{
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_ASL, ASMIM_IMPLIED));
|
||||
}
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg));
|
||||
}
|
||||
}
|
||||
|
||||
int NativeCodeBasicBlock::ShortMultiply(InterCodeProcedure* proc, NativeCodeProcedure* nproc, const InterInstruction * ins, const InterInstruction* sins, int index, int mul)
|
||||
{
|
||||
mul &= 0xffff;
|
||||
|
@ -4695,7 +4750,14 @@ int NativeCodeBasicBlock::ShortMultiply(InterCodeProcedure* proc, NativeCodeProc
|
|||
{
|
||||
#if 1
|
||||
case 1:
|
||||
ShiftRegisterLeft(proc, BC_REG_ACCU, lshift);
|
||||
if (ins->mDst.IsUByte())
|
||||
{
|
||||
ShiftRegisterLeftByte(proc, BC_REG_ACCU, lshift);
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, 0));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 1));
|
||||
}
|
||||
else
|
||||
ShiftRegisterLeft(proc, BC_REG_ACCU, lshift);
|
||||
return BC_REG_ACCU;
|
||||
case 3:
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 0));
|
||||
|
@ -10862,6 +10924,58 @@ void NativeCodeBasicBlock::BlockSizeReduction(void)
|
|||
j += 2;
|
||||
i += 4;
|
||||
}
|
||||
else if (i + 1 < mIns.Size() &&
|
||||
mIns[i + 0].mType == ASMIT_LDA && mIns[i + 0].mMode == ASMIM_ABSOLUTE_X &&
|
||||
mIns[i + 1].mType == ASMIT_TAY && !(mIns[i + 1].mLive & LIVE_CPU_REG_A))
|
||||
{
|
||||
mIns[j] = mIns[i];
|
||||
mIns[j].mType = ASMIT_LDY;
|
||||
mIns[j].mLive |= LIVE_CPU_REG_Y;
|
||||
j++;
|
||||
i += 2;
|
||||
}
|
||||
else if (i + 1 < mIns.Size() &&
|
||||
mIns[i + 0].mType == ASMIT_LDA && mIns[i + 0].mMode == ASMIM_ABSOLUTE_Y &&
|
||||
mIns[i + 1].mType == ASMIT_TAX && !(mIns[i + 1].mLive & LIVE_CPU_REG_A))
|
||||
{
|
||||
mIns[j] = mIns[i];
|
||||
mIns[j].mType = ASMIT_LDX;
|
||||
mIns[j].mLive |= LIVE_CPU_REG_Y;
|
||||
j++;
|
||||
i += 2;
|
||||
}
|
||||
else if (i + 2 < mIns.Size() &&
|
||||
mIns[i + 0].mType == ASMIT_LDY && !(mIns[i + 0].mLive & LIVE_CPU_REG_X) && (mIns[i + 0].mMode == ASMIM_ZERO_PAGE || mIns[i + 0].mMode == ASMIM_ABSOLUTE) &&
|
||||
mIns[i + 1].mType == ASMIT_LDA && mIns[i + 1].mMode == ASMIM_ABSOLUTE_Y &&
|
||||
mIns[i + 2].mType == ASMIT_TAY && !(mIns[i + 2].mLive & LIVE_CPU_REG_A))
|
||||
{
|
||||
mIns[j + 0] = mIns[i + 0];
|
||||
mIns[j + 1] = mIns[i + 1];
|
||||
|
||||
mIns[j + 0].mType = ASMIT_LDX;
|
||||
mIns[j + 0].mLive |= LIVE_CPU_REG_X;
|
||||
mIns[j + 1].mType = ASMIT_LDY;
|
||||
mIns[j + 1].mMode = ASMIM_ABSOLUTE_X;
|
||||
mIns[j + 1].mLive |= LIVE_CPU_REG_Y;
|
||||
j += 2;
|
||||
i += 3;
|
||||
}
|
||||
else if (i + 2 < mIns.Size() &&
|
||||
mIns[i + 0].mType == ASMIT_LDX && !(mIns[i + 0].mLive & LIVE_CPU_REG_Y) && (mIns[i + 0].mMode == ASMIM_ZERO_PAGE || mIns[i + 0].mMode == ASMIM_ABSOLUTE) &&
|
||||
mIns[i + 1].mType == ASMIT_LDA && mIns[i + 1].mMode == ASMIM_ABSOLUTE_X &&
|
||||
mIns[i + 2].mType == ASMIT_TAX && !(mIns[i + 2].mLive & LIVE_CPU_REG_A))
|
||||
{
|
||||
mIns[j + 0] = mIns[i + 0];
|
||||
mIns[j + 1] = mIns[i + 1];
|
||||
|
||||
mIns[j + 0].mType = ASMIT_LDY;
|
||||
mIns[j + 0].mLive |= LIVE_CPU_REG_Y;
|
||||
mIns[j + 1].mType = ASMIT_LDX;
|
||||
mIns[j + 1].mMode = ASMIM_ABSOLUTE_Y;
|
||||
mIns[j + 1].mLive |= LIVE_CPU_REG_X;
|
||||
j += 2;
|
||||
i += 3;
|
||||
}
|
||||
else
|
||||
mIns[j++] = mIns[i++];
|
||||
}
|
||||
|
@ -12574,7 +12688,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass)
|
|||
progress = true;
|
||||
}
|
||||
else if (
|
||||
mIns[i + 0].mType == ASMIT_LDA &&
|
||||
mIns[i + 0].mType == ASMIT_LDA &&
|
||||
mIns[i + 1].mType == ASMIT_STA && mIns[i + 1].mMode == ASMIM_ZERO_PAGE &&
|
||||
mIns[i + 3].mMode == ASMIM_ZERO_PAGE && mIns[i + 1].mAddress && mIns[i + 3].mAddress &&
|
||||
mIns[i + 2].mMode == ASMIM_IMPLIED && !(mIns[i + 3].mLive & LIVE_MEM) &&
|
||||
|
@ -12583,7 +12697,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass)
|
|||
{
|
||||
mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED;
|
||||
mIns[i + 3].mMode = mIns[i + 0].mMode;
|
||||
mIns[i + 3].mAddress= mIns[i + 0].mAddress;
|
||||
mIns[i + 3].mAddress = mIns[i + 0].mAddress;
|
||||
mIns[i + 3].mLinkerObject = mIns[i + 0].mLinkerObject;
|
||||
mIns[i + 3].mFlags = mIns[i + 0].mFlags;
|
||||
progress = true;
|
||||
|
@ -12668,6 +12782,22 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass)
|
|||
|
||||
progress = true;
|
||||
}
|
||||
#if 1
|
||||
else if (
|
||||
mIns[i + 0].mType == ASMIT_LDY && mIns[i + 0].mMode == ASMIM_ZERO_PAGE &&
|
||||
!(mIns[i + 1].ChangesYReg() || mIns[i + 1].mMode == ASMIM_INDIRECT_Y || mIns[i + 1].RequiresXReg()) &&
|
||||
mIns[i + 2].mType == ASMIT_TYA &&
|
||||
mIns[i + 3].mType == ASMIT_TAX && !(mIns[i + 3].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_Z | LIVE_CPU_REG_Y)))
|
||||
{
|
||||
mIns[i + 0].mType = ASMIT_LDX;
|
||||
mIns[i + 0].mLive |= LIVE_CPU_REG_X;
|
||||
mIns[i + 1].ReplaceYRegWithXReg();
|
||||
mIns[i + 2].mType = ASMIT_NOP; mIns[i + 2].mMode = ASMIM_IMPLIED;
|
||||
mIns[i + 3].mType = ASMIT_NOP; mIns[i + 3].mMode = ASMIM_IMPLIED;
|
||||
progress = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if 1
|
||||
if (
|
||||
|
|
|
@ -96,6 +96,8 @@ public:
|
|||
bool IsSame(const NativeCodeInstruction& ins) const;
|
||||
bool IsCommutative(void) const;
|
||||
bool IsShift(void) const;
|
||||
|
||||
void ReplaceYRegWithXReg(void);
|
||||
};
|
||||
|
||||
class NativeCodeBasicBlock
|
||||
|
@ -174,6 +176,7 @@ public:
|
|||
void CallFunction(InterCodeProcedure* proc, NativeCodeProcedure* nproc, const InterInstruction * ins);
|
||||
|
||||
void ShiftRegisterLeft(InterCodeProcedure* proc, int reg, int shift);
|
||||
void ShiftRegisterLeftByte(InterCodeProcedure* proc, int reg, int shift);
|
||||
int ShortMultiply(InterCodeProcedure* proc, NativeCodeProcedure* nproc, const InterInstruction * ins, const InterInstruction* sins, int index, int mul);
|
||||
|
||||
bool CheckPredAccuStore(int reg);
|
||||
|
|
|
@ -0,0 +1,95 @@
|
|||
#include <c64/memmap.h>
|
||||
#include <c64/vic.h>
|
||||
#include <gfx/bitmap.h>
|
||||
#include <string.h>
|
||||
#include <conio.h>
|
||||
#include <math.h>
|
||||
|
||||
#define Color ((char *)0xd000)
|
||||
#define Hires ((char *)0xe000)
|
||||
|
||||
Bitmap Screen, Brush;
|
||||
|
||||
void init(void)
|
||||
{
|
||||
mmap_trampoline();
|
||||
mmap_set(MMAP_RAM);
|
||||
|
||||
memset(Color, 0x10, 1000);
|
||||
memset(Hires, 0x00, 8000);
|
||||
|
||||
mmap_set(MMAP_NO_ROM);
|
||||
|
||||
vic_setmode(VICM_HIRES, Color, Hires);
|
||||
|
||||
vic.color_border = VCOL_WHITE;
|
||||
|
||||
bm_init(&Screen, Hires, 40, 25);
|
||||
}
|
||||
|
||||
void done(void)
|
||||
{
|
||||
mmap_set(MMAP_ROM);
|
||||
|
||||
getch();
|
||||
|
||||
vic_setmode(VICM_TEXT, (char *)0x0400, (char *)0x1000);
|
||||
}
|
||||
|
||||
int poly_x[] = {0, 32, 32, 24, 40, 32, 32, 64, 52, 42, 22, 12};
|
||||
int poly_y[] = {64, 0, 20, 36, 36, 20, 0, 64, 64, 44, 44, 64};
|
||||
|
||||
struct BlitDemo
|
||||
{
|
||||
const char * name;
|
||||
BlitOp op;
|
||||
};
|
||||
|
||||
BlitDemo blitDemos[11] = {
|
||||
|
||||
{"SET", BLTOP_SET},
|
||||
{"RESET", BLTOP_RESET},
|
||||
{"NOT", BLTOP_NOT},
|
||||
|
||||
{"XOR", BLTOP_XOR},
|
||||
{"OR", BLTOP_OR},
|
||||
{"AND", BLTOP_AND},
|
||||
{"NAND", BLTOP_AND_NOT},
|
||||
|
||||
{"COPY", BLTOP_COPY},
|
||||
{"NCOPY", BLTOP_NCOPY},
|
||||
|
||||
{"PATTERN", BLTOP_PATTERN},
|
||||
{"MASKPAT", BLTOP_PATTERN_AND_SRC},
|
||||
};
|
||||
|
||||
char pat[] = {0x6c, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00};
|
||||
|
||||
int main(void)
|
||||
{
|
||||
init();
|
||||
|
||||
bm_alloc(&Brush, 8, 8);
|
||||
bm_fill(&Brush, 0);
|
||||
|
||||
ClipRect bcr = {0, 0, 64, 64};
|
||||
|
||||
bm_polygon_nc_fill(&Brush, &bcr, poly_x, poly_y, 12, NineShadesOfGrey[8]);
|
||||
|
||||
bmu_rect_pattern(&Screen, 0, 0, 320, 200, NineShadesOfGrey[2]);
|
||||
|
||||
ClipRect scr = {0, 0, 320, 200};
|
||||
|
||||
for(int i=0; i<11; i++)
|
||||
{
|
||||
int dx = 80 * ((i + 1) % 4);
|
||||
int dy = 66 * ((i + 1) / 4);
|
||||
|
||||
bmu_bitblit(&Screen, dx + 8, dy + 1, &Brush, 0, 0, 64, 64, pat, blitDemos[i].op);
|
||||
bm_put_string(&Screen, &scr, dx + 8, dy + 20, blitDemos[i].name, BLTOP_COPY);
|
||||
}
|
||||
|
||||
done();
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,7 +1,5 @@
|
|||
// func3d
|
||||
#include <c64/memmap.h>
|
||||
#include <c64/vic.h>
|
||||
#include <c64/cia.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <conio.h>
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
#include <c64/memmap.h>
|
||||
#include <c64/vic.h>
|
||||
#include <gfx/bitmap.h>
|
||||
#include <string.h>
|
||||
#include <conio.h>
|
||||
|
||||
|
||||
#define Color ((char *)0xd000)
|
||||
#define Hires ((char *)0xe000)
|
||||
|
||||
Bitmap Screen;
|
||||
|
||||
void init(void)
|
||||
{
|
||||
mmap_trampoline();
|
||||
mmap_set(MMAP_RAM);
|
||||
|
||||
memset(Color, 0x01, 1000);
|
||||
memset(Hires, 0x00, 8000);
|
||||
|
||||
mmap_set(MMAP_NO_ROM);
|
||||
|
||||
vic_setmode(VICM_HIRES, Color, Hires);
|
||||
|
||||
vic.color_border = VCOL_WHITE;
|
||||
|
||||
bm_init(&Screen, Hires, 40, 25);
|
||||
}
|
||||
|
||||
void done(void)
|
||||
{
|
||||
mmap_set(MMAP_ROM);
|
||||
|
||||
getch();
|
||||
|
||||
vic_setmode(VICM_TEXT, (char *)0x0400, (char *)0x1000);
|
||||
}
|
||||
|
||||
void draw(ClipRect * cr, byte pattern)
|
||||
{
|
||||
for(int i=0; i<40; i ++)
|
||||
{
|
||||
bm_line(&Screen, cr, 8 * i, 0, 319, 5 * i, pattern);
|
||||
bm_line(&Screen, cr, 319, 5 * i, 319 - 8 * i, 199, pattern);
|
||||
bm_line(&Screen, cr, 319 - 8 * i, 199, 0, 199 - 5 * i, pattern);
|
||||
bm_line(&Screen, cr, 0, 199 - 5 * i, 8 * i, 0, pattern);
|
||||
}
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
init();
|
||||
|
||||
ClipRect cr = {0, 0, 320, 200};
|
||||
|
||||
draw(&cr, 0xff);
|
||||
draw(&cr, 0x00);
|
||||
|
||||
draw(&cr, 0xff);
|
||||
draw(&cr, 0xaa);
|
||||
draw(&cr, 0x88);
|
||||
draw(&cr, 0x80);
|
||||
draw(&cr, 0x00);
|
||||
|
||||
done();
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,2 +1,5 @@
|
|||
..\..\bin\oscar64 splitscreen.c
|
||||
..\..\bin\oscar64 func3d.c -n
|
||||
..\..\bin\oscar64 lines.c -n
|
||||
..\..\bin\oscar64 polygon.c -n
|
||||
..\..\bin\oscar64 bitblit.c -n
|
||||
|
|
|
@ -0,0 +1,84 @@
|
|||
#include <c64/memmap.h>
|
||||
#include <c64/vic.h>
|
||||
#include <gfx/bitmap.h>
|
||||
#include <string.h>
|
||||
#include <conio.h>
|
||||
#include <math.h>
|
||||
|
||||
#define Color ((char *)0xd000)
|
||||
#define Hires ((char *)0xe000)
|
||||
|
||||
Bitmap Screen;
|
||||
|
||||
void init(void)
|
||||
{
|
||||
mmap_trampoline();
|
||||
mmap_set(MMAP_RAM);
|
||||
|
||||
memset(Color, 0x10, 1000);
|
||||
memset(Hires, 0x00, 8000);
|
||||
|
||||
mmap_set(MMAP_NO_ROM);
|
||||
|
||||
vic_setmode(VICM_HIRES, Color, Hires);
|
||||
|
||||
vic.color_border = VCOL_WHITE;
|
||||
|
||||
bm_init(&Screen, Hires, 40, 25);
|
||||
}
|
||||
|
||||
void done(void)
|
||||
{
|
||||
mmap_set(MMAP_ROM);
|
||||
|
||||
getch();
|
||||
|
||||
vic_setmode(VICM_TEXT, (char *)0x0400, (char *)0x1000);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
init();
|
||||
|
||||
bmu_rect_pattern(&Screen, 0, 0, 320, 200, NineShadesOfGrey[4]);
|
||||
bmu_rect_clear(&Screen, 14, 14, 304, 184);
|
||||
bmu_rect_fill(&Screen, 8, 8, 304, 184);
|
||||
bmu_rect_clear(&Screen, 10, 10, 300, 180);
|
||||
|
||||
ClipRect cr = {11, 11, 309, 189};
|
||||
|
||||
float px[10], py[10];
|
||||
|
||||
for(int i=0; i<10; i++)
|
||||
{
|
||||
float w = i * PI / 5, c = cos(w), s = sin(w), r = (i & 1) ? 1.0 : 0.4;
|
||||
px[i] = r * c; py[i] = r * s;
|
||||
|
||||
}
|
||||
|
||||
for(int i=0; i<128; i++)
|
||||
{
|
||||
int rpx[10], rpy[10];
|
||||
float r = i + 4;
|
||||
float w = i * PI / 16, c = r * cos(w), s = r * sin(w), cw = r * cos(w * 2.0), sw = r * sin(w * 2.0);
|
||||
|
||||
for(int j=0; j<10; j++)
|
||||
{
|
||||
float fx = px[j], fy = py[j];
|
||||
rpx[j] = 160 + cw + fx * c + fy * s;
|
||||
rpy[j] = 100 + sw - fx * s + fy * c;
|
||||
}
|
||||
|
||||
bm_polygon_nc_fill(&Screen, &cr, rpx, rpy, 10, NineShadesOfGrey[i % 9]);
|
||||
|
||||
for(int j=0; j<10; j++)
|
||||
{
|
||||
int k = (j + 1) % 10;
|
||||
bm_line(&Screen, &cr, rpx[j], rpy[j], rpx[k], rpy[k], 0xff);
|
||||
}
|
||||
}
|
||||
|
||||
done();
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -34,15 +34,12 @@ int main(void)
|
|||
|
||||
rirq_init(true);
|
||||
|
||||
vic.ctrl1 = VIC_CTRL1_BMM | VIC_CTRL1_DEN | VIC_CTRL1_RSEL | 3;
|
||||
vic.ctrl2 = VIC_CTRL2_CSEL;
|
||||
|
||||
vic.color_back = VCOL_BLACK;
|
||||
|
||||
memset(Color, 0x10, 1000);
|
||||
memset(Hires, 0, 8000);
|
||||
|
||||
vic_setbank(3);
|
||||
vic.memptr = 0x28;
|
||||
vic_setmode(VICM_HIRES, Color, Hires);
|
||||
|
||||
rirq_build(&rirqtop, 2);
|
||||
rirq_write(&rirqtop, 0, &vic.memptr, 0x28);
|
||||
|
|
|
@ -25,7 +25,6 @@ char charset[2048] = {
|
|||
|
||||
#pragma data(data)
|
||||
|
||||
char x;
|
||||
int main(void)
|
||||
{
|
||||
// map the vic to the new charset
|
||||
|
|
Binary file not shown.
|
@ -51,17 +51,6 @@ const char * text =
|
|||
s"invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam "
|
||||
s"et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet."
|
||||
|
||||
inline void waitBottom(void)
|
||||
{
|
||||
while (!(vic.ctrl1 & VIC_CTRL1_RST8))
|
||||
;
|
||||
}
|
||||
|
||||
inline void waitTop(void)
|
||||
{
|
||||
while ((vic.ctrl1 & VIC_CTRL1_RST8))
|
||||
;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
|
@ -87,19 +76,19 @@ int main(void)
|
|||
{
|
||||
for(char i=0; i<2; i++)
|
||||
{
|
||||
waitBottom();
|
||||
vic_waitBottom();
|
||||
vic.ctrl2 = 4;
|
||||
waitTop();
|
||||
vic_waitTop();
|
||||
|
||||
waitBottom();
|
||||
vic_waitBottom();
|
||||
vic.ctrl2 = 2;
|
||||
waitTop();
|
||||
vic_waitTop();
|
||||
|
||||
waitBottom();
|
||||
vic_waitBottom();
|
||||
vic.ctrl2 = 0;
|
||||
waitTop();
|
||||
vic_waitTop();
|
||||
|
||||
waitBottom();
|
||||
vic_waitBottom();
|
||||
vic.ctrl2 = 6;
|
||||
|
||||
scrollLeft();
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
#include <c64/sprites.h>
|
||||
#include <c64/joystick.h>
|
||||
#include <string.h>
|
||||
|
||||
char spdata[] = {
|
||||
#embed "../resources/friendlybear.bin"
|
||||
};
|
||||
|
||||
int spx, spy;
|
||||
|
||||
#define SpriteData ((char *)0x0380)
|
||||
|
||||
int main(void)
|
||||
{
|
||||
memcpy(SpriteData, spdata, 128);
|
||||
|
||||
spr_init((char*)0x0400);
|
||||
|
||||
spx = 160;
|
||||
spy = 100;
|
||||
|
||||
spr_set(0, true, spx, spy, 0x03c0 / 64, VCOL_BLACK, false, false, false);
|
||||
spr_set(1, true, spx, spy, 0x0380 / 64, VCOL_ORANGE, true, false, false);
|
||||
|
||||
vic.spr_mcolor0 = VCOL_BROWN;
|
||||
vic.spr_mcolor1 = VCOL_WHITE;
|
||||
|
||||
for(;;)
|
||||
{
|
||||
joy_poll(1);
|
||||
|
||||
spx += joyx[1];
|
||||
spy += joyy[1];
|
||||
|
||||
spr_move(0, spx, spy);
|
||||
spr_move(1, spx, spy);
|
||||
|
||||
vic_waitFrame();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
..\..\bin\oscar64 joycontrol.c
|
||||
..\..\bin\oscar64 multiplexer.c -n
|
|
@ -0,0 +1,90 @@
|
|||
#include <c64/vic.h>
|
||||
#include <c64/rasterirq.h>
|
||||
#include <c64/sprites.h>
|
||||
#include <math.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, 0x2800, , , {spriteset} )
|
||||
|
||||
// everything beyond will be code, data, bss and heap to the end
|
||||
|
||||
#pragma region( main, 0x2800, 0xa000, , , {code, data, bss, heap, stack} )
|
||||
|
||||
|
||||
// spriteset at fixed location
|
||||
|
||||
#pragma data(spriteset)
|
||||
|
||||
char spriteset[2048] = {
|
||||
#embed "../samples/resources/digitsprites.bin"
|
||||
};
|
||||
|
||||
#pragma data(data)
|
||||
|
||||
// sinus table for circular movement
|
||||
|
||||
int sintab[128];
|
||||
|
||||
int main(void)
|
||||
{
|
||||
// calculate sine table
|
||||
for(int i=0; i<128; i++)
|
||||
sintab[i] = (int)(80 * sin(i * PI / 64));
|
||||
|
||||
// enable raster interrupt via kernal path
|
||||
rirq_init(true);
|
||||
|
||||
// initialize sprite multiplexer
|
||||
vspr_init(Screen);
|
||||
|
||||
// initalize sprites
|
||||
for(int i=0; i<16; i++)
|
||||
{
|
||||
vspr_set(i, 30 + 16 * i, 220 - 8 * i, (unsigned)&(spriteset[0]) / 64 + i, (i & 7) + 8);
|
||||
}
|
||||
|
||||
// initial sort and update
|
||||
vspr_sort();
|
||||
vspr_update();
|
||||
rirq_sort();
|
||||
|
||||
// start raster IRQ processing
|
||||
rirq_start();
|
||||
|
||||
// animation loop
|
||||
unsigned j = 0;
|
||||
for(;;)
|
||||
{
|
||||
// move sprites around
|
||||
char k = j >> 4;
|
||||
for(char i=0; i<16; i++)
|
||||
{
|
||||
vspr_move(i, 200 + sintab[(j + 8 * i) & 127] + sintab[k & 127], 140 + sintab[(j + 8 * i + 32) & 127] + sintab[(k + 32) & 127]);
|
||||
}
|
||||
j++;
|
||||
|
||||
// sort virtual sprites by y position
|
||||
vspr_sort();
|
||||
|
||||
// wait for raster IRQ to reach and of frame
|
||||
rirq_wait();
|
||||
|
||||
// update sprites back to normal and set up raster IRQ for second set
|
||||
vspr_update();
|
||||
|
||||
// sort raster IRQs
|
||||
rirq_sort();
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
Loading…
Reference in New Issue