From ea38612fad50103e224a3d00492d40b7dcff9e94 Mon Sep 17 00:00:00 2001 From: notaz Date: Sun, 6 Aug 2017 02:03:35 +0300 Subject: [PATCH] eliminate texrels (wip) --- pico/32x/draw.c | 4 +- pico/cd/gfx_dma.c | 2 +- pico/debug.c | 2 +- pico/draw.c | 183 ++++++++++++++++++++++++-------------------- pico/draw_arm.S | 182 ++++++++++++++++++++++--------------------- pico/mode4.c | 8 +- pico/pico.c | 3 + pico/pico.h | 6 +- pico/pico_cmn.c | 2 +- pico/pico_int.h | 15 +++- pico/pico_int_o32.h | 5 ++ pico/videoport.c | 12 +-- platform/gp2x/emu.c | 2 +- platform/psp/emu.c | 4 +- tools/Makefile | 5 +- tools/mkoffsets.c | 31 ++++++++ 16 files changed, 268 insertions(+), 198 deletions(-) create mode 100644 pico/pico_int_o32.h create mode 100644 tools/mkoffsets.c diff --git a/pico/32x/draw.c b/pico/32x/draw.c index 66f67a7..9500e08 100644 --- a/pico/32x/draw.c +++ b/pico/32x/draw.c @@ -83,7 +83,7 @@ static void convert_pal555(int invert_prio) } // this is almost never used (Wiz and menu bg gen only) -void FinalizeLine32xRGB555(int sh, int line) +void FinalizeLine32xRGB555(int sh, int line, struct PicoEState *est) { unsigned short *pd = DrawLineDest; unsigned short *pal = Pico32xMem->pal_native; @@ -91,7 +91,7 @@ void FinalizeLine32xRGB555(int sh, int line) unsigned short *dram, *p32x; unsigned char mdbg; - FinalizeLine555(sh, line); + FinalizeLine555(sh, line, est); if ((Pico32x.vdp_regs[0] & P32XV_Mx) == 0 || // 32x blanking // XXX: how is 32col mode hadled by real hardware? diff --git a/pico/cd/gfx_dma.c b/pico/cd/gfx_dma.c index 44fa7ab..a24a1c3 100644 --- a/pico/cd/gfx_dma.c +++ b/pico/cd/gfx_dma.c @@ -37,7 +37,7 @@ PICO_INTERNAL void DmaSlowCell(unsigned int source, unsigned int a, int len, uns // AutoIncrement a=(u16)(a+inc); } - rendstatus |= PDRAW_SPRITES_MOVED; + Pico.est.rendstatus |= PDRAW_SPRITES_MOVED; break; case 3: // cram diff --git a/pico/debug.c b/pico/debug.c index 959331f..91bff56 100644 --- a/pico/debug.c +++ b/pico/debug.c @@ -203,7 +203,7 @@ void PDebugShowPalette(unsigned short *screen, int stride) if (PicoAHW & PAHW_SMS) PicoDoHighPal555M4(); else - PicoDoHighPal555(1); + PicoDoHighPal555(1, 0, &Pico.est); Pico.m.dirtyPal = 1; screen += 16*stride+8; diff --git a/pico/draw.c b/pico/draw.c index ca9a140..ff84be5 100644 --- a/pico/draw.c +++ b/pico/draw.c @@ -54,9 +54,8 @@ int HighPreSpr[80*2+1]; // slightly preprocessed sprites #define SPRL_LO_ABOVE_HI 0x10 // low priority sprites may be on top of hi unsigned char HighLnSpr[240][3 + MAX_LINE_SPRITES]; // sprite_count, ^flags, tile_count, [spritep]... -int rendstatus, rendstatus_old; +int rendstatus_old; int rendlines; -int DrawScanline; int PicoDrawMask = -1; static int skip_next_line=0; @@ -75,12 +74,15 @@ struct TileStrip // stuff available in asm: #ifdef _ASM_DRAW_C -void DrawWindow(int tstart, int tend, int prio, int sh); -void DrawAllSprites(unsigned char *sprited, int prio, int sh); -void DrawTilesFromCache(int *hc, int sh, int rlim); -void DrawSpritesSHi(unsigned char *sprited); -void DrawLayer(int plane_sh, int *hcache, int cellskip, int maxcells); -void FinalizeLineBGR444(int sh, int line); +void DrawWindow(int tstart, int tend, int prio, int sh, + struct PicoEState *est); +void DrawAllSprites(unsigned char *sprited, int prio, int sh, + struct PicoEState *est); +void DrawTilesFromCache(int *hc, int sh, int rlim, + struct PicoEState *est); +void DrawSpritesSHi(unsigned char *sprited, struct PicoEState *est); +void DrawLayer(int plane_sh, int *hcache, int cellskip, int maxcells, + struct PicoEState *est); void *blockcpy(void *dst, const void *src, size_t n); void blockcpy_or(void *dst, void *src, size_t n, int pat); #else @@ -258,7 +260,7 @@ static void DrawStrip(struct TileStrip *ts, int plane_sh, int cellskip) // terminate the cache list *ts->hc = 0; // if oldcode wasn't changed, it means all layer is hi priority - if (oldcode == -1) rendstatus |= PDRAW_PLANE_HI_PRIO; + if (oldcode == -1) Pico.est.rendstatus |= PDRAW_PLANE_HI_PRIO; } // this is messy @@ -266,7 +268,7 @@ void DrawStripVSRam(struct TileStrip *ts, int plane_sh, int cellskip) { int tilex,dx,code=0,addr=0,cell=0; int oldcode=-1,blank=-1; // The tile we know is blank - int pal=0,scan=DrawScanline; + int pal=0,scan=Pico.est.DrawScanline; // Draw tiles across screen: tilex=(-ts->hscroll)>>3; @@ -317,7 +319,7 @@ void DrawStripVSRam(struct TileStrip *ts, int plane_sh, int cellskip) // terminate the cache list *ts->hc = 0; - if (oldcode == -1) rendstatus |= PDRAW_PLANE_HI_PRIO; + if (oldcode == -1) Pico.est.rendstatus |= PDRAW_PLANE_HI_PRIO; } #endif @@ -374,7 +376,8 @@ void DrawStripInterlace(struct TileStrip *ts) // -------------------------------------------- #ifndef _ASM_DRAW_C -static void DrawLayer(int plane_sh, int *hcache, int cellskip, int maxcells) +static void DrawLayer(int plane_sh, int *hcache, int cellskip, int maxcells, + struct PicoEState *est) { struct PicoVideo *pvid=&Pico.video; const char shift[4]={5,6,5,7}; // 32,64 or 128 sized tilemaps (2 is invalid) @@ -401,7 +404,7 @@ static void DrawLayer(int plane_sh, int *hcache, int cellskip, int maxcells) else ts.nametab=(pvid->reg[2]&0x38)<< 9; // A htab=pvid->reg[13]<<9; // Horizontal scroll table address - if ( pvid->reg[11]&2) htab+=DrawScanline<<1; // Offset by line + if ( pvid->reg[11]&2) htab+=est->DrawScanline<<1; // Offset by line if ((pvid->reg[11]&1)==0) htab&=~0xf; // Offset by tile htab+=plane_sh&1; // A or B @@ -413,7 +416,7 @@ static void DrawLayer(int plane_sh, int *hcache, int cellskip, int maxcells) vscroll=Pico.vsram[plane_sh&1]; // Get vertical scroll value // Find the line in the name table - ts.line=(vscroll+(DrawScanline<<1))&((ymask<<1)|1); + ts.line=(vscroll+(est->DrawScanline<<1))&((ymask<<1)|1); ts.nametab+=(ts.line>>4)<DrawScanline)&ymask; ts.nametab+=(ts.line>>3)<reg[12]&1) { nametab=(pvid->reg[3]&0x3c)<<9; // 40-cell mode - nametab+=(DrawScanline>>3)<<6; + nametab+=(est->DrawScanline>>3)<<6; } else { nametab=(pvid->reg[3]&0x3e)<<9; // 32-cell mode - nametab+=(DrawScanline>>3)<<5; + nametab+=(est->DrawScanline>>3)<<5; } tilex=tstart<<1; - if (!(rendstatus & PDRAW_WND_DIFF_PRIO)) { + if (!(est->rendstatus & PDRAW_WND_DIFF_PRIO)) { // check the first tile code code=Pico.vram[nametab+tilex]; // if the whole window uses same priority (what is often the case), we may be able to skip this field @@ -465,7 +469,7 @@ static void DrawWindow(int tstart, int tend, int prio, int sh) // int *hcache } tend<<=1; - ty=(DrawScanline&7)<<1; // Y-Offset into tile + ty=(est->DrawScanline&7)<<1; // Y-Offset into tile // Draw tiles across screen: if (!sh) @@ -478,7 +482,7 @@ static void DrawWindow(int tstart, int tend, int prio, int sh) // int *hcache code=Pico.vram[nametab+tilex]; if (code==blank) continue; if ((code>>15) != prio) { - rendstatus |= PDRAW_WND_DIFF_PRIO; + est->rendstatus |= PDRAW_WND_DIFF_PRIO; continue; } @@ -504,7 +508,7 @@ static void DrawWindow(int tstart, int tend, int prio, int sh) // int *hcache code=Pico.vram[nametab+tilex]; if(code==blank) continue; if((code>>15) != prio) { - rendstatus |= PDRAW_WND_DIFF_PRIO; + est->rendstatus |= PDRAW_WND_DIFF_PRIO; continue; } @@ -538,23 +542,23 @@ static void DrawTilesFromCacheShPrep(void) // we can process whole line and then act as if sh/hi mode was off, // but leave lo pri op sprite markers alone int c = 320/4, *zb = (int *)(HighCol+8); - rendstatus |= PDRAW_SHHI_DONE; + Pico.est.rendstatus |= PDRAW_SHHI_DONE; while (c--) { *zb++ &= 0xbfbfbfbf; } } -static void DrawTilesFromCache(int *hc, int sh, int rlim) +static void DrawTilesFromCache(int *hc, int sh, int rlim, struct PicoEState *est) { int code, addr, dx; int pal; // *ts->hc++ = code | (dx<<16) | (ty<<25); // cache it - if (sh && (rendstatus & (PDRAW_SHHI_DONE|PDRAW_PLANE_HI_PRIO))) + if (sh && (est->rendstatus & (PDRAW_SHHI_DONE|PDRAW_PLANE_HI_PRIO))) { - if (!(rendstatus & PDRAW_SHHI_DONE)) + if (!(est->rendstatus & PDRAW_SHHI_DONE)) DrawTilesFromCacheShPrep(); sh = 0; } @@ -658,7 +662,7 @@ static void DrawSprite(int *sprite, int sh) height=(sy>>24)&7; // Width and height in tiles sy=(sy<<16)>>16; // Y - row=DrawScanline-sy; // Row of the sprite we are on + row=Pico.est.DrawScanline-sy; // Row of the sprite we are on if (code&0x1000) row=(height<<3)-1-row; // Flip Y @@ -706,7 +710,7 @@ static void DrawSpriteInterlace(unsigned int *sprite) width=(height>>2)&3; height&=3; width++; height++; // Width and height in tiles - row=(DrawScanline<<1)-sy; // Row of the sprite we are on + row=(Pico.est.DrawScanline<<1)-sy; // Row of the sprite we are on code=sprite[1]; sx=((code>>16)&0x1ff)-0x78; // X @@ -738,7 +742,7 @@ static void DrawSpriteInterlace(unsigned int *sprite) static void DrawAllSpritesInterlace(int pri, int sh) { struct PicoVideo *pvid=&Pico.video; - int i,u,table,link=0,sline=DrawScanline<<1; + int i,u,table,link=0,sline=Pico.est.DrawScanline<<1; unsigned int *sprites[80]; // Sprite index table=pvid->reg[5]&0x7f; @@ -790,7 +794,7 @@ static void DrawAllSpritesInterlace(int pri, int sh) * Index + 0 : hhhhvvvv ----hhvv yyyyyyyy yyyyyyyy // v, h: vert./horiz. size * Index + 4 : xxxxxxxx xxxxxxxx pccvhnnn nnnnnnnn // x: x coord + 8 */ -static void DrawSpritesSHi(unsigned char *sprited) +static void DrawSpritesSHi(unsigned char *sprited, const struct PicoEState *est) { int (*fTileFunc)(int sx,int addr,int pal); unsigned char *p; @@ -835,7 +839,7 @@ static void DrawSpritesSHi(unsigned char *sprited) height=(sy>>24)&7; // Width and height in tiles sy=(sy<<16)>>16; // Y - row=DrawScanline-sy; // Row of the sprite we are on + row=est->DrawScanline-sy; // Row of the sprite we are on if (code&0x1000) row=(height<<3)-1-row; // Flip Y @@ -867,7 +871,7 @@ static void DrawSpritesHiAS(unsigned char *sprited, int sh) cnt = sprited[0] & 0x7f; if (cnt == 0) return; - rendstatus |= PDRAW_SPR_LO_ON_HI; + Pico.est.rendstatus |= PDRAW_SPR_LO_ON_HI; p = &sprited[3]; @@ -906,7 +910,7 @@ static void DrawSpritesHiAS(unsigned char *sprited, int sh) height=(sy>>24)&7; // Width and height in tiles sy=(sy<<16)>>16; // Y - row=DrawScanline-sy; // Row of the sprite we are on + row=Pico.est.DrawScanline-sy; // Row of the sprite we are on if (code&0x1000) row=(height<<3)-1-row; // Flip Y @@ -942,7 +946,7 @@ static void DrawSpritesHiAS(unsigned char *sprited, int sh) /* nasty 2: sh operator pass */ sprited[0] = sh_cnt; - DrawSpritesSHi(sprited); + DrawSpritesSHi(sprited, &Pico.est); } @@ -954,7 +958,8 @@ static void DrawSpritesHiAS(unsigned char *sprited, int sh) void PrepareSprites(int full) { - struct PicoVideo *pvid=&Pico.video; + const struct PicoVideo *pvid=&Pico.video; + const struct PicoEState *est=&Pico.est; int u,link=0,sh; int table=0; int *pd = HighPreSpr; @@ -991,10 +996,11 @@ void PrepareSprites(int full) sy = (pack << 16) >> 16; height = (pack >> 24) & 0xf; - if (sy < max_lines && sy + (height<<3) > DrawScanline && // sprite onscreen (y)? + if (sy < max_lines && + sy + (height<<3) > est->DrawScanline && // sprite onscreen (y)? (sx > -24 || sx < max_width)) // onscreen x { - int y = (sy >= DrawScanline) ? sy : DrawScanline; + int y = (sy >= est->DrawScanline) ? sy : est->DrawScanline; int entry = ((pd - HighPreSpr) / 2) | ((code2>>8)&0x80); for (; y < sy + (height<<3) && y < max_lines; y++) { @@ -1047,7 +1053,7 @@ found:; sx = (code2>>16)&0x1ff; sx -= 0x78; // Get X coordinate + 8 - if (sy < max_lines && sy + (height<<3) > DrawScanline) // sprite onscreen (y)? + if (sy < max_lines && sy + (height<<3) > est->DrawScanline) // sprite onscreen (y)? { int entry, y, sx_min, onscr_x, maybe_op = 0; @@ -1057,7 +1063,7 @@ found:; maybe_op = SPRL_MAY_HAVE_OP; entry = ((pd - HighPreSpr) / 2) | ((code2>>8)&0x80); - y = (sy >= DrawScanline) ? sy : DrawScanline; + y = (sy >= est->DrawScanline) ? sy : est->DrawScanline; for (; y < sy + (height<<3) && y < max_lines; y++) { unsigned char *p = &HighLnSpr[y][0]; @@ -1110,16 +1116,17 @@ found:; } #ifndef _ASM_DRAW_C -static void DrawAllSprites(unsigned char *sprited, int prio, int sh) +static void DrawAllSprites(unsigned char *sprited, int prio, int sh, + struct PicoEState *est) { - int rs = rendstatus; + int rs = est->rendstatus; unsigned char *p; int cnt; if (rs & (PDRAW_SPRITES_MOVED|PDRAW_DIRTY_SPRITES)) { //elprintf(EL_STATUS, "PrepareSprites(%i)", (rs>>4)&1); PrepareSprites(rs & PDRAW_DIRTY_SPRITES); - rendstatus = rs & ~(PDRAW_SPRITES_MOVED|PDRAW_DIRTY_SPRITES); + est->rendstatus = rs & ~(PDRAW_SPRITES_MOVED|PDRAW_DIRTY_SPRITES); } cnt = sprited[0] & 0x7f; @@ -1159,7 +1166,7 @@ void BackFill(int reg7, int sh) unsigned short HighPal[0x100]; #ifndef _ASM_DRAW_C -void PicoDoHighPal555(int sh) +void PicoDoHighPal555(int sh, int line, struct PicoEState *est) { unsigned int *spal, *dpal; unsigned int t, i; @@ -1205,7 +1212,7 @@ void FinalizeLine555(int sh, int line) int len; if (Pico.m.dirtyPal) - PicoDoHighPal555(sh); + PicoDoHighPal555(sh, line, est); if (Pico.video.reg[12]&1) { len = 320; @@ -1217,7 +1224,7 @@ void FinalizeLine555(int sh, int line) { #ifndef PSP int i, mask=0xff; - if (!sh && (rendstatus & PDRAW_SPR_LO_ON_HI)) + if (!sh && (est->rendstatus & PDRAW_SPR_LO_ON_HI)) mask=0x3f; // accurate sprites, upper bits are priority stuff for (i = 0; i < len; i++) @@ -1225,7 +1232,7 @@ void FinalizeLine555(int sh, int line) #else extern void amips_clut(unsigned short *dst, unsigned char *src, unsigned short *pal, int count); extern void amips_clut_6bit(unsigned short *dst, unsigned char *src, unsigned short *pal, int count); - if (!sh && (rendstatus & PDRAW_SPR_LO_ON_HI)) + if (!sh && (est->rendstatus & PDRAW_SPR_LO_ON_HI)) amips_clut_6bit(pd, ps, pal, len); else amips_clut(pd, ps, pal, len); #endif @@ -1233,10 +1240,10 @@ void FinalizeLine555(int sh, int line) } #endif -static void FinalizeLine8bit(int sh, int line) +static void FinalizeLine8bit(int sh, int line, struct PicoEState *est) { unsigned char *pd = DrawLineDest; - int len, rs = rendstatus; + int len, rs = est->rendstatus; static int dirty_count; if (!sh && Pico.m.dirtyPal == 1) @@ -1246,7 +1253,7 @@ static void FinalizeLine8bit(int sh, int line) dirty_count = 1; else dirty_count++; rs |= PDRAW_SONIC_MODE; - rendstatus = rs; + est->rendstatus = rs; if (dirty_count == 3) { blockcpy(HighPal, Pico.cram, 0x40*2); } else if (dirty_count == 11) { @@ -1273,18 +1280,19 @@ static void FinalizeLine8bit(int sh, int line) } } -static void (*FinalizeLine)(int sh, int line); +static void (*FinalizeLine)(int sh, int line, struct PicoEState *est); // -------------------------------------------- static int DrawDisplay(int sh) { - unsigned char *sprited = &HighLnSpr[DrawScanline][0]; + struct PicoEState *est=&Pico.est; + unsigned char *sprited = &HighLnSpr[est->DrawScanline][0]; struct PicoVideo *pvid=&Pico.video; int win=0,edge=0,hvwind=0; int maxw,maxcells; - rendstatus &= ~(PDRAW_SHHI_DONE|PDRAW_PLANE_HI_PRIO); + est->rendstatus &= ~(PDRAW_SHHI_DONE|PDRAW_PLANE_HI_PRIO); if (pvid->reg[12]&1) { maxw = 328; maxcells = 40; @@ -1296,8 +1304,8 @@ static int DrawDisplay(int sh) win=pvid->reg[0x12]; edge=(win&0x1f)<<3; - if (win&0x80) { if (DrawScanline>=edge) hvwind=1; } - else { if (DrawScanline< edge) hvwind=1; } + if (win&0x80) { if (est->DrawScanline>=edge) hvwind=1; } + else { if (est->DrawScanline< edge) hvwind=1; } if (!hvwind) // we might have a vertical window here { @@ -1315,53 +1323,56 @@ static int DrawDisplay(int sh) /* - layer B low - */ if (PicoDrawMask & PDRAW_LAYERB_ON) - DrawLayer(1|(sh<<1), HighCacheB, 0, maxcells); + DrawLayer(1|(sh<<1), HighCacheB, 0, maxcells, est); /* - layer A low - */ if (!(PicoDrawMask & PDRAW_LAYERA_ON)); else if (hvwind == 1) - DrawWindow(0, maxcells>>1, 0, sh); + DrawWindow(0, maxcells>>1, 0, sh, est); else if (hvwind == 2) { - DrawLayer(0|(sh<<1), HighCacheA, (win&0x80) ? 0 : edge<<1, (win&0x80) ? edge<<1 : maxcells); - DrawWindow( (win&0x80) ? edge : 0, (win&0x80) ? maxcells>>1 : edge, 0, sh); + DrawLayer(0|(sh<<1), HighCacheA, (win&0x80) ? 0 : edge<<1, (win&0x80) ? edge<<1 : maxcells, est); + DrawWindow( (win&0x80) ? edge : 0, (win&0x80) ? maxcells>>1 : edge, 0, sh, est); } else - DrawLayer(0|(sh<<1), HighCacheA, 0, maxcells); + DrawLayer(0|(sh<<1), HighCacheA, 0, maxcells, est); /* - sprites low - */ if (!(PicoDrawMask & PDRAW_SPRITES_LOW_ON)); - else if (rendstatus & PDRAW_INTERLACE) + else if (Pico.est.rendstatus & PDRAW_INTERLACE) DrawAllSpritesInterlace(0, sh); else if (sprited[1] & SPRL_HAVE_LO) - DrawAllSprites(sprited, 0, sh); + DrawAllSprites(sprited, 0, sh, est); /* - layer B hi - */ if ((PicoDrawMask & PDRAW_LAYERB_ON) && HighCacheB[0]) - DrawTilesFromCache(HighCacheB, sh, maxw); + DrawTilesFromCache(HighCacheB, sh, maxw, est); /* - layer A hi - */ if (!(PicoDrawMask & PDRAW_LAYERA_ON)); else if (hvwind == 1) - DrawWindow(0, maxcells>>1, 1, sh); + DrawWindow(0, maxcells>>1, 1, sh, est); else if (hvwind == 2) { - if (HighCacheA[0]) DrawTilesFromCache(HighCacheA, sh, (win&0x80) ? edge<<4 : maxw); - DrawWindow((win&0x80) ? edge : 0, (win&0x80) ? maxcells>>1 : edge, 1, sh); + if (HighCacheA[0]) + DrawTilesFromCache(HighCacheA, sh, (win&0x80) ? edge<<4 : maxw, est); + DrawWindow((win&0x80) ? edge : 0, (win&0x80) ? maxcells>>1 : edge, 1, sh, est); } else - if (HighCacheA[0]) DrawTilesFromCache(HighCacheA, sh, maxw); + if (HighCacheA[0]) + DrawTilesFromCache(HighCacheA, sh, maxw, est); /* - sprites hi - */ if (!(PicoDrawMask & PDRAW_SPRITES_HI_ON)); - else if (rendstatus & PDRAW_INTERLACE) + else if (Pico.est.rendstatus & PDRAW_INTERLACE) DrawAllSpritesInterlace(1, sh); // have sprites without layer pri bit ontop of sprites with that bit else if ((sprited[1] & 0xd0) == 0xd0 && (PicoOpt & POPT_ACC_SPRITES)) DrawSpritesHiAS(sprited, sh); else if (sh && (sprited[1] & SPRL_MAY_HAVE_OP)) - DrawSpritesSHi(sprited); + DrawSpritesSHi(sprited, est); else if (sprited[1] & SPRL_HAVE_HI) - DrawAllSprites(sprited, 1, 0); + DrawAllSprites(sprited, 1, 0, est); #if 0 { int *c, a, b; for (a = 0, c = HighCacheA; *c; c++, a++); for (b = 0, c = HighCacheB; *c; c++, b++); - printf("%i:%03i: a=%i, b=%i\n", Pico.m.frame_count, DrawScanline, a, b); + printf("%i:%03i: a=%i, b=%i\n", Pico.m.frame_count, + Pico.est.DrawScanline, a, b); } #endif @@ -1374,27 +1385,27 @@ PICO_INTERNAL void PicoFrameStart(void) int offs = 8, lines = 224; // prepare to do this frame - rendstatus = 0; + Pico.est.rendstatus = 0; if ((Pico.video.reg[12] & 6) == 6) - rendstatus |= PDRAW_INTERLACE; // interlace mode + Pico.est.rendstatus |= PDRAW_INTERLACE; // interlace mode if (!(Pico.video.reg[12] & 1)) - rendstatus |= PDRAW_32_COLS; + Pico.est.rendstatus |= PDRAW_32_COLS; if (Pico.video.reg[1] & 8) { offs = 0; lines = 240; } - if (rendstatus != rendstatus_old || lines != rendlines) { + if (Pico.est.rendstatus != rendstatus_old || lines != rendlines) { rendlines = lines; // mode_change() might reset rendstatus_old by calling SetColorFormat emu_video_mode_change((lines == 240) ? 0 : 8, lines, (Pico.video.reg[12] & 1) ? 0 : 1); - rendstatus_old = rendstatus; + rendstatus_old = Pico.est.rendstatus; } HighCol = HighColBase + offs * HighColIncrement; DrawLineDest = (char *)DrawLineDestBase + offs * DrawLineDestIncrement; - DrawScanline = 0; + Pico.est.DrawScanline = 0; skip_next_line = 0; if (PicoOpt & POPT_ALT_RENDERER) @@ -1413,7 +1424,7 @@ static void DrawBlankedLine(int line, int offs, int sh, int bgc) BackFill(bgc, sh); if (FinalizeLine != NULL) - FinalizeLine(sh, line); + FinalizeLine(sh, line, &Pico.est); if (PicoScanEnd != NULL) PicoScanEnd(line + offs); @@ -1431,7 +1442,7 @@ static void PicoLine(int line, int offs, int sh, int bgc) return; } - DrawScanline = line; + Pico.est.DrawScanline = line; if (PicoScanBegin != NULL) skip = PicoScanBegin(line + offs); @@ -1446,7 +1457,7 @@ static void PicoLine(int line, int offs, int sh, int bgc) DrawDisplay(sh); if (FinalizeLine != NULL) - FinalizeLine(sh, line); + FinalizeLine(sh, line, &Pico.est); if (PicoScanEnd != NULL) skip_next_line = PicoScanEnd(line + offs); @@ -1466,7 +1477,7 @@ void PicoDrawSync(int to, int blank_last_line) if (rendlines != 240) offs = 8; - for (line = DrawScanline; line < to; line++) + for (line = Pico.est.DrawScanline; line < to; line++) { PicoLine(line, offs, sh, bgc); } @@ -1479,7 +1490,7 @@ void PicoDrawSync(int to, int blank_last_line) else PicoLine(line, offs, sh, bgc); line++; } - DrawScanline = line; + Pico.est.DrawScanline = line; pprof_end(draw); } @@ -1491,8 +1502,8 @@ void PicoDrawUpdateHighPal(void) if (PicoOpt & POPT_ALT_RENDERER) sh = 0; // no s/h support - PicoDoHighPal555(sh); - if (rendstatus & PDRAW_SONIC_MODE) { + PicoDoHighPal555(sh, 0, &Pico.est); + if (Pico.est.rendstatus & PDRAW_SONIC_MODE) { // FIXME? memcpy(HighPal + 0x40, HighPal, 0x40*2); memcpy(HighPal + 0x80, HighPal, 0x40*2); @@ -1528,7 +1539,7 @@ void PicoDrawSetOutBuf(void *dest, int increment) { DrawLineDestBase = dest; DrawLineDestIncrement = increment; - DrawLineDest = DrawLineDestBase + DrawScanline * increment; + DrawLineDest = DrawLineDestBase + Pico.est.DrawScanline * increment; } void PicoDrawSetInternalBuf(void *dest, int increment) @@ -1536,7 +1547,7 @@ void PicoDrawSetInternalBuf(void *dest, int increment) if (dest != NULL) { HighColBase = dest; HighColIncrement = increment; - HighCol = HighColBase + DrawScanline * increment; + HighCol = HighColBase + Pico.est.DrawScanline * increment; } else { HighColBase = DefHighCol; @@ -1560,3 +1571,5 @@ void PicoDrawSetCallbacks(int (*begin)(unsigned int num), int (*end)(unsigned in PicoScanEnd = end; } } + +// vim:ts=4:sw=4:expandtab diff --git a/pico/draw_arm.S b/pico/draw_arm.S index bbdda5b..2c1db10 100644 --- a/pico/draw_arm.S +++ b/pico/draw_arm.S @@ -1,6 +1,6 @@ /* * assembly optimized versions of most funtions from draw.c - * (C) notaz, 2006-2010 + * (C) notaz, 2006-2010,2017 * * This work is licensed under the terms of MAME license. * See COPYING file in the top-level directory. @@ -8,12 +8,11 @@ * this is highly specialized, be careful if changing related C code! */ -.extern Pico +#include "pico_int_o32.h" + .extern PicoOpt .extern HighCol -.extern DrawScanline .extern HighSprZ -.extern rendstatus .extern HighPreSpr .extern DrawLineDest .extern DrawStripInterlace @@ -287,14 +286,16 @@ @ int cells; // 0x14 @ }; -@ void DrawLayer(int plane_sh, int *hcache, int cellskip, int maxcells); +@ void DrawLayer(int plane_sh, int *hcache, int cellskip, int maxcells, +@ struct PicoEState *est) .global DrawLayer DrawLayer: + ldr r12, [sp] @ est stmfd sp!, {r4-r11,lr} - ldr r11, =(Pico+0x22228) @ Pico.video + ldr r11, [r12, #OFS_Pico_video] mov r8, #1 ldrb r7, [r11, #16] @ ??vv??hh @@ -316,17 +317,17 @@ DrawLayer: cmp r10, #7 subge r10, r10, #1 @ r10=shift[width] (5,6,6,7) - @ calculate xmask: - mov r5, r8, lsl r10 - sub r5, r5, #1 @ r5=xmask + ldr r2, [r12, #OFS_DrawScanline] + ldr lr, [r12, #OFS_Pico_vram] @ Find name table: ands r0, r0, #1 ldreqb r12, [r11, #2] ldrneb r12, [r11, #4] - ldr r2, =DrawScanline @ trying to make good use of pipeline here - ldr lr, =(Pico+0x10000) @ lr=Pico.vram + @ calculate xmask: + mov r5, r8, lsl r10 + sub r5, r5, #1 @ r5=xmask moveq r12, r12, lsl #10 movne r12, r12, lsl #13 @@ -334,7 +335,6 @@ DrawLayer: ldrh r8, [r11, #12] ldrb r7, [r11, #11] - ldr r2, [r2] mov r4, r8, lsr #8 @ pvid->reg[13] mov r4, r4, lsl #10 @ htab=pvid->reg[13]<<9; (halfwords) @@ -504,12 +504,12 @@ DrawLayer: .dsloop_exit: tst r10, #1<<21 @ seen non hi-prio tile - ldreq r1, =rendstatus + ldr r1, [sp, #9*4] @ est mov r0, #0 - ldreq r2, [r1] + ldreq r2, [r1, #OFS_rendstatus] str r0, [r6] @ terminate the cache list orreq r2, r2, #PDRAW_PLANE_HI_PRIO @ had a layer with all hi-prio tiles - streq r2, [r1] + streq r2, [r1, #OFS_rendstatus] ldmfd sp!, {r4-r11,lr} bx lr @@ -522,9 +522,9 @@ DrawLayer: bic r8, r8, #0x3fc00000 orr r8, r8, r5, lsl #25 @ r8=(xmask[31:25]|had_output[24]|tilex[21:0]) - ldr r4, =DrawScanline + ldr r11, [sp, #9*4] @ est orr r5, r1, r10, lsl #24 - ldr r4, [r4] + ldr r4, [r11, #OFS_DrawScanline] sub r1, r3, #1 orr r5, r5, r4, lsl #16 @ r5=(shift_width[31:24]|scanline[23:16]|ymask[15:0]) and r1, r1, #7 @@ -679,12 +679,12 @@ DrawLayer: .dsloop_vs_exit: tst r8, #(1<<24) @ seen non hi-prio tile - ldreq r1, =rendstatus + ldr r1, [sp, #9*4] @ est mov r0, #0 - ldreq r2, [r1] + ldreq r2, [r1, #OFS_rendstatus] str r0, [r6] @ terminate the cache list orreq r2, r2, #PDRAW_PLANE_HI_PRIO @ had a layer with all hi-prio tiles - streq r2, [r1] + streq r2, [r1, #OFS_rendstatus] ldmfd sp!, {r4-r11,lr} bx lr @@ -770,11 +770,12 @@ BackFill: @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@ void DrawTilesFromCache(int *hc, int sh, int rlim, struct PicoEState *est) -.global DrawTilesFromCache @ int *hc, int sh, int rlim +.global DrawTilesFromCache DrawTilesFromCache: - stmfd sp!, {r4-r8,r11,lr} + stmfd sp!, {r4-r9,r11,lr} @ cache some stuff to avoid mem access .if OVERRIDE_HIGHCOL @@ -785,7 +786,8 @@ DrawTilesFromCache: ldr r11,=HighCol mov r12,#0xf .endif - ldr lr, =(Pico+0x10000) @ lr=Pico.vram + ldr lr, [r3, #OFS_Pico_vram] + mov r9, r3 @ est mvn r5, #0 @ r5=prevcode=-1 ands r8, r1, #1 @@ -796,7 +798,7 @@ DrawTilesFromCache: .dtfc_loop: ldr r6, [r0], #4 @ read code movs r1, r6, lsr #16 @ r1=dx; - ldmeqfd sp!, {r4-r8,r11,pc} @ dx is never zero, this must be a terminator, return + ldmeqfd sp!, {r4-r9,r11,pc} @ dx is never zero, this must be a terminator, return bic r4, r1, #0xfe00 add r1, r11, r4 @ r1=pdest @@ -915,15 +917,14 @@ DrawTilesFromCache: @ check if we have detected layer covered with hi-prio tiles: .dtfc_check_rendflags: - ldr r1, =rendstatus - ldr r2, [r1] + ldr r2, [r9, #OFS_rendstatus] tst r2, #(PDRAW_PLANE_HI_PRIO|PDRAW_SHHI_DONE) beq .dtfc_loop bic r8, r8, #1 @ sh/hi mode off tst r2, #PDRAW_SHHI_DONE bne .dtfc_loop @ already processed orr r2, r2, #PDRAW_SHHI_DONE - str r2, [r1] + str r2, [r9, #OFS_rendstatus] add r1, r11,#8 mov r3, #320/4/4 @@ -948,7 +949,9 @@ DrawTilesFromCache: @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -.global DrawSpritesSHi @ unsigned char *sprited +@ void DrawSpritesSHi(unsigned char *sprited, struct PicoEState *est) + +.global DrawSpritesSHi DrawSpritesSHi: ldr r3, [r0] @@ -956,7 +959,7 @@ DrawSpritesSHi: ands r3, r3, #0x7f bxeq lr - stmfd sp!, {r4-r11,lr} + stmfd sp!, {r1,r4-r11,lr} @ +est strb r12,[r0,#2] @ set end marker add r10,r0, #3 @ r10=HighLnSpr end add r10,r10,r3 @ r10=HighLnSpr end @@ -969,16 +972,16 @@ DrawSpritesSHi: ldr r11,=HighCol mov r12,#0xf .endif - ldr lr, =(Pico+0x10000) @ lr=Pico.vram + ldr lr, [r1, #OFS_Pico_vram] DrawSpriteSHi: @ draw next sprite ldrb r0, [r10,#-1]! + ldr r7, [sp] @ est ldr r1, =HighPreSpr -@ ldr r8, [sp, #-4] cmp r0, #0xff - ldmeqfd sp!, {r4-r11,pc} @ end of list + ldmeqfd sp!, {r1,r4-r11,pc} @ end of list and r0, r0, #0x7f add r0, r1, r0, lsl #3 @@ -997,15 +1000,14 @@ DrawSpriteSHi: bne DrawSpriteSHi @ non-operator low sprite, already drawn ldr r3, [r0] @ sprite[0] - ldr r7, =DrawScanline mov r6, r3, lsr #28 sub r6, r6, #1 @ r6=width-1 (inc later) mov r5, r3, lsr #24 and r5, r5, #7 @ r5=height + ldr r7, [r7, #OFS_DrawScanline] mov r0, r3, lsl #16 @ r4=sy<<16 (tmp) - ldr r7, [r7] sub r7, r7, r0, asr #16 @ r7=row=DrawScanline-sy tst r9, #0x1000 @@ -1128,34 +1130,34 @@ DrawSpriteSHi: @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -.global DrawAllSprites @ unsigned char *sprited, int prio, int sh +@ void DrawAllSprites(unsigned char *sprited, int prio, int sh, +@ struct PicoEState *est) + +.global DrawAllSprites DrawAllSprites: - ldr r3, =rendstatus orr r1, r2, r1, lsl #1 - ldr r12,[r3] + ldr r12,[r3, #OFS_rendstatus] tst r12,#(PDRAW_DIRTY_SPRITES|PDRAW_SPRITES_MOVED) beq das_no_prep - stmfd sp!, {r0,r1,lr} + stmfd sp!, {r0,r1,r3,lr} and r0, r12,#PDRAW_DIRTY_SPRITES bic r12,r12,#(PDRAW_DIRTY_SPRITES|PDRAW_SPRITES_MOVED) - str r12,[r3] + str r12,[r3, #OFS_rendstatus] bl PrepareSprites - ldmfd sp!, {r0,r1,lr} + ldmfd sp!, {r0,r1,r3,lr} das_no_prep: - ldr r3, [r0] - ands r3, r3, #0x7f + ldr r2, [r0] + ands r2, r2, #0x7f bxeq lr @ time to do some real work - stmfd sp!, {r4-r11,lr} + stmfd sp!, {r1,r3-r11,lr} @ +sh|prio<<1 +est mov r12,#0xff strb r12,[r0,#2] @ set end marker add r10,r0, #3 - add r10,r10,r3 @ r10=HighLnSpr end - - str r1, [sp, #-4] @ no calls after this point + add r10,r10,r2 @ r10=HighLnSpr end .if OVERRIDE_HIGHCOL ldr r11,=HighCol @@ -1165,29 +1167,27 @@ das_no_prep: ldr r11,=HighCol mov r12,#0xf .endif - ldr lr, =(Pico+0x10000) @ lr=Pico.vram + ldr lr, [r3, #OFS_Pico_vram] @ + 0 : hhhhvvvv ----hhvv yyyyyyyy yyyyyyyy // v, h: horiz. size @ + 4 : xxxxxxxx xxxxxxxx pccvhnnn nnnnnnnn // x: x coord + 8 -DrawSprite: @ was: unsigned int *sprite, int sh, int acc_sprites +DrawSprite: @ draw next sprite ldrb r0, [r10,#-1]! - ldr r1, =HighPreSpr - ldr r8, [sp, #-4] + ldr r8, [sp] @ sh|prio<<1 + ldr r7, [sp, #4] @ est mov r2, r0, lsr #7 cmp r0, #0xff - ldmeqfd sp!, {r4-r11,pc} @ end of list + ldmeqfd sp!, {r1,r3-r11,pc} @ end of list cmp r2, r8, lsr #1 bne DrawSprite @ wrong priority + ldr r1, =HighPreSpr and r0, r0, #0x7f add r0, r1, r0, lsl #3 -@ stmfd sp!, {r4-r9,r11,lr} -@ orr r8, r2, r1, lsl #4 - ldr r3, [r0] @ sprite[0] - ldr r7, =DrawScanline + ldr r7, [r7, #OFS_DrawScanline] mov r6, r3, lsr #28 sub r6, r6, #1 @ r6=width-1 (inc later) mov r5, r3, lsr #24 @@ -1195,7 +1195,6 @@ DrawSprite: @ was: unsigned int *sprite, int sh, int acc_sprites mov r4, r3, lsl #16 @ r4=sy<<16 (tmp) - ldr r7, [r7] ldr r9, [r0, #4] sub r7, r7, r4, asr #16 @ r7=row=DrawScanline-sy @@ -1307,17 +1306,21 @@ DrawSprite: @ was: unsigned int *sprite, int sh, int acc_sprites @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -.global DrawWindow @ int tstart, int tend, int prio, int sh // int *hcache +@ void DrawWindow(int tstart, int tend, int prio, int sh +@ struct PicoEState *est) + +.global DrawWindow DrawWindow: + ldr r12, [sp] @ est stmfd sp!, {r4-r11,lr} - ldr r11, =(Pico+0x22228) @ Pico.video - ldr r10, =DrawScanline - ldrb r12, [r11, #3] @ pvid->reg[3] + ldr r6, [r12, #OFS_Pico_video] + ldr r10, [r12, #OFS_DrawScanline] + mov r11, r12 @ est + ldrb r12, [r6, #3] @ pvid->reg[3] - ldr r10, [r10] - ldr r4, [r11, #12] + ldr r4, [r6, #12] mov r5, r10, lsr #3 and r10, r10, #7 mov r10, r10, lsl #1 @ r10=ty @@ -1331,9 +1334,8 @@ DrawWindow: addeq r12, r12, r5, lsl #6 @ nametab add r12, r12, r0, lsl #2 @ +starttile - ldr r6, =rendstatus - ldr lr, =(Pico+0x10000) @ lr=Pico.vram - ldr r6, [r6] + ldr lr, [r11, #OFS_Pico_vram] + ldr r6, [r11, #OFS_rendstatus] @ fetch the first code now ldrh r7, [lr, r12] @@ -1442,14 +1444,14 @@ DrawWindow: b .dw_shadow_done .dwloop_end: - ldr r0, =rendstatus - ldr r1, [r0] - and r6, r6, #PDRAW_WND_DIFF_PRIO - orr r1, r1, r6 - str r1, [r0] + and r2, r6, #PDRAW_WND_DIFF_PRIO + ldmfd sp!, {r4-r11,lr} + ldr r0, [sp] + ldr r1, [r0, #OFS_rendstatus] + orr r1, r1, r2 + str r1, [r0, #OFS_rendstatus] - ldmfd sp!, {r4-r11,r12} - bx r12 + bx lr @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@ -1531,12 +1533,15 @@ vidConvCpyRGB565: @ void *to, void *from, int pixels bx lr -.global PicoDoHighPal555 @ int sh +@ void PicoDoHighPal555(int sh, int line, struct PicoEState *est) + +.global PicoDoHighPal555 PicoDoHighPal555: - stmfd sp!, {r4-r9,lr} + stmfd sp!, {r4-r10,lr} + mov r10,r2 @ est mov r1, #0 - ldr r8, =(Pico+0x22228) @ Pico.video + ldr r8, [r10, #OFS_Pico_video] PicoDoHighPal555_nopush: orr r9, r1, r0, lsl #31 @ 0:called from FinalizeLine555, 31: s/h @@ -1598,17 +1603,20 @@ PicoDoHighPal555_nopush: PicoDoHighPal555_end: tst r9, #1 - ldmeqfd sp!, {r4-r9,pc} + ldmeqfd sp!, {r4-r10,pc} - ldr r8, =(Pico+0x22228) @ Pico.video + ldr r8, [r10, #OFS_Pico_video] b FinalizeLineRGB555_pal_done -.global FinalizeLine555 @ int sh +@ void FinalizeLine555(int sh, int line, struct PicoEState *est) + +.global FinalizeLine555 FinalizeLine555: - stmfd sp!, {r4-r9,lr} - ldr r8, =(Pico+0x22228) @ Pico.video + stmfd sp!, {r4-r10,lr} + mov r10,r2 @ est + ldr r8, [r10, #OFS_Pico_video] ldrb r2, [r8, #-0x1a] @ 0x2220e ~ dirtyPal mov r1, #1 @@ -1618,9 +1626,8 @@ FinalizeLine555: FinalizeLineRGB555_pal_done: ldr r3, =HighPal - ldr r12,=rendstatus + ldr r12, [r10, #OFS_rendstatus] eors r0, r0, #1 @ sh is 0 - ldr r12,[r12] mov lr, #0xff tstne r12,#PDRAW_ACC_SPRITES movne lr, #0x3f @@ -1691,12 +1698,11 @@ FinalizeLineRGB555_pal_done: stmia r0!, {r4,r5,r8,r12} bne .fl_loopRGB555 - ldmfd sp!, {r4-r9,lr} + ldmfd sp!, {r4-r10,lr} bx lr .fl_32scale_RGB555: - stmfd sp!, {r10} mov r9, #0x3900 @ f800 07e0 001f | e000 0780 001c | 3800 01e0 0007 orr r9, r9, #0x00e7 @@ -1757,8 +1763,7 @@ FinalizeLineRGB555_pal_done: stmia r0!, {r4,r5,r6,r8,r10} bne .fl_loop32scale_RGB555 - ldmfd sp!, {r10} - ldmfd sp!, {r4-r9,lr} + ldmfd sp!, {r4-r10,lr} bx lr #ifdef UNALIGNED_DRAWLINEDEST @@ -1804,7 +1809,7 @@ FinalizeLineRGB555_pal_done: strh r8, [r0], #2 - ldmfd sp!, {r4-r9,lr} + ldmfd sp!, {r4-r10,lr} bx lr @@ -1870,8 +1875,7 @@ FinalizeLineRGB555_pal_done: strh r4, [r0], #2 - ldmfd sp!, {r10} - ldmfd sp!, {r4-r9,lr} + ldmfd sp!, {r4-r10,lr} bx lr #endif /* UNALIGNED_DRAWLINEDEST */ diff --git a/pico/mode4.c b/pico/mode4.c index 22e3041..c945f6f 100644 --- a/pico/mode4.c +++ b/pico/mode4.c @@ -200,7 +200,7 @@ void PicoFrameStartMode4(void) int lines = 192; skip_next_line = 0; screen_offset = 24; - rendstatus = PDRAW_32_COLS; + Pico.est.rendstatus = PDRAW_32_COLS; if ((Pico.video.reg[0] & 6) == 6 && (Pico.video.reg[1] & 0x18)) { if (Pico.video.reg[1] & 0x08) { @@ -213,9 +213,9 @@ void PicoFrameStartMode4(void) } } - if (rendstatus != rendstatus_old || lines != rendlines) { + if (Pico.est.rendstatus != rendstatus_old || lines != rendlines) { emu_video_mode_change(screen_offset, lines, 1); - rendstatus_old = rendstatus; + rendstatus_old = Pico.est.rendstatus; rendlines = lines; } @@ -277,7 +277,7 @@ static void FinalizeLineRGB555M4(int line) // standard FinalizeLine can finish it for us, // with features like scaling and such - FinalizeLine555(0, line); + FinalizeLine555(0, line, &Pico.est); } static void FinalizeLine8bitM4(int line) diff --git a/pico/pico.c b/pico/pico.c index 8535d48..1c58f22 100644 --- a/pico/pico.c +++ b/pico/pico.c @@ -36,6 +36,9 @@ void PicoInit(void) memset(&PicoPad,0,sizeof(PicoPad)); memset(&PicoPadInt,0,sizeof(PicoPadInt)); + Pico.est.Pico_video = &Pico.video; + Pico.est.Pico_vram = Pico.vram; + // Init CPUs: SekInit(); z80_init(); // init even if we aren't going to use it diff --git a/pico/pico.h b/pico/pico.h index d541672..c033c2d 100644 --- a/pico/pico.h +++ b/pico/pico.h @@ -99,6 +99,8 @@ typedef enum { PI_ROM, PI_ISPAL, PI_IS40_CELL, PI_IS240_LINES } pint_t; typedef union { int vint; void *vptr; } pint_ret_t; void PicoGetInternal(pint_t which, pint_ret_t *ret); +struct PicoEState; + // cd/mcd.c extern void (*PicoMCDopenTray)(void); extern void (*PicoMCDcloseTray)(void); @@ -175,7 +177,7 @@ extern unsigned char *HighCol; #ifdef _ASM_DRAW_C void vidConvCpyRGB565(void *to, void *from, int pixels); #endif -void PicoDoHighPal555(int sh); +void PicoDoHighPal555(int sh, int line, struct PicoEState *est); extern int PicoDrawMask; #define PDRAW_LAYERB_ON (1<<2) #define PDRAW_LAYERA_ON (1<<3) @@ -192,7 +194,7 @@ extern int PicoDrawMask; #define PDRAW_PLANE_HI_PRIO (1<<6) // have layer with all hi prio tiles (mk3) #define PDRAW_SHHI_DONE (1<<7) // layer sh/hi already processed #define PDRAW_32_COLS (1<<8) // 32 column mode -extern int rendstatus, rendstatus_old; +extern int rendstatus_old; extern int rendlines; extern unsigned short HighPal[0x100]; diff --git a/pico/pico_cmn.c b/pico/pico_cmn.c index 341255a..2de65d0 100644 --- a/pico/pico_cmn.c +++ b/pico/pico_cmn.c @@ -168,7 +168,7 @@ static int PicoFrameHints(void) if (!skip) { - if (DrawScanline < y) + if (Pico.est.DrawScanline < y) PicoDrawSync(y - 1, 0); #ifdef DRAW_FINISH_FUNC DRAW_FINISH_FUNC(); diff --git a/pico/pico_int.h b/pico/pico_int.h index c85319c..da49e04 100644 --- a/pico/pico_int.h +++ b/pico/pico_int.h @@ -328,6 +328,15 @@ struct PicoMS unsigned char pad[0x4e]; }; +// emu state and data for the asm code +struct PicoEState +{ + int DrawScanline; + int rendstatus; + void *Pico_video; + void *Pico_vram; +}; + // some assembly stuff depend on these, do not touch! struct Pico { @@ -348,6 +357,7 @@ struct Pico struct PicoMisc m; struct PicoVideo video; struct PicoMS ms; + struct PicoEState est; }; // sram @@ -577,10 +587,9 @@ int CM_compareRun(int cyc, int is_sub); PICO_INTERNAL void PicoFrameStart(void); void PicoDrawSync(int to, int blank_last_line); void BackFill(int reg7, int sh); -void FinalizeLine555(int sh, int line); +void FinalizeLine555(int sh, int line, struct PicoEState *est); extern int (*PicoScanBegin)(unsigned int num); extern int (*PicoScanEnd)(unsigned int num); -extern int DrawScanline; #define MAX_LINE_SPRITES 29 extern unsigned char HighLnSpr[240][3 + MAX_LINE_SPRITES]; extern void *DrawLineDestBase; @@ -856,7 +865,7 @@ void p32x_sh2_poll_event(SH2 *sh2, unsigned int flags, unsigned int m68k_cycles) // 32x/draw.c void PicoDrawSetOutFormat32x(pdso_t which, int use_32x_line_mode); -void FinalizeLine32xRGB555(int sh, int line); +void FinalizeLine32xRGB555(int sh, int line, struct PicoEState *est); void PicoDraw32xLayer(int offs, int lines, int mdbg); void PicoDraw32xLayerMdOnly(int offs, int lines); extern int (*PicoScan32xBegin)(unsigned int num); diff --git a/pico/pico_int_o32.h b/pico/pico_int_o32.h new file mode 100644 index 0000000..1cdc6b5 --- /dev/null +++ b/pico/pico_int_o32.h @@ -0,0 +1,5 @@ +/* autogenerated by ./tools/mkoffsets, do not edit */ +#define OFS_DrawScanline 0x00 +#define OFS_rendstatus 0x04 +#define OFS_Pico_video 0x08 +#define OFS_Pico_vram 0x0c diff --git a/pico/videoport.c b/pico/videoport.c index 6c876ae..9ddc167 100644 --- a/pico/videoport.c +++ b/pico/videoport.c @@ -36,7 +36,7 @@ static void VideoWrite(u16 d) case 1: if(a&1) d=(u16)((d<<8)|(d>>8)); // If address is odd, bytes are swapped (which game needs this?) Pico.vram [(a>>1)&0x7fff]=d; if (a - ((unsigned)(Pico.video.reg[5]&0x7f) << 9) < 0x400) - rendstatus |= PDRAW_DIRTY_SPRITES; + Pico.est.rendstatus |= PDRAW_DIRTY_SPRITES; break; case 3: Pico.m.dirtyPal = 1; Pico.cram [(a>>1)&0x003f]=d; break; // wraps (Desert Strike) @@ -172,7 +172,7 @@ static void DmaSlow(int len) //if(pd >= pdend) pd-=0x8000; // should be good for RAM, bad for ROM } } - rendstatus |= PDRAW_DIRTY_SPRITES; + Pico.est.rendstatus |= PDRAW_DIRTY_SPRITES; break; case 3: // cram @@ -241,7 +241,7 @@ static void DmaCopy(int len) } // remember addr Pico.video.addr=a; - rendstatus |= PDRAW_DIRTY_SPRITES; + Pico.est.rendstatus |= PDRAW_DIRTY_SPRITES; } // check: Contra, Megaman @@ -280,7 +280,7 @@ static void DmaFill(int data) // update length Pico.video.reg[0x13] = Pico.video.reg[0x14] = 0; // Dino Dini's Soccer (E) (by Haze) - rendstatus |= PDRAW_DIRTY_SPRITES; + Pico.est.rendstatus |= PDRAW_DIRTY_SPRITES; } static void CommandDma(void) @@ -319,7 +319,7 @@ static void CommandChange(void) static void DrawSync(int blank_on) { if (Pico.m.scanline < 224 && !(PicoOpt & POPT_ALT_RENDERER) && - !PicoSkipFrame && DrawScanline <= Pico.m.scanline) { + !PicoSkipFrame && Pico.est.DrawScanline <= Pico.m.scanline) { //elprintf(EL_ANOMALY, "sync"); PicoDrawSync(Pico.m.scanline, blank_on); } @@ -412,7 +412,7 @@ PICO_INTERNAL_ASM void PicoVideoWrite(unsigned int a,unsigned short d) goto update_irq; case 0x05: //elprintf(EL_STATUS, "spritep moved to %04x", (unsigned)(Pico.video.reg[5]&0x7f) << 9); - if (d^dold) rendstatus |= PDRAW_SPRITES_MOVED; + if (d^dold) Pico.est.rendstatus |= PDRAW_SPRITES_MOVED; break; case 0x0c: // renderers should update their palettes if sh/hi mode is changed diff --git a/platform/gp2x/emu.c b/platform/gp2x/emu.c index 7741ba6..7e91361 100644 --- a/platform/gp2x/emu.c +++ b/platform/gp2x/emu.c @@ -310,7 +310,7 @@ static int make_local_pal_md(int fast_mode) localPal[0xf0] = 0x00ffffff; pallen = 0x100; } - else if (rendstatus & PDRAW_SONIC_MODE) { // mid-frame palette changes + else if (Pico.est.rendstatus & PDRAW_SONIC_MODE) { // mid-frame palette changes bgr444_to_rgb32(localPal+0x40, HighPal); bgr444_to_rgb32(localPal+0x80, HighPal+0x40); } diff --git a/platform/psp/emu.c b/platform/psp/emu.c index 5a2e880..8deb7fd 100644 --- a/platform/psp/emu.c +++ b/platform/psp/emu.c @@ -223,7 +223,7 @@ static void do_pal_update(int allow_sh, int allow_as) localPal[0xe0] = 0; localPal[0xf0] = 0x001f; } - else if (allow_as && (rendstatus & PDRAW_SPR_LO_ON_HI)) + else if (allow_as && (Pico.est.rendstatus & PDRAW_SPR_LO_ON_HI)) { memcpy32((int *)dpal+0x80/2, (void *)localPal, 0x40*2/4); } @@ -250,7 +250,7 @@ static void EmuScanPrepare(void) if (Pico.m.dirtyPal) do_pal_update(1, 1); - if ((rendstatus & PDRAW_SPR_LO_ON_HI) && !(Pico.video.reg[0xC]&8)) + if ((Pico.est.rendstatus & PDRAW_SPR_LO_ON_HI) && !(Pico.video.reg[0xC]&8)) amips_clut_f = amips_clut_6bit; else amips_clut_f = amips_clut; } diff --git a/tools/Makefile b/tools/Makefile index 0c126cc..28b748d 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -1,6 +1,6 @@ CFLAGS = -Wall -ggdb -TARGETS = amalgamate textfilter +TARGETS = amalgamate textfilter mkoffsets OBJS = $(addsuffix .o,$(TARGETS)) all: $(TARGETS) @@ -8,3 +8,6 @@ all: $(TARGETS) clean: $(RM) $(TARGETS) $(OBJS) +mkoffsets: CFLAGS += -m32 -I.. + +.PHONY: clean all diff --git a/tools/mkoffsets.c b/tools/mkoffsets.c new file mode 100644 index 0000000..4044ad3 --- /dev/null +++ b/tools/mkoffsets.c @@ -0,0 +1,31 @@ +#include +#include + +#include "../pico/pico_int.h" + +#define DUMP(f, field) \ + fprintf(f, "#define %-20s 0x%02x\n", \ + "OFS_" #field, \ + (int)offsetof(struct PicoEState, field)) + +int main(int argc, char *argv[]) +{ + char buf[128]; + FILE *f; + + snprintf(buf, sizeof(buf), "pico/pico_int_o%d.h", sizeof(void *) * 8); + f = fopen(buf, "w"); + if (!f) { + perror("fopen"); + return 1; + } + + fprintf(f, "/* autogenerated by %s, do not edit */\n", argv[0]); + DUMP(f, DrawScanline); + DUMP(f, rendstatus); + DUMP(f, Pico_video); + DUMP(f, Pico_vram); + fclose(f); + + return 0; +} -- 2.39.2