Accessing OAM during H-blank

Discussion of hardware and software development for Super NES and Super Famicom.

Moderator: Moderators

Forum rules
  • For making cartridges of your Super NES games, see Reproduction.
Post Reply
psycopathicteen
Posts: 3001
Joined: Wed May 19, 2010 6:12 pm

Accessing OAM during H-blank

Post by psycopathicteen »

This morning my brain hatched the idea of using H-blank IRQs to allow the sPPU to display up to 900 small sprites at once. It requires updating 16 bytes in the OAM per line. I'm not quite sure if I'm allowed to do that on real hardware, so I'm asking that here? If there are any quirks or hardware bugs to watch out for please tell me. What emulator would I need to test it out properly?
User avatar
blargg
Posts: 3717
Joined: Mon Sep 27, 2004 8:33 am
Location: Central Texas, USA
Contact:

Post by blargg »

No substitute for a SNES in this case. You might also be able to use HDMA for this, perhaps getting more writes into hblank. Maybe even a combination of the two, with the HDMA doing the first 8 writes to whatever registers, then the CPU finishing it.
tepples
Posts: 22345
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Post by tepples »

At least on the GBA, it's definitely doable on hardware, and in fact, that's how Super Puzzle Fighter II displays its playfields. But I've never seen it done on the Super NES; you'll definitely want to try that on hardware.
psycopathicteen
Posts: 3001
Joined: Wed May 19, 2010 6:12 pm

Post by psycopathicteen »

I think having 900 8x8 sprites could make the Snes more programmer friendly since you no longer have to rely on 2 sizes at one time, and the collumn/row sprite pattern allocation.
Near
Founder of higan project
Posts: 1553
Joined: Mon Mar 27, 2006 5:23 pm

Post by Near »

OAM is not supposed to be accessed during any portion of the active display or Hblank, unless force blank is enabled.

If you try and do it anyway, the writes will not go to OAMADDR, but will instead go to whatever the S-PPU is currently fetching for its internal processing.

During the active display area, it builds a sprite item cache. It first fetches data from the low attribute table; and then once it's done, from the high attribute table.

Your write during Hblank will end up going to the high attribute table address of the last sprite the S-PPU fetched. Even if you hit a patch of empty scanlines, the address is still the last sprite fetched. Rewriting OAMADDR during Hblank will not help you.

Also note that the PPU fetches sprite information for the next scanline, and not the current one, for obvious reasons.

I would strongly recommend you stick to real hardware if you are still crazy enough to try this. Your best bet for playing with this effect in an emulator would be bsnes using the dot-based renderer, here:
http://bsnes.googlecode.com/files/bsnes_v067r04.tar.bz2
(Get the DLLs from v067 official here: http://bsnes.googlecode.com/files/bsnes_v067.zip)

Any other emulator will just allow your write to go wherever you set OAMADDR to, regardless of whether or not the screen is in force blank, active display, Hblank or Vblank.

Lastly, for fun, I will note that Uniracers in two-player mode does exactly what you suggest, but does it for only two sprites. Every other SNES emulator uses hacks to get that game playable as a result.
psycopathicteen
Posts: 3001
Joined: Wed May 19, 2010 6:12 pm

Post by psycopathicteen »

So it leave off on the highest numbered sprite that appears on the scanline in the extra 32 bytes?
Near
Founder of higan project
Posts: 1553
Joined: Mon Mar 27, 2006 5:23 pm

Post by Near »

Yes, writing to OAM during Hblank goes to:

Code: Select all

uint16 addr = 0x0200 + (last_accessed_sprite_item >> 2);
memory::oam[addr] = (uint8)data;
As you should know, the extended 32-bytes encode data for four sprites at a time. It control d8 of X and the size of the sprite (small or large.) It's not a very useful thing to be able to write to, but again, Uniracers manages to make use of this. I haven't really bothered to figure out how.
psycopathicteen
Posts: 3001
Joined: Wed May 19, 2010 6:12 pm

Post by psycopathicteen »

Does it auto-increment when writing to it more than once, and if it does, does it wrap around back to the beginning of the oam?
Near
Founder of higan project
Posts: 1553
Joined: Mon Mar 27, 2006 5:23 pm

Post by Near »

I have no idea, I would suspect not but you'd have to try for yourself.
User avatar
TmEE
Posts: 790
Joined: Wed Feb 13, 2008 9:10 am
Location: Estonia, Rapla city (50 and 60Hz compatible :P)
Contact:

Post by TmEE »

it can be done on MD to some extent... I messed around with single sprite every line and could display 240 "sprites", in a jiggly manner (got to forget interrupts when doing this, VDP polling would be effective but the use gets severly limited then)...
Post Reply