It is currently Sun Sep 23, 2018 3:11 am

All times are UTC - 7 hours





Post new topic Reply to topic  [ 45 posts ]  Go to page Previous  1, 2, 3  Next
Author Message
PostPosted: Wed Sep 05, 2018 1:39 am 
Offline
User avatar

Joined: Fri Nov 12, 2004 2:49 pm
Posts: 7518
Location: Chexbres, VD, Switzerland
Indeed for NMI it's not a problem, as it is edge-triggered and not level-triggered, so NMIs will trigger once and won't necessary need to be acknowledged.


Top
 Profile  
 
PostPosted: Wed Sep 05, 2018 6:02 am 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 20565
Location: NE Indiana, USA (NTSC)
For IRQ, you could SEI while the address is being changed (unless you have an NMI handler that does CLI).


Top
 Profile  
 
PostPosted: Wed Sep 05, 2018 8:07 am 
Offline
User avatar

Joined: Tue Jun 24, 2008 8:38 pm
Posts: 1955
Location: Fukuoka, Japan
I do not use CLI inside NMI.

I think I could always try both and see how it goes but for now, the only thing I'm a little bit confused is about when to start so it goes the right scanline.

How do I start it properly to make it sure it will be run at scanline 100? For example, inside the NMI I first scroll the top part to it's proper position. Then I enable the IRQ then set the latch but when you set it, the wiki say something like:

Quote:
this value will be copied to the IRQ counter at the NEXT rising edge of the PPU address, presumably at PPU cycle 260 of the current scanline.


Since we are inside NMI and the code is executed between scanline 240~260 of vblank, wouldn't that affect where the counting would stop (unless, just guessing, vblank doesn't have a rising edge on A12)? If it was that fragile nobody would be using it so this comment in the wiki is puzzling me a little bit.

I guess I need to check more deeper the inner working to know if vlbank has a rising edge of not. I don't know why I need to know that much just to understand a counter but I don't mind knowing more about it :lol:


Top
 Profile  
 
PostPosted: Wed Sep 05, 2018 8:27 am 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10814
Location: Rio de Janeiro - Brazil
The scanline counter is only clocked during rendering (actually, when the PPU address lines change, so $2006/7 can also affect it). If you set up the IRQ after you're done with all PPU manipulation in vblank, the counter won't be affected until rendering starts, so the IRQ will reliably fire on the scanline of your choice even if you don't set it up at the same time every vblank.

Subsequent IRQs should be set up before the end of the next scanline though, since that's when the counter will be clocked.


Top
 Profile  
 
PostPosted: Wed Sep 05, 2018 8:41 am 
Offline
User avatar

Joined: Tue Jun 24, 2008 8:38 pm
Posts: 1955
Location: Fukuoka, Japan
The "during rendering" is the part I didn't figure out from the wiki. I'm sure I understood how it worked when I tried it a long time ago, I don't know why I'm not able to figure out by myself this time. strange.

So I will first test a IRQ defined inside the NMI. When you chain them the location of the previous one is important but let's say you only have 1 line to check. Once the IRQ is fired, you just disable the IRQ inside the handler? If not, if the IRQ is set at 50, it would fire more or less 4 time because of the 240 lines available. Is my understanding correct?


Top
 Profile  
 
PostPosted: Wed Sep 05, 2018 10:15 am 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10814
Location: Rio de Janeiro - Brazil
Banshaku wrote:
The "during rendering" is the part I didn't figure out from the wiki.

Yeah, the mapper is designed to be clocked by the memory fetches that happen during rendering, but you can, intentionally or not, manipulate the VRAM address manually in ways that'll also clock the scanline counter.

Quote:
So I will first test a IRQ defined inside the NMI. When you chain them the location of the previous one is important but let's say you only have 1 line to check. Once the IRQ is fired, you just disable the IRQ inside the handler? If not, if the IRQ is set at 50, it would fire more or less 4 time because of the 240 lines available. Is my understanding correct?

Well, you have to acknowledge the IRQ by disabling them (I think), otherwise the CPU would jump to the IRQ handler again as soon as you RTI'd, and since you're disabling them, no more will fire unless you enable them again.


Top
 Profile  
 
PostPosted: Wed Sep 05, 2018 7:09 pm 
Offline
User avatar

Joined: Tue Jun 24, 2008 8:38 pm
Posts: 1955
Location: Fukuoka, Japan
tokumaru wrote:
Well, you have to acknowledge the IRQ by disabling them (I think), otherwise the CPU would jump to the IRQ handler again as soon as you RTI'd, and since you're disabling them, no more will fire unless you enable them again.


Oh, that's an important point that I missed and don't remember reading that on the wiki. So if you don't acknowledge and the code in the RTI finishes it will cause some find of infinite loop since the counter is now at zero and is fired indefinitely. That's brutal :lol:

I will re-read the wiki because I want to know why I missed that. So the order would be:

- you latch to a specific count ($C000)
- enable the IRQ ($E001)
- wait for the RTI
- once triggered, process task and acknowledge the IRQ ($E000)
! If you forget to acknowledge, you will end up in an infinite loop

What is left to figure out is what is reload ($C001) and how it is used. Maybe it so change the counter while a count is running?

edit:

The wiki talks about acknowledge on disable. I completely missed that part. Maybe I was either too tired of didn't understand the meaning of acknowledge in this context.


Top
 Profile  
 
PostPosted: Wed Sep 05, 2018 9:27 pm 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10814
Location: Rio de Janeiro - Brazil
Banshaku wrote:
So if you don't acknowledge and the code in the RTI finishes it will cause some find of infinite loop since the counter is now at zero and is fired indefinitely.

It's not so much the state of the counter, but the difference between how the CPU handles NMIs and IRQs: https://wiki.nesdev.com/w/index.php/CPU_interrupts

Like Bregalad said, NMIs are edge-triggered, meaning that the CPU generates an NMI when the /NMI pin transitions from high to low. This means that even if the pin remains low, no more NMIs will fire, because there's no transition, it's permanently low.

IRQs however, are level triggered, so as long as that line remains asserted, the CPU will keep generating IRQs. Most IRQ sources provide a way to acknowledge the interrupt and turn off the IRQ signal. For the MMC3, that's the IRQ disable register ($E000).

Quote:
- you latch to a specific count ($C000)
- enable the IRQ ($E001)
- wait for the RTI

I think it's LATCH, RELOAD, ENABLE (you forgot "reload"). Also, you mean wait for the IRQ, right?

Quote:
- once triggered, process task and acknowledge the IRQ ($E000)
! If you forget to acknowledge, you will end up in an infinite loop

Yup.

Quote:
What is left to figure out is what is reload ($C001) and how it is used. Maybe it so change the counter while a count is running?

Reload is what effectively puts the value you latched into the counter. Latching won't do anything unless you reload.


Top
 Profile  
 
PostPosted: Wed Sep 05, 2018 10:19 pm 
Offline
User avatar

Joined: Tue Jun 24, 2008 8:38 pm
Posts: 1955
Location: Fukuoka, Japan
Sorry regarding RTI, it was IRQ. I'm sleep deprived today and I make twice as much mistake as usual (and I usually do a lot of them! ^^;;)

Now that I have the right order to execute it, I should be able to try it properly. I think I should write a small document later that explain how to go from A to B without all the details from the wiki. Often the "recipe" is more than enough without understanding why the "ingredients" where used that way.

You mention this:

Quote:
Reload is what effectively puts the value you latched into the counter. Latching won't do anything unless you reload.


This is why the wiki confuse me. If I read the wiki under the latch section:

Quote:
This register specifies the IRQ counter reload value. When the IRQ counter is zero (or a reload is requested through $C001), this value will be copied to the IRQ counter at the NEXT rising edge of the PPU address, presumably at PPU cycle 260 of the current scanline.


and you look at the part I highlighted, they say that it will be copied to the IRQ counter but their is no mention that you have to reload to activate it. From that phrase, I'm making a wrong assumption. Maybe it should be clarified at that specific place (maybe I should just add it to the wiki).

There is some mention later that it will not be activated until reloaded or counter reach zero but that doesn't explain what you are supposed to do when you are in the initializing phase. Basically, all the information is actually there but not in away to understand in which order to use it unless you actually know about it.

Thank you again for the details, I should be able to do a quick test today.


Top
 Profile  
 
PostPosted: Wed Sep 05, 2018 10:36 pm 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10814
Location: Rio de Janeiro - Brazil
Banshaku wrote:
Sorry regarding RTI, it was IRQ. I'm sleep deprived today and I make twice as much mistake as usual (and I usually do a lot of them! ^^;;)

Don't worry!

Quote:
Often the "recipe" is more than enough without understanding why the "ingredients" where used that way.

Yeah, the actual operation of MMC3 IRQs is fairly simple, you don't really need to know all the intricate details of the hardware... I sure don't!

Quote:
Quote:
This register specifies the IRQ counter reload value. When the IRQ counter is zero (or a reload is requested through $C001), this value will be copied to the IRQ counter at the NEXT rising edge of the PPU address, presumably at PPU cycle 260 of the current scanline.


and you look at the part I highlighted, they say that it will be copied to the IRQ counter but their is no mention that you have to reload to activate it.

It does say that the value is only copied to the counter when the counter reaches zero or when a reload is requested, which implies that a reload is necessary. It doesn't seem very relevant to us programmers that the copy only happens at cycle 260 though.

Quote:
There is some mention later that it will not be activated until reloaded or counter reach zero but that doesn't explain what you are supposed to do when you are in the initializing phase. Basically, all the information is actually there but not in away to understand in which order to use it unless you actually know about it.

I agree, the information is all there, but the actual steps you have to take in order to just use the IRQ are not very clear. Maybe a quick example of a single IRQ being set up and acknowledged would help.


Top
 Profile  
 
PostPosted: Wed Sep 05, 2018 11:07 pm 
Offline
User avatar

Joined: Tue Jun 24, 2008 8:38 pm
Posts: 1955
Location: Fukuoka, Japan
I did a quick test during lunch and I was able to make it work at a specific line. Even with code mixed in C/asm it worked quite well.

On thing that may be obvious (but not when you are half asleep at the wheel):

you have to CLI even though you enable the interrupt. So even enabled, if CLI is not set then nothing happens. oppsie. :lol: Beginners will forget that, I'm pretty sure. I guess I should write a basic sample later in the wiki then. Can't wait to test the real target, triple counter with scroll from left and right and static at bottom with bankswitching.

edit:

As for latch/reload, for me I read it the opposite way. When I latch I "load" it. To me, reload means to load it again so it idea get stuck in the back of my head even though it is written you have to reload it. From a vocabulary point of view, it latch loads it, why do I need to "reload" it to load the value? :?


Top
 Profile  
 
PostPosted: Thu Sep 06, 2018 12:51 am 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10814
Location: Rio de Janeiro - Brazil
Yeah, you absolutely need the CLI. Unlike NMIs, IRQs can be masked by the CPU, and they will be ignored if the I flag is set. One mistake I made when I first experimented with the MMC3 was to CLI inside the NMI handler, which obviously didn't work, because once the handler returned via RTI, the status flags were restored from the stack, and the I flag was set when the NMI fired. It took me a while to realize I had to CLI in the main thread, not inside an interrupt handler.

Banshaku wrote:
I did a quick test during lunch and I was able to make it work at a specific line. Even with code mixed in C/asm it worked quite well.

Cool.

Quote:
As for latch/reload, for me I read it the opposite way. When I latch I "load" it. To me, reload means to load it again so it idea get stuck in the back of my head even though it is written you have to reload it. From a vocabulary point of view, it latch loads it, why do I need to "reload" it to load the value? :?

I can understand the confusion, but reading it carefully (while not sleep-deprived, preferably!), you can tell that the counter can't be directly modified, it can only be copied from the latch, and there are 2 cases where that can happen - when the counter reaches 0, or when you manually request a reload. I guess that the word "reload" is used because the mapper will automatically restore the counter every time the counter reaches 0, kinda like you reload a gun when you've fired all the bullets. Yeah, not a great analogy, I know... :mrgreen:

When I started learning NES programming, I was very puzzled by the word "latch"... I don't think we have a portuguese translation for it in the context of electronics, so it took me a while to really grasp the concept. I don't know if this is a problem that happens in English too... maybe most people just think of the metal things you use to close doors/gates when they think of the word "latch", which IMO doesn't really help understand what a latch is in electronics.


Top
 Profile  
 
PostPosted: Thu Sep 06, 2018 1:23 am 
Offline
User avatar

Joined: Tue Jun 24, 2008 8:38 pm
Posts: 1955
Location: Fukuoka, Japan
So this is why I had all kind of weird jitters by setting CLI in the nmi :lol: I just made a quick method that call it from C in the main thread and it started to works fine.

Explained that way, that you cannot update the counter directly, because of the way you phrased it, it is actually more complete and easier to read than the wiki one. Now it is perfectly clear. I guess the low level technical speech and the explanation for a programmer is completely different.

still today, I have the same problem with the meaning of latch too . I remember seeing that in the DOS days for VGA X-Mode where you have to unchain the latch or something like that (maybe I'm mixing wordds now ^^;;) to access all the 256 k or memory but that word always stumbled me since I never found an equivalent in French and the only word I found is the metallic thing, like you mentioned, which make little sense. I guess I need to understand the electronic concept and it will make a lot more sense.

Maybe @Bregalad has a simple explanation on the subject since being French native, he may have had the same issue as me with this word?


Top
 Profile  
 
PostPosted: Thu Sep 06, 2018 2:39 am 
Offline
User avatar

Joined: Fri Nov 12, 2004 2:49 pm
Posts: 7518
Location: Chexbres, VD, Switzerland
I always had huge problems for the word "latch" (usually used untranslated when speaking French). Sometimes it's used as an equivalent to "D flip-flop" (for instance, the CNROM/UNROM "latch" retaining the bank number is a series of D flip-flops). On the other hand when doign CPLD/FPGA developement I was taught to "avoid latches and use registers instead", which means that I had to avoid design that ordered the programmable logic to have one transition condition being clocked mixed up with another transition being asynchronous.

For instance if I wanted to have a flip-flop that sets to "1" immediately when a button is pressed, and reset to "0" on a clock cycle when some condition is met, this would synthetise a "latch" that should be avoided at all costs. Either both conditions must be clocked; or (more rarely) both shouldn't.


Top
 Profile  
 
PostPosted: Thu Sep 06, 2018 6:32 pm 
Offline
User avatar

Joined: Tue Jun 24, 2008 8:38 pm
Posts: 1955
Location: Fukuoka, Japan
I guess latch is not easy to understand without an electronic background. Which kind of latch is the one on MMC3 then?

As for counter, I did some extra testing while being half alseep yesteday before going to bed. This time on line 200 I was changing the bank so the text would be shown properly then in VBLANK I would bring back the original bank so the top part would not be affected. It was "kinda" working except the part after 200 was going back and fort between was was shown. Either there is a bug in the code (most probable cause) ir there is something I don't know about switching banks at specific location.

Right now CHR is in 2K mode for background and a little bit of sprites are used for cosmetics reason (adding color to a few part of the background).

It's a good thing that it's not inside the game but it's all uncharted territory for me so I'm not sure where it went wrong yet. Getting close though!

One more thing: if I need to do some color animation for a short time for the upper part but for some reason 1 color only happens to be on the lower part and should not be affected, if I change that one color only on a scanline that is black with no sprites, should I expect any artifacts? Unfortunately there is too many colors on the screen that I cannot rearrange the color to avoid that clash (#$@$@ nametable way of thing) but now that I'm thinking out loud, maybe "that" part could be switched to sprites if not more than 8 but I think it is... Hmmm...

Cannot show what I'm doing yet.. Will show it someday, when ready ;)


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 45 posts ]  Go to page Previous  1, 2, 3  Next

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 3 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