vdp rendering, cleanup and optimisation

This commit is contained in:
kub 2020-10-04 23:10:10 +02:00
parent 13e220715e
commit 71a2e205ea
2 changed files with 168 additions and 112 deletions

View file

@ -25,8 +25,8 @@
* 10 shadow pal index
* 11 hilight|shadow=normal pal index
*
* sprite ops can only be correctly done after the plane rendering s/h state is
* known since the op result changes if there's at least one high prio plane.
* sprite s/h can only be correctly done after the plane rendering s/h state is
* known since the s/h result changes if there's at least one high prio plane.
* sprite op rendering is deferred until this is known, and hilight is used as
* mark since it can't occur before sprite ops:
* x1 op marker pal index
@ -36,10 +36,10 @@
* - sprite op pixel rendering is marked with hilight (deferred)
* high prio s/h rendering:
* - plane and non-op sprite pixels are normal
* - all op sprite pixels (marked low, or high prio) are rendered
* - all op sprite pixels (either marked or high prio) are rendered
*
* not handled properly:
* - high prio s/h ops overlapping low prio sprite shows low sprite, not A,B,G
* - high prio s/h sprite overlapping low prio sprite shows sprite, not A,B,G
*/
#include "pico_int.h"
@ -66,7 +66,7 @@ unsigned int VdpSATCache[128]; // VDP sprite cache (1st 32 sprite attr bits)
#define LF_PLANE (1 << 0) // must be = 1
#define LF_SH (1 << 1) // must be = 2
#define LF_FORCE (1 << 2)
//#define LF_FORCE (1 << 2)
#define LF_PLANE_A 0
#define LF_PLANE_B 1
@ -178,18 +178,20 @@ TileFlipMaker(TileFlip, pix_just_write)
// draw sprite pixels, process operator colors
#define pix_sh(x) \
if (!t); \
else if (t>=0xe) pd[x]|=(t-1)<<6; /* 80 shadow, 40 hilight */ \
else pd[x]=pal|t
if (t) { \
if (t>=0xe) pd[x]|=(t-1)<<6; /* 80 shadow, 40 hilight */ \
else pd[x]=pal|t; \
}
TileNormMaker(TileNormSH, pix_sh)
TileFlipMaker(TileFlipSH, pix_sh)
// draw sprite pixels, mark but don't process operator colors
#define pix_sh_markop(x) \
if (!t); \
else if (t>=0xe) pd[x]|=0x40; \
else pd[x]=pal|t
if (t) { \
if (t>=0xe) pd[x]|=0x40; \
else pd[x]=pal|t; \
}
TileNormMaker(TileNormSH_markop, pix_sh_markop)
TileFlipMaker(TileFlipSH_markop, pix_sh_markop)
@ -199,7 +201,7 @@ TileFlipMaker(TileFlipSH_markop, pix_sh_markop)
// draw low prio sprite operator pixels if visible (i.e. marked)
#define pix_sh_onlyop(x) \
if (t>=0xe && (pd[x]&0x40)) \
pd[x]=(pd[x]&0xbf)|((t-1)<<6)
pd[x]=(pd[x]&~0x40)|((t-1)<<6)
#ifndef _ASM_DRAW_C
@ -218,11 +220,11 @@ TileNormMakerAS(TileNormAS, pix_as)
TileFlipMakerAS(TileFlipAS, pix_as)
// draw high prio sprite pixels, process operator colors (AS)
// sprite+planes: h+s->n, h+[nh]->h, s+[nhs]->s, hence mask h before op
// NB sprite+planes: h+s->n, h+[nh]->h, s+[nhs]->s, hence mask h before op
#define pix_sh_as(x) \
if (t && (m & (1<<(x+8)))) { \
m &= ~(1<<(x+8)); \
if (t>=0xe) pd[x]=(pd[x]&0xbf)|((t-1)<<6); \
if (t>=0xe) pd[x]=(pd[x]&~0x40)|((t-1)<<6); \
else pd[x] = pal | t; \
}
@ -247,6 +249,7 @@ TileNormMakerAS(TileNormAS_onlymark, pix_sh_as_onlymark)
TileFlipMakerAS(TileFlipAS_onlymark, pix_sh_as_onlymark)
#ifdef FORCE
// NB s/h already resolved by non-forced drawing
// forced both layer draw (through debug reg)
#define pix_and(x) \
pd[x] = (pd[x] & 0xc0) | (pd[x] & (pal | t))
@ -255,11 +258,10 @@ TileNormMaker(TileNorm_and, pix_and)
TileFlipMaker(TileFlip_and, pix_and)
// forced sprite draw (through debug reg)
#define pix_sh_as_and(x) /* XXX is there S/H with forced draw? */ \
#define pix_sh_as_and(x) \
if (m & (1<<(x+8))) { \
m &= ~(1<<(x+8)); \
if (t>=0xe) pd[x]=(pd[x]&0xbf)|((t-1)<<6); \
else pd[x] = (pd[x] & 0xc0) | (pd[x] & (pal | t)); \
if (t<0xe) pd[x] = (pd[x] & 0xc0) | (pd[x] & (pal | t)); \
}
TileNormMakerAS(TileNormSH_AS_and, pix_sh_as_and)
@ -272,10 +274,10 @@ TileFlipMakerAS(TileFlipSH_AS_and, pix_sh_as_and)
static void DrawStrip(struct TileStrip *ts, int lflags, int cellskip)
{
unsigned char *pd = Pico.est.HighCol;
int tilex,dx,ty,code=0,addr=0,cells;
int oldcode=-1,blank=-1; // The tile we know is blank
int pal=0;
unsigned int pack = 0;
int *hc = ts->hc;
int tilex, dx, ty, cells;
int oldcode = -1, blank = -1; // The tile we know is blank
unsigned int pal = 0, pack = 0;
// Draw tiles across screen:
tilex=((-ts->hscroll)>>3)+cellskip;
@ -285,9 +287,14 @@ static void DrawStrip(struct TileStrip *ts, int lflags, int cellskip)
if(dx != 8) cells++; // have hscroll, need to draw 1 cell more
dx+=cellskip<<3;
// int force = (lflags&LF_FORCE) << 13;
for (; cells > 0; dx+=8, tilex++, cells--)
{
code = PicoMem.vram[ts->nametab + (tilex & ts->xmask)];
u32 code = PicoMem.vram[ts->nametab + (tilex & ts->xmask)];
// code &= ~force; // forced always draw everything
if (code == blank && !((code & 0x8000) && (lflags & LF_SH)))
continue;
if (code!=oldcode) {
oldcode = code;
@ -295,11 +302,10 @@ static void DrawStrip(struct TileStrip *ts, int lflags, int cellskip)
pack = 0;
if (code != blank) {
// Get tile address/2:
addr=(code&0x7ff)<<4;
addr+=ty;
if (code&0x1000) addr^=0xe; // Y-flip
u32 addr = ((code&0x7ff)<<4) + ty;
if (code & 0x1000) addr ^= 0xe; // Y-flip
pal=((code>>9)&0x30)|((lflags&LF_SH)<<6); // shadow
pal = ((code>>9)&0x30) | ((lflags&LF_SH)<<6); // shadow
pack = *(unsigned int *)(PicoMem.vram + addr);
if (!pack)
@ -307,23 +313,19 @@ static void DrawStrip(struct TileStrip *ts, int lflags, int cellskip)
}
}
if ((code >> 15) | (lflags & LF_FORCE)) { // high priority tile
if ((lflags&LF_SH) | (code!=blank)) {
int cval = code | (dx<<16) | (ty<<25);
if (code&0x1000) cval^=0xe<<25;
*ts->hc++ = cval, *ts->hc++ = pack; // cache it
}
continue;
if (code & 0x8000) { // (un-forced) high priority tile
int cval = code | (dx<<16) | (ty<<25);
if (code & 0x1000) cval ^= 0xe<<25;
*hc++ = cval, *hc++ = pack; // cache it
} else if (code != blank) {
if (code & 0x0800) TileFlip(pd + dx, pack, pal);
else TileNorm(pd + dx, pack, pal);
}
if (code == blank)
continue;
if (code & 0x0800) TileFlip(pd + dx, pack, pal);
else TileNorm(pd + dx, pack, pal);
}
// terminate the cache list
*ts->hc = 0;
*hc = 0;
// if oldcode wasn't changed, it means all layer is hi priority
if (oldcode == -1) Pico.est.rendstatus |= PDRAW_PLANE_HI_PRIO;
}
@ -332,9 +334,10 @@ static void DrawStrip(struct TileStrip *ts, int lflags, int cellskip)
static void DrawStripVSRam(struct TileStrip *ts, int plane_sh, int cellskip)
{
unsigned char *pd = Pico.est.HighCol;
int tilex,dx,code=0,addr=0,cell=0;
int oldcode=-1,blank=-1; // The tile we know is blank
int pal=0,scan=Pico.est.DrawScanline;
int *hc = ts->hc;
int tilex, dx, ty = 0, addr = 0, cell = 0, nametabadd = 0;
int oldcode = -1, blank = -1; // The tile we know is blank
unsigned int pal = 0, scan = Pico.est.DrawScanline;
// Draw tiles across screen:
tilex=(-ts->hscroll)>>3;
@ -349,15 +352,15 @@ static void DrawStripVSRam(struct TileStrip *ts, int plane_sh, int cellskip)
tilex+=cellskip;
dx+=cellskip<<3;
// int force = (plane_sh&LF_FORCE) << 13;
for (; cell < ts->cells; dx+=8,tilex++,cell++)
{
int nametabadd, ty;
unsigned int pack;
u32 code, pack;
//if((cell&1)==0)
if ((cell&1)==0 || cell<0)
{
int line,vscroll;
vscroll=PicoMem.vsram[(plane_sh&1)+(cell&0x3e)];
vscroll = PicoMem.vsram[(plane_sh&1) + (cell&0x3e)];
// Find the line in the name table
line=(vscroll+scan)&ts->line&0xffff; // ts->line is really ymask ..
@ -365,36 +368,39 @@ static void DrawStripVSRam(struct TileStrip *ts, int plane_sh, int cellskip)
ty=(line&7)<<1; // Y-Offset into tile
}
code=PicoMem.vram[ts->nametab+nametabadd+(tilex&ts->xmask)];
code= PicoMem.vram[ts->nametab + nametabadd + (tilex & ts->xmask)];
// code &= ~force; // forced always draw everything
code |= ty<<16; // add ty since that can change pixel row for every 2nd tile
if (code == blank && !((code & 0x8000) && (plane_sh & LF_SH)))
continue;
if (code!=oldcode) {
oldcode = code;
// Get tile address/2:
addr = (code&0x7ff)<<4;
pal = ((code>>9)&0x30)|((plane_sh&LF_SH)<<6); // shadow
pal = ((code>>9)&0x30) | ((plane_sh&LF_SH)<<6); // shadow
}
code |= ty<<16;
if (code & 0x1000) ty ^= 0xe; // Y-flip
pack = *(unsigned int *)(PicoMem.vram + addr+ty);
pack = (code & 0x1000 ? ty^0xe : ty); // Y-flip
pack = *(unsigned int *)(PicoMem.vram + addr+pack);
if (!pack)
blank = code;
if ((code >> 15) | (plane_sh & LF_FORCE)) { // high priority tile
if ((plane_sh&LF_SH) | (code!=blank)) {
int cval = code | (dx<<16) | (ty<<25);
*ts->hc++ = cval, *ts->hc++ = pack; // cache it
}
continue;
if (code & 0x8000) { // (un-forced) high priority tile
int cval = (u16)code | (dx<<16) | (ty<<25);
if (code & 0x1000) cval ^= 0xe<<25;
*hc++ = cval, *hc++ = pack; // cache it
} else if (code != blank) {
if (code & 0x0800) TileFlip(pd + dx, pack, pal);
else TileNorm(pd + dx, pack, pal);
}
if (code == blank) continue;
if (code & 0x0800) TileFlip(pd + dx, pack, pal);
else TileNorm(pd + dx, pack, pal);
}
// terminate the cache list
*ts->hc = 0;
*hc = 0;
if (oldcode == -1) Pico.est.rendstatus |= PDRAW_PLANE_HI_PRIO;
}
#endif
@ -405,10 +411,10 @@ static
void DrawStripInterlace(struct TileStrip *ts, int plane_sh)
{
unsigned char *pd = Pico.est.HighCol;
int tilex=0,dx=0,ty=0,code=0,addr=0,cells;
int oldcode=-1,blank=-1; // The tile we know is blank
int pal=0;
unsigned int pack = 0;
int *hc = ts->hc;
int tilex = 0, dx = 0, ty = 0, cells;
int oldcode = -1, blank = -1; // The tile we know is blank
unsigned int pal = 0, pack = 0;
// Draw tiles across screen:
tilex=(-ts->hscroll)>>3;
@ -417,9 +423,14 @@ void DrawStripInterlace(struct TileStrip *ts, int plane_sh)
cells = ts->cells;
if(dx != 8) cells++; // have hscroll, need to draw 1 cell more
// int force = (plane_sh&LF_FORCE) << 13;
for (; cells; dx+=8,tilex++,cells--)
{
code = PicoMem.vram[ts->nametab + (tilex & ts->xmask)];
u32 code = PicoMem.vram[ts->nametab + (tilex & ts->xmask)];
// code &= ~force; // forced always draw everything
if (code == blank && !(code & 0x8000))
continue;
if (code!=oldcode) {
oldcode = code;
@ -427,10 +438,10 @@ void DrawStripInterlace(struct TileStrip *ts, int plane_sh)
pack = 0;
if (code != blank) {
// Get tile address/2:
addr = (code&0x3ff)<<5;
if (code&0x1000) addr+=30-ty; else addr+=ty; // Y-flip
u32 addr = ((code&0x3ff)<<5) + ty;
if (code & 0x1000) addr ^= 0x1e; // Y-flip
pal = ((code>>9)&0x30)|((plane_sh&LF_SH)<<6); // shadow
pal = ((code>>9)&0x30) | ((plane_sh&LF_SH)<<6); // shadow
pack = *(unsigned int *)(PicoMem.vram + addr);
if (!pack)
@ -438,24 +449,21 @@ void DrawStripInterlace(struct TileStrip *ts, int plane_sh)
}
}
if ((code >> 15) | (plane_sh & LF_FORCE)) { // high priority tile
if (code & 0x8000) { // high priority tile
if ((plane_sh&LF_SH) | (code!=blank)) {
int cval = (code&0xfc00) | (dx<<16) | (ty<<25);
cval|=(code&0x3ff)<<1;
if (code&0x1000) cval^=0x1e<<25;
*ts->hc++ = cval, *ts->hc++ = pack; // cache it
int cval = (code&0xfc00) | ((code&0x3ff)<<1) | (dx<<16) | (ty<<25);
if (code & 0x1000) cval ^= 0x1e<<25;
*hc++ = cval, *hc++ = pack; // cache it
}
continue;
} else if (code != blank) {
if (code & 0x0800) TileFlip(pd + dx, pack, pal);
else TileNorm(pd + dx, pack, pal);
}
if (code == blank)
continue;
if (code & 0x0800) TileFlip(pd + dx, pack, pal);
else TileNorm(pd + dx, pack, pal);
}
// terminate the cache list
*ts->hc = 0;
*hc = 0;
}
// --------------------------------------------
@ -1049,12 +1057,14 @@ static void DrawSpritesHiAS(unsigned char *sprited, int sh)
}
#ifdef FORCE
static void DrawStripForced(struct TileStrip *ts, int lflags, int cellskip)
// NB lots of duplicate code, all for the sake of a small performance gain.
static void DrawStripForced(struct TileStrip *ts, int cellskip)
{
unsigned char *pd = Pico.est.HighCol;
int tilex,dx,ty,code=0,addr=0,cells;
int oldcode=-1;
int pal=0;
int tilex, dx, ty, code=0, addr=0, cells;
int oldcode = -1;
int pal = 0;
// Draw tiles across screen:
tilex=((-ts->hscroll)>>3)+cellskip;
@ -1073,11 +1083,10 @@ static void DrawStripForced(struct TileStrip *ts, int lflags, int cellskip)
if (code!=oldcode) {
oldcode = code;
// Get tile address/2:
addr=(code&0x7ff)<<4;
addr+=ty;
if (code&0x1000) addr^=0xe; // Y-flip
addr = ((code&0x7ff)<<4) + ty;
if (code & 0x1000) addr^=0xe; // Y-flip
pal=((code>>9)&0x30)|((lflags & LF_SH) << 6);
pal = (code>>9)&0x30;
}
pack = *(unsigned int *)(PicoMem.vram + addr);
@ -1087,11 +1096,10 @@ static void DrawStripForced(struct TileStrip *ts, int lflags, int cellskip)
}
}
// this is messy
static void DrawStripVSRamForced(struct TileStrip *ts, int plane_sh, int cellskip)
{
unsigned char *pd = Pico.est.HighCol;
int tilex,dx,code=0,addr=0,cell=0;
int tilex, dx, ty=0, code=0, addr=0, cell=0, nametabadd=0;
int oldcode=-1;
int pal=0,scan=Pico.est.DrawScanline;
@ -1110,13 +1118,12 @@ static void DrawStripVSRamForced(struct TileStrip *ts, int plane_sh, int cellski
for (; cell < ts->cells; dx+=8,tilex++,cell++)
{
int nametabadd, ty;
unsigned int pack;
//if((cell&1)==0)
if ((cell&1)==0 || cell<0)
{
int line,vscroll;
vscroll=PicoMem.vsram[(plane_sh&1)+(cell&0x3e)];
vscroll = PicoMem.vsram[(plane_sh&1)+(cell&0x3e)];
// Find the line in the name table
line=(vscroll+scan)&ts->line&0xffff; // ts->line is really ymask ..
@ -1131,17 +1138,53 @@ static void DrawStripVSRamForced(struct TileStrip *ts, int plane_sh, int cellski
// Get tile address/2:
addr=(code&0x7ff)<<4;
pal=((code>>9)&0x30)|((plane_sh&LF_SH)<<6); // shadow
pal = (code>>9)&0x30; // shadow
}
if (code & 0x1000) ty ^= 0xe; // Y-flip
pack = *(unsigned int *)(PicoMem.vram + addr+ty);
pack = code & 0x1000 ? ty^0xe : ty; // Y-flip
pack = *(unsigned int *)(PicoMem.vram + addr+pack);
if (code & 0x0800) TileFlip_and(pd + dx, pack, pal);
else TileNorm_and(pd + dx, pack, pal);
}
}
void DrawStripInterlaceForced(struct TileStrip *ts)
{
unsigned char *pd = Pico.est.HighCol;
int tilex = 0, dx = 0, ty = 0, cells;
int oldcode = -1;
unsigned int pal = 0, pack = 0;
// Draw tiles across screen:
tilex=(-ts->hscroll)>>3;
ty=(ts->line&15)<<1; // Y-Offset into tile
dx=((ts->hscroll-1)&7)+1;
cells = ts->cells;
if(dx != 8) cells++; // have hscroll, need to draw 1 cell more
for (; cells; dx+=8,tilex++,cells--)
{
u32 code = PicoMem.vram[ts->nametab + (tilex & ts->xmask)];
if (code!=oldcode) {
oldcode = code;
// Get tile address/2:
u32 addr = ((code&0x3ff)<<5) + ty;
if (code & 0x1000) addr ^= 0x1e; // Y-flip
pal = (code>>9)&0x30; // shadow
pack = *(unsigned int *)(PicoMem.vram + addr);
}
if (code & 0x0800) TileFlip_and(pd + dx, pack, pal);
else TileNorm_and(pd + dx, pack, pal);
}
}
// XXX only duplicated to avoid ARM asm hassles
static void DrawLayerForced(int plane_sh, int cellskip, int maxcells,
struct PicoEState *est)
{
@ -1190,7 +1233,7 @@ static void DrawLayerForced(int plane_sh, int cellskip, int maxcells,
ts.line=(vscroll+(est->DrawScanline<<1))&((ymask<<1)|1);
ts.nametab+=(ts.line>>4)<<shift[width];
DrawStripInterlace(&ts, plane_sh);
DrawStripInterlaceForced(&ts);
} else if( pvid->reg[11]&4) {
// shit, we have 2-cell column based vscroll
// luckily this doesn't happen too often
@ -1207,11 +1250,10 @@ static void DrawLayerForced(int plane_sh, int cellskip, int maxcells,
ts.line=(vscroll+est->DrawScanline)&ymask;
ts.nametab+=(ts.line>>3)<<shift[width];
DrawStripForced(&ts, plane_sh, cellskip);
DrawStripForced(&ts, cellskip);
}
}
// rather messy (XXX revisit layer compositing)
static void DrawSpritesForced(unsigned char *sprited)
{
unsigned (*fTileFunc)(unsigned m, unsigned char *pd, unsigned int pack, int pal);
@ -1281,10 +1323,10 @@ static void DrawSpritesForced(unsigned char *sprited)
// anything not covered by a sprite is off (XXX or bg?)
for (cnt = 1; cnt < sizeof(mb)-1; cnt++)
if (mb[cnt] == 0xff)
for (m = 0; m < 8; m++)
pd[8*cnt+m] = 0;
else if (mb[cnt])
if (mb[cnt] == 0xff) {
*(u32 *)(pd+8*cnt+0) = 0;
*(u32 *)(pd+8*cnt+4) = 0;
} else if (mb[cnt])
for (m = 0; m < 8; m++)
if (mb[cnt] & (1<<m))
pd[8*cnt+m] = 0;

View file

@ -391,7 +391,7 @@ DrawLayer:
movs r3, r9, lsl #1 @ (force[31]|sh[30]) << 1
mov r3, #0
orrmi r10,r10, #1<<23 @ r10=cells[31:24]|sh[23]|hi_not_empty[22]
orrcs r10,r10, #1<<20 @ |had_output[21]|force[20]|ty[15:0]
@ orrcc r10,r10, #1<<20 @ |had_output[21]|!force[20]|ty[15:0]
movmi r3, #0x80 @ default to shadowed pal on sh mode
cmp r7, #8
@ -410,7 +410,8 @@ DrawLayer:
mvn r9, #0 @ r9=prevcode=-1
add r1, r11, r7 @ r1=pdest
@ r10=cells[31:24]|sh[23]|hi_not_empty[22]|had_output[21]|!force[20]|ty[15:0]
@ r1=pd+dx r2=pack r3=pal r5=xmask r6=hc r8=tilex r9=prevcode r11=HighCol r12=nametab lr=vram
@ r4 & r7 are scratch in this loop
.dsloop_subr1:
sub r1, r1, #8
@ -441,7 +442,7 @@ DrawLayer:
.DrawStrip_samecode:
tst r9, #0x8000
tsteq r10, #1<<20 @ force?
@ tstne r10, #1<<20 @ !force[20]
bne .DrawStrip_hiprio
orr r10, r10, #1<<21 @ seen non hi-prio tile
@ -515,7 +516,7 @@ DrawLayer:
rsb r8, r3, #0
mov r8, r8, lsr #3 @ r8=tilex=(-ts->hscroll)>>3
bic r8, r8, #0x3fc00000
orr r8, r8, r5, lsl #25 @ r8=(xmask[31:25]|had_output[24]|tilex[21:0])
orr r8, r8, r5, lsl #25 @ r8=(xmask[31:25]|had_output[24]|!force[23]|tilex[21:0])
ldr r11, [sp, #9*4] @ est
orr r5, r1, r10, lsl #24
@ -547,6 +548,8 @@ DrawLayer:
mov r3, #0
orrne r10,r10, #1<<23 @ r10=(cell[31:24]|sh[23]|hi_not_empty[22]|cells_max[21:16]|plane[15]|ty[14:0])
movne r3, #0x80 @ default to shadowed pal on sh mode
@ tst r9, #1<<31
@ orreq r8, r8, #1<<23
and r9, r9, #0xff00
add r8, r8, r9, lsr #8 @ tilex+=cellskip
@ -561,6 +564,11 @@ DrawLayer:
mvn r9, #0 @ r9=prevcode=-1
add r1, r11, r7 @ r1=pdest
@ r10=cells[31:24]|sh[23]|hi_not_empty[22]|cells_max[21:16]|plane[15]|ty[14:0]
@ r8=xmask[31:25]|had_output[24]|!force[23]|tilex[21:0]
@ r5=shift_width[31:24]|scanline[23:16]|ymask[15:0]
@ r3=nametabadd[31:16]|must_be_0[15:8]|pal[7:0]
@ r1=pd+dx r2=pack r6=hc r9=prevcode r11=HighCol r12=nametab lr=vram
@ r4 & r7 are scratch in this loop
.dsloop_vs_subr1:
sub r1, r1, #8
@ -570,6 +578,11 @@ DrawLayer:
cmp r4, r10, asr #8
ble .dsloop_vs_exit
@ need to calc new ty?
lsls r7, r10, #7 @ (cell&1) && ...
mvnmis r7, r10 @ ... cell>=0
bmi 0f
@ calc offset and read tileline code to r7, also calc ty
add_c24 r7, lr, (OFS_PMEM_vsram-OFS_PMEM_vram)
and r4, r10, #0x3e000000
@ -588,10 +601,12 @@ DrawLayer:
mov r4, r4, lsr #19
mov r7, r5, lsr #24
mov r4, r4, lsl r7 @ nametabadd
and r3, r3, #0xff
orr r3, r3, r4, lsl #16 @ r3=(nametabadd[31:16],pal[15:0])
0:
and r7, r8, r8, lsr #25
add r7, lr, r7, lsl #1 @ PicoMem.vram+((tilex&ts->xmask) as halfwords)
add r7, r7, r4, lsl #1
add r7, r7, r3, lsr #15
ldrh r7, [r7, r12] @ r7=code (int, but from unsigned, no sign extend)
add r1, r1, #8
@ -613,7 +628,7 @@ DrawLayer:
.DrawStrip_vs_samecode:
tst r9, #0x8000
tsteq r10, #(1<<20) @ force[20]
@ tstne r8, #1<<23 @ !force[23]
bne .DrawStrip_vs_hiprio
orr r8, r8, #(1<<24)@ seen non hi-prio tile
@ -905,7 +920,6 @@ DrawTilesFromCache:
stmia r1!,{r2,r4,r5,r7}
bne .dtfc_loop_shprep
mvn r5, #0 @ r5=prevcode=-1
b .dtfc_loop
.pool