It is currently Mon Oct 15, 2018 11:43 pm

All times are UTC - 7 hours





Post new topic Reply to topic  [ 12 posts ] 
Author Message
PostPosted: Mon Sep 17, 2018 4:32 pm 
Offline

Joined: Tue Feb 27, 2018 10:41 am
Posts: 10
Location: Brazil
Besides sprite-0 hit and interrupts generated by mappers implementations like MMC3, which options exists for scanline detection for proper screen split, name table swap, chr bank switch, etc..?
Thanks in advance.


Top
 Profile  
 
PostPosted: Mon Sep 17, 2018 4:35 pm 
Offline

Joined: Sun Apr 13, 2008 11:12 am
Posts: 7648
Location: Seattle
The only remaining option is cleverly misusing DPCM IRQs.

And manually counting cycles.


Top
 Profile  
 
PostPosted: Mon Sep 17, 2018 4:35 pm 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 20656
Location: NE Indiana, USA (NTSC)
That or 9 sprites on a line, which is mostly useful for a top status bar split.


Top
 Profile  
 
PostPosted: Mon Sep 17, 2018 8:14 pm 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10892
Location: Rio de Janeiro - Brazil
The options are very limited. On a stock NES, only the sprite 0 hit and the sprite overflow flags will let you know which scanline the PPU is rendering. The sprite overflow can be triggered unintentionally though, so it's only reliable if you have full control over the number of sprites until the 9 sprites that will trigger the overflow. One big disadvantage of using these 2 flags is that you have to waste CPU time waiting for them.

The other thing you can do on a stock NES is abuse DPCM IRQs. You can configure the APU to fire an IRQ when a DPCM sample finishes playing, so it's possible to have the APU play a silent sample and fire an IRQ when it ends. This would work great if the APU started playing a sample exactly when you told it to, because IRQs would always fire a constant amount of time later, but unfortunately the APU doesn't work like that, and you have to "calibrate" the timing difference between the APU and the PPU and compensate for that difference every time an IRQ fires. I's quite a very complicated technique to pull off... I personally could never make it as steady as I'd like.

lidnariq wrote:

I didn't know someone had explained this technique in detail... cool!


Top
 Profile  
 
PostPosted: Tue Sep 18, 2018 7:25 am 
Offline

Joined: Tue Feb 27, 2018 10:41 am
Posts: 10
Location: Brazil
@tepples and @tokumaru, I read all the pages of this topic viewtopic.php?t=6521 and would like to congratulate you for your effort to make this work.

This technique works or not? From the topic I mentioned above, I'd the impression that it didn't...but the wiki tells the opposite: "Unfortunately it's a bit complicated, but used correctly, it can function as a crude scanline counter, eliminating the need for an advanced mapper."
By the way, I've read about 3 times the wiki and didn't get how to implement this yet... :oops:

Anyone have any clues how Battletoads implements all those background effects and still have a status bar, all this into a non-irq discrete board?


Top
 Profile  
 
PostPosted: Tue Sep 18, 2018 7:33 am 
Offline
User avatar

Joined: Fri May 08, 2015 7:17 pm
Posts: 2297
Location: DIGDUG
register $4010, set the IRQ enable bit.

Also allow irqs by CLI.

Then, at the beginning of NMI, trigger a DMC sample to start. When the sample reaches the end, an IRQ will fire.

You can point the DMC to all zeros, and it shouldn't sound like anything.

Don't touch the output load $4011. It will make popping sounds.

write IRQ code, pointed to by the IRQ/BRK vector, which does the mid screen change you want.


A DMC sample is triggered by...
set address of DMC sample, write to $4012
set length of DMC sample, write to $4013
set sample rate, write to $4010
turn off DMC channel, write $0f to 4015
tuen on DMC channel, write $1f to 4015

Edit, I'm not sure of the order of this. You might have to write to 4010 again after that last 4015 write, because the wiki ways that a write to 4015 clears the dmc irq bit, I can't remember.

It's been a while since I tried this, and I don't have working example code, since I never ended up using it. correct me if I'm wrong.

_________________
nesdoug.com -- blog/tutorial on programming for the NES


Top
 Profile  
 
PostPosted: Tue Sep 18, 2018 10:49 am 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10892
Location: Rio de Janeiro - Brazil
dougeff, your description completely omits the compensation for the APU-PPU desynchronization, which is the "heart" of this technique. Without this compensation, there's not nearly enough precision to do raster effects (the time at which the IRQ fired can vary by up to 4 scanlines). This would only be useful if you were trying to get an IRQ to fire near a sprite 0 hit or sprite overflow in order to reduce the time spent waiting for the flags to change.

NOOPr wrote:
This technique works or not?

I remember tepples getting it to work in a demo, but I couldn't get it to work in a satisfactory way. IIRC, the split points in tepple's demo were fixed, but I was going for something dynamic that would take a variable scanline count. I ALMOST got it to work, the effect would stay stable for several frames, but every once in a while it would be several cycles off for a frame. That alone was a deal breaker for me, but the whole thing was too complex anyway, and there was still too much CPU time being wasted on wait loops, so I kinda wrote off the technique as impractical and moved on.


Top
 Profile  
 
PostPosted: Tue Sep 18, 2018 11:28 am 
Offline
User avatar

Joined: Fri May 08, 2015 7:17 pm
Posts: 2297
Location: DIGDUG
Ok.

Hypothetically. Could you use another method to improve the timing, such as polling the OAM after the IRQ? Doesn't one of the unlicensed games do this? Micro Machines or something?

(however, I have a feeling that exactly zero emulators would play the game).

_________________
nesdoug.com -- blog/tutorial on programming for the NES


Top
 Profile  
 
PostPosted: Tue Sep 18, 2018 11:45 am 
Offline

Joined: Sun Apr 13, 2008 11:12 am
Posts: 7648
Location: Seattle
OAM polling only really lets you get timing within a scanline; it's not really helpful if your DPCM IRQ could vary by up to four.

nesdevwiki:PPU sprite evaluation says that:
cycles 1-64 : reading OAMDATA shows $FF
cycles 65-256 : reading OAMDATA returns random contents of OAM
cycles 257-320 : reading OAMDATA returns the entirety of OAM for the upcoming scanline (i.e. "secondary" OAM, mostly repeating the X coordinate for each active sprite)
cycles 321-340,0 : reading OAMDATA returns the Y coordinate for the first sprite that is present on the upcoming scanline

... maybe there's something klever here?

edit x 2: Micro Machines is looking at the contents of the scanline that had the sprite 0 hit and nothing else: in this case, it's looking at the edge between cycle 320 and cycle 321, where the value read back will switch from $FF (because secondary OAM is mostly empty, and $FF is the "empty" value) to 16 (the Y coordinate for the sprite used to generate the sprite 0 hit)


Last edited by lidnariq on Tue Sep 18, 2018 12:15 pm, edited 2 times in total.

Top
 Profile  
 
PostPosted: Tue Sep 18, 2018 11:54 am 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10892
Location: Rio de Janeiro - Brazil
Sounds interesting, but isn't OAM readback something that doesn't work on all PPU revisions? I seem to remember early Famicoms not allowing it...


Top
 Profile  
 
PostPosted: Tue Sep 18, 2018 12:07 pm 
Offline
User avatar

Joined: Sun Sep 19, 2004 9:28 pm
Posts: 3629
Location: Mountain View, CA
https://wiki.nesdev.com/w/index.php/PPU ... ad.2Fwrite

...has a very large bullet list about the complications this MMIO reg brings with it. Early model Famicoms can't read from this register, but later model ones can.

P.S. -- I love how the Wiki is now riddled with these arbitrary chip silkscreenings everywhere, intermixed with PAL or NTSC or Dendy, with absolutely no reference table anywhere that I can find -- RP2A03, RP2A03G, 2A03E, 2C02, 2C02E, 2C03, 2C04, 2C05, 2C07, RP2C02G, and it just keeps getting worse. Don't tell me I'm the only one either, because I'm not. While it's good for precision (and I commend that), without a sane reference table none of it helps anyone except for those who are in-the-know. I think this weekend I'm going to make a page that acts as a reference for all of those, then set it up so that all of those strings (when used as links) go to that page.


Last edited by koitsu on Tue Sep 18, 2018 12:11 pm, edited 1 time in total.

Top
 Profile  
 
PostPosted: Tue Sep 18, 2018 12:10 pm 
Offline

Joined: Sun Apr 13, 2008 11:12 am
Posts: 7648
Location: Seattle
Doesn't work in the older NTSC PPUs (2C02letterless, A, B, C, D, E). But as far as I can tell, the number of NESes/Famicoms/Famiclones without the ability to read OAM or palette memory is a tremendously smaller proportion than the number of SNESes with the DMA-HDMA collision bug.

(P.S. Koitsu: I have an extremely rough draft (mostly "pile of notes") pair of articles here and here)


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: No registered users 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