NewRisingSun wrote:
It says
here that the MMC3A "generates IRQs when the scanline counter is
decremented to 0". But it also says that "writing to $C001 with $C000 still at $00 will result in another single IRQ being generated". Why does writing to $C001 to set the reload flag still generate another single IRQ, even as nothing is being decremented?
There are two general approaches to implementing a counter: synchronous and asynchronous. In an asynchronous "down" counter, the lowest stage is triggered by the input, and every other stage flips its value in response to a rising edge on the stage below. If e.g. the counter holds 1100 and an input pulse is received, the bottom stage will flip yielding 1101, then the rising edge on that stage will flip the next one, yielding 1111, then the flipped stage second from the bottom will flip the next one yielding 1011. Since that stage changed from 1 to 0, it won't trigger anything. Note that the outputs don't all flip at once; instead, the lower bits will flip before the upper bits.
In a synchronous "down" counter, all stages are triggered by the same input signal, but before that signal arrives each stage determines whether it will flip in response to the next input pulse. When that signal arrives, all stages that are going to flip in response to it will do so essentially simultaneously. After that, all stages will start determining whether they will flip in response to the next input pulse.
When using an asynchronous counter, the easiest way to trigger an action in response to the counter hitting zero is to feed all the timer stages into a "NOR" gate. The output of that gate will go high when the count goes from 0001 to 0000 but will not trigger when e.g. counting from 1000 to 0111 because the upper bits won't change to "0" until after the lower bits have changed to "1" [since it is the action of those lower bits changing to 1 that triggers the upper bits].
When using a synchronous counter, that approach won't work. When the count advances from 1000 to 0111, all count bits will change essentially simultaneously, but unpredictable factors may cause one to switch slightly faster than another. Consequently, it's might be possible for the upper bit to switch to 0 before any of the lower bits switch to 1, thus allowing a "NOR" gate on the output to momentarily generate an erroneous pulse. To prevent such issues, a common way to detect counting to zero with a synchronous counter is to have a circuit that determines whether the next count will be 0 (i.e. whether the current count is 1), and then capture the output of that circuit at the same time as the counter stages are triggered.
Various factors may cause synchronous or asynchronous designs to be more practical. A counter which triggers when advancing from 1 to 0 but doesn't retrigger when sitting at zero is indicative of a synchronous design. A counter that continuously retriggers when sitting at zero is often indicative of an asynchronous design.