newppu: refine mmc3 hblank timing even more, fixes crystalis and kirby
This commit is contained in:
parent
2930675eac
commit
29350a7bdd
40
src/ppu.cpp
40
src/ppu.cpp
|
@ -340,6 +340,7 @@ int FCEUPPU_GetAttr(int ntnum, int xt, int yt) {
|
||||||
//new ppu-----
|
//new ppu-----
|
||||||
void FFCEUX_PPUWrite_Default(uint32 A, uint8 V) {
|
void FFCEUX_PPUWrite_Default(uint32 A, uint8 V) {
|
||||||
uint32 tmp = A;
|
uint32 tmp = A;
|
||||||
|
|
||||||
if(tmp>=0x3F00)
|
if(tmp>=0x3F00)
|
||||||
{
|
{
|
||||||
// hmmm....
|
// hmmm....
|
||||||
|
@ -361,6 +362,7 @@ void FFCEUX_PPUWrite_Default(uint32 A, uint8 V) {
|
||||||
|
|
||||||
uint8 FFCEUX_PPURead_Default(uint32 A) {
|
uint8 FFCEUX_PPURead_Default(uint32 A) {
|
||||||
uint32 tmp = A;
|
uint32 tmp = A;
|
||||||
|
|
||||||
if(tmp<0x2000)
|
if(tmp<0x2000)
|
||||||
{
|
{
|
||||||
return VPage[tmp>>10][tmp];
|
return VPage[tmp>>10][tmp];
|
||||||
|
@ -1977,23 +1979,17 @@ int FCEUX_PPU_Loop(int skip) {
|
||||||
}
|
}
|
||||||
oamcounts[scanslot] = oamcount;
|
oamcounts[scanslot] = oamcount;
|
||||||
|
|
||||||
|
//FV is clocked by the PPU's horizontal blanking impulse, and therefore will increment every scanline.
|
||||||
|
//well, according to (which?) tests, maybe at the end of hblank.
|
||||||
|
//but, according to what it took to get crystalis working, it is at the beginning of hblank.
|
||||||
|
if(PPUON && sl != 0)
|
||||||
|
ppur.increment_vs();
|
||||||
|
|
||||||
//todo - think about clearing oams to a predefined value to force deterministic behavior
|
//todo - think about clearing oams to a predefined value to force deterministic behavior
|
||||||
|
|
||||||
//fetch sprite patterns
|
//fetch sprite patterns
|
||||||
for(int s=0;s<8;s++) {
|
for(int s=0;s<8;s++) {
|
||||||
|
|
||||||
if(s==1 && sl != 0) {
|
|
||||||
//begin hblank!
|
|
||||||
//the screen is always behind the ppu operation so we need to wait a little longer before triggering it
|
|
||||||
//NOTE: SMB3 is very sensitive about this timing, for the statusbar
|
|
||||||
if(PPUON) {
|
|
||||||
if(GameHBIRQHook)
|
|
||||||
GameHBIRQHook();
|
|
||||||
} else {
|
|
||||||
int zzz=9;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8* oam = oams[scanslot][s];
|
uint8* oam = oams[scanslot][s];
|
||||||
uint32 line = yp - oam[0];
|
uint32 line = yp - oam[0];
|
||||||
if(oam[2]&0x80) //vflip
|
if(oam[2]&0x80) //vflip
|
||||||
|
@ -2019,6 +2015,18 @@ int FCEUX_PPU_Loop(int skip) {
|
||||||
|
|
||||||
//garbage nametable fetches
|
//garbage nametable fetches
|
||||||
runppu(kFetchTime);
|
runppu(kFetchTime);
|
||||||
|
|
||||||
|
if(((PPU[0]&0x38)!=0x18) && s == 2 && SpriteON ) {
|
||||||
|
//(The MMC3 scanline counter is based entirely on PPU A12, triggered on rising edges (after the line remains low for a sufficiently long period of time))
|
||||||
|
//http://nesdevwiki.org/wiki/index.php/Nintendo_MMC3
|
||||||
|
//test cases for timing: SMB3, Crystalis
|
||||||
|
//crystalis requires deferring this til somewhere in sprite [1,3]
|
||||||
|
//kirby requires deferring this til somewhere in sprite [2,5..
|
||||||
|
if(PPUON && GameHBIRQHook) {
|
||||||
|
GameHBIRQHook();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
runppu(kFetchTime);
|
runppu(kFetchTime);
|
||||||
|
|
||||||
//pattern table fetches
|
//pattern table fetches
|
||||||
|
@ -2029,6 +2037,7 @@ int FCEUX_PPU_Loop(int skip) {
|
||||||
oam[5] = FFCEUX_PPURead(RefreshAddr);
|
oam[5] = FFCEUX_PPURead(RefreshAddr);
|
||||||
runppu(kFetchTime);
|
runppu(kFetchTime);
|
||||||
|
|
||||||
|
|
||||||
//hflip
|
//hflip
|
||||||
if(!(oam[2]&0x40)) {
|
if(!(oam[2]&0x40)) {
|
||||||
oam[4] = bitrevlut[oam[4]];
|
oam[4] = bitrevlut[oam[4]];
|
||||||
|
@ -2036,12 +2045,7 @@ int FCEUX_PPU_Loop(int skip) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// FV is clocked by the PPU's horizontal blanking impulse, and therefore will increment every scanline.
|
|
||||||
//well, according to my tests, maybe at the end of hblank.
|
|
||||||
//but where is the end of hblank?
|
|
||||||
//well, i imagine it needs to be before the BG fetches for the next line.
|
|
||||||
if(PPUON && sl != 0)
|
|
||||||
ppur.increment_vs();
|
|
||||||
|
|
||||||
//so.. this is the end of hblank. latch horizontal scroll values
|
//so.. this is the end of hblank. latch horizontal scroll values
|
||||||
if(PPUON && sl != 0)
|
if(PPUON && sl != 0)
|
||||||
|
|
Loading…
Reference in New Issue