mirror of
https://github.com/RaySollium99/picodrive.git
synced 2025-09-05 15:27:46 -04:00
PicoVideoRead optimization
git-svn-id: file:///home/notaz/opt/svn/PicoDrive@511 be3aeb3a-fb24-0410-a615-afba39da0efa
This commit is contained in:
parent
2aa27095f2
commit
9761a7d0d4
10 changed files with 90 additions and 64 deletions
|
@ -344,9 +344,9 @@ PICO_INTERNAL_ASM u32 PicoRead8(u32 a)
|
|||
log_io(a, 8, 0);
|
||||
if ((a&0xff4000)==0xa00000) { d=z80Read8(a); goto end; } // Z80 Ram
|
||||
|
||||
if ((a&0xe700e0)==0xc00000) // VDP
|
||||
d=PicoVideoRead(a);
|
||||
else d=OtherRead16(a&~1, 8);
|
||||
if ((a&0xe700e0)==0xc00000) { d=PicoVideoRead8(a); goto end; } // VDP
|
||||
|
||||
d=OtherRead16(a&~1, 8);
|
||||
if ((a&1)==0) d>>=8;
|
||||
|
||||
end:
|
||||
|
|
|
@ -415,13 +415,7 @@ m_read8_vdp:
|
|||
tst r0, #0x70000
|
||||
tsteq r0, #0x000e0
|
||||
bxne lr @ invalid read
|
||||
stmfd sp!,{r0,lr}
|
||||
bic r0, r0, #1
|
||||
bl PicoVideoRead
|
||||
ldmfd sp!,{r1,lr}
|
||||
tst r1, #1
|
||||
moveq r0, r0, lsr #8
|
||||
bx lr
|
||||
b PicoVideoRead8
|
||||
|
||||
m_read8_ram:
|
||||
ldr r1, =Pico
|
||||
|
|
|
@ -469,7 +469,9 @@ m_read8_vdp:
|
|||
andi $t1, $a0, 0xe0
|
||||
or $t0, $t1
|
||||
bnez $t0, m_read_null # invalid address
|
||||
m_read8_call16 PicoVideoRead
|
||||
nop
|
||||
j PicoVideoRead8
|
||||
nop
|
||||
|
||||
m_read8_ram:
|
||||
lui $t0, %hi(Pico)
|
||||
|
|
|
@ -218,7 +218,8 @@ PICO_INTERNAL int CheckDMA(void)
|
|||
if(Pico.video.reg[12] & 1) dma_op |= 4; // 40 cell mode?
|
||||
if(!(Pico.video.status&8)&&(Pico.video.reg[1]&0x40)) dma_op|=8; // active display?
|
||||
xfers_can = dma_timings[dma_op];
|
||||
if(xfers <= xfers_can) {
|
||||
if(xfers <= xfers_can)
|
||||
{
|
||||
if(dma_op&2) Pico.video.status&=~2; // dma no longer busy
|
||||
else {
|
||||
burn = xfers * dma_bsycles[dma_op] >> 8; // have to be approximate because can't afford division..
|
||||
|
|
|
@ -22,8 +22,7 @@ static u32 PicoReadPico8(u32 a)
|
|||
a&=0xffffff;
|
||||
|
||||
if ((a&0xfffff0)==0xc00000) { // VDP
|
||||
d=PicoVideoRead(a);
|
||||
if ((a&1)==0) d>>=8;
|
||||
d=PicoVideoRead8(a);
|
||||
goto end;
|
||||
}
|
||||
|
||||
|
|
|
@ -35,10 +35,10 @@
|
|||
static int PicoFrameHints(void)
|
||||
{
|
||||
struct PicoVideo *pv=&Pico.video;
|
||||
int lines, y, lines_vis = 224, line_sample, skip;
|
||||
int lines, y, lines_vis = 224, line_sample, skip, vcnt_wrap;
|
||||
int hint; // Hint counter
|
||||
|
||||
Pico.m.scanline = 0;
|
||||
pv->v_counter = Pico.m.scanline = 0;
|
||||
|
||||
if ((PicoOpt&POPT_ALT_RENDERER) && !PicoSkipFrame && (pv->reg[1]&0x40)) { // fast rend., display enabled
|
||||
// draw a frame just after vblank in alternative render mode
|
||||
|
@ -53,7 +53,7 @@ static int PicoFrameHints(void)
|
|||
|
||||
if (Pico.m.pal) {
|
||||
line_sample = 68;
|
||||
if(pv->reg[1]&8) lines_vis = 240;
|
||||
if (pv->reg[1]&8) lines_vis = 240;
|
||||
} else {
|
||||
line_sample = 93;
|
||||
}
|
||||
|
@ -75,7 +75,12 @@ static int PicoFrameHints(void)
|
|||
|
||||
for (y = 0; y < lines_vis; y++)
|
||||
{
|
||||
Pico.m.scanline = y;
|
||||
pv->v_counter = Pico.m.scanline = y;
|
||||
if ((pv->reg[12]&6) == 6) { // interlace mode 2
|
||||
pv->v_counter <<= 1;
|
||||
pv->v_counter |= pv->v_counter >> 8;
|
||||
pv->v_counter &= 0xff;
|
||||
}
|
||||
|
||||
// VDP FIFO
|
||||
pv->lwrite_cnt -= 12;
|
||||
|
@ -138,6 +143,11 @@ static int PicoFrameHints(void)
|
|||
#endif
|
||||
}
|
||||
|
||||
// V-int line (224 or 240)
|
||||
Pico.m.scanline = y;
|
||||
pv->v_counter = 0xe0; // bad for 240 mode
|
||||
if ((pv->reg[12]&6) == 6) pv->v_counter = 0xc1;
|
||||
|
||||
if (!skip)
|
||||
{
|
||||
if (DrawScanline < y)
|
||||
|
@ -147,9 +157,6 @@ static int PicoFrameHints(void)
|
|||
#endif
|
||||
}
|
||||
|
||||
// V-int line (224 or 240)
|
||||
Pico.m.scanline = y;
|
||||
|
||||
// VDP FIFO
|
||||
pv->lwrite_cnt=0;
|
||||
Pico.video.status|=0x200;
|
||||
|
@ -168,7 +175,6 @@ static int PicoFrameHints(void)
|
|||
if (pv->reg[0]&0x10) SekInterrupt(4);
|
||||
}
|
||||
|
||||
// V-Interrupt:
|
||||
pv->status|=0x08; // go into vblank
|
||||
pv->pending_ints|=0x20;
|
||||
|
||||
|
@ -212,10 +218,16 @@ static int PicoFrameHints(void)
|
|||
|
||||
// PAL line count might actually be 313 according to Steve Snake, but that would complicate things.
|
||||
lines = Pico.m.pal ? 312 : 262;
|
||||
vcnt_wrap = Pico.m.pal ? 0x103 : 0xEB; // based on Gens
|
||||
|
||||
for (y++; y < lines; y++)
|
||||
{
|
||||
Pico.m.scanline = y;
|
||||
pv->v_counter = Pico.m.scanline = y;
|
||||
if (y >= vcnt_wrap)
|
||||
pv->v_counter -= Pico.m.pal ? 56 : 6;
|
||||
if ((pv->reg[12]&6) == 6)
|
||||
pv->v_counter = (pv->v_counter << 1) | 1;
|
||||
pv->v_counter &= 0xff;
|
||||
|
||||
PAD_DELAY
|
||||
#ifdef PICO_CD
|
||||
|
|
|
@ -237,7 +237,8 @@ struct PicoVideo
|
|||
int status; // Status bits
|
||||
unsigned char pending_ints; // pending interrupts: ??VH????
|
||||
signed char lwrite_cnt; // VDP write count during active display line
|
||||
unsigned char pad[0x12];
|
||||
unsigned short v_counter; // V-counter
|
||||
unsigned char pad[0x10];
|
||||
};
|
||||
|
||||
struct PicoMisc
|
||||
|
@ -504,6 +505,7 @@ void ym2612_unpack_state(void);
|
|||
// VideoPort.c
|
||||
PICO_INTERNAL_ASM void PicoVideoWrite(unsigned int a,unsigned short d);
|
||||
PICO_INTERNAL_ASM unsigned int PicoVideoRead(unsigned int a);
|
||||
PICO_INTERNAL_ASM unsigned int PicoVideoRead8(unsigned int a);
|
||||
extern int (*PicoDmaHook)(unsigned int source, int len, unsigned short **srcp, unsigned short **limitp);
|
||||
|
||||
// Misc.c
|
||||
|
|
|
@ -449,24 +449,19 @@ PICO_INTERNAL_ASM unsigned int PicoVideoRead(unsigned int a)
|
|||
{
|
||||
a&=0x1c;
|
||||
|
||||
if (a==0x00) // data port
|
||||
{
|
||||
return VideoRead();
|
||||
}
|
||||
|
||||
if (a==0x04) // control port
|
||||
{
|
||||
struct PicoVideo *pv=&Pico.video;
|
||||
unsigned int d;
|
||||
d=pv->status;
|
||||
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 (PicoOpt&POPT_ALT_RENDERER) d|=0x0020; // sprite collision (Shadow of the Beast)
|
||||
if (SekCyclesLeft < 84+4) d|=0x0004; // H-Blank (Sonic3 vs)
|
||||
|
||||
d|=(pv->pending_ints&0x20)<<2; // V-int pending?
|
||||
d |= ((pv->reg[1]&0x40)^0x40) >> 3; // set V-Blank if display is disabled
|
||||
d |= (pv->pending_ints&0x20)<<2; // V-int pending?
|
||||
if (d&0x100) pv->status&=~0x100; // FIFO no longer full
|
||||
|
||||
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);
|
||||
return d;
|
||||
|
@ -489,32 +484,60 @@ 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
|
||||
if ((a&0x1c)==0x08)
|
||||
{
|
||||
unsigned int hc, d;
|
||||
unsigned int d;
|
||||
int lineCycles;
|
||||
|
||||
lineCycles = (488-SekCyclesLeft)&0x1ff;
|
||||
d = Pico.m.scanline; // V-Counter
|
||||
|
||||
if (Pico.video.reg[12]&1)
|
||||
hc=hcounts_40[lineCycles];
|
||||
else hc=hcounts_32[lineCycles];
|
||||
d = hcounts_40[lineCycles];
|
||||
else d = hcounts_32[lineCycles];
|
||||
|
||||
if (Pico.m.pal) {
|
||||
if (d >= 0x103) d-=56; // based on Gens
|
||||
} else {
|
||||
if (d >= 0xEB) d-=6;
|
||||
}
|
||||
elprintf(EL_HVCNT, "hv: %02x %02x (%i) @ %06x", d, Pico.video.v_counter, SekCyclesDone(), SekPc);
|
||||
return d | (Pico.video.v_counter << 8);
|
||||
}
|
||||
|
||||
if ((Pico.video.reg[12]&6) == 6) {
|
||||
// interlace mode 2 (Combat Cars (UE) [!])
|
||||
d <<= 1;
|
||||
if (d&0xf00) d|= 1;
|
||||
}
|
||||
|
||||
elprintf(EL_HVCNT, "hv: %02x %02x (%i) @ %06x", hc, d, SekCyclesDone(), SekPc);
|
||||
d&=0xff; d<<=8;
|
||||
d|=hc;
|
||||
return d;
|
||||
if (a==0x00) // data port
|
||||
{
|
||||
return VideoRead();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned int PicoVideoRead8(unsigned int a)
|
||||
{
|
||||
unsigned int d;
|
||||
a&=0x1d;
|
||||
|
||||
switch (a)
|
||||
{
|
||||
case 0: return VideoRead() >> 8;
|
||||
case 1: return VideoRead() & 0xff;
|
||||
case 4: // control port/status reg
|
||||
d = Pico.video.status >> 8;
|
||||
if (d&1) Pico.video.status&=~0x100; // FIFO no longer full
|
||||
Pico.video.pending = 0;
|
||||
elprintf(EL_SR, "SR read (h): %02x @ %06x", d, SekPc);
|
||||
return d;
|
||||
case 5:
|
||||
d = Pico.video.status & 0xff;
|
||||
//if (PicoOpt&POPT_ALT_RENDERER) d|=0x0020; // sprite collision (Shadow of the Beast)
|
||||
d |= ((Pico.video.reg[1]&0x40)^0x40) >> 3; // set V-Blank if display is disabled
|
||||
d |= (Pico.video.pending_ints&0x20)<<2; // V-int pending?
|
||||
if (SekCyclesLeft < 84+4) d |= 4; // H-Blank
|
||||
Pico.video.pending = 0;
|
||||
elprintf(EL_SR, "SR read (l): %02x @ %06x", d, SekPc);
|
||||
return d;
|
||||
case 8: // hv counter
|
||||
elprintf(EL_HVCNT, "vcounter: %02x (%i) @ %06x", Pico.video.v_counter, SekCyclesDone(), SekPc);
|
||||
return Pico.video.v_counter;
|
||||
case 9:
|
||||
d = (488-SekCyclesLeft)&0x1ff;
|
||||
if (Pico.video.reg[12]&1)
|
||||
d = hcounts_40[d];
|
||||
else d = hcounts_32[d];
|
||||
elprintf(EL_HVCNT, "hcounter: %02x (%i) @ %06x", d, SekCyclesDone(), SekPc);
|
||||
return d;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -501,10 +501,8 @@ u32 PicoReadM68k8(u32 a)
|
|||
case 0xd0>>1: case 0xd2>>1: case 0xd4>>1: case 0xd6>>1:
|
||||
case 0xd8>>1: case 0xda>>1: case 0xdc>>1: case 0xde>>1:
|
||||
// VDP
|
||||
if ((a&0xe700e0)==0xc00000) {
|
||||
d=PicoVideoRead(a);
|
||||
if ((a&1)==0) d>>=8;
|
||||
}
|
||||
if ((a&0xe700e0)==0xc00000)
|
||||
d=PicoVideoRead8(a);
|
||||
break;
|
||||
case 0xe0>>1: case 0xe2>>1: case 0xe4>>1: case 0xe6>>1:
|
||||
case 0xe8>>1: case 0xea>>1: case 0xec>>1: case 0xee>>1:
|
||||
|
|
|
@ -126,6 +126,7 @@ m_s68k_decode_write_table:
|
|||
.extern z80Read8
|
||||
.extern OtherRead16
|
||||
.extern PicoVideoRead
|
||||
.extern PicoVideoRead8
|
||||
.extern Read_CDC_Host
|
||||
.extern m68k_reg_write8
|
||||
.extern OtherWrite16
|
||||
|
@ -611,13 +612,7 @@ m_m68k_read8_vdp:
|
|||
tst r0, #0x70000
|
||||
tsteq r0, #0x000e0
|
||||
bxne lr @ invalid read
|
||||
stmfd sp!,{r0,lr}
|
||||
bic r0, r0, #1
|
||||
bl PicoVideoRead @ TODO: implement it in asm
|
||||
ldmfd sp!,{r1,lr}
|
||||
tst r1, #1
|
||||
moveq r0, r0, lsr #8
|
||||
bx lr
|
||||
b PicoVideoRead8
|
||||
|
||||
|
||||
m_m68k_read8_ram:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue