It is currently Sun Oct 22, 2017 12:18 pm

All times are UTC - 7 hours





Post new topic Reply to topic  [ 12 posts ] 
Author Message
PostPosted: Sat Feb 21, 2015 11:20 am 
Offline
User avatar

Joined: Mon Dec 29, 2014 1:46 pm
Posts: 710
Location: New York, NY
As shown below, my emulator makes it to the Stage 1 - 1 screen, the player can control the sprayer (left, right and fire works) and the music and sound effects work. But, the Stage 1 - 1 message never vanishes and no enemies ever appear.

Image

I carefully implemented the PPU sprite evaluation incorporating the ideas from these links: Obscure details of OAMADDR and Where to start DMA. But, that was not enough.

On even cycles (65--256), my code does this:

Code:
            int address = (n + oamAddress) << 2;
            spriteY = primaryOAM[0xFF & (address + m)];
            spriteT = primaryOAM[0xFF & (address + m + 1)];
            spriteA = primaryOAM[0xFF & (address + m + 2)];
            spriteX = primaryOAM[0xFF & (address + m + 3)];


On odd cycles, it does this:

Code:
            if (secondaryOamWritesEnabled) {
              int address = s << 2;
              secondaryOAM[address] = spriteY;
              if (!(spriteY > scanline
                  || spriteY + spriteBottomOffset < scanline)) {
                if (n == 0) {
                  sprite0Used = true;
                }               
                secondaryOAM[address + 1] = spriteT;
                secondaryOAM[address + 2] = spriteA;
                secondaryOAM[address + 3] = spriteX;
                if (++s == 8) {
                  secondaryOamWritesEnabled = false;                 
                }
              }
              n = 0x3F & (n + 1);
              if (n == 0) {
                oamTransferCompleted = true;
              }
            } else {
              if (!(spriteY > scanline
                  || spriteY + spriteBottomOffset < scanline)) {
                spriteOverflowDetected = true;
                for(int k = 0; k < 4; k++) {
                  m = 0x03 & (m + 1);
                  if (m == 0) {
                    n = 0x3F & (n + 1);
                    if (n == 0) {
                      oamTransferCompleted = true;
                      break;
                    }
                  }
                }
              } else {
                m = 0x03 & (m + 1);
                n = 0x3F & (n + 1);
                if (n == 0) {
                  oamTransferCompleted = true;
                }
              }
            }
          }


Those pieces of code execute while oamTransferCompleted is false. n, m and s are initialized to 0. secondaryOamWritesEnabled is initialized to true. spriteBottomOffset is either 8 or 16 depending on sprite size mode.

oamAddress is set to 0 during each of ticks 257--320 (the sprite tile loading interval) of the pre-render and visible scanlines.

At cycle 257, the PPU status register ($2002) is updated with the value of spriteOverflowDetected. I found that if the code updates the status register during cycles 65--256, some games had issues. For instance, in Battletoads level 2, the player could not injure the yellow venus fly trap creatures and vice versa; the player and the enemy would pass through each other.


Top
 Profile  
 
PostPosted: Sun Feb 22, 2015 7:00 am 
Offline
Formerly Fx3
User avatar

Joined: Fri Nov 12, 2004 4:59 pm
Posts: 3064
Location: Brazil
EDIT: fixed the problem. According to Nintendulator:
Quote:
If Sprite address is not zero at the beginning of the pre-render scanline, then copy the contents of its 8-byte page into the first 8 bytes.

B00M, working like a charm. :)
---------------------------------------
Hehe, a Sachen game. :) In my emulator, it's almost the same problem. :)
I can move the shooter (&shoot), but that's it. If your sprite evaluation code is wrong, mine is wrong too. ^_^;;


Attachments:
Huge Insect (Sachen) (Unreleased) 000.bmp
Huge Insect (Sachen) (Unreleased) 000.bmp [ 1.58 MiB | Viewed 2340 times ]
Top
 Profile  
 
PostPosted: Sun Feb 22, 2015 9:13 am 
Offline
User avatar

Joined: Mon Dec 29, 2014 1:46 pm
Posts: 710
Location: New York, NY
I missed this on the wiki:

Quote:
On the 2C02, writes to OAMADDR reliably corrupt OAM. This can then be worked around by writing all 256 bytes of OAM. It is also the case that if OAMADDR is not less than eight when rendering starts, the eight bytes starting at OAMADDR & 0xF8 are copied to the first eight bytes of OAM; it seems likely that this is related. The former bug is known to have been fixed in the 2C07; the latter is believed to be.


And, yes, that solved the problem:

Code:
if (oamAddress >= 8) {
  for(int i = 0; i < 8; i++) {
    primaryOAM[i] = primaryOAM[(oamAddress & 0xF8) + i];
  }
}


Thanks.


Top
 Profile  
 
PostPosted: Sun Feb 22, 2015 9:42 am 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 19115
Location: NE Indiana, USA (NTSC)
I just wonder what the h███ Sachen engineers were thinking when they decided to rely on this bug.


Top
 Profile  
 
PostPosted: Sun Feb 22, 2015 10:16 am 
Offline
Formerly Fx3
User avatar

Joined: Fri Nov 12, 2004 4:59 pm
Posts: 3064
Location: Brazil
No no... there's a japanese Capcom game that's glitched if such thing isn't emulated...

but... what's its name? A side scroller, a guy with a sword and a shield walking in a city in background, night time.
After the title screen, a map is displayed, much like Ghost'n Gobblins.


Top
 Profile  
 
PostPosted: Sun Feb 22, 2015 12:31 pm 
Offline

Joined: Sun Apr 13, 2008 11:12 am
Posts: 6294
Location: Seattle
tepples wrote:
I just wonder what the h███ Sachen engineers were thinking when they decided to rely on this bug.
"Free sprite rotation!"
1- Assuming OAMADDR & 7 = 0, the first two entries you upload always become Sprite 0 and Sprite 1
→ You don't need to restructure your OAM page at all
2- They probably didn't notice the loss of the two sprites that were obliterated by the copy.


Zepper: One of the latter Ironsword games?


Top
 Profile  
 
PostPosted: Sun Feb 22, 2015 12:57 pm 
Offline
Formerly Fx3
User avatar

Joined: Fri Nov 12, 2004 4:59 pm
Posts: 3064
Location: Brazil
Tatakai no Banka (J).

It's glitched if sprite rotation isn't emulated.


Attachments:
Tatakai no Banka (Japan) 002.bmp
Tatakai no Banka (Japan) 002.bmp [ 720.05 KiB | Viewed 2285 times ]
Tatakai no Banka (Japan) 001.bmp
Tatakai no Banka (Japan) 001.bmp [ 720.05 KiB | Viewed 2285 times ]
Tatakai no Banka (Japan) 000.bmp
Tatakai no Banka (Japan) 000.bmp [ 720.05 KiB | Viewed 2285 times ]
Top
 Profile  
 
PostPosted: Sun Feb 22, 2015 1:07 pm 
Offline
User avatar

Joined: Mon Dec 29, 2014 1:46 pm
Posts: 710
Location: New York, NY
Zepper wrote:
Tatakai no Banka (J).


That game seems to work. But, it's horrible. It looks like some kid's high school game project. How did something like that get through Nintendo's quality control.


Top
 Profile  
 
PostPosted: Sun Feb 22, 2015 1:45 pm 
Offline
User avatar

Joined: Sun Sep 19, 2004 9:28 pm
Posts: 3192
Location: Mountain View, CA, USA
Tatakai no Banka (Eulogy of War) is also known as Trojan in the US and other countries. It's an arcade port. It's also not that bad of a game -- really. It doesn't feel like a "high school project" to me. :-)

That game is also useful in some way for testing certain mirroring quirks. I forget what the details are, sadly, but I remember some emulators not implementing something correctly, so during the map screen ("Let's try the first stage, good luck!") text would get printed oddly or in the wrong on-screen location. Ugh, I wish I could remember what the issue was. IMO this, and the use of $2003/$2004, make it a good subject for "emulator testing".

And if I remember right, the quirks with $2003/$2004 are why everyone advocates using $4014 (DMA) instead.


Top
 Profile  
 
PostPosted: Sun Feb 22, 2015 5:36 pm 
Offline
Formerly Fx3
User avatar

Joined: Fri Nov 12, 2004 4:59 pm
Posts: 3064
Location: Brazil
I remembered the japanese name (!) after a nap during the afternoon. ^_^;; Go figure... :D


Top
 Profile  
 
PostPosted: Sun Feb 22, 2015 10:29 pm 
Offline

Joined: Tue Feb 10, 2015 10:16 am
Posts: 3
koitsu wrote:
Tatakai no Banka (Eulogy of War) is also known as Trojan in the US and other countries. It's an arcade port. It's also not that bad of a game -- really. It doesn't feel like a "high school project" to me. :-)

That game is also useful in some way for testing certain mirroring quirks. I forget what the details are, sadly, but I remember some emulators not implementing something correctly, so during the map screen ("Let's try the first stage, good luck!") text would get printed oddly or in the wrong on-screen location. Ugh, I wish I could remember what the issue was. IMO this, and the use of $2003/$2004, make it a good subject for "emulator testing".

And if I remember right, the quirks with $2003/$2004 are why everyone advocates using $4014 (DMA) instead.


I played this game on my NES with my cousins back in the late 1980s when it was new. I remember it was a lot of fun at the time.


Top
 Profile  
 
PostPosted: Fri Mar 20, 2015 7:38 pm 
Offline
User avatar

Joined: Mon Dec 29, 2014 1:46 pm
Posts: 710
Location: New York, NY
By the way, was Huge Insect a ripoff of Buzz Bombers?


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 12 posts ] 

All times are UTC - 7 hours


Who is online

Users browsing this forum: Yodak and 2 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group