mirror of
https://github.com/RaySollium99/picodrive.git
synced 2025-09-05 15:27:46 -04:00
line draw deferment implemented
git-svn-id: file:///home/notaz/opt/svn/PicoDrive@508 be3aeb3a-fb24-0410-a615-afba39da0efa
This commit is contained in:
parent
1a65e3b161
commit
b6d7ac7090
8 changed files with 120 additions and 99 deletions
86
Pico/Draw.c
86
Pico/Draw.c
|
@ -39,7 +39,7 @@ static int HighPreSpr[80*2+1]; // slightly preprocessed sprites
|
||||||
int *HighCacheS_ptr;
|
int *HighCacheS_ptr;
|
||||||
|
|
||||||
int rendstatus = 0;
|
int rendstatus = 0;
|
||||||
int Scanline = 0; // Scanline
|
int DrawScanline = 0;
|
||||||
|
|
||||||
static int SpriteBlocks;
|
static int SpriteBlocks;
|
||||||
static int skip_next_line=0;
|
static int skip_next_line=0;
|
||||||
|
@ -252,7 +252,7 @@ void DrawStripVSRam(struct TileStrip *ts, int plane_sh, int cellskip)
|
||||||
{
|
{
|
||||||
int tilex,dx,code=0,addr=0,cell=0;
|
int tilex,dx,code=0,addr=0,cell=0;
|
||||||
int oldcode=-1,blank=-1; // The tile we know is blank
|
int oldcode=-1,blank=-1; // The tile we know is blank
|
||||||
int pal=0,scan=Scanline;
|
int pal=0,scan=DrawScanline;
|
||||||
|
|
||||||
// Draw tiles across screen:
|
// Draw tiles across screen:
|
||||||
tilex=(-ts->hscroll)>>3;
|
tilex=(-ts->hscroll)>>3;
|
||||||
|
@ -387,7 +387,7 @@ static void DrawLayer(int plane_sh, int *hcache, int cellskip, int maxcells)
|
||||||
else ts.nametab=(pvid->reg[2]&0x38)<< 9; // A
|
else ts.nametab=(pvid->reg[2]&0x38)<< 9; // A
|
||||||
|
|
||||||
htab=pvid->reg[13]<<9; // Horizontal scroll table address
|
htab=pvid->reg[13]<<9; // Horizontal scroll table address
|
||||||
if ( pvid->reg[11]&2) htab+=Scanline<<1; // Offset by line
|
if ( pvid->reg[11]&2) htab+=DrawScanline<<1; // Offset by line
|
||||||
if ((pvid->reg[11]&1)==0) htab&=~0xf; // Offset by tile
|
if ((pvid->reg[11]&1)==0) htab&=~0xf; // Offset by tile
|
||||||
htab+=plane_sh&1; // A or B
|
htab+=plane_sh&1; // A or B
|
||||||
|
|
||||||
|
@ -399,7 +399,7 @@ static void DrawLayer(int plane_sh, int *hcache, int cellskip, int maxcells)
|
||||||
vscroll=Pico.vsram[plane_sh&1]; // Get vertical scroll value
|
vscroll=Pico.vsram[plane_sh&1]; // Get vertical scroll value
|
||||||
|
|
||||||
// Find the line in the name table
|
// Find the line in the name table
|
||||||
ts.line=(vscroll+(Scanline<<1))&((ymask<<1)|1);
|
ts.line=(vscroll+(DrawScanline<<1))&((ymask<<1)|1);
|
||||||
ts.nametab+=(ts.line>>4)<<shift[width];
|
ts.nametab+=(ts.line>>4)<<shift[width];
|
||||||
|
|
||||||
DrawStripInterlace(&ts);
|
DrawStripInterlace(&ts);
|
||||||
|
@ -412,7 +412,7 @@ static void DrawLayer(int plane_sh, int *hcache, int cellskip, int maxcells)
|
||||||
vscroll=Pico.vsram[plane_sh&1]; // Get vertical scroll value
|
vscroll=Pico.vsram[plane_sh&1]; // Get vertical scroll value
|
||||||
|
|
||||||
// Find the line in the name table
|
// Find the line in the name table
|
||||||
ts.line=(vscroll+Scanline)&ymask;
|
ts.line=(vscroll+DrawScanline)&ymask;
|
||||||
ts.nametab+=(ts.line>>3)<<shift[width];
|
ts.nametab+=(ts.line>>3)<<shift[width];
|
||||||
|
|
||||||
DrawStrip(&ts, plane_sh, cellskip);
|
DrawStrip(&ts, plane_sh, cellskip);
|
||||||
|
@ -433,12 +433,12 @@ static void DrawWindow(int tstart, int tend, int prio, int sh) // int *hcache
|
||||||
if (pvid->reg[12]&1)
|
if (pvid->reg[12]&1)
|
||||||
{
|
{
|
||||||
nametab=(pvid->reg[3]&0x3c)<<9; // 40-cell mode
|
nametab=(pvid->reg[3]&0x3c)<<9; // 40-cell mode
|
||||||
nametab+=(Scanline>>3)<<6;
|
nametab+=(DrawScanline>>3)<<6;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
nametab=(pvid->reg[3]&0x3e)<<9; // 32-cell mode
|
nametab=(pvid->reg[3]&0x3e)<<9; // 32-cell mode
|
||||||
nametab+=(Scanline>>3)<<5;
|
nametab+=(DrawScanline>>3)<<5;
|
||||||
}
|
}
|
||||||
|
|
||||||
tilex=tstart<<1;
|
tilex=tstart<<1;
|
||||||
|
@ -451,7 +451,7 @@ static void DrawWindow(int tstart, int tend, int prio, int sh) // int *hcache
|
||||||
}
|
}
|
||||||
|
|
||||||
tend<<=1;
|
tend<<=1;
|
||||||
ty=(Scanline&7)<<1; // Y-Offset into tile
|
ty=(DrawScanline&7)<<1; // Y-Offset into tile
|
||||||
|
|
||||||
// Draw tiles across screen:
|
// Draw tiles across screen:
|
||||||
if (!sh)
|
if (!sh)
|
||||||
|
@ -643,7 +643,7 @@ static void DrawSprite(int *sprite, int sh, int as)
|
||||||
height=(sy>>24)&7; // Width and height in tiles
|
height=(sy>>24)&7; // Width and height in tiles
|
||||||
sy=(sy<<16)>>16; // Y
|
sy=(sy<<16)>>16; // Y
|
||||||
|
|
||||||
row=Scanline-sy; // Row of the sprite we are on
|
row=DrawScanline-sy; // Row of the sprite we are on
|
||||||
|
|
||||||
if (code&0x1000) row=(height<<3)-1-row; // Flip Y
|
if (code&0x1000) row=(height<<3)-1-row; // Flip Y
|
||||||
|
|
||||||
|
@ -699,7 +699,7 @@ static void DrawSpriteInterlace(unsigned int *sprite)
|
||||||
width=(height>>2)&3; height&=3;
|
width=(height>>2)&3; height&=3;
|
||||||
width++; height++; // Width and height in tiles
|
width++; height++; // Width and height in tiles
|
||||||
|
|
||||||
row=(Scanline<<1)-sy; // Row of the sprite we are on
|
row=(DrawScanline<<1)-sy; // Row of the sprite we are on
|
||||||
|
|
||||||
code=sprite[1];
|
code=sprite[1];
|
||||||
sx=((code>>16)&0x1ff)-0x78; // X
|
sx=((code>>16)&0x1ff)-0x78; // X
|
||||||
|
@ -731,7 +731,7 @@ static void DrawSpriteInterlace(unsigned int *sprite)
|
||||||
static void DrawAllSpritesInterlace(int *hcache, int maxwidth, int pri, int sh)
|
static void DrawAllSpritesInterlace(int *hcache, int maxwidth, int pri, int sh)
|
||||||
{
|
{
|
||||||
struct PicoVideo *pvid=&Pico.video;
|
struct PicoVideo *pvid=&Pico.video;
|
||||||
int i,u,table,link=0,sline=Scanline<<1;
|
int i,u,table,link=0,sline=DrawScanline<<1;
|
||||||
unsigned int *sprites[80]; // Sprite index
|
unsigned int *sprites[80]; // Sprite index
|
||||||
|
|
||||||
table=pvid->reg[5]&0x7f;
|
table=pvid->reg[5]&0x7f;
|
||||||
|
@ -1020,7 +1020,7 @@ static void DrawAllSprites(int *hcache, int maxwidth, int prio, int sh)
|
||||||
int ntiles = 0; // tile counter for sprite limit emulation
|
int ntiles = 0; // tile counter for sprite limit emulation
|
||||||
int *sprites[40]; // Sprites to draw in fast mode
|
int *sprites[40]; // Sprites to draw in fast mode
|
||||||
int max_line_sprites = 20; // 20 sprites, 40 tiles
|
int max_line_sprites = 20; // 20 sprites, 40 tiles
|
||||||
int *ps, pack, rs = rendstatus, scan = Scanline;
|
int *ps, pack, rs = rendstatus, scan = DrawScanline;
|
||||||
|
|
||||||
if (rs & (PDRAW_SPRITES_MOVED|PDRAW_DIRTY_SPRITES)) {
|
if (rs & (PDRAW_SPRITES_MOVED|PDRAW_DIRTY_SPRITES)) {
|
||||||
//dprintf("PrepareSprites(%i) [%i]", (rs>>4)&1, scan);
|
//dprintf("PrepareSprites(%i) [%i]", (rs>>4)&1, scan);
|
||||||
|
@ -1212,7 +1212,7 @@ static void FinalizeLine8bit(int sh)
|
||||||
int len, rs = rendstatus;
|
int len, rs = rendstatus;
|
||||||
static int dirty_count;
|
static int dirty_count;
|
||||||
|
|
||||||
if (!sh && !(rs & PDRAW_ACC_SPRITES) && Pico.m.dirtyPal == 1 && Scanline < 222)
|
if (!sh && !(rs & PDRAW_ACC_SPRITES) && Pico.m.dirtyPal == 1 && DrawScanline < 222)
|
||||||
{
|
{
|
||||||
// a hack for mid-frame palette changes
|
// a hack for mid-frame palette changes
|
||||||
if (!(rs & PDRAW_SONIC_MODE))
|
if (!(rs & PDRAW_SONIC_MODE))
|
||||||
|
@ -1247,14 +1247,14 @@ static void FinalizeLine8bit(int sh)
|
||||||
|
|
||||||
static void (*FinalizeLine)(int sh) = FinalizeLineBGR444;
|
static void (*FinalizeLine)(int sh) = FinalizeLineBGR444;
|
||||||
|
|
||||||
// hblank was enabled early during prev line processng -
|
// --------------------------------------------
|
||||||
// it should have been blanked
|
|
||||||
static void handle_early_blank(int scanline, int sh)
|
static void DrawBlankedLine(void)
|
||||||
{
|
{
|
||||||
scanline--;
|
int sh=(Pico.video.reg[0xC]&8)>>3; // shadow/hilight?
|
||||||
|
|
||||||
if (PicoScanBegin != NULL)
|
if (PicoScanBegin != NULL)
|
||||||
PicoScanBegin(scanline);
|
PicoScanBegin(DrawScanline);
|
||||||
|
|
||||||
BackFill(Pico.video.reg[7], sh);
|
BackFill(Pico.video.reg[7], sh);
|
||||||
|
|
||||||
|
@ -1262,11 +1262,9 @@ static void handle_early_blank(int scanline, int sh)
|
||||||
FinalizeLine(sh);
|
FinalizeLine(sh);
|
||||||
|
|
||||||
if (PicoScanEnd != NULL)
|
if (PicoScanEnd != NULL)
|
||||||
PicoScanEnd(scanline);
|
PicoScanEnd(DrawScanline);
|
||||||
}
|
}
|
||||||
|
|
||||||
// --------------------------------------------
|
|
||||||
|
|
||||||
static int DrawDisplay(int sh, int as)
|
static int DrawDisplay(int sh, int as)
|
||||||
{
|
{
|
||||||
struct PicoVideo *pvid=&Pico.video;
|
struct PicoVideo *pvid=&Pico.video;
|
||||||
|
@ -1285,8 +1283,8 @@ static int DrawDisplay(int sh, int as)
|
||||||
win=pvid->reg[0x12];
|
win=pvid->reg[0x12];
|
||||||
edge=(win&0x1f)<<3;
|
edge=(win&0x1f)<<3;
|
||||||
|
|
||||||
if (win&0x80) { if (Scanline>=edge) hvwind=1; }
|
if (win&0x80) { if (DrawScanline>=edge) hvwind=1; }
|
||||||
else { if (Scanline< edge) hvwind=1; }
|
else { if (DrawScanline< edge) hvwind=1; }
|
||||||
|
|
||||||
if (!hvwind) { // we might have a vertical window here
|
if (!hvwind) { // we might have a vertical window here
|
||||||
win=pvid->reg[0x11];
|
win=pvid->reg[0x11];
|
||||||
|
@ -1327,7 +1325,7 @@ static int DrawDisplay(int sh, int as)
|
||||||
int *c, a, b;
|
int *c, a, b;
|
||||||
for (a = 0, c = HighCacheA; *c; c++, a++);
|
for (a = 0, c = HighCacheA; *c; c++, a++);
|
||||||
for (b = 0, c = HighCacheB; *c; c++, b++);
|
for (b = 0, c = HighCacheB; *c; c++, b++);
|
||||||
printf("%i:%03i: a=%i, b=%i\n", Pico.m.frame_count, Scanline, a, b);
|
printf("%i:%03i: a=%i, b=%i\n", Pico.m.frame_count, DrawScanline, a, b);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1354,24 +1352,19 @@ PICO_INTERNAL void PicoFrameStart(void)
|
||||||
|
|
||||||
PrepareSprites(1);
|
PrepareSprites(1);
|
||||||
skip_next_line=0;
|
skip_next_line=0;
|
||||||
|
DrawScanline=0;
|
||||||
}
|
}
|
||||||
|
|
||||||
PICO_INTERNAL int PicoLine(int scan)
|
static void PicoLine(void)
|
||||||
{
|
{
|
||||||
int sh, as = 0;
|
int sh, as = 0;
|
||||||
if (skip_next_line>0) { skip_next_line--; return 0; } // skip_next_line rendering lines
|
if (skip_next_line>0) { skip_next_line--; return; } // skip rendering lines
|
||||||
|
|
||||||
Scanline=scan;
|
|
||||||
sh=(Pico.video.reg[0xC]&8)>>3; // shadow/hilight?
|
sh=(Pico.video.reg[0xC]&8)>>3; // shadow/hilight?
|
||||||
if (rendstatus & PDRAW_ACC_SPRITES) as|=1; // accurate sprites
|
if (rendstatus & PDRAW_ACC_SPRITES) as|=1; // accurate sprites
|
||||||
|
|
||||||
if (rendstatus & PDRAW_EARLY_BLANK) {
|
|
||||||
if (scan > 0) handle_early_blank(scan, sh);
|
|
||||||
rendstatus &= ~PDRAW_EARLY_BLANK;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (PicoScanBegin != NULL)
|
if (PicoScanBegin != NULL)
|
||||||
skip_next_line = PicoScanBegin(scan);
|
skip_next_line = PicoScanBegin(DrawScanline);
|
||||||
|
|
||||||
// Draw screen:
|
// Draw screen:
|
||||||
BackFill(Pico.video.reg[7], sh|as);
|
BackFill(Pico.video.reg[7], sh|as);
|
||||||
|
@ -1382,11 +1375,32 @@ PICO_INTERNAL int PicoLine(int scan)
|
||||||
FinalizeLine(sh);
|
FinalizeLine(sh);
|
||||||
|
|
||||||
if (PicoScanEnd != NULL)
|
if (PicoScanEnd != NULL)
|
||||||
PicoScanEnd(scan);
|
PicoScanEnd(DrawScanline);
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PicoDrawSync(int to, int blank_last_line)
|
||||||
|
{
|
||||||
|
for (; DrawScanline < to; DrawScanline++)
|
||||||
|
{
|
||||||
|
#if !CAN_HANDLE_240_LINES
|
||||||
|
if (DrawScanline >= 224) break;
|
||||||
|
#endif
|
||||||
|
PicoLine();
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !CAN_HANDLE_240_LINES
|
||||||
|
if (DrawScanline >= 224) DrawScanline = 240, return;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// last line
|
||||||
|
if (DrawScanline <= to)
|
||||||
|
{
|
||||||
|
if (blank_last_line)
|
||||||
|
DrawBlankedLine();
|
||||||
|
else PicoLine();
|
||||||
|
DrawScanline++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void PicoDrawSetColorFormat(int which)
|
void PicoDrawSetColorFormat(int which)
|
||||||
{
|
{
|
||||||
|
|
16
Pico/Draw.s
16
Pico/Draw.s
|
@ -11,7 +11,7 @@
|
||||||
.extern Pico
|
.extern Pico
|
||||||
.extern PicoOpt
|
.extern PicoOpt
|
||||||
.extern HighCol
|
.extern HighCol
|
||||||
.extern Scanline
|
.extern DrawScanline
|
||||||
.extern HighSprZ
|
.extern HighSprZ
|
||||||
.extern rendstatus
|
.extern rendstatus
|
||||||
.extern DrawLineDest
|
.extern DrawLineDest
|
||||||
|
@ -316,7 +316,7 @@ DrawLayer:
|
||||||
ldreqb r12, [r11, #2]
|
ldreqb r12, [r11, #2]
|
||||||
ldrneb r12, [r11, #4]
|
ldrneb r12, [r11, #4]
|
||||||
|
|
||||||
ldr r2, =Scanline @ trying to make good use of pipeline here
|
ldr r2, =DrawScanline @ trying to make good use of pipeline here
|
||||||
ldr lr, =(Pico+0x10000) @ lr=Pico.vram
|
ldr lr, =(Pico+0x10000) @ lr=Pico.vram
|
||||||
|
|
||||||
moveq r12, r12, lsl #10
|
moveq r12, r12, lsl #10
|
||||||
|
@ -330,7 +330,7 @@ DrawLayer:
|
||||||
mov r4, r8, lsr #8 @ pvid->reg[13]
|
mov r4, r8, lsr #8 @ pvid->reg[13]
|
||||||
mov r4, r4, lsl #10 @ htab=pvid->reg[13]<<9; (halfwords)
|
mov r4, r4, lsl #10 @ htab=pvid->reg[13]<<9; (halfwords)
|
||||||
tst r7, #2
|
tst r7, #2
|
||||||
addne r4, r4, r2, lsl #2 @ htab+=Scanline<<1; // Offset by line
|
addne r4, r4, r2, lsl #2 @ htab+=DrawScanline<<1; // Offset by line
|
||||||
tst r7, #1
|
tst r7, #1
|
||||||
biceq r4, r4, #0x1f @ htab&=~0xf; // Offset by tile
|
biceq r4, r4, #0x1f @ htab&=~0xf; // Offset by tile
|
||||||
add r4, r4, r0, lsl #1 @ htab+=plane
|
add r4, r4, r0, lsl #1 @ htab+=plane
|
||||||
|
@ -513,7 +513,7 @@ DrawLayer:
|
||||||
bic r8, r8, #0x3fc00000
|
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]|tilex[21:0])
|
||||||
|
|
||||||
ldr r4, =Scanline
|
ldr r4, =DrawScanline
|
||||||
orr r5, r1, r10, lsl #24
|
orr r5, r1, r10, lsl #24
|
||||||
ldr r4, [r4]
|
ldr r4, [r4]
|
||||||
sub r1, r3, #1
|
sub r1, r3, #1
|
||||||
|
@ -690,7 +690,7 @@ DrawLayer:
|
||||||
movne r7, r7, lsl #5
|
movne r7, r7, lsl #5
|
||||||
|
|
||||||
@ Find the line in the name table
|
@ Find the line in the name table
|
||||||
add r2, r7, r2, lsl #22 @ r2=(vscroll+(Scanline<<1))<<21 (11 bits);
|
add r2, r7, r2, lsl #22 @ r2=(vscroll+(DrawScanline<<1))<<21 (11 bits);
|
||||||
orr r1, r1, #0x80000000
|
orr r1, r1, #0x80000000
|
||||||
and r2, r2, r1, ror #10 @ &((ymask<<1)|1)<<21;
|
and r2, r2, r1, ror #10 @ &((ymask<<1)|1)<<21;
|
||||||
mov r2, r2, lsr #21
|
mov r2, r2, lsr #21
|
||||||
|
@ -1097,7 +1097,7 @@ DrawSprite:
|
||||||
|
|
||||||
orr r8, r2, r1, lsl #4
|
orr r8, r2, r1, lsl #4
|
||||||
ldr r3, [r0] @ sprite[0]
|
ldr r3, [r0] @ sprite[0]
|
||||||
ldr r7, =Scanline
|
ldr r7, =DrawScanline
|
||||||
mov r6, r3, lsr #28
|
mov r6, r3, lsr #28
|
||||||
sub r6, r6, #1 @ r6=width-1 (inc later)
|
sub r6, r6, #1 @ r6=width-1 (inc later)
|
||||||
mov r5, r3, lsr #24
|
mov r5, r3, lsr #24
|
||||||
|
@ -1107,7 +1107,7 @@ DrawSprite:
|
||||||
|
|
||||||
ldr r7, [r7]
|
ldr r7, [r7]
|
||||||
ldr r9, [r0, #4]
|
ldr r9, [r0, #4]
|
||||||
sub r7, r7, r4, asr #16 @ r7=row=Scanline-sy
|
sub r7, r7, r4, asr #16 @ r7=row=DrawScanline-sy
|
||||||
|
|
||||||
mov r2, r9, asr #16 @ r2=sx
|
mov r2, r9, asr #16 @ r2=sx
|
||||||
mov r9, r9, lsl #16
|
mov r9, r9, lsl #16
|
||||||
|
@ -1266,7 +1266,7 @@ DrawWindow:
|
||||||
stmfd sp!, {r4-r11,lr}
|
stmfd sp!, {r4-r11,lr}
|
||||||
|
|
||||||
ldr r11, =(Pico+0x22228) @ Pico.video
|
ldr r11, =(Pico+0x22228) @ Pico.video
|
||||||
ldr r10, =Scanline
|
ldr r10, =DrawScanline
|
||||||
ldrb r12, [r11, #3] @ pvid->reg[3]
|
ldrb r12, [r11, #3] @ pvid->reg[3]
|
||||||
|
|
||||||
ldr r10, [r10]
|
ldr r10, [r10]
|
||||||
|
|
|
@ -424,6 +424,7 @@ static int PicoFrameSimple(void)
|
||||||
if (!(PicoOpt&POPT_ALT_RENDERER))
|
if (!(PicoOpt&POPT_ALT_RENDERER))
|
||||||
{
|
{
|
||||||
// Draw the screen
|
// Draw the screen
|
||||||
|
#if 0
|
||||||
#if CAN_HANDLE_240_LINES
|
#if CAN_HANDLE_240_LINES
|
||||||
if (pv->reg[1]&8) {
|
if (pv->reg[1]&8) {
|
||||||
for (y=0;y<240;y++) PicoLine(y);
|
for (y=0;y<240;y++) PicoLine(y);
|
||||||
|
@ -432,6 +433,7 @@ static int PicoFrameSimple(void)
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
for (y=0;y<224;y++) PicoLine(y);
|
for (y=0;y<224;y++) PicoLine(y);
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else PicoFrameFull();
|
else PicoFrameFull();
|
||||||
|
|
|
@ -167,7 +167,6 @@ void vidConvCpyRGB565(void *to, void *from, int pixels);
|
||||||
#define PDRAW_SONIC_MODE (1<<5) // mid-frame palette changes for 8bit renderer
|
#define PDRAW_SONIC_MODE (1<<5) // mid-frame palette changes for 8bit renderer
|
||||||
#define PDRAW_PLANE_HI_PRIO (1<<6) // have layer with all hi prio tiles (mk3)
|
#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_SHHI_DONE (1<<7) // layer sh/hi already processed
|
||||||
#define PDRAW_EARLY_BLANK (1<<8) // blanking enabled at the start of prev line
|
|
||||||
extern int rendstatus;
|
extern int rendstatus;
|
||||||
extern unsigned short HighPal[0x100];
|
extern unsigned short HighPal[0x100];
|
||||||
|
|
||||||
|
|
|
@ -73,7 +73,7 @@ static int PicoFrameHints(void)
|
||||||
// This is to make active scan longer (needed for Double Dragon 2, mainly)
|
// This is to make active scan longer (needed for Double Dragon 2, mainly)
|
||||||
CPUS_RUN(CYCLES_M68K_ASD, CYCLES_S68K_ASD);
|
CPUS_RUN(CYCLES_M68K_ASD, CYCLES_S68K_ASD);
|
||||||
|
|
||||||
for (y=0;y<lines_vis;y++)
|
for (y = 0; y < lines_vis; y++)
|
||||||
{
|
{
|
||||||
Pico.m.scanline=(short)y;
|
Pico.m.scanline=(short)y;
|
||||||
|
|
||||||
|
@ -101,24 +101,15 @@ static int PicoFrameHints(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
// decide if we draw this line
|
// decide if we draw this line
|
||||||
if (!skip)
|
if (!skip && (PicoOpt & POPT_ALT_RENDERER))
|
||||||
{
|
{
|
||||||
if (PicoOpt&POPT_ALT_RENDERER) {
|
// find the right moment for frame renderer, when display is no longer blanked
|
||||||
// find the right moment for fast renderer, when display is no longer blanked
|
if ((pv->reg[1]&0x40) || y > 100) {
|
||||||
if ((pv->reg[1]&0x40) || y > 100) {
|
PicoFrameFull();
|
||||||
PicoFrameFull();
|
|
||||||
#ifdef DRAW_FINISH_FUNC
|
#ifdef DRAW_FINISH_FUNC
|
||||||
DRAW_FINISH_FUNC();
|
DRAW_FINISH_FUNC();
|
||||||
#endif
|
#endif
|
||||||
skip = 1;
|
skip = 1;
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
#if !CAN_HANDLE_240_LINES
|
|
||||||
if (y < 224)
|
|
||||||
#endif
|
|
||||||
PicoLine(y);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -147,10 +138,14 @@ static int PicoFrameHints(void)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DRAW_FINISH_FUNC
|
|
||||||
if (!skip)
|
if (!skip)
|
||||||
|
{
|
||||||
|
if (DrawScanline < y)
|
||||||
|
PicoDrawSync(y - 1, 0);
|
||||||
|
#ifdef DRAW_FINISH_FUNC
|
||||||
DRAW_FINISH_FUNC();
|
DRAW_FINISH_FUNC();
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
// V-int line (224 or 240)
|
// V-int line (224 or 240)
|
||||||
Pico.m.scanline=(short)y;
|
Pico.m.scanline=(short)y;
|
||||||
|
@ -218,7 +213,7 @@ static int PicoFrameHints(void)
|
||||||
// PAL line count might actually be 313 according to Steve Snake, but that would complicate things.
|
// PAL line count might actually be 313 according to Steve Snake, but that would complicate things.
|
||||||
lines = Pico.m.pal ? 312 : 262;
|
lines = Pico.m.pal ? 312 : 262;
|
||||||
|
|
||||||
for (y++;y<lines;y++)
|
for (y++; y < lines; y++)
|
||||||
{
|
{
|
||||||
Pico.m.scanline=(short)y;
|
Pico.m.scanline=(short)y;
|
||||||
|
|
||||||
|
|
|
@ -394,8 +394,9 @@ extern void (*PicoCartUnloadHook)(void);
|
||||||
int CM_compareRun(int cyc, int is_sub);
|
int CM_compareRun(int cyc, int is_sub);
|
||||||
|
|
||||||
// Draw.c
|
// Draw.c
|
||||||
PICO_INTERNAL int PicoLine(int scan);
|
|
||||||
PICO_INTERNAL void PicoFrameStart(void);
|
PICO_INTERNAL void PicoFrameStart(void);
|
||||||
|
void PicoDrawSync(int to, int blank_last_line);
|
||||||
|
extern int DrawScanline;
|
||||||
|
|
||||||
// Draw2.c
|
// Draw2.c
|
||||||
PICO_INTERNAL void PicoFrameFull();
|
PICO_INTERNAL void PicoFrameFull();
|
||||||
|
|
|
@ -323,14 +323,32 @@ static void CommandChange(void)
|
||||||
if (cmd&0x80) CommandDma();
|
if (cmd&0x80) CommandDma();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static __inline void DrawSync(int blank_on)
|
||||||
|
{
|
||||||
|
if (Pico.m.scanline < 224 && !(PicoOpt & POPT_ALT_RENDERER) &&
|
||||||
|
!PicoSkipFrame && DrawScanline <= Pico.m.scanline) {
|
||||||
|
elprintf(EL_ANOMALY, "sync");
|
||||||
|
PicoDrawSync(Pico.m.scanline, blank_on);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
PICO_INTERNAL_ASM void PicoVideoWrite(unsigned int a,unsigned short d)
|
PICO_INTERNAL_ASM void PicoVideoWrite(unsigned int a,unsigned short d)
|
||||||
{
|
{
|
||||||
struct PicoVideo *pvid=&Pico.video;
|
struct PicoVideo *pvid=&Pico.video;
|
||||||
|
|
||||||
|
if (Pico.m.scanline < 224)
|
||||||
|
elprintf(EL_STATUS, "PicoVideoWrite [%06x] %04x", a, d);
|
||||||
a&=0x1c;
|
a&=0x1c;
|
||||||
|
|
||||||
if (a==0x00) // Data port 0 or 2
|
if (a==0x00) // Data port 0 or 2
|
||||||
{
|
{
|
||||||
|
// try avoiding the sync..
|
||||||
|
if (Pico.m.scanline < 224 && (pvid->reg[1]&0x40) &&
|
||||||
|
!(!pvid->pending &&
|
||||||
|
((pvid->command & 0xc00000f0) == 0x40000010 && Pico.vsram[pvid->addr>>1] == d))
|
||||||
|
)
|
||||||
|
DrawSync(0);
|
||||||
|
|
||||||
if (pvid->pending) {
|
if (pvid->pending) {
|
||||||
CommandChange();
|
CommandChange();
|
||||||
pvid->pending=0;
|
pvid->pending=0;
|
||||||
|
@ -344,7 +362,7 @@ PICO_INTERNAL_ASM void PicoVideoWrite(unsigned int a,unsigned short d)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// preliminary FIFO emulation for Chaos Engine, The (E)
|
// preliminary FIFO emulation for Chaos Engine, The (E)
|
||||||
if(!(pvid->status&8) && (pvid->reg[1]&0x40) && Pico.m.scanline!=-1 && !(PicoOpt&POPT_DIS_VDP_FIFO)) // active display, accurate mode?
|
if (!(pvid->status&8) && (pvid->reg[1]&0x40) && Pico.m.scanline!=-1 && !(PicoOpt&POPT_DIS_VDP_FIFO)) // active display, accurate mode?
|
||||||
{
|
{
|
||||||
pvid->status&=~0x200; // FIFO no longer empty
|
pvid->status&=~0x200; // FIFO no longer empty
|
||||||
pvid->lwrite_cnt++;
|
pvid->lwrite_cnt++;
|
||||||
|
@ -362,8 +380,9 @@ PICO_INTERNAL_ASM void PicoVideoWrite(unsigned int a,unsigned short d)
|
||||||
|
|
||||||
if (a==0x04) // Control (command) port 4 or 6
|
if (a==0x04) // Control (command) port 4 or 6
|
||||||
{
|
{
|
||||||
if(pvid->pending)
|
if (pvid->pending)
|
||||||
{
|
{
|
||||||
|
if (d & 0x80) DrawSync(0); // only need sync for DMA
|
||||||
// Low word of command:
|
// Low word of command:
|
||||||
pvid->command&=0xffff0000;
|
pvid->command&=0xffff0000;
|
||||||
pvid->command|=d;
|
pvid->command|=d;
|
||||||
|
@ -377,24 +396,26 @@ PICO_INTERNAL_ASM void PicoVideoWrite(unsigned int a,unsigned short d)
|
||||||
// Register write:
|
// Register write:
|
||||||
int num=(d>>8)&0x1f;
|
int num=(d>>8)&0x1f;
|
||||||
int dold=pvid->reg[num];
|
int dold=pvid->reg[num];
|
||||||
|
int update_irq = 0, blank_on = 0;
|
||||||
pvid->type=0; // register writes clear command (else no Sega logo in Golden Axe II)
|
pvid->type=0; // register writes clear command (else no Sega logo in Golden Axe II)
|
||||||
if (num > 0x0a && !(pvid->reg[1]&4)) {
|
if (num > 0x0a && !(pvid->reg[1]&4)) {
|
||||||
elprintf(EL_ANOMALY, "%02x written to reg %02x in SMS mode @ %06x", d, num, SekPc);
|
elprintf(EL_ANOMALY, "%02x written to reg %02x in SMS mode @ %06x", d, num, SekPc);
|
||||||
return;
|
return;
|
||||||
} else
|
}
|
||||||
pvid->reg[num]=(unsigned char)d;
|
|
||||||
|
|
||||||
switch (num)
|
switch (num)
|
||||||
{
|
{
|
||||||
case 0x00:
|
case 0x00:
|
||||||
elprintf(EL_INTSW, "hint_onoff: %i->%i [%i] pend=%i @ %06x", (dold&0x10)>>4,
|
elprintf(EL_INTSW, "hint_onoff: %i->%i [%i] pend=%i @ %06x", (dold&0x10)>>4,
|
||||||
(d&0x10)>>4, SekCyclesDone(), (pvid->pending_ints&0x10)>>4, SekPc);
|
(d&0x10)>>4, SekCyclesDone(), (pvid->pending_ints&0x10)>>4, SekPc);
|
||||||
goto update_irq;
|
update_irq = 1;
|
||||||
|
break;
|
||||||
case 0x01:
|
case 0x01:
|
||||||
elprintf(EL_INTSW, "vint_onoff: %i->%i [%i] pend=%i @ %06x", (dold&0x20)>>5,
|
elprintf(EL_INTSW, "vint_onoff: %i->%i [%i] pend=%i @ %06x", (dold&0x20)>>5,
|
||||||
(d&0x20)>>5, SekCyclesDone(), (pvid->pending_ints&0x20)>>5, SekPc);
|
(d&0x20)>>5, SekCyclesDone(), (pvid->pending_ints&0x20)>>5, SekPc);
|
||||||
if (!(d&0x40) && SekCyclesLeft > 390) rendstatus |= PDRAW_EARLY_BLANK;
|
if (!(d&0x40) && SekCyclesLeft > 390) blank_on = 1;
|
||||||
goto update_irq;
|
update_irq = 1;
|
||||||
|
break;
|
||||||
case 0x05:
|
case 0x05:
|
||||||
if (d^dold) rendstatus |= PDRAW_SPRITES_MOVED;
|
if (d^dold) rendstatus |= PDRAW_SPRITES_MOVED;
|
||||||
break;
|
break;
|
||||||
|
@ -403,21 +424,19 @@ PICO_INTERNAL_ASM void PicoVideoWrite(unsigned int a,unsigned short d)
|
||||||
if ((d^dold)&8) Pico.m.dirtyPal = 2;
|
if ((d^dold)&8) Pico.m.dirtyPal = 2;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return;
|
DrawSync(blank_on);
|
||||||
|
pvid->reg[num]=(unsigned char)d;
|
||||||
|
if (!update_irq) return;
|
||||||
|
|
||||||
update_irq:;
|
|
||||||
#ifndef EMU_CORE_DEBUG
|
#ifndef EMU_CORE_DEBUG
|
||||||
// update IRQ level (Lemmings, Wiz 'n' Liz intro, ... )
|
// update IRQ level
|
||||||
// may break if done improperly:
|
|
||||||
// International Superstar Soccer Deluxe (crash), Street Racer (logos), Burning Force (gfx),
|
|
||||||
// Fatal Rewind (crash), Sesame Street Counting Cafe
|
|
||||||
if (!SekShouldInterrupt) // hack
|
if (!SekShouldInterrupt) // hack
|
||||||
{
|
{
|
||||||
int lines, pints, irq=0;
|
int lines, pints, irq=0;
|
||||||
lines = (pvid->reg[1] & 0x20) | (pvid->reg[0] & 0x10);
|
lines = (pvid->reg[1] & 0x20) | (pvid->reg[0] & 0x10);
|
||||||
pints = (pvid->pending_ints&lines);
|
pints = (pvid->pending_ints&lines);
|
||||||
if(pints & 0x20) irq = 6;
|
if (pints & 0x20) irq = 6;
|
||||||
else if(pints & 0x10) irq = 4;
|
else if (pints & 0x10) irq = 4;
|
||||||
SekInterrupt(irq); // update line
|
SekInterrupt(irq); // update line
|
||||||
|
|
||||||
if (irq && Pico.m.scanline!=-1) SekEndRun(24); // make it delayed
|
if (irq && Pico.m.scanline!=-1) SekEndRun(24); // make it delayed
|
||||||
|
@ -437,20 +456,17 @@ update_irq:;
|
||||||
|
|
||||||
PICO_INTERNAL_ASM unsigned int PicoVideoRead(unsigned int a)
|
PICO_INTERNAL_ASM unsigned int PicoVideoRead(unsigned int a)
|
||||||
{
|
{
|
||||||
unsigned int d=0;
|
|
||||||
|
|
||||||
a&=0x1c;
|
a&=0x1c;
|
||||||
|
|
||||||
|
|
||||||
if (a==0x00) // data port
|
if (a==0x00) // data port
|
||||||
{
|
{
|
||||||
d=VideoRead();
|
return VideoRead();
|
||||||
goto end;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (a==0x04) // control port
|
if (a==0x04) // control port
|
||||||
{
|
{
|
||||||
struct PicoVideo *pv=&Pico.video;
|
struct PicoVideo *pv=&Pico.video;
|
||||||
|
unsigned int d;
|
||||||
d=pv->status;
|
d=pv->status;
|
||||||
if (PicoOpt&POPT_ALT_RENDERER) d|=0x0020; // sprite collision (Shadow of the Beast)
|
if (PicoOpt&POPT_ALT_RENDERER) d|=0x0020; // sprite collision (Shadow of the Beast)
|
||||||
if (!(pv->reg[1]&0x40)) d|=0x0008; // set V-Blank if display is disabled
|
if (!(pv->reg[1]&0x40)) d|=0x0008; // set V-Blank if display is disabled
|
||||||
|
@ -462,7 +478,7 @@ PICO_INTERNAL_ASM unsigned int PicoVideoRead(unsigned int a)
|
||||||
pv->pending=0; // ctrl port reads clear write-pending flag (Charles MacDonald)
|
pv->pending=0; // ctrl port reads clear write-pending flag (Charles MacDonald)
|
||||||
|
|
||||||
elprintf(EL_SR, "SR read: %04x @ %06x", d, SekPc);
|
elprintf(EL_SR, "SR read: %04x @ %06x", d, SekPc);
|
||||||
goto end;
|
return d;
|
||||||
}
|
}
|
||||||
|
|
||||||
// H-counter info (based on Generator):
|
// H-counter info (based on Generator):
|
||||||
|
@ -482,9 +498,10 @@ PICO_INTERNAL_ASM unsigned int PicoVideoRead(unsigned int a)
|
||||||
// check: Sonic 3D Blast bonus, Cannon Fodder, Chase HQ II, 3 Ninjas kick back, Road Rash 3, Skitchin', Wheel of Fortune
|
// check: Sonic 3D Blast bonus, Cannon Fodder, Chase HQ II, 3 Ninjas kick back, Road Rash 3, Skitchin', Wheel of Fortune
|
||||||
if ((a&0x1c)==0x08)
|
if ((a&0x1c)==0x08)
|
||||||
{
|
{
|
||||||
unsigned int hc;
|
unsigned int hc, d;
|
||||||
|
|
||||||
if(Pico.m.scanline != -1) {
|
if (Pico.m.scanline != -1)
|
||||||
|
{
|
||||||
int lineCycles=(488-SekCyclesLeft)&0x1ff;
|
int lineCycles=(488-SekCyclesLeft)&0x1ff;
|
||||||
d=Pico.m.scanline; // V-Counter
|
d=Pico.m.scanline; // V-Counter
|
||||||
|
|
||||||
|
@ -500,9 +517,9 @@ PICO_INTERNAL_ASM unsigned int PicoVideoRead(unsigned int a)
|
||||||
}
|
}
|
||||||
|
|
||||||
if(Pico.m.pal) {
|
if(Pico.m.pal) {
|
||||||
if(d >= 0x103) d-=56; // based on Gens
|
if (d >= 0x103) d-=56; // based on Gens
|
||||||
} else {
|
} else {
|
||||||
if(d >= 0xEB) d-=6;
|
if (d >= 0xEB) d-=6;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((Pico.video.reg[12]&6) == 6) {
|
if((Pico.video.reg[12]&6) == 6) {
|
||||||
|
@ -514,10 +531,8 @@ PICO_INTERNAL_ASM unsigned int PicoVideoRead(unsigned int a)
|
||||||
elprintf(EL_HVCNT, "hv: %02x %02x (%i) @ %06x", hc, d, SekCyclesDone(), SekPc);
|
elprintf(EL_HVCNT, "hv: %02x %02x (%i) @ %06x", hc, d, SekCyclesDone(), SekPc);
|
||||||
d&=0xff; d<<=8;
|
d&=0xff; d<<=8;
|
||||||
d|=hc;
|
d|=hc;
|
||||||
goto end;
|
return d;
|
||||||
}
|
}
|
||||||
|
|
||||||
end:
|
return 0;
|
||||||
|
|
||||||
return d;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1833,12 +1833,7 @@ int YM2612Write_(unsigned int a, unsigned int v)
|
||||||
ret = OPNWriteReg(addr, v);
|
ret = OPNWriteReg(addr, v);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
if(ret) {
|
|
||||||
extern int Scanline;
|
|
||||||
dprintf("ymw [%i]", Scanline);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue