For example, this measures how long sprite DMA takes:
Code: Select all
jsr time_code_begin
lda #1
sta $4014
jsr time_code_end
jsr print_dec_xa ; prints 520
* Sprite DMA takes 513/514 clocks, depending on whether it's started on an even or odd clock.
* DMC DMA read normally takes 4 clocks, but only 3 if a memory write is occurring at a critical moment (the write probably cuts the DMA read short).
* Starting a DMC sample can add 3 or 4 clocks if the sample byte needs to be read immediately. It seems to depend on whether the write is on an even or odd clock.
It's also a convenient way to time a short routine (assuming you can quickly upload new code to your NES, that is). Don't expect it to work on emulators yet, as it probably depends on some aspects of the DMC not yet fully documented.
The timing technique is fairly simple. It is composed of two parts: synchronization and elapsed time determination.
Synchronization: Let's say there's a digital clock that only shows minutes (no seconds), and you want to be looking at it right when the minutes change, but you can only look at it for a second at a time, and must wait at least 10 seconds between checks. How do you efficiently arrange it so you're looking at it the moment the minutes change? First, make a note of the current time, then check it every 10 seconds until the time has changed sometime between checks. At that point, begin checking it every 59 seconds. Within ten minutes you will be observing it the moment the minutes change.
Code: Select all
Check ------C----------C----------C----------C
Minutes ---M-----------M-----------M-----------M
Code: Select all
Check -------C----------C----------C----------C----------C
Minutes ---M-----------M-----------M-----------M-----------M