https://www.nesdev.org/w/api.php?action=feedcontributions&user=Rainwarrior&feedformat=atomNESdev Wiki - User contributions [en]2024-03-29T10:22:08ZUser contributionsMediaWiki 1.39.0https://www.nesdev.org/w/index.php?title=Timing&diff=21510Timing2024-01-12T19:27:50Z<p>Rainwarrior: redirect Cycle reference chart</p>
<hr />
<div>#redirect [[Cycle reference chart]]</div>Rainwarriorhttps://www.nesdev.org/w/index.php?title=Controller_reading_code&diff=21509Controller reading code2024-01-12T19:21:54Z<p>Rainwarrior: /* Directional Safety */ trying to improve the commentary on this, why it might be used</p>
<hr />
<div>This page contains example code for reading the [[NES controller]].<br />
<br />
See also: [[Controller reading]]<br />
<br />
== Controller Reading Code ==<br />
<br />
=== Basic Example ===<br />
<br />
This is a tutorial example of the bare minimum needed to read the controller.<br />
It will explain the basic principles in detail, but once understood, you may wish to continue to the [[#Standard Read for 2 Controllers and Famicom|Standard Read]] example that follows,<br />
as a more complete and ready-to-use code example.<br />
<br />
This code describes an efficient method of reading the [[standard controller]] using [http://cc65.github.io/cc65/ ca65] syntax.<br />
<br />
The result byte ''buttons'' should be placed in zero page to save a cycle each time through the loop.<br />
<pre><br />
; we reserve one byte for storing the data that is read from controller<br />
.zeropage<br />
buttons .res 1<br />
</pre><br />
<br />
When reading from ''JOYPAD*'' what is read might be different from $01/$00 for various reasons. (See [[Controller reading]].) In this code the only concern is bit 0 read from ''JOYPAD*.''.<br />
<pre><br />
JOYPAD1 = $4016<br />
JOYPAD2 = $4017<br />
</pre><br />
<br />
This is the end result that will be stored in ''buttons''. '''1''' if the button was pressed, '''0''' otherwise.<br />
<br />
{| class="wikitable" style="text-align:center;"<br />
|-<br />
! bit<br />
| &nbsp;&nbsp;&nbsp;&nbsp;7&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;6&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;5&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;4&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;3&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;2&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;1&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;&nbsp;<br />
|-<br />
! button<br />
| A<br />
| B<br />
| Select<br />
| Start<br />
| Up<br />
| Down<br />
| Left<br />
| Right<br />
|}<br />
<br />
This subroutine takes 132 cycles to execute but ignores the Famicom expansion controller.<br />
Many controller reading subroutines use the X or Y register to count 8 times through the loop.<br />
But this one uses a more clever [[wikipedia:Ring counter|ring counter]] technique: $01 is loaded into the result first, and once eight bits are shifted in, the 1 bit will be shifted out, terminating the loop.<br />
<pre><br />
; At the same time that we strobe bit 0, we initialize the ring counter<br />
; so we're hitting two birds with one stone here<br />
readjoy:<br />
lda #$01<br />
; While the strobe bit is set, buttons will be continuously reloaded.<br />
; This means that reading from JOYPAD1 will only return the state of the<br />
; first button: button A.<br />
sta JOYPAD1<br />
sta buttons<br />
lsr a ; now A is 0<br />
; By storing 0 into JOYPAD1, the strobe bit is cleared and the reloading stops.<br />
; This allows all 8 buttons (newly reloaded) to be read from JOYPAD1.<br />
sta JOYPAD1<br />
loop:<br />
lda JOYPAD1<br />
lsr a ; bit 0 -> Carry<br />
rol buttons ; Carry -> bit 0; bit 7 -> Carry<br />
bcc loop<br />
rts<br />
</pre><br />
<br />
Continue to the next example for a more complete read routine that handles both controllers and the standard Famicom expansion controllers.<br />
<br />
=== Standard Read for 2 Controllers and Famicom ===<br />
<br />
Adding support for controllers on the Famicom's DA15 expansion port and for player 2's controller is straightforward. Something similar to the following routine is used in most Famicom games.<br />
Even though the expansion port is unused on the NES, the unconnected bit will read as 0, so this solution works safely with both Famicom and NES hardware.<br />
<pre><br />
.zeropage<br />
buttons: .res 2 ; space for 2 reads<br />
<br />
.code<br />
readjoyx2:<br />
ldx #$00<br />
jsr readjoyx ; X=0: read controller 1<br />
inx<br />
; fall through to readjoyx below, X=1: read controller 2<br />
<br />
readjoyx: ; X register = 0 for controller 1, 1 for controller 2<br />
lda #$01<br />
sta JOYPAD1<br />
sta buttons, x<br />
lsr a<br />
sta JOYPAD1<br />
loop:<br />
lda JOYPAD1, x<br />
and #%00000011 ; ignore bits other than controller<br />
cmp #$01 ; Set carry if and only if nonzero<br />
rol buttons, x ; Carry -> bit 0; but 7 -> Carry<br />
bcc loop<br />
rts<br />
</pre><br />
<br />
If playing DPCM samples, there is an additional reread step to prevent errors ([[#DPCM Safety using Repeated Reads|see below]]).<br />
<br />
Note that the <tt>and</tt> to ignore bits is not optional, as the upper bits of <tt>JOYPAD1</tt> read are not guaranteed to be 1 or 0<ref>[[Controller_reading#Unconnected_data_lines_and_open_bus|Controller reading: Unconnected data lines and open bus]]</ref>.<br />
<br />
=== Alternative 2 Controllers Read ===<br />
<br />
Alternatively, we could combine both controller reads into 1 loop with a single strobe, though this routine is not safe to use with DPCM samples playing ([[#DPCM Safety using Repeated Reads|see below]]).<br />
<pre><br />
.zeropage<br />
buttons: .res 2<br />
<br />
.code<br />
readjoy2:<br />
lda #$01<br />
sta JOYPAD1<br />
sta buttons+1 ; player 2's buttons double as a ring counter<br />
lsr a<br />
sta JOYPAD1<br />
loop:<br />
lda JOYPAD1<br />
and #%00000011<br />
cmp #$01<br />
rol buttons+0<br />
lda JOYPAD2<br />
and #%00000011<br />
cmp #$01<br />
rol buttons+1<br />
bcc loop<br />
rts<br />
</pre><br />
<br />
=== DPCM Safety using Repeated Reads ===<br />
<br />
If your code is intended to be used with [[APU DMC]] playback, this code will need to be altered. The NES occasionally glitches the controller port twice in a row if sample playback is enabled, and games using samples need to work around this. The most common technique, as seen in ''Super Mario Bros. 3''<ref>[//forums.nesdev.org/viewtopic.php?p=151720#p151720 Super Mario Bros. 3 controller reread method]</ref> and other games, will read each controller twice, but in the event of a mismatch it will keep re-reading the controller until two results in a row are the same.<br />
<pre><br />
readjoy2_safe:<br />
ldx #$00<br />
jsr readjoyx_safe ; X=0: safe read controller 1<br />
inx<br />
; fall through to readjoyx_safe, X=1: safe read controller 2<br />
<br />
readjoyx_safe:<br />
jsr readjoyx<br />
reread:<br />
lda buttons, x<br />
pha<br />
jsr readjoyx<br />
pla<br />
cmp buttons, x<br />
bne reread<br />
rts<br />
</pre><br />
<br />
Note that the time between the start of one read and the end of the next read must be less than the length of the fastest DMC fetch period (432 cycles). For this reason, it is normal to read controllers one at a time with this method, rather than attempting both at once. (Note: <code>readjoy2</code> above takes too long to be suitable.) [[Game bugs|''Gimmick!'' has such a bug]] resulting from trying to read both at once.<br />
<br />
Most often a controller will be read 2 times, and 3 or 4 in the case of a DPCM corruption, or the player pressing a button during the read. With the assistance of tools, a malicious controller input could change the buttons on every read, holding it in this reread loop indefinitely<ref>[https://arstechnica.com/gaming/2016/07/how-to-beat-super-mario-bros-3-in-less-than-a-second/ Ars Technica: How to beat Super Mario Bros. 3 in less than a second]</ref><ref>https://tasvideos.org/6466S Tool-Assisted Speedrun of Super Mario Bros. 3 which first demonstrated abusing controller reread routines.</ref>, but this is generally not an important edge case to account for.<br />
<br />
=== DPCM Safety using OAM DMA ===<br />
<br />
Because halts for DPCM fetches normally only occur on an put cycles, it is possible to get glitch-free controller reads by timing all '''$4016''' and '''$4017''' reads to fall on get cycles. This is made possible by the behavior of OAM DMA: the first cycle after an OAM DMA is normally guaranteed to be a get cycle.<ref>[http://forums.nesdev.org/viewtopic.php?p=171971 Forum post:] Rahsennor's OAM-synchronized controller read</ref> This is a relatively new technique and is not supported by some emulators.<ref>[http://forums.nesdev.org/viewtopic.php?f=2&t=14319&start=15#p172099 Forum post:] as of May 2016, Nintendulator and Nestopia do not accurately emulate OAM-synchronized controller reading.</ref> In the following example code, the controller1 and controller2 labels must be in zeropage for the timing to work.<br />
<br />
This solution might be ideal, using fewer cycles than doing repeated reads, and taking a consistent amount of time. It can also be adapted for DPCM-conflict free reading of controllers that require a longer report like [[four player adapters]], or the [[SNES mouse]] (see notes below).<br />
<br />
However, unlike the other solutions above, it can't be executed at any time. Instead it must be integrated into your NMI routine to coincide with your sprite OAM DMA once per frame.<br />
<br />
<pre><br />
lda #OAM<br />
sta $4014 ; ------ OAM DMA ------<br />
ldx #1 ; get put <- strobe code must take an odd number of cycles total<br />
stx buttons+0 ; get put get <- buttons must be in the zeropage<br />
stx $4016 ; put get put get<br />
dex ; put get<br />
stx $4016 ; put get put get<br />
loop:<br />
lda $4017 ; put get put GET <- loop code must take an even number of cycles total<br />
and #3 ; put get<br />
cmp #1 ; put get<br />
rol buttons+1, x ; put get put get put get (X = 0; waste 1 cycle and 0 bytes for alignment)<br />
lda $4016 ; put get put GET<br />
and #3 ; put get<br />
cmp #1 ; put get<br />
rol buttons+0 ; put get put get put<br />
bcc loop ; get put [get] <- this branch must not be allowed to cross a page<br />
</pre><br />
<br />
Note that this example routine only reads two 8-bit controllers and does not take enough time to span more than one DPCM fetch. Routines longer than this must contend with two additional constraints:<br />
* When DMC DMA is delayed by an odd number of cycles, it takes 3 cycles instead of 4, changing the cycle parity. If extending this function to read more bits, care must be taken so that ''all'' CPU write cycles are aligned. Instructions with a single write cycle must align the write to avoid conflict with the DPCM fetch, and double-write instructions like ROL need to align both writes so that the DPCM fetch falls on the first write.<ref>[//forums.nesdev.org/viewtopic.php?p=231604#p231604 Forum post:] demonstration of how ROL instruction affects alignment for OAM DMA synchronized controller reading.</ref> If an interrupt can occur during the routine, it must be aligned so the fetch can only fall on the second of the three automatic stack writes.<br />
* When DMC DMA occurs near the end of OAM DMA, it only steals 1 or 3 cycles, inverting the cycle parity. Every DMC period after that, a misaligned DPCM fetch will occur. Care must be taken to ensure this does not land on a joypad read.<br />
<br />
See [[DMA]] for detailed information on DMA timing.<br />
<br />
== Other Useful Operations ==<br />
<br />
=== Button Flags ===<br />
<br />
It is helpful to define the buttons as a series of bit flags:<br />
<pre><br />
BUTTON_A = 1 << 7<br />
BUTTON_B = 1 << 6<br />
BUTTON_SELECT = 1 << 5<br />
BUTTON_START = 1 << 4<br />
BUTTON_UP = 1 << 3<br />
BUTTON_DOWN = 1 << 2<br />
BUTTON_LEFT = 1 << 1<br />
BUTTON_RIGHT = 1 << 0<br />
</pre><br />
<br />
And then buttons can be checked as follows:<br />
<pre><br />
lda buttons<br />
and #BUTTON_A | BUTTON_B<br />
beq notPressingAorB<br />
; Handle presses.<br />
notPressingAorB:<br />
</pre><br />
<br />
=== Calculating Presses and Releases ===<br />
<br />
To calculate newly pressed and newly released buttons by comparing against the last frame's buttons:<br />
<pre><br />
; newly pressed buttons: not held last frame, and held now<br />
lda last_frame_buttons, x<br />
eor #%11111111<br />
and buttons, x<br />
sta pressed_buttons, x<br />
<br />
; newly released buttons: not held now, and held last frame<br />
lda buttons, x<br />
eor #%11111111<br />
and last_frame_buttons, x<br />
sta released_buttons, x<br />
</pre><br />
<br />
=== Directional Safety ===<br />
<br />
Opposing directions (Up+Down and Left+Right) are possible on non-standard controllers, or even on a worn out standard one. Both directions can be tested for at the same time in an efficient bitwise operation:<br />
<pre><br />
lda buttons, x<br />
and #%00001010 ; Compare Up and Left...<br />
lsr a<br />
and buttons, x ; to Down and Right<br />
beq not_opposing<br />
; Use previous frame's directions<br />
lda buttons, x<br />
eor last_frame_buttons, x<br />
and #%11110000<br />
eor last_frame_buttons, x<br />
sta buttons, x<br />
not_opposing:<br />
</pre><br />
<br />
Diagonal directions can also be detected at the same time as opposing ones, by testing if more than 1 directional bit is set. This could be used as part of a 4-way joystick style control scheme:<br />
<pre><br />
lda buttons, x<br />
and #%00001111 ; If A & (A - 1) is nonzero, A has more than one bit set<br />
beq not_diagonal<br />
sec<br />
sbc #1<br />
and buttons, x<br />
beq not_diagonal<br />
; Use previous frame's directions<br />
lda buttons, x<br />
eor last_frame_buttons, x<br />
and #%11110000<br />
eor last_frame_buttons, x<br />
sta buttons, x<br />
not_diagonal:<br />
</pre><br />
<br />
As an example, the code above rejects the detected cases by using the direction bits from the previous frame, but depending on the situation another response might be more appropriate (e.g. cancel just the opposing bits, or clear all directions).<br />
<br />
== External Examples ==<br />
<br />
* [http://forums.nesdev.org/viewtopic.php?t=4124 Forum post:] Blargg's DMC-fortified controller read routine<br />
* [http://forums.nesdev.org/viewtopic.php?p=171971 Forum post:] Rahsennor's OAM-synchronized controller read<br />
* [http://forums.nesdev.org/viewtopic.php?f=2&t=14197 Forum post:] Drag's bitwise DMC-safe controller reading<br />
* [https://github.com/pinobatch/nrom-template/blob/master/src/pads.s pads.s:] pinobatch's NROM-template controller read routine<br />
<br />
== References ==<br />
<references/></div>Rainwarriorhttps://www.nesdev.org/w/index.php?title=Controller_reading_code&diff=21508Controller reading code2024-01-12T19:08:09Z<p>Rainwarrior: /* Other Useful Operations */ reversing the order of the 3 examples (i think they were in reverse order of usefulness)</p>
<hr />
<div>This page contains example code for reading the [[NES controller]].<br />
<br />
See also: [[Controller reading]]<br />
<br />
== Controller Reading Code ==<br />
<br />
=== Basic Example ===<br />
<br />
This is a tutorial example of the bare minimum needed to read the controller.<br />
It will explain the basic principles in detail, but once understood, you may wish to continue to the [[#Standard Read for 2 Controllers and Famicom|Standard Read]] example that follows,<br />
as a more complete and ready-to-use code example.<br />
<br />
This code describes an efficient method of reading the [[standard controller]] using [http://cc65.github.io/cc65/ ca65] syntax.<br />
<br />
The result byte ''buttons'' should be placed in zero page to save a cycle each time through the loop.<br />
<pre><br />
; we reserve one byte for storing the data that is read from controller<br />
.zeropage<br />
buttons .res 1<br />
</pre><br />
<br />
When reading from ''JOYPAD*'' what is read might be different from $01/$00 for various reasons. (See [[Controller reading]].) In this code the only concern is bit 0 read from ''JOYPAD*.''.<br />
<pre><br />
JOYPAD1 = $4016<br />
JOYPAD2 = $4017<br />
</pre><br />
<br />
This is the end result that will be stored in ''buttons''. '''1''' if the button was pressed, '''0''' otherwise.<br />
<br />
{| class="wikitable" style="text-align:center;"<br />
|-<br />
! bit<br />
| &nbsp;&nbsp;&nbsp;&nbsp;7&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;6&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;5&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;4&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;3&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;2&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;1&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;&nbsp;<br />
|-<br />
! button<br />
| A<br />
| B<br />
| Select<br />
| Start<br />
| Up<br />
| Down<br />
| Left<br />
| Right<br />
|}<br />
<br />
This subroutine takes 132 cycles to execute but ignores the Famicom expansion controller.<br />
Many controller reading subroutines use the X or Y register to count 8 times through the loop.<br />
But this one uses a more clever [[wikipedia:Ring counter|ring counter]] technique: $01 is loaded into the result first, and once eight bits are shifted in, the 1 bit will be shifted out, terminating the loop.<br />
<pre><br />
; At the same time that we strobe bit 0, we initialize the ring counter<br />
; so we're hitting two birds with one stone here<br />
readjoy:<br />
lda #$01<br />
; While the strobe bit is set, buttons will be continuously reloaded.<br />
; This means that reading from JOYPAD1 will only return the state of the<br />
; first button: button A.<br />
sta JOYPAD1<br />
sta buttons<br />
lsr a ; now A is 0<br />
; By storing 0 into JOYPAD1, the strobe bit is cleared and the reloading stops.<br />
; This allows all 8 buttons (newly reloaded) to be read from JOYPAD1.<br />
sta JOYPAD1<br />
loop:<br />
lda JOYPAD1<br />
lsr a ; bit 0 -> Carry<br />
rol buttons ; Carry -> bit 0; bit 7 -> Carry<br />
bcc loop<br />
rts<br />
</pre><br />
<br />
Continue to the next example for a more complete read routine that handles both controllers and the standard Famicom expansion controllers.<br />
<br />
=== Standard Read for 2 Controllers and Famicom ===<br />
<br />
Adding support for controllers on the Famicom's DA15 expansion port and for player 2's controller is straightforward. Something similar to the following routine is used in most Famicom games.<br />
Even though the expansion port is unused on the NES, the unconnected bit will read as 0, so this solution works safely with both Famicom and NES hardware.<br />
<pre><br />
.zeropage<br />
buttons: .res 2 ; space for 2 reads<br />
<br />
.code<br />
readjoyx2:<br />
ldx #$00<br />
jsr readjoyx ; X=0: read controller 1<br />
inx<br />
; fall through to readjoyx below, X=1: read controller 2<br />
<br />
readjoyx: ; X register = 0 for controller 1, 1 for controller 2<br />
lda #$01<br />
sta JOYPAD1<br />
sta buttons, x<br />
lsr a<br />
sta JOYPAD1<br />
loop:<br />
lda JOYPAD1, x<br />
and #%00000011 ; ignore bits other than controller<br />
cmp #$01 ; Set carry if and only if nonzero<br />
rol buttons, x ; Carry -> bit 0; but 7 -> Carry<br />
bcc loop<br />
rts<br />
</pre><br />
<br />
If playing DPCM samples, there is an additional reread step to prevent errors ([[#DPCM Safety using Repeated Reads|see below]]).<br />
<br />
Note that the <tt>and</tt> to ignore bits is not optional, as the upper bits of <tt>JOYPAD1</tt> read are not guaranteed to be 1 or 0<ref>[[Controller_reading#Unconnected_data_lines_and_open_bus|Controller reading: Unconnected data lines and open bus]]</ref>.<br />
<br />
=== Alternative 2 Controllers Read ===<br />
<br />
Alternatively, we could combine both controller reads into 1 loop with a single strobe, though this routine is not safe to use with DPCM samples playing ([[#DPCM Safety using Repeated Reads|see below]]).<br />
<pre><br />
.zeropage<br />
buttons: .res 2<br />
<br />
.code<br />
readjoy2:<br />
lda #$01<br />
sta JOYPAD1<br />
sta buttons+1 ; player 2's buttons double as a ring counter<br />
lsr a<br />
sta JOYPAD1<br />
loop:<br />
lda JOYPAD1<br />
and #%00000011<br />
cmp #$01<br />
rol buttons+0<br />
lda JOYPAD2<br />
and #%00000011<br />
cmp #$01<br />
rol buttons+1<br />
bcc loop<br />
rts<br />
</pre><br />
<br />
=== DPCM Safety using Repeated Reads ===<br />
<br />
If your code is intended to be used with [[APU DMC]] playback, this code will need to be altered. The NES occasionally glitches the controller port twice in a row if sample playback is enabled, and games using samples need to work around this. The most common technique, as seen in ''Super Mario Bros. 3''<ref>[//forums.nesdev.org/viewtopic.php?p=151720#p151720 Super Mario Bros. 3 controller reread method]</ref> and other games, will read each controller twice, but in the event of a mismatch it will keep re-reading the controller until two results in a row are the same.<br />
<pre><br />
readjoy2_safe:<br />
ldx #$00<br />
jsr readjoyx_safe ; X=0: safe read controller 1<br />
inx<br />
; fall through to readjoyx_safe, X=1: safe read controller 2<br />
<br />
readjoyx_safe:<br />
jsr readjoyx<br />
reread:<br />
lda buttons, x<br />
pha<br />
jsr readjoyx<br />
pla<br />
cmp buttons, x<br />
bne reread<br />
rts<br />
</pre><br />
<br />
Note that the time between the start of one read and the end of the next read must be less than the length of the fastest DMC fetch period (432 cycles). For this reason, it is normal to read controllers one at a time with this method, rather than attempting both at once. (Note: <code>readjoy2</code> above takes too long to be suitable.) [[Game bugs|''Gimmick!'' has such a bug]] resulting from trying to read both at once.<br />
<br />
Most often a controller will be read 2 times, and 3 or 4 in the case of a DPCM corruption, or the player pressing a button during the read. With the assistance of tools, a malicious controller input could change the buttons on every read, holding it in this reread loop indefinitely<ref>[https://arstechnica.com/gaming/2016/07/how-to-beat-super-mario-bros-3-in-less-than-a-second/ Ars Technica: How to beat Super Mario Bros. 3 in less than a second]</ref><ref>https://tasvideos.org/6466S Tool-Assisted Speedrun of Super Mario Bros. 3 which first demonstrated abusing controller reread routines.</ref>, but this is generally not an important edge case to account for.<br />
<br />
=== DPCM Safety using OAM DMA ===<br />
<br />
Because halts for DPCM fetches normally only occur on an put cycles, it is possible to get glitch-free controller reads by timing all '''$4016''' and '''$4017''' reads to fall on get cycles. This is made possible by the behavior of OAM DMA: the first cycle after an OAM DMA is normally guaranteed to be a get cycle.<ref>[http://forums.nesdev.org/viewtopic.php?p=171971 Forum post:] Rahsennor's OAM-synchronized controller read</ref> This is a relatively new technique and is not supported by some emulators.<ref>[http://forums.nesdev.org/viewtopic.php?f=2&t=14319&start=15#p172099 Forum post:] as of May 2016, Nintendulator and Nestopia do not accurately emulate OAM-synchronized controller reading.</ref> In the following example code, the controller1 and controller2 labels must be in zeropage for the timing to work.<br />
<br />
This solution might be ideal, using fewer cycles than doing repeated reads, and taking a consistent amount of time. It can also be adapted for DPCM-conflict free reading of controllers that require a longer report like [[four player adapters]], or the [[SNES mouse]] (see notes below).<br />
<br />
However, unlike the other solutions above, it can't be executed at any time. Instead it must be integrated into your NMI routine to coincide with your sprite OAM DMA once per frame.<br />
<br />
<pre><br />
lda #OAM<br />
sta $4014 ; ------ OAM DMA ------<br />
ldx #1 ; get put <- strobe code must take an odd number of cycles total<br />
stx buttons+0 ; get put get <- buttons must be in the zeropage<br />
stx $4016 ; put get put get<br />
dex ; put get<br />
stx $4016 ; put get put get<br />
loop:<br />
lda $4017 ; put get put GET <- loop code must take an even number of cycles total<br />
and #3 ; put get<br />
cmp #1 ; put get<br />
rol buttons+1, x ; put get put get put get (X = 0; waste 1 cycle and 0 bytes for alignment)<br />
lda $4016 ; put get put GET<br />
and #3 ; put get<br />
cmp #1 ; put get<br />
rol buttons+0 ; put get put get put<br />
bcc loop ; get put [get] <- this branch must not be allowed to cross a page<br />
</pre><br />
<br />
Note that this example routine only reads two 8-bit controllers and does not take enough time to span more than one DPCM fetch. Routines longer than this must contend with two additional constraints:<br />
* When DMC DMA is delayed by an odd number of cycles, it takes 3 cycles instead of 4, changing the cycle parity. If extending this function to read more bits, care must be taken so that ''all'' CPU write cycles are aligned. Instructions with a single write cycle must align the write to avoid conflict with the DPCM fetch, and double-write instructions like ROL need to align both writes so that the DPCM fetch falls on the first write.<ref>[//forums.nesdev.org/viewtopic.php?p=231604#p231604 Forum post:] demonstration of how ROL instruction affects alignment for OAM DMA synchronized controller reading.</ref> If an interrupt can occur during the routine, it must be aligned so the fetch can only fall on the second of the three automatic stack writes.<br />
* When DMC DMA occurs near the end of OAM DMA, it only steals 1 or 3 cycles, inverting the cycle parity. Every DMC period after that, a misaligned DPCM fetch will occur. Care must be taken to ensure this does not land on a joypad read.<br />
<br />
See [[DMA]] for detailed information on DMA timing.<br />
<br />
== Other Useful Operations ==<br />
<br />
=== Button Flags ===<br />
<br />
It is helpful to define the buttons as a series of bit flags:<br />
<pre><br />
BUTTON_A = 1 << 7<br />
BUTTON_B = 1 << 6<br />
BUTTON_SELECT = 1 << 5<br />
BUTTON_START = 1 << 4<br />
BUTTON_UP = 1 << 3<br />
BUTTON_DOWN = 1 << 2<br />
BUTTON_LEFT = 1 << 1<br />
BUTTON_RIGHT = 1 << 0<br />
</pre><br />
<br />
And then buttons can be checked as follows:<br />
<pre><br />
lda buttons<br />
and #BUTTON_A | BUTTON_B<br />
beq notPressingAorB<br />
; Handle presses.<br />
notPressingAorB:<br />
</pre><br />
<br />
=== Calculating Presses and Releases ===<br />
<br />
To calculate newly pressed and newly released buttons by comparing against the last frame's buttons:<br />
<pre><br />
; newly pressed buttons: not held last frame, and held now<br />
lda last_frame_buttons, x<br />
eor #%11111111<br />
and buttons, x<br />
sta pressed_buttons, x<br />
<br />
; newly released buttons: not held now, and held last frame<br />
lda buttons, x<br />
eor #%11111111<br />
and last_frame_buttons, x<br />
sta released_buttons, x<br />
</pre><br />
<br />
=== Directional Safety ===<br />
<br />
To reject opposing presses (Up+Down and Left+Right), which are possible on a worn Control Pad:<br />
<pre><br />
lda buttons, x<br />
and #%00001010 ; Compare Up and Left...<br />
lsr a<br />
and buttons, x ; to Down and Right<br />
beq not_updown<br />
; Use previous frame's directions<br />
lda buttons, x<br />
eor last_frame_buttons, x<br />
and #%11110000<br />
eor last_frame_buttons, x<br />
sta buttons, x<br />
not_updown:<br />
</pre><br />
<br />
To instead reject all diagonal presses, simulating a 4-way joystick:<br />
<pre><br />
lda buttons, x<br />
and #%00001111 ; If A & (A - 1) is nonzero, A has more than one bit set<br />
beq not_diagonal<br />
sec<br />
sbc #1<br />
and buttons, x<br />
beq not_diagonal<br />
; Use previous frame's directions<br />
lda buttons, x<br />
eor last_frame_buttons, x<br />
and #%11110000<br />
eor last_frame_buttons, x<br />
sta buttons, x<br />
not_diagonal:<br />
</pre><br />
<br />
== External Examples ==<br />
<br />
* [http://forums.nesdev.org/viewtopic.php?t=4124 Forum post:] Blargg's DMC-fortified controller read routine<br />
* [http://forums.nesdev.org/viewtopic.php?p=171971 Forum post:] Rahsennor's OAM-synchronized controller read<br />
* [http://forums.nesdev.org/viewtopic.php?f=2&t=14197 Forum post:] Drag's bitwise DMC-safe controller reading<br />
* [https://github.com/pinobatch/nrom-template/blob/master/src/pads.s pads.s:] pinobatch's NROM-template controller read routine<br />
<br />
== References ==<br />
<references/></div>Rainwarriorhttps://www.nesdev.org/w/index.php?title=Controller_reading_code&diff=21507Controller reading code2024-01-12T19:05:43Z<p>Rainwarrior: /* Calculating Presses and Releases */ note that we need the last frame's buttons are part of the explanation</p>
<hr />
<div>This page contains example code for reading the [[NES controller]].<br />
<br />
See also: [[Controller reading]]<br />
<br />
== Controller Reading Code ==<br />
<br />
=== Basic Example ===<br />
<br />
This is a tutorial example of the bare minimum needed to read the controller.<br />
It will explain the basic principles in detail, but once understood, you may wish to continue to the [[#Standard Read for 2 Controllers and Famicom|Standard Read]] example that follows,<br />
as a more complete and ready-to-use code example.<br />
<br />
This code describes an efficient method of reading the [[standard controller]] using [http://cc65.github.io/cc65/ ca65] syntax.<br />
<br />
The result byte ''buttons'' should be placed in zero page to save a cycle each time through the loop.<br />
<pre><br />
; we reserve one byte for storing the data that is read from controller<br />
.zeropage<br />
buttons .res 1<br />
</pre><br />
<br />
When reading from ''JOYPAD*'' what is read might be different from $01/$00 for various reasons. (See [[Controller reading]].) In this code the only concern is bit 0 read from ''JOYPAD*.''.<br />
<pre><br />
JOYPAD1 = $4016<br />
JOYPAD2 = $4017<br />
</pre><br />
<br />
This is the end result that will be stored in ''buttons''. '''1''' if the button was pressed, '''0''' otherwise.<br />
<br />
{| class="wikitable" style="text-align:center;"<br />
|-<br />
! bit<br />
| &nbsp;&nbsp;&nbsp;&nbsp;7&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;6&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;5&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;4&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;3&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;2&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;1&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;&nbsp;<br />
|-<br />
! button<br />
| A<br />
| B<br />
| Select<br />
| Start<br />
| Up<br />
| Down<br />
| Left<br />
| Right<br />
|}<br />
<br />
This subroutine takes 132 cycles to execute but ignores the Famicom expansion controller.<br />
Many controller reading subroutines use the X or Y register to count 8 times through the loop.<br />
But this one uses a more clever [[wikipedia:Ring counter|ring counter]] technique: $01 is loaded into the result first, and once eight bits are shifted in, the 1 bit will be shifted out, terminating the loop.<br />
<pre><br />
; At the same time that we strobe bit 0, we initialize the ring counter<br />
; so we're hitting two birds with one stone here<br />
readjoy:<br />
lda #$01<br />
; While the strobe bit is set, buttons will be continuously reloaded.<br />
; This means that reading from JOYPAD1 will only return the state of the<br />
; first button: button A.<br />
sta JOYPAD1<br />
sta buttons<br />
lsr a ; now A is 0<br />
; By storing 0 into JOYPAD1, the strobe bit is cleared and the reloading stops.<br />
; This allows all 8 buttons (newly reloaded) to be read from JOYPAD1.<br />
sta JOYPAD1<br />
loop:<br />
lda JOYPAD1<br />
lsr a ; bit 0 -> Carry<br />
rol buttons ; Carry -> bit 0; bit 7 -> Carry<br />
bcc loop<br />
rts<br />
</pre><br />
<br />
Continue to the next example for a more complete read routine that handles both controllers and the standard Famicom expansion controllers.<br />
<br />
=== Standard Read for 2 Controllers and Famicom ===<br />
<br />
Adding support for controllers on the Famicom's DA15 expansion port and for player 2's controller is straightforward. Something similar to the following routine is used in most Famicom games.<br />
Even though the expansion port is unused on the NES, the unconnected bit will read as 0, so this solution works safely with both Famicom and NES hardware.<br />
<pre><br />
.zeropage<br />
buttons: .res 2 ; space for 2 reads<br />
<br />
.code<br />
readjoyx2:<br />
ldx #$00<br />
jsr readjoyx ; X=0: read controller 1<br />
inx<br />
; fall through to readjoyx below, X=1: read controller 2<br />
<br />
readjoyx: ; X register = 0 for controller 1, 1 for controller 2<br />
lda #$01<br />
sta JOYPAD1<br />
sta buttons, x<br />
lsr a<br />
sta JOYPAD1<br />
loop:<br />
lda JOYPAD1, x<br />
and #%00000011 ; ignore bits other than controller<br />
cmp #$01 ; Set carry if and only if nonzero<br />
rol buttons, x ; Carry -> bit 0; but 7 -> Carry<br />
bcc loop<br />
rts<br />
</pre><br />
<br />
If playing DPCM samples, there is an additional reread step to prevent errors ([[#DPCM Safety using Repeated Reads|see below]]).<br />
<br />
Note that the <tt>and</tt> to ignore bits is not optional, as the upper bits of <tt>JOYPAD1</tt> read are not guaranteed to be 1 or 0<ref>[[Controller_reading#Unconnected_data_lines_and_open_bus|Controller reading: Unconnected data lines and open bus]]</ref>.<br />
<br />
=== Alternative 2 Controllers Read ===<br />
<br />
Alternatively, we could combine both controller reads into 1 loop with a single strobe, though this routine is not safe to use with DPCM samples playing ([[#DPCM Safety using Repeated Reads|see below]]).<br />
<pre><br />
.zeropage<br />
buttons: .res 2<br />
<br />
.code<br />
readjoy2:<br />
lda #$01<br />
sta JOYPAD1<br />
sta buttons+1 ; player 2's buttons double as a ring counter<br />
lsr a<br />
sta JOYPAD1<br />
loop:<br />
lda JOYPAD1<br />
and #%00000011<br />
cmp #$01<br />
rol buttons+0<br />
lda JOYPAD2<br />
and #%00000011<br />
cmp #$01<br />
rol buttons+1<br />
bcc loop<br />
rts<br />
</pre><br />
<br />
=== DPCM Safety using Repeated Reads ===<br />
<br />
If your code is intended to be used with [[APU DMC]] playback, this code will need to be altered. The NES occasionally glitches the controller port twice in a row if sample playback is enabled, and games using samples need to work around this. The most common technique, as seen in ''Super Mario Bros. 3''<ref>[//forums.nesdev.org/viewtopic.php?p=151720#p151720 Super Mario Bros. 3 controller reread method]</ref> and other games, will read each controller twice, but in the event of a mismatch it will keep re-reading the controller until two results in a row are the same.<br />
<pre><br />
readjoy2_safe:<br />
ldx #$00<br />
jsr readjoyx_safe ; X=0: safe read controller 1<br />
inx<br />
; fall through to readjoyx_safe, X=1: safe read controller 2<br />
<br />
readjoyx_safe:<br />
jsr readjoyx<br />
reread:<br />
lda buttons, x<br />
pha<br />
jsr readjoyx<br />
pla<br />
cmp buttons, x<br />
bne reread<br />
rts<br />
</pre><br />
<br />
Note that the time between the start of one read and the end of the next read must be less than the length of the fastest DMC fetch period (432 cycles). For this reason, it is normal to read controllers one at a time with this method, rather than attempting both at once. (Note: <code>readjoy2</code> above takes too long to be suitable.) [[Game bugs|''Gimmick!'' has such a bug]] resulting from trying to read both at once.<br />
<br />
Most often a controller will be read 2 times, and 3 or 4 in the case of a DPCM corruption, or the player pressing a button during the read. With the assistance of tools, a malicious controller input could change the buttons on every read, holding it in this reread loop indefinitely<ref>[https://arstechnica.com/gaming/2016/07/how-to-beat-super-mario-bros-3-in-less-than-a-second/ Ars Technica: How to beat Super Mario Bros. 3 in less than a second]</ref><ref>https://tasvideos.org/6466S Tool-Assisted Speedrun of Super Mario Bros. 3 which first demonstrated abusing controller reread routines.</ref>, but this is generally not an important edge case to account for.<br />
<br />
=== DPCM Safety using OAM DMA ===<br />
<br />
Because halts for DPCM fetches normally only occur on an put cycles, it is possible to get glitch-free controller reads by timing all '''$4016''' and '''$4017''' reads to fall on get cycles. This is made possible by the behavior of OAM DMA: the first cycle after an OAM DMA is normally guaranteed to be a get cycle.<ref>[http://forums.nesdev.org/viewtopic.php?p=171971 Forum post:] Rahsennor's OAM-synchronized controller read</ref> This is a relatively new technique and is not supported by some emulators.<ref>[http://forums.nesdev.org/viewtopic.php?f=2&t=14319&start=15#p172099 Forum post:] as of May 2016, Nintendulator and Nestopia do not accurately emulate OAM-synchronized controller reading.</ref> In the following example code, the controller1 and controller2 labels must be in zeropage for the timing to work.<br />
<br />
This solution might be ideal, using fewer cycles than doing repeated reads, and taking a consistent amount of time. It can also be adapted for DPCM-conflict free reading of controllers that require a longer report like [[four player adapters]], or the [[SNES mouse]] (see notes below).<br />
<br />
However, unlike the other solutions above, it can't be executed at any time. Instead it must be integrated into your NMI routine to coincide with your sprite OAM DMA once per frame.<br />
<br />
<pre><br />
lda #OAM<br />
sta $4014 ; ------ OAM DMA ------<br />
ldx #1 ; get put <- strobe code must take an odd number of cycles total<br />
stx buttons+0 ; get put get <- buttons must be in the zeropage<br />
stx $4016 ; put get put get<br />
dex ; put get<br />
stx $4016 ; put get put get<br />
loop:<br />
lda $4017 ; put get put GET <- loop code must take an even number of cycles total<br />
and #3 ; put get<br />
cmp #1 ; put get<br />
rol buttons+1, x ; put get put get put get (X = 0; waste 1 cycle and 0 bytes for alignment)<br />
lda $4016 ; put get put GET<br />
and #3 ; put get<br />
cmp #1 ; put get<br />
rol buttons+0 ; put get put get put<br />
bcc loop ; get put [get] <- this branch must not be allowed to cross a page<br />
</pre><br />
<br />
Note that this example routine only reads two 8-bit controllers and does not take enough time to span more than one DPCM fetch. Routines longer than this must contend with two additional constraints:<br />
* When DMC DMA is delayed by an odd number of cycles, it takes 3 cycles instead of 4, changing the cycle parity. If extending this function to read more bits, care must be taken so that ''all'' CPU write cycles are aligned. Instructions with a single write cycle must align the write to avoid conflict with the DPCM fetch, and double-write instructions like ROL need to align both writes so that the DPCM fetch falls on the first write.<ref>[//forums.nesdev.org/viewtopic.php?p=231604#p231604 Forum post:] demonstration of how ROL instruction affects alignment for OAM DMA synchronized controller reading.</ref> If an interrupt can occur during the routine, it must be aligned so the fetch can only fall on the second of the three automatic stack writes.<br />
* When DMC DMA occurs near the end of OAM DMA, it only steals 1 or 3 cycles, inverting the cycle parity. Every DMC period after that, a misaligned DPCM fetch will occur. Care must be taken to ensure this does not land on a joypad read.<br />
<br />
See [[DMA]] for detailed information on DMA timing.<br />
<br />
== Other Useful Operations ==<br />
<br />
=== Directional Safety ===<br />
<br />
To reject opposing presses (Up+Down and Left+Right), which are possible on a worn Control Pad:<br />
<pre><br />
lda buttons, x<br />
and #%00001010 ; Compare Up and Left...<br />
lsr a<br />
and buttons, x ; to Down and Right<br />
beq not_updown<br />
; Use previous frame's directions<br />
lda buttons, x<br />
eor last_frame_buttons, x<br />
and #%11110000<br />
eor last_frame_buttons, x<br />
sta buttons, x<br />
not_updown:<br />
</pre><br />
<br />
To instead reject all diagonal presses, simulating a 4-way joystick:<br />
<pre><br />
lda buttons, x<br />
and #%00001111 ; If A & (A - 1) is nonzero, A has more than one bit set<br />
beq not_diagonal<br />
sec<br />
sbc #1<br />
and buttons, x<br />
beq not_diagonal<br />
; Use previous frame's directions<br />
lda buttons, x<br />
eor last_frame_buttons, x<br />
and #%11110000<br />
eor last_frame_buttons, x<br />
sta buttons, x<br />
not_diagonal:<br />
</pre><br />
<br />
=== Calculating Presses and Releases ===<br />
<br />
To calculate newly pressed and newly released buttons by comparing against the last frame's buttons:<br />
<pre><br />
; newly pressed buttons: not held last frame, and held now<br />
lda last_frame_buttons, x<br />
eor #%11111111<br />
and buttons, x<br />
sta pressed_buttons, x<br />
<br />
; newly released buttons: not held now, and held last frame<br />
lda buttons, x<br />
eor #%11111111<br />
and last_frame_buttons, x<br />
sta released_buttons, x<br />
</pre><br />
<br />
=== Button Flags ===<br />
<br />
It is helpful to define the buttons as a series of bit flags:<br />
<pre><br />
BUTTON_A = 1 << 7<br />
BUTTON_B = 1 << 6<br />
BUTTON_SELECT = 1 << 5<br />
BUTTON_START = 1 << 4<br />
BUTTON_UP = 1 << 3<br />
BUTTON_DOWN = 1 << 2<br />
BUTTON_LEFT = 1 << 1<br />
BUTTON_RIGHT = 1 << 0<br />
</pre><br />
<br />
And then buttons can be checked as follows:<br />
<pre><br />
lda buttons<br />
and #BUTTON_A | BUTTON_B<br />
beq notPressingAorB<br />
; Handle presses.<br />
notPressingAorB:<br />
</pre><br />
<br />
== External Examples ==<br />
<br />
* [http://forums.nesdev.org/viewtopic.php?t=4124 Forum post:] Blargg's DMC-fortified controller read routine<br />
* [http://forums.nesdev.org/viewtopic.php?p=171971 Forum post:] Rahsennor's OAM-synchronized controller read<br />
* [http://forums.nesdev.org/viewtopic.php?f=2&t=14197 Forum post:] Drag's bitwise DMC-safe controller reading<br />
* [https://github.com/pinobatch/nrom-template/blob/master/src/pads.s pads.s:] pinobatch's NROM-template controller read routine<br />
<br />
== References ==<br />
<references/></div>Rainwarriorhttps://www.nesdev.org/w/index.php?title=Controller_reading_code&diff=21506Controller reading code2024-01-12T19:04:24Z<p>Rainwarrior: /* Calculating Presses and Releases */ a newline probably makes this more legible</p>
<hr />
<div>This page contains example code for reading the [[NES controller]].<br />
<br />
See also: [[Controller reading]]<br />
<br />
== Controller Reading Code ==<br />
<br />
=== Basic Example ===<br />
<br />
This is a tutorial example of the bare minimum needed to read the controller.<br />
It will explain the basic principles in detail, but once understood, you may wish to continue to the [[#Standard Read for 2 Controllers and Famicom|Standard Read]] example that follows,<br />
as a more complete and ready-to-use code example.<br />
<br />
This code describes an efficient method of reading the [[standard controller]] using [http://cc65.github.io/cc65/ ca65] syntax.<br />
<br />
The result byte ''buttons'' should be placed in zero page to save a cycle each time through the loop.<br />
<pre><br />
; we reserve one byte for storing the data that is read from controller<br />
.zeropage<br />
buttons .res 1<br />
</pre><br />
<br />
When reading from ''JOYPAD*'' what is read might be different from $01/$00 for various reasons. (See [[Controller reading]].) In this code the only concern is bit 0 read from ''JOYPAD*.''.<br />
<pre><br />
JOYPAD1 = $4016<br />
JOYPAD2 = $4017<br />
</pre><br />
<br />
This is the end result that will be stored in ''buttons''. '''1''' if the button was pressed, '''0''' otherwise.<br />
<br />
{| class="wikitable" style="text-align:center;"<br />
|-<br />
! bit<br />
| &nbsp;&nbsp;&nbsp;&nbsp;7&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;6&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;5&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;4&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;3&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;2&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;1&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;&nbsp;<br />
|-<br />
! button<br />
| A<br />
| B<br />
| Select<br />
| Start<br />
| Up<br />
| Down<br />
| Left<br />
| Right<br />
|}<br />
<br />
This subroutine takes 132 cycles to execute but ignores the Famicom expansion controller.<br />
Many controller reading subroutines use the X or Y register to count 8 times through the loop.<br />
But this one uses a more clever [[wikipedia:Ring counter|ring counter]] technique: $01 is loaded into the result first, and once eight bits are shifted in, the 1 bit will be shifted out, terminating the loop.<br />
<pre><br />
; At the same time that we strobe bit 0, we initialize the ring counter<br />
; so we're hitting two birds with one stone here<br />
readjoy:<br />
lda #$01<br />
; While the strobe bit is set, buttons will be continuously reloaded.<br />
; This means that reading from JOYPAD1 will only return the state of the<br />
; first button: button A.<br />
sta JOYPAD1<br />
sta buttons<br />
lsr a ; now A is 0<br />
; By storing 0 into JOYPAD1, the strobe bit is cleared and the reloading stops.<br />
; This allows all 8 buttons (newly reloaded) to be read from JOYPAD1.<br />
sta JOYPAD1<br />
loop:<br />
lda JOYPAD1<br />
lsr a ; bit 0 -> Carry<br />
rol buttons ; Carry -> bit 0; bit 7 -> Carry<br />
bcc loop<br />
rts<br />
</pre><br />
<br />
Continue to the next example for a more complete read routine that handles both controllers and the standard Famicom expansion controllers.<br />
<br />
=== Standard Read for 2 Controllers and Famicom ===<br />
<br />
Adding support for controllers on the Famicom's DA15 expansion port and for player 2's controller is straightforward. Something similar to the following routine is used in most Famicom games.<br />
Even though the expansion port is unused on the NES, the unconnected bit will read as 0, so this solution works safely with both Famicom and NES hardware.<br />
<pre><br />
.zeropage<br />
buttons: .res 2 ; space for 2 reads<br />
<br />
.code<br />
readjoyx2:<br />
ldx #$00<br />
jsr readjoyx ; X=0: read controller 1<br />
inx<br />
; fall through to readjoyx below, X=1: read controller 2<br />
<br />
readjoyx: ; X register = 0 for controller 1, 1 for controller 2<br />
lda #$01<br />
sta JOYPAD1<br />
sta buttons, x<br />
lsr a<br />
sta JOYPAD1<br />
loop:<br />
lda JOYPAD1, x<br />
and #%00000011 ; ignore bits other than controller<br />
cmp #$01 ; Set carry if and only if nonzero<br />
rol buttons, x ; Carry -> bit 0; but 7 -> Carry<br />
bcc loop<br />
rts<br />
</pre><br />
<br />
If playing DPCM samples, there is an additional reread step to prevent errors ([[#DPCM Safety using Repeated Reads|see below]]).<br />
<br />
Note that the <tt>and</tt> to ignore bits is not optional, as the upper bits of <tt>JOYPAD1</tt> read are not guaranteed to be 1 or 0<ref>[[Controller_reading#Unconnected_data_lines_and_open_bus|Controller reading: Unconnected data lines and open bus]]</ref>.<br />
<br />
=== Alternative 2 Controllers Read ===<br />
<br />
Alternatively, we could combine both controller reads into 1 loop with a single strobe, though this routine is not safe to use with DPCM samples playing ([[#DPCM Safety using Repeated Reads|see below]]).<br />
<pre><br />
.zeropage<br />
buttons: .res 2<br />
<br />
.code<br />
readjoy2:<br />
lda #$01<br />
sta JOYPAD1<br />
sta buttons+1 ; player 2's buttons double as a ring counter<br />
lsr a<br />
sta JOYPAD1<br />
loop:<br />
lda JOYPAD1<br />
and #%00000011<br />
cmp #$01<br />
rol buttons+0<br />
lda JOYPAD2<br />
and #%00000011<br />
cmp #$01<br />
rol buttons+1<br />
bcc loop<br />
rts<br />
</pre><br />
<br />
=== DPCM Safety using Repeated Reads ===<br />
<br />
If your code is intended to be used with [[APU DMC]] playback, this code will need to be altered. The NES occasionally glitches the controller port twice in a row if sample playback is enabled, and games using samples need to work around this. The most common technique, as seen in ''Super Mario Bros. 3''<ref>[//forums.nesdev.org/viewtopic.php?p=151720#p151720 Super Mario Bros. 3 controller reread method]</ref> and other games, will read each controller twice, but in the event of a mismatch it will keep re-reading the controller until two results in a row are the same.<br />
<pre><br />
readjoy2_safe:<br />
ldx #$00<br />
jsr readjoyx_safe ; X=0: safe read controller 1<br />
inx<br />
; fall through to readjoyx_safe, X=1: safe read controller 2<br />
<br />
readjoyx_safe:<br />
jsr readjoyx<br />
reread:<br />
lda buttons, x<br />
pha<br />
jsr readjoyx<br />
pla<br />
cmp buttons, x<br />
bne reread<br />
rts<br />
</pre><br />
<br />
Note that the time between the start of one read and the end of the next read must be less than the length of the fastest DMC fetch period (432 cycles). For this reason, it is normal to read controllers one at a time with this method, rather than attempting both at once. (Note: <code>readjoy2</code> above takes too long to be suitable.) [[Game bugs|''Gimmick!'' has such a bug]] resulting from trying to read both at once.<br />
<br />
Most often a controller will be read 2 times, and 3 or 4 in the case of a DPCM corruption, or the player pressing a button during the read. With the assistance of tools, a malicious controller input could change the buttons on every read, holding it in this reread loop indefinitely<ref>[https://arstechnica.com/gaming/2016/07/how-to-beat-super-mario-bros-3-in-less-than-a-second/ Ars Technica: How to beat Super Mario Bros. 3 in less than a second]</ref><ref>https://tasvideos.org/6466S Tool-Assisted Speedrun of Super Mario Bros. 3 which first demonstrated abusing controller reread routines.</ref>, but this is generally not an important edge case to account for.<br />
<br />
=== DPCM Safety using OAM DMA ===<br />
<br />
Because halts for DPCM fetches normally only occur on an put cycles, it is possible to get glitch-free controller reads by timing all '''$4016''' and '''$4017''' reads to fall on get cycles. This is made possible by the behavior of OAM DMA: the first cycle after an OAM DMA is normally guaranteed to be a get cycle.<ref>[http://forums.nesdev.org/viewtopic.php?p=171971 Forum post:] Rahsennor's OAM-synchronized controller read</ref> This is a relatively new technique and is not supported by some emulators.<ref>[http://forums.nesdev.org/viewtopic.php?f=2&t=14319&start=15#p172099 Forum post:] as of May 2016, Nintendulator and Nestopia do not accurately emulate OAM-synchronized controller reading.</ref> In the following example code, the controller1 and controller2 labels must be in zeropage for the timing to work.<br />
<br />
This solution might be ideal, using fewer cycles than doing repeated reads, and taking a consistent amount of time. It can also be adapted for DPCM-conflict free reading of controllers that require a longer report like [[four player adapters]], or the [[SNES mouse]] (see notes below).<br />
<br />
However, unlike the other solutions above, it can't be executed at any time. Instead it must be integrated into your NMI routine to coincide with your sprite OAM DMA once per frame.<br />
<br />
<pre><br />
lda #OAM<br />
sta $4014 ; ------ OAM DMA ------<br />
ldx #1 ; get put <- strobe code must take an odd number of cycles total<br />
stx buttons+0 ; get put get <- buttons must be in the zeropage<br />
stx $4016 ; put get put get<br />
dex ; put get<br />
stx $4016 ; put get put get<br />
loop:<br />
lda $4017 ; put get put GET <- loop code must take an even number of cycles total<br />
and #3 ; put get<br />
cmp #1 ; put get<br />
rol buttons+1, x ; put get put get put get (X = 0; waste 1 cycle and 0 bytes for alignment)<br />
lda $4016 ; put get put GET<br />
and #3 ; put get<br />
cmp #1 ; put get<br />
rol buttons+0 ; put get put get put<br />
bcc loop ; get put [get] <- this branch must not be allowed to cross a page<br />
</pre><br />
<br />
Note that this example routine only reads two 8-bit controllers and does not take enough time to span more than one DPCM fetch. Routines longer than this must contend with two additional constraints:<br />
* When DMC DMA is delayed by an odd number of cycles, it takes 3 cycles instead of 4, changing the cycle parity. If extending this function to read more bits, care must be taken so that ''all'' CPU write cycles are aligned. Instructions with a single write cycle must align the write to avoid conflict with the DPCM fetch, and double-write instructions like ROL need to align both writes so that the DPCM fetch falls on the first write.<ref>[//forums.nesdev.org/viewtopic.php?p=231604#p231604 Forum post:] demonstration of how ROL instruction affects alignment for OAM DMA synchronized controller reading.</ref> If an interrupt can occur during the routine, it must be aligned so the fetch can only fall on the second of the three automatic stack writes.<br />
* When DMC DMA occurs near the end of OAM DMA, it only steals 1 or 3 cycles, inverting the cycle parity. Every DMC period after that, a misaligned DPCM fetch will occur. Care must be taken to ensure this does not land on a joypad read.<br />
<br />
See [[DMA]] for detailed information on DMA timing.<br />
<br />
== Other Useful Operations ==<br />
<br />
=== Directional Safety ===<br />
<br />
To reject opposing presses (Up+Down and Left+Right), which are possible on a worn Control Pad:<br />
<pre><br />
lda buttons, x<br />
and #%00001010 ; Compare Up and Left...<br />
lsr a<br />
and buttons, x ; to Down and Right<br />
beq not_updown<br />
; Use previous frame's directions<br />
lda buttons, x<br />
eor last_frame_buttons, x<br />
and #%11110000<br />
eor last_frame_buttons, x<br />
sta buttons, x<br />
not_updown:<br />
</pre><br />
<br />
To instead reject all diagonal presses, simulating a 4-way joystick:<br />
<pre><br />
lda buttons, x<br />
and #%00001111 ; If A & (A - 1) is nonzero, A has more than one bit set<br />
beq not_diagonal<br />
sec<br />
sbc #1<br />
and buttons, x<br />
beq not_diagonal<br />
; Use previous frame's directions<br />
lda buttons, x<br />
eor last_frame_buttons, x<br />
and #%11110000<br />
eor last_frame_buttons, x<br />
sta buttons, x<br />
not_diagonal:<br />
</pre><br />
<br />
=== Calculating Presses and Releases ===<br />
<br />
To calculate newly pressed and newly released buttons:<br />
<pre><br />
; newly pressed buttons: not held last frame, and held now<br />
lda last_frame_buttons, x<br />
eor #%11111111<br />
and buttons, x<br />
sta pressed_buttons, x<br />
<br />
; newly released buttons: not held now, and held last frame<br />
lda buttons, x<br />
eor #%11111111<br />
and last_frame_buttons, x<br />
sta released_buttons, x<br />
</pre><br />
<br />
=== Button Flags ===<br />
<br />
It is helpful to define the buttons as a series of bit flags:<br />
<pre><br />
BUTTON_A = 1 << 7<br />
BUTTON_B = 1 << 6<br />
BUTTON_SELECT = 1 << 5<br />
BUTTON_START = 1 << 4<br />
BUTTON_UP = 1 << 3<br />
BUTTON_DOWN = 1 << 2<br />
BUTTON_LEFT = 1 << 1<br />
BUTTON_RIGHT = 1 << 0<br />
</pre><br />
<br />
And then buttons can be checked as follows:<br />
<pre><br />
lda buttons<br />
and #BUTTON_A | BUTTON_B<br />
beq notPressingAorB<br />
; Handle presses.<br />
notPressingAorB:<br />
</pre><br />
<br />
== External Examples ==<br />
<br />
* [http://forums.nesdev.org/viewtopic.php?t=4124 Forum post:] Blargg's DMC-fortified controller read routine<br />
* [http://forums.nesdev.org/viewtopic.php?p=171971 Forum post:] Rahsennor's OAM-synchronized controller read<br />
* [http://forums.nesdev.org/viewtopic.php?f=2&t=14197 Forum post:] Drag's bitwise DMC-safe controller reading<br />
* [https://github.com/pinobatch/nrom-template/blob/master/src/pads.s pads.s:] pinobatch's NROM-template controller read routine<br />
<br />
== References ==<br />
<references/></div>Rainwarriorhttps://www.nesdev.org/w/index.php?title=Controller_reading_code&diff=21505Controller reading code2024-01-12T19:03:51Z<p>Rainwarrior: /* Calculating Presses and Releases */ put this example in the order it was described, add an annotation of what the operation is doing</p>
<hr />
<div>This page contains example code for reading the [[NES controller]].<br />
<br />
See also: [[Controller reading]]<br />
<br />
== Controller Reading Code ==<br />
<br />
=== Basic Example ===<br />
<br />
This is a tutorial example of the bare minimum needed to read the controller.<br />
It will explain the basic principles in detail, but once understood, you may wish to continue to the [[#Standard Read for 2 Controllers and Famicom|Standard Read]] example that follows,<br />
as a more complete and ready-to-use code example.<br />
<br />
This code describes an efficient method of reading the [[standard controller]] using [http://cc65.github.io/cc65/ ca65] syntax.<br />
<br />
The result byte ''buttons'' should be placed in zero page to save a cycle each time through the loop.<br />
<pre><br />
; we reserve one byte for storing the data that is read from controller<br />
.zeropage<br />
buttons .res 1<br />
</pre><br />
<br />
When reading from ''JOYPAD*'' what is read might be different from $01/$00 for various reasons. (See [[Controller reading]].) In this code the only concern is bit 0 read from ''JOYPAD*.''.<br />
<pre><br />
JOYPAD1 = $4016<br />
JOYPAD2 = $4017<br />
</pre><br />
<br />
This is the end result that will be stored in ''buttons''. '''1''' if the button was pressed, '''0''' otherwise.<br />
<br />
{| class="wikitable" style="text-align:center;"<br />
|-<br />
! bit<br />
| &nbsp;&nbsp;&nbsp;&nbsp;7&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;6&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;5&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;4&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;3&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;2&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;1&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;&nbsp;<br />
|-<br />
! button<br />
| A<br />
| B<br />
| Select<br />
| Start<br />
| Up<br />
| Down<br />
| Left<br />
| Right<br />
|}<br />
<br />
This subroutine takes 132 cycles to execute but ignores the Famicom expansion controller.<br />
Many controller reading subroutines use the X or Y register to count 8 times through the loop.<br />
But this one uses a more clever [[wikipedia:Ring counter|ring counter]] technique: $01 is loaded into the result first, and once eight bits are shifted in, the 1 bit will be shifted out, terminating the loop.<br />
<pre><br />
; At the same time that we strobe bit 0, we initialize the ring counter<br />
; so we're hitting two birds with one stone here<br />
readjoy:<br />
lda #$01<br />
; While the strobe bit is set, buttons will be continuously reloaded.<br />
; This means that reading from JOYPAD1 will only return the state of the<br />
; first button: button A.<br />
sta JOYPAD1<br />
sta buttons<br />
lsr a ; now A is 0<br />
; By storing 0 into JOYPAD1, the strobe bit is cleared and the reloading stops.<br />
; This allows all 8 buttons (newly reloaded) to be read from JOYPAD1.<br />
sta JOYPAD1<br />
loop:<br />
lda JOYPAD1<br />
lsr a ; bit 0 -> Carry<br />
rol buttons ; Carry -> bit 0; bit 7 -> Carry<br />
bcc loop<br />
rts<br />
</pre><br />
<br />
Continue to the next example for a more complete read routine that handles both controllers and the standard Famicom expansion controllers.<br />
<br />
=== Standard Read for 2 Controllers and Famicom ===<br />
<br />
Adding support for controllers on the Famicom's DA15 expansion port and for player 2's controller is straightforward. Something similar to the following routine is used in most Famicom games.<br />
Even though the expansion port is unused on the NES, the unconnected bit will read as 0, so this solution works safely with both Famicom and NES hardware.<br />
<pre><br />
.zeropage<br />
buttons: .res 2 ; space for 2 reads<br />
<br />
.code<br />
readjoyx2:<br />
ldx #$00<br />
jsr readjoyx ; X=0: read controller 1<br />
inx<br />
; fall through to readjoyx below, X=1: read controller 2<br />
<br />
readjoyx: ; X register = 0 for controller 1, 1 for controller 2<br />
lda #$01<br />
sta JOYPAD1<br />
sta buttons, x<br />
lsr a<br />
sta JOYPAD1<br />
loop:<br />
lda JOYPAD1, x<br />
and #%00000011 ; ignore bits other than controller<br />
cmp #$01 ; Set carry if and only if nonzero<br />
rol buttons, x ; Carry -> bit 0; but 7 -> Carry<br />
bcc loop<br />
rts<br />
</pre><br />
<br />
If playing DPCM samples, there is an additional reread step to prevent errors ([[#DPCM Safety using Repeated Reads|see below]]).<br />
<br />
Note that the <tt>and</tt> to ignore bits is not optional, as the upper bits of <tt>JOYPAD1</tt> read are not guaranteed to be 1 or 0<ref>[[Controller_reading#Unconnected_data_lines_and_open_bus|Controller reading: Unconnected data lines and open bus]]</ref>.<br />
<br />
=== Alternative 2 Controllers Read ===<br />
<br />
Alternatively, we could combine both controller reads into 1 loop with a single strobe, though this routine is not safe to use with DPCM samples playing ([[#DPCM Safety using Repeated Reads|see below]]).<br />
<pre><br />
.zeropage<br />
buttons: .res 2<br />
<br />
.code<br />
readjoy2:<br />
lda #$01<br />
sta JOYPAD1<br />
sta buttons+1 ; player 2's buttons double as a ring counter<br />
lsr a<br />
sta JOYPAD1<br />
loop:<br />
lda JOYPAD1<br />
and #%00000011<br />
cmp #$01<br />
rol buttons+0<br />
lda JOYPAD2<br />
and #%00000011<br />
cmp #$01<br />
rol buttons+1<br />
bcc loop<br />
rts<br />
</pre><br />
<br />
=== DPCM Safety using Repeated Reads ===<br />
<br />
If your code is intended to be used with [[APU DMC]] playback, this code will need to be altered. The NES occasionally glitches the controller port twice in a row if sample playback is enabled, and games using samples need to work around this. The most common technique, as seen in ''Super Mario Bros. 3''<ref>[//forums.nesdev.org/viewtopic.php?p=151720#p151720 Super Mario Bros. 3 controller reread method]</ref> and other games, will read each controller twice, but in the event of a mismatch it will keep re-reading the controller until two results in a row are the same.<br />
<pre><br />
readjoy2_safe:<br />
ldx #$00<br />
jsr readjoyx_safe ; X=0: safe read controller 1<br />
inx<br />
; fall through to readjoyx_safe, X=1: safe read controller 2<br />
<br />
readjoyx_safe:<br />
jsr readjoyx<br />
reread:<br />
lda buttons, x<br />
pha<br />
jsr readjoyx<br />
pla<br />
cmp buttons, x<br />
bne reread<br />
rts<br />
</pre><br />
<br />
Note that the time between the start of one read and the end of the next read must be less than the length of the fastest DMC fetch period (432 cycles). For this reason, it is normal to read controllers one at a time with this method, rather than attempting both at once. (Note: <code>readjoy2</code> above takes too long to be suitable.) [[Game bugs|''Gimmick!'' has such a bug]] resulting from trying to read both at once.<br />
<br />
Most often a controller will be read 2 times, and 3 or 4 in the case of a DPCM corruption, or the player pressing a button during the read. With the assistance of tools, a malicious controller input could change the buttons on every read, holding it in this reread loop indefinitely<ref>[https://arstechnica.com/gaming/2016/07/how-to-beat-super-mario-bros-3-in-less-than-a-second/ Ars Technica: How to beat Super Mario Bros. 3 in less than a second]</ref><ref>https://tasvideos.org/6466S Tool-Assisted Speedrun of Super Mario Bros. 3 which first demonstrated abusing controller reread routines.</ref>, but this is generally not an important edge case to account for.<br />
<br />
=== DPCM Safety using OAM DMA ===<br />
<br />
Because halts for DPCM fetches normally only occur on an put cycles, it is possible to get glitch-free controller reads by timing all '''$4016''' and '''$4017''' reads to fall on get cycles. This is made possible by the behavior of OAM DMA: the first cycle after an OAM DMA is normally guaranteed to be a get cycle.<ref>[http://forums.nesdev.org/viewtopic.php?p=171971 Forum post:] Rahsennor's OAM-synchronized controller read</ref> This is a relatively new technique and is not supported by some emulators.<ref>[http://forums.nesdev.org/viewtopic.php?f=2&t=14319&start=15#p172099 Forum post:] as of May 2016, Nintendulator and Nestopia do not accurately emulate OAM-synchronized controller reading.</ref> In the following example code, the controller1 and controller2 labels must be in zeropage for the timing to work.<br />
<br />
This solution might be ideal, using fewer cycles than doing repeated reads, and taking a consistent amount of time. It can also be adapted for DPCM-conflict free reading of controllers that require a longer report like [[four player adapters]], or the [[SNES mouse]] (see notes below).<br />
<br />
However, unlike the other solutions above, it can't be executed at any time. Instead it must be integrated into your NMI routine to coincide with your sprite OAM DMA once per frame.<br />
<br />
<pre><br />
lda #OAM<br />
sta $4014 ; ------ OAM DMA ------<br />
ldx #1 ; get put <- strobe code must take an odd number of cycles total<br />
stx buttons+0 ; get put get <- buttons must be in the zeropage<br />
stx $4016 ; put get put get<br />
dex ; put get<br />
stx $4016 ; put get put get<br />
loop:<br />
lda $4017 ; put get put GET <- loop code must take an even number of cycles total<br />
and #3 ; put get<br />
cmp #1 ; put get<br />
rol buttons+1, x ; put get put get put get (X = 0; waste 1 cycle and 0 bytes for alignment)<br />
lda $4016 ; put get put GET<br />
and #3 ; put get<br />
cmp #1 ; put get<br />
rol buttons+0 ; put get put get put<br />
bcc loop ; get put [get] <- this branch must not be allowed to cross a page<br />
</pre><br />
<br />
Note that this example routine only reads two 8-bit controllers and does not take enough time to span more than one DPCM fetch. Routines longer than this must contend with two additional constraints:<br />
* When DMC DMA is delayed by an odd number of cycles, it takes 3 cycles instead of 4, changing the cycle parity. If extending this function to read more bits, care must be taken so that ''all'' CPU write cycles are aligned. Instructions with a single write cycle must align the write to avoid conflict with the DPCM fetch, and double-write instructions like ROL need to align both writes so that the DPCM fetch falls on the first write.<ref>[//forums.nesdev.org/viewtopic.php?p=231604#p231604 Forum post:] demonstration of how ROL instruction affects alignment for OAM DMA synchronized controller reading.</ref> If an interrupt can occur during the routine, it must be aligned so the fetch can only fall on the second of the three automatic stack writes.<br />
* When DMC DMA occurs near the end of OAM DMA, it only steals 1 or 3 cycles, inverting the cycle parity. Every DMC period after that, a misaligned DPCM fetch will occur. Care must be taken to ensure this does not land on a joypad read.<br />
<br />
See [[DMA]] for detailed information on DMA timing.<br />
<br />
== Other Useful Operations ==<br />
<br />
=== Directional Safety ===<br />
<br />
To reject opposing presses (Up+Down and Left+Right), which are possible on a worn Control Pad:<br />
<pre><br />
lda buttons, x<br />
and #%00001010 ; Compare Up and Left...<br />
lsr a<br />
and buttons, x ; to Down and Right<br />
beq not_updown<br />
; Use previous frame's directions<br />
lda buttons, x<br />
eor last_frame_buttons, x<br />
and #%11110000<br />
eor last_frame_buttons, x<br />
sta buttons, x<br />
not_updown:<br />
</pre><br />
<br />
To instead reject all diagonal presses, simulating a 4-way joystick:<br />
<pre><br />
lda buttons, x<br />
and #%00001111 ; If A & (A - 1) is nonzero, A has more than one bit set<br />
beq not_diagonal<br />
sec<br />
sbc #1<br />
and buttons, x<br />
beq not_diagonal<br />
; Use previous frame's directions<br />
lda buttons, x<br />
eor last_frame_buttons, x<br />
and #%11110000<br />
eor last_frame_buttons, x<br />
sta buttons, x<br />
not_diagonal:<br />
</pre><br />
<br />
=== Calculating Presses and Releases ===<br />
<br />
To calculate newly pressed and newly released buttons:<br />
<pre><br />
; newly pressed buttons: not held last frame, and held now<br />
lda last_frame_buttons, x<br />
eor #%11111111<br />
and buttons, x<br />
sta pressed_buttons, x<br />
; newly released buttons: not held now, and held last frame<br />
lda buttons, x<br />
eor #%11111111<br />
and last_frame_buttons, x<br />
sta released_buttons, x<br />
</pre><br />
<br />
=== Button Flags ===<br />
<br />
It is helpful to define the buttons as a series of bit flags:<br />
<pre><br />
BUTTON_A = 1 << 7<br />
BUTTON_B = 1 << 6<br />
BUTTON_SELECT = 1 << 5<br />
BUTTON_START = 1 << 4<br />
BUTTON_UP = 1 << 3<br />
BUTTON_DOWN = 1 << 2<br />
BUTTON_LEFT = 1 << 1<br />
BUTTON_RIGHT = 1 << 0<br />
</pre><br />
<br />
And then buttons can be checked as follows:<br />
<pre><br />
lda buttons<br />
and #BUTTON_A | BUTTON_B<br />
beq notPressingAorB<br />
; Handle presses.<br />
notPressingAorB:<br />
</pre><br />
<br />
== External Examples ==<br />
<br />
* [http://forums.nesdev.org/viewtopic.php?t=4124 Forum post:] Blargg's DMC-fortified controller read routine<br />
* [http://forums.nesdev.org/viewtopic.php?p=171971 Forum post:] Rahsennor's OAM-synchronized controller read<br />
* [http://forums.nesdev.org/viewtopic.php?f=2&t=14197 Forum post:] Drag's bitwise DMC-safe controller reading<br />
* [https://github.com/pinobatch/nrom-template/blob/master/src/pads.s pads.s:] pinobatch's NROM-template controller read routine<br />
<br />
== References ==<br />
<references/></div>Rainwarriorhttps://www.nesdev.org/w/index.php?title=Controller_reading_code&diff=21504Controller reading code2024-01-12T18:56:19Z<p>Rainwarrior: /* DPCM Safety using OAM DMA */ adaptation for longer report is not trival, so make sure to point out the notes below</p>
<hr />
<div>This page contains example code for reading the [[NES controller]].<br />
<br />
See also: [[Controller reading]]<br />
<br />
== Controller Reading Code ==<br />
<br />
=== Basic Example ===<br />
<br />
This is a tutorial example of the bare minimum needed to read the controller.<br />
It will explain the basic principles in detail, but once understood, you may wish to continue to the [[#Standard Read for 2 Controllers and Famicom|Standard Read]] example that follows,<br />
as a more complete and ready-to-use code example.<br />
<br />
This code describes an efficient method of reading the [[standard controller]] using [http://cc65.github.io/cc65/ ca65] syntax.<br />
<br />
The result byte ''buttons'' should be placed in zero page to save a cycle each time through the loop.<br />
<pre><br />
; we reserve one byte for storing the data that is read from controller<br />
.zeropage<br />
buttons .res 1<br />
</pre><br />
<br />
When reading from ''JOYPAD*'' what is read might be different from $01/$00 for various reasons. (See [[Controller reading]].) In this code the only concern is bit 0 read from ''JOYPAD*.''.<br />
<pre><br />
JOYPAD1 = $4016<br />
JOYPAD2 = $4017<br />
</pre><br />
<br />
This is the end result that will be stored in ''buttons''. '''1''' if the button was pressed, '''0''' otherwise.<br />
<br />
{| class="wikitable" style="text-align:center;"<br />
|-<br />
! bit<br />
| &nbsp;&nbsp;&nbsp;&nbsp;7&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;6&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;5&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;4&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;3&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;2&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;1&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;&nbsp;<br />
|-<br />
! button<br />
| A<br />
| B<br />
| Select<br />
| Start<br />
| Up<br />
| Down<br />
| Left<br />
| Right<br />
|}<br />
<br />
This subroutine takes 132 cycles to execute but ignores the Famicom expansion controller.<br />
Many controller reading subroutines use the X or Y register to count 8 times through the loop.<br />
But this one uses a more clever [[wikipedia:Ring counter|ring counter]] technique: $01 is loaded into the result first, and once eight bits are shifted in, the 1 bit will be shifted out, terminating the loop.<br />
<pre><br />
; At the same time that we strobe bit 0, we initialize the ring counter<br />
; so we're hitting two birds with one stone here<br />
readjoy:<br />
lda #$01<br />
; While the strobe bit is set, buttons will be continuously reloaded.<br />
; This means that reading from JOYPAD1 will only return the state of the<br />
; first button: button A.<br />
sta JOYPAD1<br />
sta buttons<br />
lsr a ; now A is 0<br />
; By storing 0 into JOYPAD1, the strobe bit is cleared and the reloading stops.<br />
; This allows all 8 buttons (newly reloaded) to be read from JOYPAD1.<br />
sta JOYPAD1<br />
loop:<br />
lda JOYPAD1<br />
lsr a ; bit 0 -> Carry<br />
rol buttons ; Carry -> bit 0; bit 7 -> Carry<br />
bcc loop<br />
rts<br />
</pre><br />
<br />
Continue to the next example for a more complete read routine that handles both controllers and the standard Famicom expansion controllers.<br />
<br />
=== Standard Read for 2 Controllers and Famicom ===<br />
<br />
Adding support for controllers on the Famicom's DA15 expansion port and for player 2's controller is straightforward. Something similar to the following routine is used in most Famicom games.<br />
Even though the expansion port is unused on the NES, the unconnected bit will read as 0, so this solution works safely with both Famicom and NES hardware.<br />
<pre><br />
.zeropage<br />
buttons: .res 2 ; space for 2 reads<br />
<br />
.code<br />
readjoyx2:<br />
ldx #$00<br />
jsr readjoyx ; X=0: read controller 1<br />
inx<br />
; fall through to readjoyx below, X=1: read controller 2<br />
<br />
readjoyx: ; X register = 0 for controller 1, 1 for controller 2<br />
lda #$01<br />
sta JOYPAD1<br />
sta buttons, x<br />
lsr a<br />
sta JOYPAD1<br />
loop:<br />
lda JOYPAD1, x<br />
and #%00000011 ; ignore bits other than controller<br />
cmp #$01 ; Set carry if and only if nonzero<br />
rol buttons, x ; Carry -> bit 0; but 7 -> Carry<br />
bcc loop<br />
rts<br />
</pre><br />
<br />
If playing DPCM samples, there is an additional reread step to prevent errors ([[#DPCM Safety using Repeated Reads|see below]]).<br />
<br />
Note that the <tt>and</tt> to ignore bits is not optional, as the upper bits of <tt>JOYPAD1</tt> read are not guaranteed to be 1 or 0<ref>[[Controller_reading#Unconnected_data_lines_and_open_bus|Controller reading: Unconnected data lines and open bus]]</ref>.<br />
<br />
=== Alternative 2 Controllers Read ===<br />
<br />
Alternatively, we could combine both controller reads into 1 loop with a single strobe, though this routine is not safe to use with DPCM samples playing ([[#DPCM Safety using Repeated Reads|see below]]).<br />
<pre><br />
.zeropage<br />
buttons: .res 2<br />
<br />
.code<br />
readjoy2:<br />
lda #$01<br />
sta JOYPAD1<br />
sta buttons+1 ; player 2's buttons double as a ring counter<br />
lsr a<br />
sta JOYPAD1<br />
loop:<br />
lda JOYPAD1<br />
and #%00000011<br />
cmp #$01<br />
rol buttons+0<br />
lda JOYPAD2<br />
and #%00000011<br />
cmp #$01<br />
rol buttons+1<br />
bcc loop<br />
rts<br />
</pre><br />
<br />
=== DPCM Safety using Repeated Reads ===<br />
<br />
If your code is intended to be used with [[APU DMC]] playback, this code will need to be altered. The NES occasionally glitches the controller port twice in a row if sample playback is enabled, and games using samples need to work around this. The most common technique, as seen in ''Super Mario Bros. 3''<ref>[//forums.nesdev.org/viewtopic.php?p=151720#p151720 Super Mario Bros. 3 controller reread method]</ref> and other games, will read each controller twice, but in the event of a mismatch it will keep re-reading the controller until two results in a row are the same.<br />
<pre><br />
readjoy2_safe:<br />
ldx #$00<br />
jsr readjoyx_safe ; X=0: safe read controller 1<br />
inx<br />
; fall through to readjoyx_safe, X=1: safe read controller 2<br />
<br />
readjoyx_safe:<br />
jsr readjoyx<br />
reread:<br />
lda buttons, x<br />
pha<br />
jsr readjoyx<br />
pla<br />
cmp buttons, x<br />
bne reread<br />
rts<br />
</pre><br />
<br />
Note that the time between the start of one read and the end of the next read must be less than the length of the fastest DMC fetch period (432 cycles). For this reason, it is normal to read controllers one at a time with this method, rather than attempting both at once. (Note: <code>readjoy2</code> above takes too long to be suitable.) [[Game bugs|''Gimmick!'' has such a bug]] resulting from trying to read both at once.<br />
<br />
Most often a controller will be read 2 times, and 3 or 4 in the case of a DPCM corruption, or the player pressing a button during the read. With the assistance of tools, a malicious controller input could change the buttons on every read, holding it in this reread loop indefinitely<ref>[https://arstechnica.com/gaming/2016/07/how-to-beat-super-mario-bros-3-in-less-than-a-second/ Ars Technica: How to beat Super Mario Bros. 3 in less than a second]</ref><ref>https://tasvideos.org/6466S Tool-Assisted Speedrun of Super Mario Bros. 3 which first demonstrated abusing controller reread routines.</ref>, but this is generally not an important edge case to account for.<br />
<br />
=== DPCM Safety using OAM DMA ===<br />
<br />
Because halts for DPCM fetches normally only occur on an put cycles, it is possible to get glitch-free controller reads by timing all '''$4016''' and '''$4017''' reads to fall on get cycles. This is made possible by the behavior of OAM DMA: the first cycle after an OAM DMA is normally guaranteed to be a get cycle.<ref>[http://forums.nesdev.org/viewtopic.php?p=171971 Forum post:] Rahsennor's OAM-synchronized controller read</ref> This is a relatively new technique and is not supported by some emulators.<ref>[http://forums.nesdev.org/viewtopic.php?f=2&t=14319&start=15#p172099 Forum post:] as of May 2016, Nintendulator and Nestopia do not accurately emulate OAM-synchronized controller reading.</ref> In the following example code, the controller1 and controller2 labels must be in zeropage for the timing to work.<br />
<br />
This solution might be ideal, using fewer cycles than doing repeated reads, and taking a consistent amount of time. It can also be adapted for DPCM-conflict free reading of controllers that require a longer report like [[four player adapters]], or the [[SNES mouse]] (see notes below).<br />
<br />
However, unlike the other solutions above, it can't be executed at any time. Instead it must be integrated into your NMI routine to coincide with your sprite OAM DMA once per frame.<br />
<br />
<pre><br />
lda #OAM<br />
sta $4014 ; ------ OAM DMA ------<br />
ldx #1 ; get put <- strobe code must take an odd number of cycles total<br />
stx buttons+0 ; get put get <- buttons must be in the zeropage<br />
stx $4016 ; put get put get<br />
dex ; put get<br />
stx $4016 ; put get put get<br />
loop:<br />
lda $4017 ; put get put GET <- loop code must take an even number of cycles total<br />
and #3 ; put get<br />
cmp #1 ; put get<br />
rol buttons+1, x ; put get put get put get (X = 0; waste 1 cycle and 0 bytes for alignment)<br />
lda $4016 ; put get put GET<br />
and #3 ; put get<br />
cmp #1 ; put get<br />
rol buttons+0 ; put get put get put<br />
bcc loop ; get put [get] <- this branch must not be allowed to cross a page<br />
</pre><br />
<br />
Note that this example routine only reads two 8-bit controllers and does not take enough time to span more than one DPCM fetch. Routines longer than this must contend with two additional constraints:<br />
* When DMC DMA is delayed by an odd number of cycles, it takes 3 cycles instead of 4, changing the cycle parity. If extending this function to read more bits, care must be taken so that ''all'' CPU write cycles are aligned. Instructions with a single write cycle must align the write to avoid conflict with the DPCM fetch, and double-write instructions like ROL need to align both writes so that the DPCM fetch falls on the first write.<ref>[//forums.nesdev.org/viewtopic.php?p=231604#p231604 Forum post:] demonstration of how ROL instruction affects alignment for OAM DMA synchronized controller reading.</ref> If an interrupt can occur during the routine, it must be aligned so the fetch can only fall on the second of the three automatic stack writes.<br />
* When DMC DMA occurs near the end of OAM DMA, it only steals 1 or 3 cycles, inverting the cycle parity. Every DMC period after that, a misaligned DPCM fetch will occur. Care must be taken to ensure this does not land on a joypad read.<br />
<br />
See [[DMA]] for detailed information on DMA timing.<br />
<br />
== Other Useful Operations ==<br />
<br />
=== Directional Safety ===<br />
<br />
To reject opposing presses (Up+Down and Left+Right), which are possible on a worn Control Pad:<br />
<pre><br />
lda buttons, x<br />
and #%00001010 ; Compare Up and Left...<br />
lsr a<br />
and buttons, x ; to Down and Right<br />
beq not_updown<br />
; Use previous frame's directions<br />
lda buttons, x<br />
eor last_frame_buttons, x<br />
and #%11110000<br />
eor last_frame_buttons, x<br />
sta buttons, x<br />
not_updown:<br />
</pre><br />
<br />
To instead reject all diagonal presses, simulating a 4-way joystick:<br />
<pre><br />
lda buttons, x<br />
and #%00001111 ; If A & (A - 1) is nonzero, A has more than one bit set<br />
beq not_diagonal<br />
sec<br />
sbc #1<br />
and buttons, x<br />
beq not_diagonal<br />
; Use previous frame's directions<br />
lda buttons, x<br />
eor last_frame_buttons, x<br />
and #%11110000<br />
eor last_frame_buttons, x<br />
sta buttons, x<br />
not_diagonal:<br />
</pre><br />
<br />
=== Calculating Presses and Releases ===<br />
<br />
To calculate newly pressed and newly released buttons:<br />
<pre><br />
lda buttons, x<br />
eor #%11111111<br />
and last_frame_buttons, x<br />
sta released_buttons, x<br />
lda last_frame_buttons, x<br />
eor #%11111111<br />
and buttons, x<br />
sta pressed_buttons, x<br />
</pre><br />
<br />
=== Button Flags ===<br />
<br />
It is helpful to define the buttons as a series of bit flags:<br />
<pre><br />
BUTTON_A = 1 << 7<br />
BUTTON_B = 1 << 6<br />
BUTTON_SELECT = 1 << 5<br />
BUTTON_START = 1 << 4<br />
BUTTON_UP = 1 << 3<br />
BUTTON_DOWN = 1 << 2<br />
BUTTON_LEFT = 1 << 1<br />
BUTTON_RIGHT = 1 << 0<br />
</pre><br />
<br />
And then buttons can be checked as follows:<br />
<pre><br />
lda buttons<br />
and #BUTTON_A | BUTTON_B<br />
beq notPressingAorB<br />
; Handle presses.<br />
notPressingAorB:<br />
</pre><br />
<br />
== External Examples ==<br />
<br />
* [http://forums.nesdev.org/viewtopic.php?t=4124 Forum post:] Blargg's DMC-fortified controller read routine<br />
* [http://forums.nesdev.org/viewtopic.php?p=171971 Forum post:] Rahsennor's OAM-synchronized controller read<br />
* [http://forums.nesdev.org/viewtopic.php?f=2&t=14197 Forum post:] Drag's bitwise DMC-safe controller reading<br />
* [https://github.com/pinobatch/nrom-template/blob/master/src/pads.s pads.s:] pinobatch's NROM-template controller read routine<br />
<br />
== References ==<br />
<references/></div>Rainwarriorhttps://www.nesdev.org/w/index.php?title=Controller_reading_code&diff=21503Controller reading code2024-01-12T18:55:26Z<p>Rainwarrior: consistent x index notation</p>
<hr />
<div>This page contains example code for reading the [[NES controller]].<br />
<br />
See also: [[Controller reading]]<br />
<br />
== Controller Reading Code ==<br />
<br />
=== Basic Example ===<br />
<br />
This is a tutorial example of the bare minimum needed to read the controller.<br />
It will explain the basic principles in detail, but once understood, you may wish to continue to the [[#Standard Read for 2 Controllers and Famicom|Standard Read]] example that follows,<br />
as a more complete and ready-to-use code example.<br />
<br />
This code describes an efficient method of reading the [[standard controller]] using [http://cc65.github.io/cc65/ ca65] syntax.<br />
<br />
The result byte ''buttons'' should be placed in zero page to save a cycle each time through the loop.<br />
<pre><br />
; we reserve one byte for storing the data that is read from controller<br />
.zeropage<br />
buttons .res 1<br />
</pre><br />
<br />
When reading from ''JOYPAD*'' what is read might be different from $01/$00 for various reasons. (See [[Controller reading]].) In this code the only concern is bit 0 read from ''JOYPAD*.''.<br />
<pre><br />
JOYPAD1 = $4016<br />
JOYPAD2 = $4017<br />
</pre><br />
<br />
This is the end result that will be stored in ''buttons''. '''1''' if the button was pressed, '''0''' otherwise.<br />
<br />
{| class="wikitable" style="text-align:center;"<br />
|-<br />
! bit<br />
| &nbsp;&nbsp;&nbsp;&nbsp;7&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;6&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;5&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;4&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;3&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;2&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;1&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;&nbsp;<br />
|-<br />
! button<br />
| A<br />
| B<br />
| Select<br />
| Start<br />
| Up<br />
| Down<br />
| Left<br />
| Right<br />
|}<br />
<br />
This subroutine takes 132 cycles to execute but ignores the Famicom expansion controller.<br />
Many controller reading subroutines use the X or Y register to count 8 times through the loop.<br />
But this one uses a more clever [[wikipedia:Ring counter|ring counter]] technique: $01 is loaded into the result first, and once eight bits are shifted in, the 1 bit will be shifted out, terminating the loop.<br />
<pre><br />
; At the same time that we strobe bit 0, we initialize the ring counter<br />
; so we're hitting two birds with one stone here<br />
readjoy:<br />
lda #$01<br />
; While the strobe bit is set, buttons will be continuously reloaded.<br />
; This means that reading from JOYPAD1 will only return the state of the<br />
; first button: button A.<br />
sta JOYPAD1<br />
sta buttons<br />
lsr a ; now A is 0<br />
; By storing 0 into JOYPAD1, the strobe bit is cleared and the reloading stops.<br />
; This allows all 8 buttons (newly reloaded) to be read from JOYPAD1.<br />
sta JOYPAD1<br />
loop:<br />
lda JOYPAD1<br />
lsr a ; bit 0 -> Carry<br />
rol buttons ; Carry -> bit 0; bit 7 -> Carry<br />
bcc loop<br />
rts<br />
</pre><br />
<br />
Continue to the next example for a more complete read routine that handles both controllers and the standard Famicom expansion controllers.<br />
<br />
=== Standard Read for 2 Controllers and Famicom ===<br />
<br />
Adding support for controllers on the Famicom's DA15 expansion port and for player 2's controller is straightforward. Something similar to the following routine is used in most Famicom games.<br />
Even though the expansion port is unused on the NES, the unconnected bit will read as 0, so this solution works safely with both Famicom and NES hardware.<br />
<pre><br />
.zeropage<br />
buttons: .res 2 ; space for 2 reads<br />
<br />
.code<br />
readjoyx2:<br />
ldx #$00<br />
jsr readjoyx ; X=0: read controller 1<br />
inx<br />
; fall through to readjoyx below, X=1: read controller 2<br />
<br />
readjoyx: ; X register = 0 for controller 1, 1 for controller 2<br />
lda #$01<br />
sta JOYPAD1<br />
sta buttons, x<br />
lsr a<br />
sta JOYPAD1<br />
loop:<br />
lda JOYPAD1, x<br />
and #%00000011 ; ignore bits other than controller<br />
cmp #$01 ; Set carry if and only if nonzero<br />
rol buttons, x ; Carry -> bit 0; but 7 -> Carry<br />
bcc loop<br />
rts<br />
</pre><br />
<br />
If playing DPCM samples, there is an additional reread step to prevent errors ([[#DPCM Safety using Repeated Reads|see below]]).<br />
<br />
Note that the <tt>and</tt> to ignore bits is not optional, as the upper bits of <tt>JOYPAD1</tt> read are not guaranteed to be 1 or 0<ref>[[Controller_reading#Unconnected_data_lines_and_open_bus|Controller reading: Unconnected data lines and open bus]]</ref>.<br />
<br />
=== Alternative 2 Controllers Read ===<br />
<br />
Alternatively, we could combine both controller reads into 1 loop with a single strobe, though this routine is not safe to use with DPCM samples playing ([[#DPCM Safety using Repeated Reads|see below]]).<br />
<pre><br />
.zeropage<br />
buttons: .res 2<br />
<br />
.code<br />
readjoy2:<br />
lda #$01<br />
sta JOYPAD1<br />
sta buttons+1 ; player 2's buttons double as a ring counter<br />
lsr a<br />
sta JOYPAD1<br />
loop:<br />
lda JOYPAD1<br />
and #%00000011<br />
cmp #$01<br />
rol buttons+0<br />
lda JOYPAD2<br />
and #%00000011<br />
cmp #$01<br />
rol buttons+1<br />
bcc loop<br />
rts<br />
</pre><br />
<br />
=== DPCM Safety using Repeated Reads ===<br />
<br />
If your code is intended to be used with [[APU DMC]] playback, this code will need to be altered. The NES occasionally glitches the controller port twice in a row if sample playback is enabled, and games using samples need to work around this. The most common technique, as seen in ''Super Mario Bros. 3''<ref>[//forums.nesdev.org/viewtopic.php?p=151720#p151720 Super Mario Bros. 3 controller reread method]</ref> and other games, will read each controller twice, but in the event of a mismatch it will keep re-reading the controller until two results in a row are the same.<br />
<pre><br />
readjoy2_safe:<br />
ldx #$00<br />
jsr readjoyx_safe ; X=0: safe read controller 1<br />
inx<br />
; fall through to readjoyx_safe, X=1: safe read controller 2<br />
<br />
readjoyx_safe:<br />
jsr readjoyx<br />
reread:<br />
lda buttons, x<br />
pha<br />
jsr readjoyx<br />
pla<br />
cmp buttons, x<br />
bne reread<br />
rts<br />
</pre><br />
<br />
Note that the time between the start of one read and the end of the next read must be less than the length of the fastest DMC fetch period (432 cycles). For this reason, it is normal to read controllers one at a time with this method, rather than attempting both at once. (Note: <code>readjoy2</code> above takes too long to be suitable.) [[Game bugs|''Gimmick!'' has such a bug]] resulting from trying to read both at once.<br />
<br />
Most often a controller will be read 2 times, and 3 or 4 in the case of a DPCM corruption, or the player pressing a button during the read. With the assistance of tools, a malicious controller input could change the buttons on every read, holding it in this reread loop indefinitely<ref>[https://arstechnica.com/gaming/2016/07/how-to-beat-super-mario-bros-3-in-less-than-a-second/ Ars Technica: How to beat Super Mario Bros. 3 in less than a second]</ref><ref>https://tasvideos.org/6466S Tool-Assisted Speedrun of Super Mario Bros. 3 which first demonstrated abusing controller reread routines.</ref>, but this is generally not an important edge case to account for.<br />
<br />
=== DPCM Safety using OAM DMA ===<br />
<br />
Because halts for DPCM fetches normally only occur on an put cycles, it is possible to get glitch-free controller reads by timing all '''$4016''' and '''$4017''' reads to fall on get cycles. This is made possible by the behavior of OAM DMA: the first cycle after an OAM DMA is normally guaranteed to be a get cycle.<ref>[http://forums.nesdev.org/viewtopic.php?p=171971 Forum post:] Rahsennor's OAM-synchronized controller read</ref> This is a relatively new technique and is not supported by some emulators.<ref>[http://forums.nesdev.org/viewtopic.php?f=2&t=14319&start=15#p172099 Forum post:] as of May 2016, Nintendulator and Nestopia do not accurately emulate OAM-synchronized controller reading.</ref> In the following example code, the controller1 and controller2 labels must be in zeropage for the timing to work.<br />
<br />
This solution might be ideal, using fewer cycles than doing repeated reads, and taking a consistent amount of time. It can also be adapted for DPCM-conflict free reading of controllers that require a longer report like [[four player adapters]], or the [[SNES mouse]].<br />
<br />
However, unlike the other solutions above, it can't be executed at any time. Instead it must be integrated into your NMI routine to coincide with your sprite OAM DMA once per frame.<br />
<br />
<pre><br />
lda #OAM<br />
sta $4014 ; ------ OAM DMA ------<br />
ldx #1 ; get put <- strobe code must take an odd number of cycles total<br />
stx buttons+0 ; get put get <- buttons must be in the zeropage<br />
stx $4016 ; put get put get<br />
dex ; put get<br />
stx $4016 ; put get put get<br />
loop:<br />
lda $4017 ; put get put GET <- loop code must take an even number of cycles total<br />
and #3 ; put get<br />
cmp #1 ; put get<br />
rol buttons+1, x ; put get put get put get (X = 0; waste 1 cycle and 0 bytes for alignment)<br />
lda $4016 ; put get put GET<br />
and #3 ; put get<br />
cmp #1 ; put get<br />
rol buttons+0 ; put get put get put<br />
bcc loop ; get put [get] <- this branch must not be allowed to cross a page<br />
</pre><br />
<br />
Note that this example routine only reads two 8-bit controllers and does not take enough time to span more than one DPCM fetch. Routines longer than this must contend with two additional constraints:<br />
* When DMC DMA is delayed by an odd number of cycles, it takes 3 cycles instead of 4, changing the cycle parity. If extending this function to read more bits, care must be taken so that ''all'' CPU write cycles are aligned. Instructions with a single write cycle must align the write to avoid conflict with the DPCM fetch, and double-write instructions like ROL need to align both writes so that the DPCM fetch falls on the first write.<ref>[//forums.nesdev.org/viewtopic.php?p=231604#p231604 Forum post:] demonstration of how ROL instruction affects alignment for OAM DMA synchronized controller reading.</ref> If an interrupt can occur during the routine, it must be aligned so the fetch can only fall on the second of the three automatic stack writes.<br />
* When DMC DMA occurs near the end of OAM DMA, it only steals 1 or 3 cycles, inverting the cycle parity. Every DMC period after that, a misaligned DPCM fetch will occur. Care must be taken to ensure this does not land on a joypad read.<br />
<br />
See [[DMA]] for detailed information on DMA timing.<br />
<br />
== Other Useful Operations ==<br />
<br />
=== Directional Safety ===<br />
<br />
To reject opposing presses (Up+Down and Left+Right), which are possible on a worn Control Pad:<br />
<pre><br />
lda buttons, x<br />
and #%00001010 ; Compare Up and Left...<br />
lsr a<br />
and buttons, x ; to Down and Right<br />
beq not_updown<br />
; Use previous frame's directions<br />
lda buttons, x<br />
eor last_frame_buttons, x<br />
and #%11110000<br />
eor last_frame_buttons, x<br />
sta buttons, x<br />
not_updown:<br />
</pre><br />
<br />
To instead reject all diagonal presses, simulating a 4-way joystick:<br />
<pre><br />
lda buttons, x<br />
and #%00001111 ; If A & (A - 1) is nonzero, A has more than one bit set<br />
beq not_diagonal<br />
sec<br />
sbc #1<br />
and buttons, x<br />
beq not_diagonal<br />
; Use previous frame's directions<br />
lda buttons, x<br />
eor last_frame_buttons, x<br />
and #%11110000<br />
eor last_frame_buttons, x<br />
sta buttons, x<br />
not_diagonal:<br />
</pre><br />
<br />
=== Calculating Presses and Releases ===<br />
<br />
To calculate newly pressed and newly released buttons:<br />
<pre><br />
lda buttons, x<br />
eor #%11111111<br />
and last_frame_buttons, x<br />
sta released_buttons, x<br />
lda last_frame_buttons, x<br />
eor #%11111111<br />
and buttons, x<br />
sta pressed_buttons, x<br />
</pre><br />
<br />
=== Button Flags ===<br />
<br />
It is helpful to define the buttons as a series of bit flags:<br />
<pre><br />
BUTTON_A = 1 << 7<br />
BUTTON_B = 1 << 6<br />
BUTTON_SELECT = 1 << 5<br />
BUTTON_START = 1 << 4<br />
BUTTON_UP = 1 << 3<br />
BUTTON_DOWN = 1 << 2<br />
BUTTON_LEFT = 1 << 1<br />
BUTTON_RIGHT = 1 << 0<br />
</pre><br />
<br />
And then buttons can be checked as follows:<br />
<pre><br />
lda buttons<br />
and #BUTTON_A | BUTTON_B<br />
beq notPressingAorB<br />
; Handle presses.<br />
notPressingAorB:<br />
</pre><br />
<br />
== External Examples ==<br />
<br />
* [http://forums.nesdev.org/viewtopic.php?t=4124 Forum post:] Blargg's DMC-fortified controller read routine<br />
* [http://forums.nesdev.org/viewtopic.php?p=171971 Forum post:] Rahsennor's OAM-synchronized controller read<br />
* [http://forums.nesdev.org/viewtopic.php?f=2&t=14197 Forum post:] Drag's bitwise DMC-safe controller reading<br />
* [https://github.com/pinobatch/nrom-template/blob/master/src/pads.s pads.s:] pinobatch's NROM-template controller read routine<br />
<br />
== References ==<br />
<references/></div>Rainwarriorhttps://www.nesdev.org/w/index.php?title=Controller_reading_code&diff=21502Controller reading code2024-01-12T18:53:40Z<p>Rainwarrior: /* DPCM Safety using OAM DMA */ use same buttons/loop convention as other examples</p>
<hr />
<div>This page contains example code for reading the [[NES controller]].<br />
<br />
See also: [[Controller reading]]<br />
<br />
== Controller Reading Code ==<br />
<br />
=== Basic Example ===<br />
<br />
This is a tutorial example of the bare minimum needed to read the controller.<br />
It will explain the basic principles in detail, but once understood, you may wish to continue to the [[#Standard Read for 2 Controllers and Famicom|Standard Read]] example that follows,<br />
as a more complete and ready-to-use code example.<br />
<br />
This code describes an efficient method of reading the [[standard controller]] using [http://cc65.github.io/cc65/ ca65] syntax.<br />
<br />
The result byte ''buttons'' should be placed in zero page to save a cycle each time through the loop.<br />
<pre><br />
; we reserve one byte for storing the data that is read from controller<br />
.zeropage<br />
buttons .res 1<br />
</pre><br />
<br />
When reading from ''JOYPAD*'' what is read might be different from $01/$00 for various reasons. (See [[Controller reading]].) In this code the only concern is bit 0 read from ''JOYPAD*.''.<br />
<pre><br />
JOYPAD1 = $4016<br />
JOYPAD2 = $4017<br />
</pre><br />
<br />
This is the end result that will be stored in ''buttons''. '''1''' if the button was pressed, '''0''' otherwise.<br />
<br />
{| class="wikitable" style="text-align:center;"<br />
|-<br />
! bit<br />
| &nbsp;&nbsp;&nbsp;&nbsp;7&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;6&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;5&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;4&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;3&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;2&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;1&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;&nbsp;<br />
|-<br />
! button<br />
| A<br />
| B<br />
| Select<br />
| Start<br />
| Up<br />
| Down<br />
| Left<br />
| Right<br />
|}<br />
<br />
This subroutine takes 132 cycles to execute but ignores the Famicom expansion controller.<br />
Many controller reading subroutines use the X or Y register to count 8 times through the loop.<br />
But this one uses a more clever [[wikipedia:Ring counter|ring counter]] technique: $01 is loaded into the result first, and once eight bits are shifted in, the 1 bit will be shifted out, terminating the loop.<br />
<pre><br />
; At the same time that we strobe bit 0, we initialize the ring counter<br />
; so we're hitting two birds with one stone here<br />
readjoy:<br />
lda #$01<br />
; While the strobe bit is set, buttons will be continuously reloaded.<br />
; This means that reading from JOYPAD1 will only return the state of the<br />
; first button: button A.<br />
sta JOYPAD1<br />
sta buttons<br />
lsr a ; now A is 0<br />
; By storing 0 into JOYPAD1, the strobe bit is cleared and the reloading stops.<br />
; This allows all 8 buttons (newly reloaded) to be read from JOYPAD1.<br />
sta JOYPAD1<br />
loop:<br />
lda JOYPAD1<br />
lsr a ; bit 0 -> Carry<br />
rol buttons ; Carry -> bit 0; bit 7 -> Carry<br />
bcc loop<br />
rts<br />
</pre><br />
<br />
Continue to the next example for a more complete read routine that handles both controllers and the standard Famicom expansion controllers.<br />
<br />
=== Standard Read for 2 Controllers and Famicom ===<br />
<br />
Adding support for controllers on the Famicom's DA15 expansion port and for player 2's controller is straightforward. Something similar to the following routine is used in most Famicom games.<br />
Even though the expansion port is unused on the NES, the unconnected bit will read as 0, so this solution works safely with both Famicom and NES hardware.<br />
<pre><br />
.zeropage<br />
buttons: .res 2 ; space for 2 reads<br />
<br />
.code<br />
readjoyx2:<br />
ldx #$00<br />
jsr readjoyx ; X=0: read controller 1<br />
inx<br />
; fall through to readjoyx below, X=1: read controller 2<br />
<br />
readjoyx: ; X register = 0 for controller 1, 1 for controller 2<br />
lda #$01<br />
sta JOYPAD1<br />
sta buttons, X<br />
lsr a<br />
sta JOYPAD1<br />
loop:<br />
lda JOYPAD1, X<br />
and #%00000011 ; ignore bits other than controller<br />
cmp #$01 ; Set carry if and only if nonzero<br />
rol buttons, X ; Carry -> bit 0; but 7 -> Carry<br />
bcc loop<br />
rts<br />
</pre><br />
<br />
If playing DPCM samples, there is an additional reread step to prevent errors ([[#DPCM Safety using Repeated Reads|see below]]).<br />
<br />
Note that the <tt>and</tt> to ignore bits is not optional, as the upper bits of <tt>JOYPAD1</tt> read are not guaranteed to be 1 or 0<ref>[[Controller_reading#Unconnected_data_lines_and_open_bus|Controller reading: Unconnected data lines and open bus]]</ref>.<br />
<br />
=== Alternative 2 Controllers Read ===<br />
<br />
Alternatively, we could combine both controller reads into 1 loop with a single strobe, though this routine is not safe to use with DPCM samples playing ([[#DPCM Safety using Repeated Reads|see below]]).<br />
<pre><br />
.zeropage<br />
buttons: .res 2<br />
<br />
.code<br />
readjoy2:<br />
lda #$01<br />
sta JOYPAD1<br />
sta buttons+1 ; player 2's buttons double as a ring counter<br />
lsr a<br />
sta JOYPAD1<br />
loop:<br />
lda JOYPAD1<br />
and #%00000011<br />
cmp #$01<br />
rol buttons+0<br />
lda JOYPAD2<br />
and #%00000011<br />
cmp #$01<br />
rol buttons+1<br />
bcc loop<br />
rts<br />
</pre><br />
<br />
=== DPCM Safety using Repeated Reads ===<br />
<br />
If your code is intended to be used with [[APU DMC]] playback, this code will need to be altered. The NES occasionally glitches the controller port twice in a row if sample playback is enabled, and games using samples need to work around this. The most common technique, as seen in ''Super Mario Bros. 3''<ref>[//forums.nesdev.org/viewtopic.php?p=151720#p151720 Super Mario Bros. 3 controller reread method]</ref> and other games, will read each controller twice, but in the event of a mismatch it will keep re-reading the controller until two results in a row are the same.<br />
<pre><br />
readjoy2_safe:<br />
ldx #$00<br />
jsr readjoyx_safe ; X=0: safe read controller 1<br />
inx<br />
; fall through to readjoyx_safe, X=1: safe read controller 2<br />
<br />
readjoyx_safe:<br />
jsr readjoyx<br />
reread:<br />
lda buttons, X<br />
pha<br />
jsr readjoyx<br />
pla<br />
cmp buttons, X<br />
bne reread<br />
rts<br />
</pre><br />
<br />
Note that the time between the start of one read and the end of the next read must be less than the length of the fastest DMC fetch period (432 cycles). For this reason, it is normal to read controllers one at a time with this method, rather than attempting both at once. (Note: <code>readjoy2</code> above takes too long to be suitable.) [[Game bugs|''Gimmick!'' has such a bug]] resulting from trying to read both at once.<br />
<br />
Most often a controller will be read 2 times, and 3 or 4 in the case of a DPCM corruption, or the player pressing a button during the read. With the assistance of tools, a malicious controller input could change the buttons on every read, holding it in this reread loop indefinitely<ref>[https://arstechnica.com/gaming/2016/07/how-to-beat-super-mario-bros-3-in-less-than-a-second/ Ars Technica: How to beat Super Mario Bros. 3 in less than a second]</ref><ref>https://tasvideos.org/6466S Tool-Assisted Speedrun of Super Mario Bros. 3 which first demonstrated abusing controller reread routines.</ref>, but this is generally not an important edge case to account for.<br />
<br />
=== DPCM Safety using OAM DMA ===<br />
<br />
Because halts for DPCM fetches normally only occur on an put cycles, it is possible to get glitch-free controller reads by timing all '''$4016''' and '''$4017''' reads to fall on get cycles. This is made possible by the behavior of OAM DMA: the first cycle after an OAM DMA is normally guaranteed to be a get cycle.<ref>[http://forums.nesdev.org/viewtopic.php?p=171971 Forum post:] Rahsennor's OAM-synchronized controller read</ref> This is a relatively new technique and is not supported by some emulators.<ref>[http://forums.nesdev.org/viewtopic.php?f=2&t=14319&start=15#p172099 Forum post:] as of May 2016, Nintendulator and Nestopia do not accurately emulate OAM-synchronized controller reading.</ref> In the following example code, the controller1 and controller2 labels must be in zeropage for the timing to work.<br />
<br />
This solution might be ideal, using fewer cycles than doing repeated reads, and taking a consistent amount of time. It can also be adapted for DPCM-conflict free reading of controllers that require a longer report like [[four player adapters]], or the [[SNES mouse]].<br />
<br />
However, unlike the other solutions above, it can't be executed at any time. Instead it must be integrated into your NMI routine to coincide with your sprite OAM DMA once per frame.<br />
<br />
<pre><br />
lda #OAM<br />
sta $4014 ; ------ OAM DMA ------<br />
ldx #1 ; get put <- strobe code must take an odd number of cycles total<br />
stx buttons+0 ; get put get <- buttons must be in the zeropage<br />
stx $4016 ; put get put get<br />
dex ; put get<br />
stx $4016 ; put get put get<br />
loop:<br />
lda $4017 ; put get put GET <- loop code must take an even number of cycles total<br />
and #3 ; put get<br />
cmp #1 ; put get<br />
rol buttons+1, x ; put get put get put get (X = 0; waste 1 cycle and 0 bytes for alignment)<br />
lda $4016 ; put get put GET<br />
and #3 ; put get<br />
cmp #1 ; put get<br />
rol buttons+0 ; put get put get put<br />
bcc loop ; get put [get] <- this branch must not be allowed to cross a page<br />
</pre><br />
<br />
Note that this example routine only reads two 8-bit controllers and does not take enough time to span more than one DPCM fetch. Routines longer than this must contend with two additional constraints:<br />
* When DMC DMA is delayed by an odd number of cycles, it takes 3 cycles instead of 4, changing the cycle parity. If extending this function to read more bits, care must be taken so that ''all'' CPU write cycles are aligned. Instructions with a single write cycle must align the write to avoid conflict with the DPCM fetch, and double-write instructions like ROL need to align both writes so that the DPCM fetch falls on the first write.<ref>[//forums.nesdev.org/viewtopic.php?p=231604#p231604 Forum post:] demonstration of how ROL instruction affects alignment for OAM DMA synchronized controller reading.</ref> If an interrupt can occur during the routine, it must be aligned so the fetch can only fall on the second of the three automatic stack writes.<br />
* When DMC DMA occurs near the end of OAM DMA, it only steals 1 or 3 cycles, inverting the cycle parity. Every DMC period after that, a misaligned DPCM fetch will occur. Care must be taken to ensure this does not land on a joypad read.<br />
<br />
See [[DMA]] for detailed information on DMA timing.<br />
<br />
== Other Useful Operations ==<br />
<br />
=== Directional Safety ===<br />
<br />
To reject opposing presses (Up+Down and Left+Right), which are possible on a worn Control Pad:<br />
<pre><br />
lda buttons,x<br />
and #%00001010 ; Compare Up and Left...<br />
lsr a<br />
and buttons,x ; to Down and Right<br />
beq not_updown<br />
; Use previous frame's directions<br />
lda buttons,x<br />
eor last_frame_buttons,x<br />
and #%11110000<br />
eor last_frame_buttons,x<br />
sta buttons,x<br />
not_updown:<br />
</pre><br />
<br />
To instead reject all diagonal presses, simulating a 4-way joystick:<br />
<pre><br />
lda buttons,x<br />
and #%00001111 ; If A & (A - 1) is nonzero, A has more than one bit set<br />
beq not_diagonal<br />
sec<br />
sbc #1<br />
and buttons,x<br />
beq not_diagonal<br />
; Use previous frame's directions<br />
lda buttons,x<br />
eor last_frame_buttons,x<br />
and #%11110000<br />
eor last_frame_buttons,x<br />
sta buttons,x<br />
not_diagonal:<br />
</pre><br />
<br />
=== Calculating Presses and Releases ===<br />
<br />
To calculate newly pressed and newly released buttons:<br />
<pre><br />
lda buttons,x<br />
eor #%11111111<br />
and last_frame_buttons,x<br />
sta released_buttons,x<br />
lda last_frame_buttons,x<br />
eor #%11111111<br />
and buttons,x<br />
sta pressed_buttons,x<br />
</pre><br />
<br />
=== Button Flags ===<br />
<br />
It is helpful to define the buttons as a series of bit flags:<br />
<pre><br />
BUTTON_A = 1 << 7<br />
BUTTON_B = 1 << 6<br />
BUTTON_SELECT = 1 << 5<br />
BUTTON_START = 1 << 4<br />
BUTTON_UP = 1 << 3<br />
BUTTON_DOWN = 1 << 2<br />
BUTTON_LEFT = 1 << 1<br />
BUTTON_RIGHT = 1 << 0<br />
</pre><br />
<br />
And then buttons can be checked as follows:<br />
<pre><br />
lda buttons<br />
and #BUTTON_A | BUTTON_B<br />
beq notPressingAorB<br />
; Handle presses.<br />
notPressingAorB:<br />
</pre><br />
<br />
== External Examples ==<br />
<br />
* [http://forums.nesdev.org/viewtopic.php?t=4124 Forum post:] Blargg's DMC-fortified controller read routine<br />
* [http://forums.nesdev.org/viewtopic.php?p=171971 Forum post:] Rahsennor's OAM-synchronized controller read<br />
* [http://forums.nesdev.org/viewtopic.php?f=2&t=14197 Forum post:] Drag's bitwise DMC-safe controller reading<br />
* [https://github.com/pinobatch/nrom-template/blob/master/src/pads.s pads.s:] pinobatch's NROM-template controller read routine<br />
<br />
== References ==<br />
<references/></div>Rainwarriorhttps://www.nesdev.org/w/index.php?title=SNES_mouse&diff=21501SNES mouse2024-01-12T18:46:16Z<p>Rainwarrior: redirect Super NES Mouse</p>
<hr />
<div>#REDIRECT [[Super NES Mouse]]</div>Rainwarriorhttps://www.nesdev.org/w/index.php?title=Controller_reading_code&diff=21500Controller reading code2024-01-12T18:42:38Z<p>Rainwarrior: add higher level groups for "controller reading code" and "other useful operations"</p>
<hr />
<div>This page contains example code for reading the [[NES controller]].<br />
<br />
See also: [[Controller reading]]<br />
<br />
== Controller Reading Code ==<br />
<br />
=== Basic Example ===<br />
<br />
This is a tutorial example of the bare minimum needed to read the controller.<br />
It will explain the basic principles in detail, but once understood, you may wish to continue to the [[#Standard Read for 2 Controllers and Famicom|Standard Read]] example that follows,<br />
as a more complete and ready-to-use code example.<br />
<br />
This code describes an efficient method of reading the [[standard controller]] using [http://cc65.github.io/cc65/ ca65] syntax.<br />
<br />
The result byte ''buttons'' should be placed in zero page to save a cycle each time through the loop.<br />
<pre><br />
; we reserve one byte for storing the data that is read from controller<br />
.zeropage<br />
buttons .res 1<br />
</pre><br />
<br />
When reading from ''JOYPAD*'' what is read might be different from $01/$00 for various reasons. (See [[Controller reading]].) In this code the only concern is bit 0 read from ''JOYPAD*.''.<br />
<pre><br />
JOYPAD1 = $4016<br />
JOYPAD2 = $4017<br />
</pre><br />
<br />
This is the end result that will be stored in ''buttons''. '''1''' if the button was pressed, '''0''' otherwise.<br />
<br />
{| class="wikitable" style="text-align:center;"<br />
|-<br />
! bit<br />
| &nbsp;&nbsp;&nbsp;&nbsp;7&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;6&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;5&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;4&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;3&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;2&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;1&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;&nbsp;<br />
|-<br />
! button<br />
| A<br />
| B<br />
| Select<br />
| Start<br />
| Up<br />
| Down<br />
| Left<br />
| Right<br />
|}<br />
<br />
This subroutine takes 132 cycles to execute but ignores the Famicom expansion controller.<br />
Many controller reading subroutines use the X or Y register to count 8 times through the loop.<br />
But this one uses a more clever [[wikipedia:Ring counter|ring counter]] technique: $01 is loaded into the result first, and once eight bits are shifted in, the 1 bit will be shifted out, terminating the loop.<br />
<pre><br />
; At the same time that we strobe bit 0, we initialize the ring counter<br />
; so we're hitting two birds with one stone here<br />
readjoy:<br />
lda #$01<br />
; While the strobe bit is set, buttons will be continuously reloaded.<br />
; This means that reading from JOYPAD1 will only return the state of the<br />
; first button: button A.<br />
sta JOYPAD1<br />
sta buttons<br />
lsr a ; now A is 0<br />
; By storing 0 into JOYPAD1, the strobe bit is cleared and the reloading stops.<br />
; This allows all 8 buttons (newly reloaded) to be read from JOYPAD1.<br />
sta JOYPAD1<br />
loop:<br />
lda JOYPAD1<br />
lsr a ; bit 0 -> Carry<br />
rol buttons ; Carry -> bit 0; bit 7 -> Carry<br />
bcc loop<br />
rts<br />
</pre><br />
<br />
Continue to the next example for a more complete read routine that handles both controllers and the standard Famicom expansion controllers.<br />
<br />
=== Standard Read for 2 Controllers and Famicom ===<br />
<br />
Adding support for controllers on the Famicom's DA15 expansion port and for player 2's controller is straightforward. Something similar to the following routine is used in most Famicom games.<br />
Even though the expansion port is unused on the NES, the unconnected bit will read as 0, so this solution works safely with both Famicom and NES hardware.<br />
<pre><br />
.zeropage<br />
buttons: .res 2 ; space for 2 reads<br />
<br />
.code<br />
readjoyx2:<br />
ldx #$00<br />
jsr readjoyx ; X=0: read controller 1<br />
inx<br />
; fall through to readjoyx below, X=1: read controller 2<br />
<br />
readjoyx: ; X register = 0 for controller 1, 1 for controller 2<br />
lda #$01<br />
sta JOYPAD1<br />
sta buttons, X<br />
lsr a<br />
sta JOYPAD1<br />
loop:<br />
lda JOYPAD1, X<br />
and #%00000011 ; ignore bits other than controller<br />
cmp #$01 ; Set carry if and only if nonzero<br />
rol buttons, X ; Carry -> bit 0; but 7 -> Carry<br />
bcc loop<br />
rts<br />
</pre><br />
<br />
If playing DPCM samples, there is an additional reread step to prevent errors ([[#DPCM Safety using Repeated Reads|see below]]).<br />
<br />
Note that the <tt>and</tt> to ignore bits is not optional, as the upper bits of <tt>JOYPAD1</tt> read are not guaranteed to be 1 or 0<ref>[[Controller_reading#Unconnected_data_lines_and_open_bus|Controller reading: Unconnected data lines and open bus]]</ref>.<br />
<br />
=== Alternative 2 Controllers Read ===<br />
<br />
Alternatively, we could combine both controller reads into 1 loop with a single strobe, though this routine is not safe to use with DPCM samples playing ([[#DPCM Safety using Repeated Reads|see below]]).<br />
<pre><br />
.zeropage<br />
buttons: .res 2<br />
<br />
.code<br />
readjoy2:<br />
lda #$01<br />
sta JOYPAD1<br />
sta buttons+1 ; player 2's buttons double as a ring counter<br />
lsr a<br />
sta JOYPAD1<br />
loop:<br />
lda JOYPAD1<br />
and #%00000011<br />
cmp #$01<br />
rol buttons+0<br />
lda JOYPAD2<br />
and #%00000011<br />
cmp #$01<br />
rol buttons+1<br />
bcc loop<br />
rts<br />
</pre><br />
<br />
=== DPCM Safety using Repeated Reads ===<br />
<br />
If your code is intended to be used with [[APU DMC]] playback, this code will need to be altered. The NES occasionally glitches the controller port twice in a row if sample playback is enabled, and games using samples need to work around this. The most common technique, as seen in ''Super Mario Bros. 3''<ref>[//forums.nesdev.org/viewtopic.php?p=151720#p151720 Super Mario Bros. 3 controller reread method]</ref> and other games, will read each controller twice, but in the event of a mismatch it will keep re-reading the controller until two results in a row are the same.<br />
<pre><br />
readjoy2_safe:<br />
ldx #$00<br />
jsr readjoyx_safe ; X=0: safe read controller 1<br />
inx<br />
; fall through to readjoyx_safe, X=1: safe read controller 2<br />
<br />
readjoyx_safe:<br />
jsr readjoyx<br />
reread:<br />
lda buttons, X<br />
pha<br />
jsr readjoyx<br />
pla<br />
cmp buttons, X<br />
bne reread<br />
rts<br />
</pre><br />
<br />
Note that the time between the start of one read and the end of the next read must be less than the length of the fastest DMC fetch period (432 cycles). For this reason, it is normal to read controllers one at a time with this method, rather than attempting both at once. (Note: <code>readjoy2</code> above takes too long to be suitable.) [[Game bugs|''Gimmick!'' has such a bug]] resulting from trying to read both at once.<br />
<br />
Most often a controller will be read 2 times, and 3 or 4 in the case of a DPCM corruption, or the player pressing a button during the read. With the assistance of tools, a malicious controller input could change the buttons on every read, holding it in this reread loop indefinitely<ref>[https://arstechnica.com/gaming/2016/07/how-to-beat-super-mario-bros-3-in-less-than-a-second/ Ars Technica: How to beat Super Mario Bros. 3 in less than a second]</ref><ref>https://tasvideos.org/6466S Tool-Assisted Speedrun of Super Mario Bros. 3 which first demonstrated abusing controller reread routines.</ref>, but this is generally not an important edge case to account for.<br />
<br />
=== DPCM Safety using OAM DMA ===<br />
<br />
Because halts for DPCM fetches normally only occur on an put cycles, it is possible to get glitch-free controller reads by timing all '''$4016''' and '''$4017''' reads to fall on get cycles. This is made possible by the behavior of OAM DMA: the first cycle after an OAM DMA is normally guaranteed to be a get cycle.<ref>[http://forums.nesdev.org/viewtopic.php?p=171971 Forum post:] Rahsennor's OAM-synchronized controller read</ref> This is a relatively new technique and is not supported by some emulators.<ref>[http://forums.nesdev.org/viewtopic.php?f=2&t=14319&start=15#p172099 Forum post:] as of May 2016, Nintendulator and Nestopia do not accurately emulate OAM-synchronized controller reading.</ref> In the following example code, the controller1 and controller2 labels must be in zeropage for the timing to work.<br />
<br />
This solution might be ideal, using fewer cycles than doing repeated reads, and taking a consistent amount of time. It can also be adapted for DPCM-conflict free reading of controllers that require a longer report like [[four player adapters]], or the [[SNES mouse]].<br />
<br />
However, unlike the other solutions above, it can't be executed at any time. Instead it must be integrated into your NMI routine to coincide with your sprite OAM DMA once per frame.<br />
<br />
<pre><br />
lda #OAM<br />
sta $4014 ; ------ OAM DMA ------<br />
ldx #1 ; get put <- strobe code must take an odd number of cycles total<br />
stx controller1 ; get put get <- controller1 and controller2 must be in the zeropage<br />
stx $4016 ; put get put get<br />
dex ; put get<br />
stx $4016 ; put get put get<br />
read_loop:<br />
lda $4017 ; put get put GET <- loop code must take an even number of cycles total<br />
and #3 ; put get<br />
cmp #1 ; put get<br />
rol controller2, x ; put get put get put get (X = 0; waste 1 cycle and 0 bytes for alignment)<br />
lda $4016 ; put get put GET<br />
and #3 ; put get<br />
cmp #1 ; put get<br />
rol controller1 ; put get put get put<br />
bcc read_loop ; get put [get] <- this branch must not be allowed to cross a page<br />
</pre><br />
<br />
Note that this example routine only reads two 8-bit controllers and does not take enough time to span more than one DPCM fetch. Routines longer than this must contend with two additional constraints:<br />
* When DMC DMA is delayed by an odd number of cycles, it takes 3 cycles instead of 4, changing the cycle parity. If extending this function to read more bits, care must be taken so that ''all'' CPU write cycles are aligned. Instructions with a single write cycle must align the write to avoid conflict with the DPCM fetch, and double-write instructions like ROL need to align both writes so that the DPCM fetch falls on the first write.<ref>[//forums.nesdev.org/viewtopic.php?p=231604#p231604 Forum post:] demonstration of how ROL instruction affects alignment for OAM DMA synchronized controller reading.</ref> If an interrupt can occur during the routine, it must be aligned so the fetch can only fall on the second of the three automatic stack writes.<br />
* When DMC DMA occurs near the end of OAM DMA, it only steals 1 or 3 cycles, inverting the cycle parity. Every DMC period after that, a misaligned DPCM fetch will occur. Care must be taken to ensure this does not land on a joypad read.<br />
<br />
See [[DMA]] for detailed information on DMA timing.<br />
<br />
== Other Useful Operations ==<br />
<br />
=== Directional Safety ===<br />
<br />
To reject opposing presses (Up+Down and Left+Right), which are possible on a worn Control Pad:<br />
<pre><br />
lda buttons,x<br />
and #%00001010 ; Compare Up and Left...<br />
lsr a<br />
and buttons,x ; to Down and Right<br />
beq not_updown<br />
; Use previous frame's directions<br />
lda buttons,x<br />
eor last_frame_buttons,x<br />
and #%11110000<br />
eor last_frame_buttons,x<br />
sta buttons,x<br />
not_updown:<br />
</pre><br />
<br />
To instead reject all diagonal presses, simulating a 4-way joystick:<br />
<pre><br />
lda buttons,x<br />
and #%00001111 ; If A & (A - 1) is nonzero, A has more than one bit set<br />
beq not_diagonal<br />
sec<br />
sbc #1<br />
and buttons,x<br />
beq not_diagonal<br />
; Use previous frame's directions<br />
lda buttons,x<br />
eor last_frame_buttons,x<br />
and #%11110000<br />
eor last_frame_buttons,x<br />
sta buttons,x<br />
not_diagonal:<br />
</pre><br />
<br />
=== Calculating Presses and Releases ===<br />
<br />
To calculate newly pressed and newly released buttons:<br />
<pre><br />
lda buttons,x<br />
eor #%11111111<br />
and last_frame_buttons,x<br />
sta released_buttons,x<br />
lda last_frame_buttons,x<br />
eor #%11111111<br />
and buttons,x<br />
sta pressed_buttons,x<br />
</pre><br />
<br />
=== Button Flags ===<br />
<br />
It is helpful to define the buttons as a series of bit flags:<br />
<pre><br />
BUTTON_A = 1 << 7<br />
BUTTON_B = 1 << 6<br />
BUTTON_SELECT = 1 << 5<br />
BUTTON_START = 1 << 4<br />
BUTTON_UP = 1 << 3<br />
BUTTON_DOWN = 1 << 2<br />
BUTTON_LEFT = 1 << 1<br />
BUTTON_RIGHT = 1 << 0<br />
</pre><br />
<br />
And then buttons can be checked as follows:<br />
<pre><br />
lda buttons<br />
and #BUTTON_A | BUTTON_B<br />
beq notPressingAorB<br />
; Handle presses.<br />
notPressingAorB:<br />
</pre><br />
<br />
== External Examples ==<br />
<br />
* [http://forums.nesdev.org/viewtopic.php?t=4124 Forum post:] Blargg's DMC-fortified controller read routine<br />
* [http://forums.nesdev.org/viewtopic.php?p=171971 Forum post:] Rahsennor's OAM-synchronized controller read<br />
* [http://forums.nesdev.org/viewtopic.php?f=2&t=14197 Forum post:] Drag's bitwise DMC-safe controller reading<br />
* [https://github.com/pinobatch/nrom-template/blob/master/src/pads.s pads.s:] pinobatch's NROM-template controller read routine<br />
<br />
== References ==<br />
<references/></div>Rainwarriorhttps://www.nesdev.org/w/index.php?title=Controller_reading_code&diff=21499Controller reading code2024-01-12T18:40:10Z<p>Rainwarrior: /* DPCM Safety using OAM DMA */ note that this might be ideal, but has the synchronization constraint</p>
<hr />
<div>This page contains example code for reading the [[NES controller]].<br />
<br />
See also: [[Controller reading]]<br />
<br />
=== Basic Example ===<br />
<br />
This is a tutorial example of the bare minimum needed to read the controller.<br />
It will explain the basic principles in detail, but once understood, you may wish to continue to the [[#Standard Read for 2 Controllers and Famicom|Standard Read]] example that follows,<br />
as a more complete and ready-to-use code example.<br />
<br />
This code describes an efficient method of reading the [[standard controller]] using [http://cc65.github.io/cc65/ ca65] syntax.<br />
<br />
The result byte ''buttons'' should be placed in zero page to save a cycle each time through the loop.<br />
<pre><br />
; we reserve one byte for storing the data that is read from controller<br />
.zeropage<br />
buttons .res 1<br />
</pre><br />
<br />
When reading from ''JOYPAD*'' what is read might be different from $01/$00 for various reasons. (See [[Controller reading]].) In this code the only concern is bit 0 read from ''JOYPAD*.''.<br />
<pre><br />
JOYPAD1 = $4016<br />
JOYPAD2 = $4017<br />
</pre><br />
<br />
This is the end result that will be stored in ''buttons''. '''1''' if the button was pressed, '''0''' otherwise.<br />
<br />
{| class="wikitable" style="text-align:center;"<br />
|-<br />
! bit<br />
| &nbsp;&nbsp;&nbsp;&nbsp;7&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;6&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;5&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;4&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;3&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;2&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;1&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;&nbsp;<br />
|-<br />
! button<br />
| A<br />
| B<br />
| Select<br />
| Start<br />
| Up<br />
| Down<br />
| Left<br />
| Right<br />
|}<br />
<br />
This subroutine takes 132 cycles to execute but ignores the Famicom expansion controller.<br />
Many controller reading subroutines use the X or Y register to count 8 times through the loop.<br />
But this one uses a more clever [[wikipedia:Ring counter|ring counter]] technique: $01 is loaded into the result first, and once eight bits are shifted in, the 1 bit will be shifted out, terminating the loop.<br />
<pre><br />
; At the same time that we strobe bit 0, we initialize the ring counter<br />
; so we're hitting two birds with one stone here<br />
readjoy:<br />
lda #$01<br />
; While the strobe bit is set, buttons will be continuously reloaded.<br />
; This means that reading from JOYPAD1 will only return the state of the<br />
; first button: button A.<br />
sta JOYPAD1<br />
sta buttons<br />
lsr a ; now A is 0<br />
; By storing 0 into JOYPAD1, the strobe bit is cleared and the reloading stops.<br />
; This allows all 8 buttons (newly reloaded) to be read from JOYPAD1.<br />
sta JOYPAD1<br />
loop:<br />
lda JOYPAD1<br />
lsr a ; bit 0 -> Carry<br />
rol buttons ; Carry -> bit 0; bit 7 -> Carry<br />
bcc loop<br />
rts<br />
</pre><br />
<br />
Continue to the next example for a more complete read routine that handles both controllers and the standard Famicom expansion controllers.<br />
<br />
=== Standard Read for 2 Controllers and Famicom ===<br />
<br />
Adding support for controllers on the Famicom's DA15 expansion port and for player 2's controller is straightforward. Something similar to the following routine is used in most Famicom games.<br />
Even though the expansion port is unused on the NES, the unconnected bit will read as 0, so this solution works safely with both Famicom and NES hardware.<br />
<pre><br />
.zeropage<br />
buttons: .res 2 ; space for 2 reads<br />
<br />
.code<br />
readjoyx2:<br />
ldx #$00<br />
jsr readjoyx ; X=0: read controller 1<br />
inx<br />
; fall through to readjoyx below, X=1: read controller 2<br />
<br />
readjoyx: ; X register = 0 for controller 1, 1 for controller 2<br />
lda #$01<br />
sta JOYPAD1<br />
sta buttons, X<br />
lsr a<br />
sta JOYPAD1<br />
loop:<br />
lda JOYPAD1, X<br />
and #%00000011 ; ignore bits other than controller<br />
cmp #$01 ; Set carry if and only if nonzero<br />
rol buttons, X ; Carry -> bit 0; but 7 -> Carry<br />
bcc loop<br />
rts<br />
</pre><br />
<br />
If playing DPCM samples, there is an additional reread step to prevent errors ([[#DPCM Safety using Repeated Reads|see below]]).<br />
<br />
Note that the <tt>and</tt> to ignore bits is not optional, as the upper bits of <tt>JOYPAD1</tt> read are not guaranteed to be 1 or 0<ref>[[Controller_reading#Unconnected_data_lines_and_open_bus|Controller reading: Unconnected data lines and open bus]]</ref>.<br />
<br />
=== Alternative 2 Controllers Read ===<br />
<br />
Alternatively, we could combine both controller reads into 1 loop with a single strobe, though this routine is not safe to use with DPCM samples playing ([[#DPCM Safety using Repeated Reads|see below]]).<br />
<pre><br />
.zeropage<br />
buttons: .res 2<br />
<br />
.code<br />
readjoy2:<br />
lda #$01<br />
sta JOYPAD1<br />
sta buttons+1 ; player 2's buttons double as a ring counter<br />
lsr a<br />
sta JOYPAD1<br />
loop:<br />
lda JOYPAD1<br />
and #%00000011<br />
cmp #$01<br />
rol buttons+0<br />
lda JOYPAD2<br />
and #%00000011<br />
cmp #$01<br />
rol buttons+1<br />
bcc loop<br />
rts<br />
</pre><br />
<br />
=== DPCM Safety using Repeated Reads ===<br />
<br />
If your code is intended to be used with [[APU DMC]] playback, this code will need to be altered. The NES occasionally glitches the controller port twice in a row if sample playback is enabled, and games using samples need to work around this. The most common technique, as seen in ''Super Mario Bros. 3''<ref>[//forums.nesdev.org/viewtopic.php?p=151720#p151720 Super Mario Bros. 3 controller reread method]</ref> and other games, will read each controller twice, but in the event of a mismatch it will keep re-reading the controller until two results in a row are the same.<br />
<pre><br />
readjoy2_safe:<br />
ldx #$00<br />
jsr readjoyx_safe ; X=0: safe read controller 1<br />
inx<br />
; fall through to readjoyx_safe, X=1: safe read controller 2<br />
<br />
readjoyx_safe:<br />
jsr readjoyx<br />
reread:<br />
lda buttons, X<br />
pha<br />
jsr readjoyx<br />
pla<br />
cmp buttons, X<br />
bne reread<br />
rts<br />
</pre><br />
<br />
Note that the time between the start of one read and the end of the next read must be less than the length of the fastest DMC fetch period (432 cycles). For this reason, it is normal to read controllers one at a time with this method, rather than attempting both at once. (Note: <code>readjoy2</code> above takes too long to be suitable.) [[Game bugs|''Gimmick!'' has such a bug]] resulting from trying to read both at once.<br />
<br />
Most often a controller will be read 2 times, and 3 or 4 in the case of a DPCM corruption, or the player pressing a button during the read. With the assistance of tools, a malicious controller input could change the buttons on every read, holding it in this reread loop indefinitely<ref>[https://arstechnica.com/gaming/2016/07/how-to-beat-super-mario-bros-3-in-less-than-a-second/ Ars Technica: How to beat Super Mario Bros. 3 in less than a second]</ref><ref>https://tasvideos.org/6466S Tool-Assisted Speedrun of Super Mario Bros. 3 which first demonstrated abusing controller reread routines.</ref>, but this is generally not an important edge case to account for.<br />
<br />
=== DPCM Safety using OAM DMA ===<br />
<br />
Because halts for DPCM fetches normally only occur on an put cycles, it is possible to get glitch-free controller reads by timing all '''$4016''' and '''$4017''' reads to fall on get cycles. This is made possible by the behavior of OAM DMA: the first cycle after an OAM DMA is normally guaranteed to be a get cycle.<ref>[http://forums.nesdev.org/viewtopic.php?p=171971 Forum post:] Rahsennor's OAM-synchronized controller read</ref> This is a relatively new technique and is not supported by some emulators.<ref>[http://forums.nesdev.org/viewtopic.php?f=2&t=14319&start=15#p172099 Forum post:] as of May 2016, Nintendulator and Nestopia do not accurately emulate OAM-synchronized controller reading.</ref> In the following example code, the controller1 and controller2 labels must be in zeropage for the timing to work.<br />
<br />
This solution might be ideal, using fewer cycles than doing repeated reads, and taking a consistent amount of time. It can also be adapted for DPCM-conflict free reading of controllers that require a longer report like [[four player adapters]], or the [[SNES mouse]].<br />
<br />
However, unlike the other solutions above, it can't be executed at any time. Instead it must be integrated into your NMI routine to coincide with your sprite OAM DMA once per frame.<br />
<br />
<pre><br />
lda #OAM<br />
sta $4014 ; ------ OAM DMA ------<br />
ldx #1 ; get put <- strobe code must take an odd number of cycles total<br />
stx controller1 ; get put get <- controller1 and controller2 must be in the zeropage<br />
stx $4016 ; put get put get<br />
dex ; put get<br />
stx $4016 ; put get put get<br />
read_loop:<br />
lda $4017 ; put get put GET <- loop code must take an even number of cycles total<br />
and #3 ; put get<br />
cmp #1 ; put get<br />
rol controller2, x ; put get put get put get (X = 0; waste 1 cycle and 0 bytes for alignment)<br />
lda $4016 ; put get put GET<br />
and #3 ; put get<br />
cmp #1 ; put get<br />
rol controller1 ; put get put get put<br />
bcc read_loop ; get put [get] <- this branch must not be allowed to cross a page<br />
</pre><br />
<br />
Note that this example routine only reads two 8-bit controllers and does not take enough time to span more than one DPCM fetch. Routines longer than this must contend with two additional constraints:<br />
* When DMC DMA is delayed by an odd number of cycles, it takes 3 cycles instead of 4, changing the cycle parity. If extending this function to read more bits, care must be taken so that ''all'' CPU write cycles are aligned. Instructions with a single write cycle must align the write to avoid conflict with the DPCM fetch, and double-write instructions like ROL need to align both writes so that the DPCM fetch falls on the first write.<ref>[//forums.nesdev.org/viewtopic.php?p=231604#p231604 Forum post:] demonstration of how ROL instruction affects alignment for OAM DMA synchronized controller reading.</ref> If an interrupt can occur during the routine, it must be aligned so the fetch can only fall on the second of the three automatic stack writes.<br />
* When DMC DMA occurs near the end of OAM DMA, it only steals 1 or 3 cycles, inverting the cycle parity. Every DMC period after that, a misaligned DPCM fetch will occur. Care must be taken to ensure this does not land on a joypad read.<br />
<br />
See [[DMA]] for detailed information on DMA timing.<br />
<br />
=== Directional Safety ===<br />
<br />
To reject opposing presses (Up+Down and Left+Right), which are possible on a worn Control Pad:<br />
<pre><br />
lda buttons,x<br />
and #%00001010 ; Compare Up and Left...<br />
lsr a<br />
and buttons,x ; to Down and Right<br />
beq not_updown<br />
; Use previous frame's directions<br />
lda buttons,x<br />
eor last_frame_buttons,x<br />
and #%11110000<br />
eor last_frame_buttons,x<br />
sta buttons,x<br />
not_updown:<br />
</pre><br />
<br />
To instead reject all diagonal presses, simulating a 4-way joystick:<br />
<pre><br />
lda buttons,x<br />
and #%00001111 ; If A & (A - 1) is nonzero, A has more than one bit set<br />
beq not_diagonal<br />
sec<br />
sbc #1<br />
and buttons,x<br />
beq not_diagonal<br />
; Use previous frame's directions<br />
lda buttons,x<br />
eor last_frame_buttons,x<br />
and #%11110000<br />
eor last_frame_buttons,x<br />
sta buttons,x<br />
not_diagonal:<br />
</pre><br />
<br />
=== Calculating Presses and Releases ===<br />
<br />
To calculate newly pressed and newly released buttons:<br />
<pre><br />
lda buttons,x<br />
eor #%11111111<br />
and last_frame_buttons,x<br />
sta released_buttons,x<br />
lda last_frame_buttons,x<br />
eor #%11111111<br />
and buttons,x<br />
sta pressed_buttons,x<br />
</pre><br />
<br />
=== Button Flags ===<br />
<br />
It is helpful to define the buttons as a series of bit flags:<br />
<pre><br />
BUTTON_A = 1 << 7<br />
BUTTON_B = 1 << 6<br />
BUTTON_SELECT = 1 << 5<br />
BUTTON_START = 1 << 4<br />
BUTTON_UP = 1 << 3<br />
BUTTON_DOWN = 1 << 2<br />
BUTTON_LEFT = 1 << 1<br />
BUTTON_RIGHT = 1 << 0<br />
</pre><br />
<br />
And then buttons can be checked as follows:<br />
<pre><br />
lda buttons<br />
and #BUTTON_A | BUTTON_B<br />
beq notPressingAorB<br />
; Handle presses.<br />
notPressingAorB:<br />
</pre><br />
<br />
== External Examples ==<br />
<br />
* [http://forums.nesdev.org/viewtopic.php?t=4124 Forum post:] Blargg's DMC-fortified controller read routine<br />
* [http://forums.nesdev.org/viewtopic.php?p=171971 Forum post:] Rahsennor's OAM-synchronized controller read<br />
* [http://forums.nesdev.org/viewtopic.php?f=2&t=14197 Forum post:] Drag's bitwise DMC-safe controller reading<br />
* [https://github.com/pinobatch/nrom-template/blob/master/src/pads.s pads.s:] pinobatch's NROM-template controller read routine<br />
<br />
== References ==<br />
<references/></div>Rainwarriorhttps://www.nesdev.org/w/index.php?title=Controller_reading_code&diff=21498Controller reading code2024-01-12T18:25:00Z<p>Rainwarrior: /* External Examples */ link tepples' nrom-template example</p>
<hr />
<div>This page contains example code for reading the [[NES controller]].<br />
<br />
See also: [[Controller reading]]<br />
<br />
=== Basic Example ===<br />
<br />
This is a tutorial example of the bare minimum needed to read the controller.<br />
It will explain the basic principles in detail, but once understood, you may wish to continue to the [[#Standard Read for 2 Controllers and Famicom|Standard Read]] example that follows,<br />
as a more complete and ready-to-use code example.<br />
<br />
This code describes an efficient method of reading the [[standard controller]] using [http://cc65.github.io/cc65/ ca65] syntax.<br />
<br />
The result byte ''buttons'' should be placed in zero page to save a cycle each time through the loop.<br />
<pre><br />
; we reserve one byte for storing the data that is read from controller<br />
.zeropage<br />
buttons .res 1<br />
</pre><br />
<br />
When reading from ''JOYPAD*'' what is read might be different from $01/$00 for various reasons. (See [[Controller reading]].) In this code the only concern is bit 0 read from ''JOYPAD*.''.<br />
<pre><br />
JOYPAD1 = $4016<br />
JOYPAD2 = $4017<br />
</pre><br />
<br />
This is the end result that will be stored in ''buttons''. '''1''' if the button was pressed, '''0''' otherwise.<br />
<br />
{| class="wikitable" style="text-align:center;"<br />
|-<br />
! bit<br />
| &nbsp;&nbsp;&nbsp;&nbsp;7&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;6&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;5&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;4&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;3&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;2&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;1&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;&nbsp;<br />
|-<br />
! button<br />
| A<br />
| B<br />
| Select<br />
| Start<br />
| Up<br />
| Down<br />
| Left<br />
| Right<br />
|}<br />
<br />
This subroutine takes 132 cycles to execute but ignores the Famicom expansion controller.<br />
Many controller reading subroutines use the X or Y register to count 8 times through the loop.<br />
But this one uses a more clever [[wikipedia:Ring counter|ring counter]] technique: $01 is loaded into the result first, and once eight bits are shifted in, the 1 bit will be shifted out, terminating the loop.<br />
<pre><br />
; At the same time that we strobe bit 0, we initialize the ring counter<br />
; so we're hitting two birds with one stone here<br />
readjoy:<br />
lda #$01<br />
; While the strobe bit is set, buttons will be continuously reloaded.<br />
; This means that reading from JOYPAD1 will only return the state of the<br />
; first button: button A.<br />
sta JOYPAD1<br />
sta buttons<br />
lsr a ; now A is 0<br />
; By storing 0 into JOYPAD1, the strobe bit is cleared and the reloading stops.<br />
; This allows all 8 buttons (newly reloaded) to be read from JOYPAD1.<br />
sta JOYPAD1<br />
loop:<br />
lda JOYPAD1<br />
lsr a ; bit 0 -> Carry<br />
rol buttons ; Carry -> bit 0; bit 7 -> Carry<br />
bcc loop<br />
rts<br />
</pre><br />
<br />
Continue to the next example for a more complete read routine that handles both controllers and the standard Famicom expansion controllers.<br />
<br />
=== Standard Read for 2 Controllers and Famicom ===<br />
<br />
Adding support for controllers on the Famicom's DA15 expansion port and for player 2's controller is straightforward. Something similar to the following routine is used in most Famicom games.<br />
Even though the expansion port is unused on the NES, the unconnected bit will read as 0, so this solution works safely with both Famicom and NES hardware.<br />
<pre><br />
.zeropage<br />
buttons: .res 2 ; space for 2 reads<br />
<br />
.code<br />
readjoyx2:<br />
ldx #$00<br />
jsr readjoyx ; X=0: read controller 1<br />
inx<br />
; fall through to readjoyx below, X=1: read controller 2<br />
<br />
readjoyx: ; X register = 0 for controller 1, 1 for controller 2<br />
lda #$01<br />
sta JOYPAD1<br />
sta buttons, X<br />
lsr a<br />
sta JOYPAD1<br />
loop:<br />
lda JOYPAD1, X<br />
and #%00000011 ; ignore bits other than controller<br />
cmp #$01 ; Set carry if and only if nonzero<br />
rol buttons, X ; Carry -> bit 0; but 7 -> Carry<br />
bcc loop<br />
rts<br />
</pre><br />
<br />
If playing DPCM samples, there is an additional reread step to prevent errors ([[#DPCM Safety using Repeated Reads|see below]]).<br />
<br />
Note that the <tt>and</tt> to ignore bits is not optional, as the upper bits of <tt>JOYPAD1</tt> read are not guaranteed to be 1 or 0<ref>[[Controller_reading#Unconnected_data_lines_and_open_bus|Controller reading: Unconnected data lines and open bus]]</ref>.<br />
<br />
=== Alternative 2 Controllers Read ===<br />
<br />
Alternatively, we could combine both controller reads into 1 loop with a single strobe, though this routine is not safe to use with DPCM samples playing ([[#DPCM Safety using Repeated Reads|see below]]).<br />
<pre><br />
.zeropage<br />
buttons: .res 2<br />
<br />
.code<br />
readjoy2:<br />
lda #$01<br />
sta JOYPAD1<br />
sta buttons+1 ; player 2's buttons double as a ring counter<br />
lsr a<br />
sta JOYPAD1<br />
loop:<br />
lda JOYPAD1<br />
and #%00000011<br />
cmp #$01<br />
rol buttons+0<br />
lda JOYPAD2<br />
and #%00000011<br />
cmp #$01<br />
rol buttons+1<br />
bcc loop<br />
rts<br />
</pre><br />
<br />
=== DPCM Safety using Repeated Reads ===<br />
<br />
If your code is intended to be used with [[APU DMC]] playback, this code will need to be altered. The NES occasionally glitches the controller port twice in a row if sample playback is enabled, and games using samples need to work around this. The most common technique, as seen in ''Super Mario Bros. 3''<ref>[//forums.nesdev.org/viewtopic.php?p=151720#p151720 Super Mario Bros. 3 controller reread method]</ref> and other games, will read each controller twice, but in the event of a mismatch it will keep re-reading the controller until two results in a row are the same.<br />
<pre><br />
readjoy2_safe:<br />
ldx #$00<br />
jsr readjoyx_safe ; X=0: safe read controller 1<br />
inx<br />
; fall through to readjoyx_safe, X=1: safe read controller 2<br />
<br />
readjoyx_safe:<br />
jsr readjoyx<br />
reread:<br />
lda buttons, X<br />
pha<br />
jsr readjoyx<br />
pla<br />
cmp buttons, X<br />
bne reread<br />
rts<br />
</pre><br />
<br />
Note that the time between the start of one read and the end of the next read must be less than the length of the fastest DMC fetch period (432 cycles). For this reason, it is normal to read controllers one at a time with this method, rather than attempting both at once. (Note: <code>readjoy2</code> above takes too long to be suitable.) [[Game bugs|''Gimmick!'' has such a bug]] resulting from trying to read both at once.<br />
<br />
Most often a controller will be read 2 times, and 3 or 4 in the case of a DPCM corruption, or the player pressing a button during the read. With the assistance of tools, a malicious controller input could change the buttons on every read, holding it in this reread loop indefinitely<ref>[https://arstechnica.com/gaming/2016/07/how-to-beat-super-mario-bros-3-in-less-than-a-second/ Ars Technica: How to beat Super Mario Bros. 3 in less than a second]</ref><ref>https://tasvideos.org/6466S Tool-Assisted Speedrun of Super Mario Bros. 3 which first demonstrated abusing controller reread routines.</ref>, but this is generally not an important edge case to account for.<br />
<br />
=== DPCM Safety using OAM DMA ===<br />
<br />
Because halts for DPCM fetches normally only occur on an put cycles, it is possible to get glitch-free controller reads by timing all '''$4016''' and '''$4017''' reads to fall on get cycles. This is made possible by the behavior of OAM DMA: the first cycle after an OAM DMA is normally guaranteed to be a get cycle.<ref>[http://forums.nesdev.org/viewtopic.php?p=171971 Forum post:] Rahsennor's OAM-synchronized controller read</ref> This is a relatively new technique and is not supported by some emulators.<ref>[http://forums.nesdev.org/viewtopic.php?f=2&t=14319&start=15#p172099 Forum post:] as of May 2016, Nintendulator and Nestopia do not accurately emulate OAM-synchronized controller reading.</ref> In the following example code, the controller1 and controller2 labels must be in zeropage for the timing to work.<br />
<br />
<pre><br />
lda #OAM<br />
sta $4014 ; ------ OAM DMA ------<br />
ldx #1 ; get put <- strobe code must take an odd number of cycles total<br />
stx controller1 ; get put get <- controller1 and controller2 must be in the zeropage<br />
stx $4016 ; put get put get<br />
dex ; put get<br />
stx $4016 ; put get put get<br />
read_loop:<br />
lda $4017 ; put get put GET <- loop code must take an even number of cycles total<br />
and #3 ; put get<br />
cmp #1 ; put get<br />
rol controller2, x ; put get put get put get (X = 0; waste 1 cycle and 0 bytes for alignment)<br />
lda $4016 ; put get put GET<br />
and #3 ; put get<br />
cmp #1 ; put get<br />
rol controller1 ; put get put get put<br />
bcc read_loop ; get put [get] <- this branch must not be allowed to cross a page<br />
</pre><br />
<br />
Note that this example routine only reads two 8-bit controllers and does not take enough time to span more than one DPCM fetch. Routines longer than this must contend with two additional constraints:<br />
* When DMC DMA is delayed by an odd number of cycles, it takes 3 cycles instead of 4, changing the cycle parity. If extending this function to read more bits, care must be taken so that ''all'' CPU write cycles are aligned. Instructions with a single write cycle must align the write to avoid conflict with the DPCM fetch, and double-write instructions like ROL need to align both writes so that the DPCM fetch falls on the first write.<ref>[//forums.nesdev.org/viewtopic.php?p=231604#p231604 Forum post:] demonstration of how ROL instruction affects alignment for OAM DMA synchronized controller reading.</ref> If an interrupt can occur during the routine, it must be aligned so the fetch can only fall on the second of the three automatic stack writes.<br />
* When DMC DMA occurs near the end of OAM DMA, it only steals 1 or 3 cycles, inverting the cycle parity. Every DMC period after that, a misaligned DPCM fetch will occur. Care must be taken to ensure this does not land on a joypad read.<br />
<br />
See [[DMA]] for detailed information on DMA timing.<br />
<br />
=== Directional Safety ===<br />
<br />
To reject opposing presses (Up+Down and Left+Right), which are possible on a worn Control Pad:<br />
<pre><br />
lda buttons,x<br />
and #%00001010 ; Compare Up and Left...<br />
lsr a<br />
and buttons,x ; to Down and Right<br />
beq not_updown<br />
; Use previous frame's directions<br />
lda buttons,x<br />
eor last_frame_buttons,x<br />
and #%11110000<br />
eor last_frame_buttons,x<br />
sta buttons,x<br />
not_updown:<br />
</pre><br />
<br />
To instead reject all diagonal presses, simulating a 4-way joystick:<br />
<pre><br />
lda buttons,x<br />
and #%00001111 ; If A & (A - 1) is nonzero, A has more than one bit set<br />
beq not_diagonal<br />
sec<br />
sbc #1<br />
and buttons,x<br />
beq not_diagonal<br />
; Use previous frame's directions<br />
lda buttons,x<br />
eor last_frame_buttons,x<br />
and #%11110000<br />
eor last_frame_buttons,x<br />
sta buttons,x<br />
not_diagonal:<br />
</pre><br />
<br />
=== Calculating Presses and Releases ===<br />
<br />
To calculate newly pressed and newly released buttons:<br />
<pre><br />
lda buttons,x<br />
eor #%11111111<br />
and last_frame_buttons,x<br />
sta released_buttons,x<br />
lda last_frame_buttons,x<br />
eor #%11111111<br />
and buttons,x<br />
sta pressed_buttons,x<br />
</pre><br />
<br />
=== Button Flags ===<br />
<br />
It is helpful to define the buttons as a series of bit flags:<br />
<pre><br />
BUTTON_A = 1 << 7<br />
BUTTON_B = 1 << 6<br />
BUTTON_SELECT = 1 << 5<br />
BUTTON_START = 1 << 4<br />
BUTTON_UP = 1 << 3<br />
BUTTON_DOWN = 1 << 2<br />
BUTTON_LEFT = 1 << 1<br />
BUTTON_RIGHT = 1 << 0<br />
</pre><br />
<br />
And then buttons can be checked as follows:<br />
<pre><br />
lda buttons<br />
and #BUTTON_A | BUTTON_B<br />
beq notPressingAorB<br />
; Handle presses.<br />
notPressingAorB:<br />
</pre><br />
<br />
== External Examples ==<br />
<br />
* [http://forums.nesdev.org/viewtopic.php?t=4124 Forum post:] Blargg's DMC-fortified controller read routine<br />
* [http://forums.nesdev.org/viewtopic.php?p=171971 Forum post:] Rahsennor's OAM-synchronized controller read<br />
* [http://forums.nesdev.org/viewtopic.php?f=2&t=14197 Forum post:] Drag's bitwise DMC-safe controller reading<br />
* [https://github.com/pinobatch/nrom-template/blob/master/src/pads.s pads.s:] pinobatch's NROM-template controller read routine<br />
<br />
== References ==<br />
<references/></div>Rainwarriorhttps://www.nesdev.org/w/index.php?title=Controller_reading_code&diff=21497Controller reading code2024-01-11T02:00:22Z<p>Rainwarrior: /* Basic Example */ replace tab with spaces for alignment</p>
<hr />
<div>This page contains example code for reading the [[NES controller]].<br />
<br />
See also: [[Controller reading]]<br />
<br />
=== Basic Example ===<br />
<br />
This is a tutorial example of the bare minimum needed to read the controller.<br />
It will explain the basic principles in detail, but once understood, you may wish to continue to the [[#Standard Read for 2 Controllers and Famicom|Standard Read]] example that follows,<br />
as a more complete and ready-to-use code example.<br />
<br />
This code describes an efficient method of reading the [[standard controller]] using [http://cc65.github.io/cc65/ ca65] syntax.<br />
<br />
The result byte ''buttons'' should be placed in zero page to save a cycle each time through the loop.<br />
<pre><br />
; we reserve one byte for storing the data that is read from controller<br />
.zeropage<br />
buttons .res 1<br />
</pre><br />
<br />
When reading from ''JOYPAD*'' what is read might be different from $01/$00 for various reasons. (See [[Controller reading]].) In this code the only concern is bit 0 read from ''JOYPAD*.''.<br />
<pre><br />
JOYPAD1 = $4016<br />
JOYPAD2 = $4017<br />
</pre><br />
<br />
This is the end result that will be stored in ''buttons''. '''1''' if the button was pressed, '''0''' otherwise.<br />
<br />
{| class="wikitable" style="text-align:center;"<br />
|-<br />
! bit<br />
| &nbsp;&nbsp;&nbsp;&nbsp;7&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;6&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;5&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;4&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;3&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;2&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;1&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;&nbsp;<br />
|-<br />
! button<br />
| A<br />
| B<br />
| Select<br />
| Start<br />
| Up<br />
| Down<br />
| Left<br />
| Right<br />
|}<br />
<br />
This subroutine takes 132 cycles to execute but ignores the Famicom expansion controller.<br />
Many controller reading subroutines use the X or Y register to count 8 times through the loop.<br />
But this one uses a more clever [[wikipedia:Ring counter|ring counter]] technique: $01 is loaded into the result first, and once eight bits are shifted in, the 1 bit will be shifted out, terminating the loop.<br />
<pre><br />
; At the same time that we strobe bit 0, we initialize the ring counter<br />
; so we're hitting two birds with one stone here<br />
readjoy:<br />
lda #$01<br />
; While the strobe bit is set, buttons will be continuously reloaded.<br />
; This means that reading from JOYPAD1 will only return the state of the<br />
; first button: button A.<br />
sta JOYPAD1<br />
sta buttons<br />
lsr a ; now A is 0<br />
; By storing 0 into JOYPAD1, the strobe bit is cleared and the reloading stops.<br />
; This allows all 8 buttons (newly reloaded) to be read from JOYPAD1.<br />
sta JOYPAD1<br />
loop:<br />
lda JOYPAD1<br />
lsr a ; bit 0 -> Carry<br />
rol buttons ; Carry -> bit 0; bit 7 -> Carry<br />
bcc loop<br />
rts<br />
</pre><br />
<br />
Continue to the next example for a more complete read routine that handles both controllers and the standard Famicom expansion controllers.<br />
<br />
=== Standard Read for 2 Controllers and Famicom ===<br />
<br />
Adding support for controllers on the Famicom's DA15 expansion port and for player 2's controller is straightforward. Something similar to the following routine is used in most Famicom games.<br />
Even though the expansion port is unused on the NES, the unconnected bit will read as 0, so this solution works safely with both Famicom and NES hardware.<br />
<pre><br />
.zeropage<br />
buttons: .res 2 ; space for 2 reads<br />
<br />
.code<br />
readjoyx2:<br />
ldx #$00<br />
jsr readjoyx ; X=0: read controller 1<br />
inx<br />
; fall through to readjoyx below, X=1: read controller 2<br />
<br />
readjoyx: ; X register = 0 for controller 1, 1 for controller 2<br />
lda #$01<br />
sta JOYPAD1<br />
sta buttons, X<br />
lsr a<br />
sta JOYPAD1<br />
loop:<br />
lda JOYPAD1, X<br />
and #%00000011 ; ignore bits other than controller<br />
cmp #$01 ; Set carry if and only if nonzero<br />
rol buttons, X ; Carry -> bit 0; but 7 -> Carry<br />
bcc loop<br />
rts<br />
</pre><br />
<br />
If playing DPCM samples, there is an additional reread step to prevent errors ([[#DPCM Safety using Repeated Reads|see below]]).<br />
<br />
Note that the <tt>and</tt> to ignore bits is not optional, as the upper bits of <tt>JOYPAD1</tt> read are not guaranteed to be 1 or 0<ref>[[Controller_reading#Unconnected_data_lines_and_open_bus|Controller reading: Unconnected data lines and open bus]]</ref>.<br />
<br />
=== Alternative 2 Controllers Read ===<br />
<br />
Alternatively, we could combine both controller reads into 1 loop with a single strobe, though this routine is not safe to use with DPCM samples playing ([[#DPCM Safety using Repeated Reads|see below]]).<br />
<pre><br />
.zeropage<br />
buttons: .res 2<br />
<br />
.code<br />
readjoy2:<br />
lda #$01<br />
sta JOYPAD1<br />
sta buttons+1 ; player 2's buttons double as a ring counter<br />
lsr a<br />
sta JOYPAD1<br />
loop:<br />
lda JOYPAD1<br />
and #%00000011<br />
cmp #$01<br />
rol buttons+0<br />
lda JOYPAD2<br />
and #%00000011<br />
cmp #$01<br />
rol buttons+1<br />
bcc loop<br />
rts<br />
</pre><br />
<br />
=== DPCM Safety using Repeated Reads ===<br />
<br />
If your code is intended to be used with [[APU DMC]] playback, this code will need to be altered. The NES occasionally glitches the controller port twice in a row if sample playback is enabled, and games using samples need to work around this. The most common technique, as seen in ''Super Mario Bros. 3''<ref>[//forums.nesdev.org/viewtopic.php?p=151720#p151720 Super Mario Bros. 3 controller reread method]</ref> and other games, will read each controller twice, but in the event of a mismatch it will keep re-reading the controller until two results in a row are the same.<br />
<pre><br />
readjoy2_safe:<br />
ldx #$00<br />
jsr readjoyx_safe ; X=0: safe read controller 1<br />
inx<br />
; fall through to readjoyx_safe, X=1: safe read controller 2<br />
<br />
readjoyx_safe:<br />
jsr readjoyx<br />
reread:<br />
lda buttons, X<br />
pha<br />
jsr readjoyx<br />
pla<br />
cmp buttons, X<br />
bne reread<br />
rts<br />
</pre><br />
<br />
Note that the time between the start of one read and the end of the next read must be less than the length of the fastest DMC fetch period (432 cycles). For this reason, it is normal to read controllers one at a time with this method, rather than attempting both at once. (Note: <code>readjoy2</code> above takes too long to be suitable.) [[Game bugs|''Gimmick!'' has such a bug]] resulting from trying to read both at once.<br />
<br />
Most often a controller will be read 2 times, and 3 or 4 in the case of a DPCM corruption, or the player pressing a button during the read. With the assistance of tools, a malicious controller input could change the buttons on every read, holding it in this reread loop indefinitely<ref>[https://arstechnica.com/gaming/2016/07/how-to-beat-super-mario-bros-3-in-less-than-a-second/ Ars Technica: How to beat Super Mario Bros. 3 in less than a second]</ref><ref>https://tasvideos.org/6466S Tool-Assisted Speedrun of Super Mario Bros. 3 which first demonstrated abusing controller reread routines.</ref>, but this is generally not an important edge case to account for.<br />
<br />
=== DPCM Safety using OAM DMA ===<br />
<br />
Because halts for DPCM fetches normally only occur on an put cycles, it is possible to get glitch-free controller reads by timing all '''$4016''' and '''$4017''' reads to fall on get cycles. This is made possible by the behavior of OAM DMA: the first cycle after an OAM DMA is normally guaranteed to be a get cycle.<ref>[http://forums.nesdev.org/viewtopic.php?p=171971 Forum post:] Rahsennor's OAM-synchronized controller read</ref> This is a relatively new technique and is not supported by some emulators.<ref>[http://forums.nesdev.org/viewtopic.php?f=2&t=14319&start=15#p172099 Forum post:] as of May 2016, Nintendulator and Nestopia do not accurately emulate OAM-synchronized controller reading.</ref> In the following example code, the controller1 and controller2 labels must be in zeropage for the timing to work.<br />
<br />
<pre><br />
lda #OAM<br />
sta $4014 ; ------ OAM DMA ------<br />
ldx #1 ; get put <- strobe code must take an odd number of cycles total<br />
stx controller1 ; get put get <- controller1 and controller2 must be in the zeropage<br />
stx $4016 ; put get put get<br />
dex ; put get<br />
stx $4016 ; put get put get<br />
read_loop:<br />
lda $4017 ; put get put GET <- loop code must take an even number of cycles total<br />
and #3 ; put get<br />
cmp #1 ; put get<br />
rol controller2, x ; put get put get put get (X = 0; waste 1 cycle and 0 bytes for alignment)<br />
lda $4016 ; put get put GET<br />
and #3 ; put get<br />
cmp #1 ; put get<br />
rol controller1 ; put get put get put<br />
bcc read_loop ; get put [get] <- this branch must not be allowed to cross a page<br />
</pre><br />
<br />
Note that this example routine only reads two 8-bit controllers and does not take enough time to span more than one DPCM fetch. Routines longer than this must contend with two additional constraints:<br />
* When DMC DMA is delayed by an odd number of cycles, it takes 3 cycles instead of 4, changing the cycle parity. If extending this function to read more bits, care must be taken so that ''all'' CPU write cycles are aligned. Instructions with a single write cycle must align the write to avoid conflict with the DPCM fetch, and double-write instructions like ROL need to align both writes so that the DPCM fetch falls on the first write.<ref>[//forums.nesdev.org/viewtopic.php?p=231604#p231604 Forum post:] demonstration of how ROL instruction affects alignment for OAM DMA synchronized controller reading.</ref> If an interrupt can occur during the routine, it must be aligned so the fetch can only fall on the second of the three automatic stack writes.<br />
* When DMC DMA occurs near the end of OAM DMA, it only steals 1 or 3 cycles, inverting the cycle parity. Every DMC period after that, a misaligned DPCM fetch will occur. Care must be taken to ensure this does not land on a joypad read.<br />
<br />
See [[DMA]] for detailed information on DMA timing.<br />
<br />
=== Directional Safety ===<br />
<br />
To reject opposing presses (Up+Down and Left+Right), which are possible on a worn Control Pad:<br />
<pre><br />
lda buttons,x<br />
and #%00001010 ; Compare Up and Left...<br />
lsr a<br />
and buttons,x ; to Down and Right<br />
beq not_updown<br />
; Use previous frame's directions<br />
lda buttons,x<br />
eor last_frame_buttons,x<br />
and #%11110000<br />
eor last_frame_buttons,x<br />
sta buttons,x<br />
not_updown:<br />
</pre><br />
<br />
To instead reject all diagonal presses, simulating a 4-way joystick:<br />
<pre><br />
lda buttons,x<br />
and #%00001111 ; If A & (A - 1) is nonzero, A has more than one bit set<br />
beq not_diagonal<br />
sec<br />
sbc #1<br />
and buttons,x<br />
beq not_diagonal<br />
; Use previous frame's directions<br />
lda buttons,x<br />
eor last_frame_buttons,x<br />
and #%11110000<br />
eor last_frame_buttons,x<br />
sta buttons,x<br />
not_diagonal:<br />
</pre><br />
<br />
=== Calculating Presses and Releases ===<br />
<br />
To calculate newly pressed and newly released buttons:<br />
<pre><br />
lda buttons,x<br />
eor #%11111111<br />
and last_frame_buttons,x<br />
sta released_buttons,x<br />
lda last_frame_buttons,x<br />
eor #%11111111<br />
and buttons,x<br />
sta pressed_buttons,x<br />
</pre><br />
<br />
=== Button Flags ===<br />
<br />
It is helpful to define the buttons as a series of bit flags:<br />
<pre><br />
BUTTON_A = 1 << 7<br />
BUTTON_B = 1 << 6<br />
BUTTON_SELECT = 1 << 5<br />
BUTTON_START = 1 << 4<br />
BUTTON_UP = 1 << 3<br />
BUTTON_DOWN = 1 << 2<br />
BUTTON_LEFT = 1 << 1<br />
BUTTON_RIGHT = 1 << 0<br />
</pre><br />
<br />
And then buttons can be checked as follows:<br />
<pre><br />
lda buttons<br />
and #BUTTON_A | BUTTON_B<br />
beq notPressingAorB<br />
; Handle presses.<br />
notPressingAorB:<br />
</pre><br />
<br />
== External Examples ==<br />
<br />
* [http://forums.nesdev.org/viewtopic.php?t=4124 Forum post:] Blargg's DMC-fortified controller read routine<br />
* [http://forums.nesdev.org/viewtopic.php?p=171971 Forum post:] Rahsennor's OAM-synchronized controller read<br />
* [http://forums.nesdev.org/viewtopic.php?f=2&t=14197 Forum post:] Drag's bitwise DMC-safe controller reading<br />
<br />
== References ==<br />
<references/></div>Rainwarriorhttps://www.nesdev.org/w/index.php?title=Controller_reading_code&diff=21496Controller reading code2024-01-11T01:58:52Z<p>Rainwarrior: examples now use "buttons", not "buttons1, buttons2"</p>
<hr />
<div>This page contains example code for reading the [[NES controller]].<br />
<br />
See also: [[Controller reading]]<br />
<br />
=== Basic Example ===<br />
<br />
This is a tutorial example of the bare minimum needed to read the controller.<br />
It will explain the basic principles in detail, but once understood, you may wish to continue to the [[#Standard Read for 2 Controllers and Famicom|Standard Read]] example that follows,<br />
as a more complete and ready-to-use code example.<br />
<br />
This code describes an efficient method of reading the [[standard controller]] using [http://cc65.github.io/cc65/ ca65] syntax.<br />
<br />
The result byte ''buttons'' should be placed in zero page to save a cycle each time through the loop.<br />
<pre><br />
; we reserve one byte for storing the data that is read from controller<br />
.zeropage<br />
buttons .res 1<br />
</pre><br />
<br />
When reading from ''JOYPAD*'' what is read might be different from $01/$00 for various reasons. (See [[Controller reading]].) In this code the only concern is bit 0 read from ''JOYPAD*.''.<br />
<pre><br />
JOYPAD1 = $4016<br />
JOYPAD2 = $4017<br />
</pre><br />
<br />
This is the end result that will be stored in ''buttons''. '''1''' if the button was pressed, '''0''' otherwise.<br />
<br />
{| class="wikitable" style="text-align:center;"<br />
|-<br />
! bit<br />
| &nbsp;&nbsp;&nbsp;&nbsp;7&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;6&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;5&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;4&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;3&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;2&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;1&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;&nbsp;<br />
|-<br />
! button<br />
| A<br />
| B<br />
| Select<br />
| Start<br />
| Up<br />
| Down<br />
| Left<br />
| Right<br />
|}<br />
<br />
This subroutine takes 132 cycles to execute but ignores the Famicom expansion controller.<br />
Many controller reading subroutines use the X or Y register to count 8 times through the loop.<br />
But this one uses a more clever [[wikipedia:Ring counter|ring counter]] technique: $01 is loaded into the result first, and once eight bits are shifted in, the 1 bit will be shifted out, terminating the loop.<br />
<pre><br />
; At the same time that we strobe bit 0, we initialize the ring counter<br />
; so we're hitting two birds with one stone here<br />
readjoy:<br />
lda #$01<br />
; While the strobe bit is set, buttons will be continuously reloaded.<br />
; This means that reading from JOYPAD1 will only return the state of the<br />
; first button: button A.<br />
sta JOYPAD1<br />
sta buttons<br />
lsr a ; now A is 0<br />
; By storing 0 into JOYPAD1, the strobe bit is cleared and the reloading stops.<br />
; This allows all 8 buttons (newly reloaded) to be read from JOYPAD1.<br />
sta JOYPAD1<br />
loop:<br />
lda JOYPAD1<br />
lsr a ; bit 0 -> Carry<br />
rol buttons ; Carry -> bit 0; bit 7 -> Carry<br />
bcc loop<br />
rts<br />
</pre><br />
<br />
Continue to the next example for a more complete read routine that handles both controllers and the standard Famicom expansion controllers.<br />
<br />
=== Standard Read for 2 Controllers and Famicom ===<br />
<br />
Adding support for controllers on the Famicom's DA15 expansion port and for player 2's controller is straightforward. Something similar to the following routine is used in most Famicom games.<br />
Even though the expansion port is unused on the NES, the unconnected bit will read as 0, so this solution works safely with both Famicom and NES hardware.<br />
<pre><br />
.zeropage<br />
buttons: .res 2 ; space for 2 reads<br />
<br />
.code<br />
readjoyx2:<br />
ldx #$00<br />
jsr readjoyx ; X=0: read controller 1<br />
inx<br />
; fall through to readjoyx below, X=1: read controller 2<br />
<br />
readjoyx: ; X register = 0 for controller 1, 1 for controller 2<br />
lda #$01<br />
sta JOYPAD1<br />
sta buttons, X<br />
lsr a<br />
sta JOYPAD1<br />
loop:<br />
lda JOYPAD1, X<br />
and #%00000011 ; ignore bits other than controller<br />
cmp #$01 ; Set carry if and only if nonzero<br />
rol buttons, X ; Carry -> bit 0; but 7 -> Carry<br />
bcc loop<br />
rts<br />
</pre><br />
<br />
If playing DPCM samples, there is an additional reread step to prevent errors ([[#DPCM Safety using Repeated Reads|see below]]).<br />
<br />
Note that the <tt>and</tt> to ignore bits is not optional, as the upper bits of <tt>JOYPAD1</tt> read are not guaranteed to be 1 or 0<ref>[[Controller_reading#Unconnected_data_lines_and_open_bus|Controller reading: Unconnected data lines and open bus]]</ref>.<br />
<br />
=== Alternative 2 Controllers Read ===<br />
<br />
Alternatively, we could combine both controller reads into 1 loop with a single strobe, though this routine is not safe to use with DPCM samples playing ([[#DPCM Safety using Repeated Reads|see below]]).<br />
<pre><br />
.zeropage<br />
buttons: .res 2<br />
<br />
.code<br />
readjoy2:<br />
lda #$01<br />
sta JOYPAD1<br />
sta buttons+1 ; player 2's buttons double as a ring counter<br />
lsr a<br />
sta JOYPAD1<br />
loop:<br />
lda JOYPAD1<br />
and #%00000011<br />
cmp #$01<br />
rol buttons+0<br />
lda JOYPAD2<br />
and #%00000011<br />
cmp #$01<br />
rol buttons+1<br />
bcc loop<br />
rts<br />
</pre><br />
<br />
=== DPCM Safety using Repeated Reads ===<br />
<br />
If your code is intended to be used with [[APU DMC]] playback, this code will need to be altered. The NES occasionally glitches the controller port twice in a row if sample playback is enabled, and games using samples need to work around this. The most common technique, as seen in ''Super Mario Bros. 3''<ref>[//forums.nesdev.org/viewtopic.php?p=151720#p151720 Super Mario Bros. 3 controller reread method]</ref> and other games, will read each controller twice, but in the event of a mismatch it will keep re-reading the controller until two results in a row are the same.<br />
<pre><br />
readjoy2_safe:<br />
ldx #$00<br />
jsr readjoyx_safe ; X=0: safe read controller 1<br />
inx<br />
; fall through to readjoyx_safe, X=1: safe read controller 2<br />
<br />
readjoyx_safe:<br />
jsr readjoyx<br />
reread:<br />
lda buttons, X<br />
pha<br />
jsr readjoyx<br />
pla<br />
cmp buttons, X<br />
bne reread<br />
rts<br />
</pre><br />
<br />
Note that the time between the start of one read and the end of the next read must be less than the length of the fastest DMC fetch period (432 cycles). For this reason, it is normal to read controllers one at a time with this method, rather than attempting both at once. (Note: <code>readjoy2</code> above takes too long to be suitable.) [[Game bugs|''Gimmick!'' has such a bug]] resulting from trying to read both at once.<br />
<br />
Most often a controller will be read 2 times, and 3 or 4 in the case of a DPCM corruption, or the player pressing a button during the read. With the assistance of tools, a malicious controller input could change the buttons on every read, holding it in this reread loop indefinitely<ref>[https://arstechnica.com/gaming/2016/07/how-to-beat-super-mario-bros-3-in-less-than-a-second/ Ars Technica: How to beat Super Mario Bros. 3 in less than a second]</ref><ref>https://tasvideos.org/6466S Tool-Assisted Speedrun of Super Mario Bros. 3 which first demonstrated abusing controller reread routines.</ref>, but this is generally not an important edge case to account for.<br />
<br />
=== DPCM Safety using OAM DMA ===<br />
<br />
Because halts for DPCM fetches normally only occur on an put cycles, it is possible to get glitch-free controller reads by timing all '''$4016''' and '''$4017''' reads to fall on get cycles. This is made possible by the behavior of OAM DMA: the first cycle after an OAM DMA is normally guaranteed to be a get cycle.<ref>[http://forums.nesdev.org/viewtopic.php?p=171971 Forum post:] Rahsennor's OAM-synchronized controller read</ref> This is a relatively new technique and is not supported by some emulators.<ref>[http://forums.nesdev.org/viewtopic.php?f=2&t=14319&start=15#p172099 Forum post:] as of May 2016, Nintendulator and Nestopia do not accurately emulate OAM-synchronized controller reading.</ref> In the following example code, the controller1 and controller2 labels must be in zeropage for the timing to work.<br />
<br />
<pre><br />
lda #OAM<br />
sta $4014 ; ------ OAM DMA ------<br />
ldx #1 ; get put <- strobe code must take an odd number of cycles total<br />
stx controller1 ; get put get <- controller1 and controller2 must be in the zeropage<br />
stx $4016 ; put get put get<br />
dex ; put get<br />
stx $4016 ; put get put get<br />
read_loop:<br />
lda $4017 ; put get put GET <- loop code must take an even number of cycles total<br />
and #3 ; put get<br />
cmp #1 ; put get<br />
rol controller2, x ; put get put get put get (X = 0; waste 1 cycle and 0 bytes for alignment)<br />
lda $4016 ; put get put GET<br />
and #3 ; put get<br />
cmp #1 ; put get<br />
rol controller1 ; put get put get put<br />
bcc read_loop ; get put [get] <- this branch must not be allowed to cross a page<br />
</pre><br />
<br />
Note that this example routine only reads two 8-bit controllers and does not take enough time to span more than one DPCM fetch. Routines longer than this must contend with two additional constraints:<br />
* When DMC DMA is delayed by an odd number of cycles, it takes 3 cycles instead of 4, changing the cycle parity. If extending this function to read more bits, care must be taken so that ''all'' CPU write cycles are aligned. Instructions with a single write cycle must align the write to avoid conflict with the DPCM fetch, and double-write instructions like ROL need to align both writes so that the DPCM fetch falls on the first write.<ref>[//forums.nesdev.org/viewtopic.php?p=231604#p231604 Forum post:] demonstration of how ROL instruction affects alignment for OAM DMA synchronized controller reading.</ref> If an interrupt can occur during the routine, it must be aligned so the fetch can only fall on the second of the three automatic stack writes.<br />
* When DMC DMA occurs near the end of OAM DMA, it only steals 1 or 3 cycles, inverting the cycle parity. Every DMC period after that, a misaligned DPCM fetch will occur. Care must be taken to ensure this does not land on a joypad read.<br />
<br />
See [[DMA]] for detailed information on DMA timing.<br />
<br />
=== Directional Safety ===<br />
<br />
To reject opposing presses (Up+Down and Left+Right), which are possible on a worn Control Pad:<br />
<pre><br />
lda buttons,x<br />
and #%00001010 ; Compare Up and Left...<br />
lsr a<br />
and buttons,x ; to Down and Right<br />
beq not_updown<br />
; Use previous frame's directions<br />
lda buttons,x<br />
eor last_frame_buttons,x<br />
and #%11110000<br />
eor last_frame_buttons,x<br />
sta buttons,x<br />
not_updown:<br />
</pre><br />
<br />
To instead reject all diagonal presses, simulating a 4-way joystick:<br />
<pre><br />
lda buttons,x<br />
and #%00001111 ; If A & (A - 1) is nonzero, A has more than one bit set<br />
beq not_diagonal<br />
sec<br />
sbc #1<br />
and buttons,x<br />
beq not_diagonal<br />
; Use previous frame's directions<br />
lda buttons,x<br />
eor last_frame_buttons,x<br />
and #%11110000<br />
eor last_frame_buttons,x<br />
sta buttons,x<br />
not_diagonal:<br />
</pre><br />
<br />
=== Calculating Presses and Releases ===<br />
<br />
To calculate newly pressed and newly released buttons:<br />
<pre><br />
lda buttons,x<br />
eor #%11111111<br />
and last_frame_buttons,x<br />
sta released_buttons,x<br />
lda last_frame_buttons,x<br />
eor #%11111111<br />
and buttons,x<br />
sta pressed_buttons,x<br />
</pre><br />
<br />
=== Button Flags ===<br />
<br />
It is helpful to define the buttons as a series of bit flags:<br />
<pre><br />
BUTTON_A = 1 << 7<br />
BUTTON_B = 1 << 6<br />
BUTTON_SELECT = 1 << 5<br />
BUTTON_START = 1 << 4<br />
BUTTON_UP = 1 << 3<br />
BUTTON_DOWN = 1 << 2<br />
BUTTON_LEFT = 1 << 1<br />
BUTTON_RIGHT = 1 << 0<br />
</pre><br />
<br />
And then buttons can be checked as follows:<br />
<pre><br />
lda buttons<br />
and #BUTTON_A | BUTTON_B<br />
beq notPressingAorB<br />
; Handle presses.<br />
notPressingAorB:<br />
</pre><br />
<br />
== External Examples ==<br />
<br />
* [http://forums.nesdev.org/viewtopic.php?t=4124 Forum post:] Blargg's DMC-fortified controller read routine<br />
* [http://forums.nesdev.org/viewtopic.php?p=171971 Forum post:] Rahsennor's OAM-synchronized controller read<br />
* [http://forums.nesdev.org/viewtopic.php?f=2&t=14197 Forum post:] Drag's bitwise DMC-safe controller reading<br />
<br />
== References ==<br />
<references/></div>Rainwarriorhttps://www.nesdev.org/w/index.php?title=Controller_reading_code&diff=21494Controller reading code2024-01-11T01:32:03Z<p>Rainwarrior: /* DPCM Safety using Repeated Reads */ fix arstechnica link</p>
<hr />
<div>This page contains example code for reading the [[NES controller]].<br />
<br />
See also: [[Controller reading]]<br />
<br />
=== Basic Example ===<br />
<br />
This is a tutorial example of the bare minimum needed to read the controller.<br />
It will explain the basic principles in detail, but once understood, you may wish to continue to the [[#Standard Read for 2 Controllers and Famicom|Standard Read]] example that follows,<br />
as a more complete and ready-to-use code example.<br />
<br />
This code describes an efficient method of reading the [[standard controller]] using [http://cc65.github.io/cc65/ ca65] syntax.<br />
<br />
The result byte ''buttons'' should be placed in zero page to save a cycle each time through the loop.<br />
<pre><br />
; we reserve one byte for storing the data that is read from controller<br />
.zeropage<br />
buttons .res 1<br />
</pre><br />
<br />
When reading from ''JOYPAD*'' what is read might be different from $01/$00 for various reasons. (See [[Controller reading]].) In this code the only concern is bit 0 read from ''JOYPAD*.''.<br />
<pre><br />
JOYPAD1 = $4016<br />
JOYPAD2 = $4017<br />
</pre><br />
<br />
This is the end result that will be stored in ''buttons''. '''1''' if the button was pressed, '''0''' otherwise.<br />
<br />
{| class="wikitable" style="text-align:center;"<br />
|-<br />
! bit<br />
| &nbsp;&nbsp;&nbsp;&nbsp;7&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;6&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;5&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;4&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;3&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;2&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;1&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;&nbsp;<br />
|-<br />
! button<br />
| A<br />
| B<br />
| Select<br />
| Start<br />
| Up<br />
| Down<br />
| Left<br />
| Right<br />
|}<br />
<br />
This subroutine takes 132 cycles to execute but ignores the Famicom expansion controller.<br />
Many controller reading subroutines use the X or Y register to count 8 times through the loop.<br />
But this one uses a more clever [[wikipedia:Ring counter|ring counter]] technique: $01 is loaded into the result first, and once eight bits are shifted in, the 1 bit will be shifted out, terminating the loop.<br />
<pre><br />
; At the same time that we strobe bit 0, we initialize the ring counter<br />
; so we're hitting two birds with one stone here<br />
readjoy:<br />
lda #$01<br />
; While the strobe bit is set, buttons will be continuously reloaded.<br />
; This means that reading from JOYPAD1 will only return the state of the<br />
; first button: button A.<br />
sta JOYPAD1<br />
sta buttons<br />
lsr a ; now A is 0<br />
; By storing 0 into JOYPAD1, the strobe bit is cleared and the reloading stops.<br />
; This allows all 8 buttons (newly reloaded) to be read from JOYPAD1.<br />
sta JOYPAD1<br />
loop:<br />
lda JOYPAD1<br />
lsr a ; bit 0 -> Carry<br />
rol buttons ; Carry -> bit 0; bit 7 -> Carry<br />
bcc loop<br />
rts<br />
</pre><br />
<br />
Continue to the next example for a more complete read routine that handles both controllers and the standard Famicom expansion controllers.<br />
<br />
=== Standard Read for 2 Controllers and Famicom ===<br />
<br />
Adding support for controllers on the Famicom's DA15 expansion port and for player 2's controller is straightforward. Something similar to the following routine is used in most Famicom games.<br />
Even though the expansion port is unused on the NES, the unconnected bit will read as 0, so this solution works safely with both Famicom and NES hardware.<br />
<pre><br />
.zeropage<br />
buttons: .res 2 ; space for 2 reads<br />
<br />
.code<br />
readjoyx2:<br />
ldx #$00<br />
jsr readjoyx ; X=0: read controller 1<br />
inx<br />
; fall through to readjoyx below, X=1: read controller 2<br />
<br />
readjoyx: ; X register = 0 for controller 1, 1 for controller 2<br />
lda #$01<br />
sta JOYPAD1<br />
sta buttons, X<br />
lsr a<br />
sta JOYPAD1<br />
loop:<br />
lda JOYPAD1, X<br />
and #%00000011 ; ignore bits other than controller<br />
cmp #$01 ; Set carry if and only if nonzero<br />
rol buttons, X ; Carry -> bit 0; but 7 -> Carry<br />
bcc loop<br />
rts<br />
</pre><br />
<br />
If playing DPCM samples, there is an additional reread step to prevent errors ([[#DPCM Safety using Repeated Reads|see below]]).<br />
<br />
Note that the <tt>and</tt> to ignore bits is not optional, as the upper bits of <tt>JOYPAD1</tt> read are not guaranteed to be 1 or 0<ref>[[Controller_reading#Unconnected_data_lines_and_open_bus|Controller reading: Unconnected data lines and open bus]]</ref>.<br />
<br />
=== Alternative 2 Controllers Read ===<br />
<br />
Alternatively, we could combine both controller reads into 1 loop with a single strobe, though this routine is not safe to use with DPCM samples playing ([[#DPCM Safety using Repeated Reads|see below]]).<br />
<pre><br />
.zeropage<br />
buttons: .res 2<br />
<br />
.code<br />
readjoy2:<br />
lda #$01<br />
sta JOYPAD1<br />
sta buttons+1 ; player 2's buttons double as a ring counter<br />
lsr a<br />
sta JOYPAD1<br />
loop:<br />
lda JOYPAD1<br />
and #%00000011<br />
cmp #$01<br />
rol buttons+0<br />
lda JOYPAD2<br />
and #%00000011<br />
cmp #$01<br />
rol buttons+1<br />
bcc loop<br />
rts<br />
</pre><br />
<br />
=== DPCM Safety using Repeated Reads ===<br />
<br />
If your code is intended to be used with [[APU DMC]] playback, this code will need to be altered. The NES occasionally glitches the controller port twice in a row if sample playback is enabled, and games using samples need to work around this. The most common technique, as seen in ''Super Mario Bros. 3''<ref>[//forums.nesdev.org/viewtopic.php?p=151720#p151720 Super Mario Bros. 3 controller reread method]</ref> and other games, will read each controller twice, but in the event of a mismatch it will keep re-reading the controller until two results in a row are the same.<br />
<pre><br />
readjoy2_safe:<br />
ldx #$00<br />
jsr readjoyx_safe ; X=0: safe read controller 1<br />
inx<br />
; fall through to readjoyx_safe, X=1: safe read controller 2<br />
<br />
readjoyx_safe:<br />
jsr readjoyx<br />
reread:<br />
lda buttons, X<br />
pha<br />
jsr readjoyx<br />
pla<br />
cmp buttons, X<br />
bne reread<br />
rts<br />
</pre><br />
<br />
Note that the time between the start of one read and the end of the next read must be less than the length of the fastest DMC fetch period (432 cycles). For this reason, it is normal to read controllers one at a time with this method, rather than attempting both at once. (Note: <code>readjoy2</code> above takes too long to be suitable.) [[Game bugs|''Gimmick!'' has such a bug]] resulting from trying to read both at once.<br />
<br />
Most often a controller will be read 2 times, and 3 or 4 in the case of a DPCM corruption, or the player pressing a button during the read. With the assistance of tools, a malicious controller input could change the buttons on every read, holding it in this reread loop indefinitely<ref>[https://arstechnica.com/gaming/2016/07/how-to-beat-super-mario-bros-3-in-less-than-a-second/ Ars Technica: How to beat Super Mario Bros. 3 in less than a second]</ref>, but this is generally not an important edge case to account for.<br />
<br />
=== DPCM Safety using OAM DMA ===<br />
<br />
Because halts for DPCM fetches normally only occur on an put cycles, it is possible to get glitch-free controller reads by timing all '''$4016''' and '''$4017''' reads to fall on get cycles. This is made possible by the behavior of OAM DMA: the first cycle after an OAM DMA is normally guaranteed to be a get cycle.<ref>[http://forums.nesdev.org/viewtopic.php?p=171971 Forum post:] Rahsennor's OAM-synchronized controller read</ref> This is a relatively new technique and is not supported by some emulators.<ref>[http://forums.nesdev.org/viewtopic.php?f=2&t=14319&start=15#p172099 Forum post:] as of May 2016, Nintendulator and Nestopia do not accurately emulate OAM-synchronized controller reading.</ref> In the following example code, the controller1 and controller2 labels must be in zeropage for the timing to work.<br />
<br />
<pre><br />
lda #OAM<br />
sta $4014 ; ------ OAM DMA ------<br />
ldx #1 ; get put <- strobe code must take an odd number of cycles total<br />
stx controller1 ; get put get <- controller1 and controller2 must be in the zeropage<br />
stx $4016 ; put get put get<br />
dex ; put get<br />
stx $4016 ; put get put get<br />
read_loop:<br />
lda $4017 ; put get put GET <- loop code must take an even number of cycles total<br />
and #3 ; put get<br />
cmp #1 ; put get<br />
rol controller2, x ; put get put get put get (X = 0; waste 1 cycle and 0 bytes for alignment)<br />
lda $4016 ; put get put GET<br />
and #3 ; put get<br />
cmp #1 ; put get<br />
rol controller1 ; put get put get put<br />
bcc read_loop ; get put [get] <- this branch must not be allowed to cross a page<br />
</pre><br />
<br />
Note that this example routine only reads two 8-bit controllers and does not take enough time to span more than one DPCM fetch. Routines longer than this must contend with two additional constraints:<br />
* When DMC DMA is delayed by an odd number of cycles, it takes 3 cycles instead of 4, changing the cycle parity. If extending this function to read more bits, care must be taken so that ''all'' CPU write cycles are aligned. Instructions with a single write cycle must align the write to avoid conflict with the DPCM fetch, and double-write instructions like ROL need to align both writes so that the DPCM fetch falls on the first write.<ref>[//forums.nesdev.org/viewtopic.php?p=231604#p231604 Forum post:] demonstration of how ROL instruction affects alignment for OAM DMA synchronized controller reading.</ref> If an interrupt can occur during the routine, it must be aligned so the fetch can only fall on the second of the three automatic stack writes.<br />
* When DMC DMA occurs near the end of OAM DMA, it only steals 1 or 3 cycles, inverting the cycle parity. Every DMC period after that, a misaligned DPCM fetch will occur. Care must be taken to ensure this does not land on a joypad read.<br />
<br />
See [[DMA]] for detailed information on DMA timing.<br />
<br />
=== Directional Safety ===<br />
<br />
To reject opposing presses (Up+Down and Left+Right), which are possible on a worn Control Pad:<br />
<pre><br />
lda buttons1,x<br />
and #%00001010 ; Compare Up and Left...<br />
lsr a<br />
and buttons1,x ; to Down and Right<br />
beq not_updown<br />
; Use previous frame's directions<br />
lda buttons1,x<br />
eor last_frame_buttons1,x<br />
and #%11110000<br />
eor last_frame_buttons1,x<br />
sta buttons1,x<br />
not_updown:<br />
</pre><br />
<br />
To instead reject all diagonal presses, simulating a 4-way joystick:<br />
<pre><br />
lda buttons1,x<br />
and #%00001111 ; If A & (A - 1) is nonzero, A has more than one bit set<br />
beq not_diagonal<br />
sec<br />
sbc #1<br />
and buttons1,x<br />
beq not_diagonal<br />
; Use previous frame's directions<br />
lda buttons1,x<br />
eor last_frame_buttons1,x<br />
and #%11110000<br />
eor last_frame_buttons1,x<br />
sta buttons1,x<br />
not_diagonal:<br />
</pre><br />
<br />
=== Calculating Presses and Releases ===<br />
<br />
To calculate newly pressed and newly released buttons:<br />
<pre><br />
lda buttons1,x<br />
eor #%11111111<br />
and last_frame_buttons1,x<br />
sta released_buttons1,x<br />
lda last_frame_buttons1,x<br />
eor #%11111111<br />
and buttons1,x<br />
sta pressed_buttons1,x<br />
</pre><br />
<br />
=== Button Flags ===<br />
<br />
It is helpful to define the buttons as a series of bit flags:<br />
<pre><br />
BUTTON_A = 1 << 7<br />
BUTTON_B = 1 << 6<br />
BUTTON_SELECT = 1 << 5<br />
BUTTON_START = 1 << 4<br />
BUTTON_UP = 1 << 3<br />
BUTTON_DOWN = 1 << 2<br />
BUTTON_LEFT = 1 << 1<br />
BUTTON_RIGHT = 1 << 0<br />
</pre><br />
<br />
And then buttons can be checked as follows:<br />
<pre><br />
lda buttons<br />
and #BUTTON_A | BUTTON_B<br />
beq notPressingAorB<br />
; Handle presses.<br />
notPressingAorB:<br />
</pre><br />
<br />
== External Examples ==<br />
<br />
* [http://forums.nesdev.org/viewtopic.php?t=4124 Forum post:] Blargg's DMC-fortified controller read routine<br />
* [http://forums.nesdev.org/viewtopic.php?p=171971 Forum post:] Rahsennor's OAM-synchronized controller read<br />
* [http://forums.nesdev.org/viewtopic.php?f=2&t=14197 Forum post:] Drag's bitwise DMC-safe controller reading<br />
<br />
== References ==<br />
<references/></div>Rainwarriorhttps://www.nesdev.org/w/index.php?title=Controller_reading_code&diff=21493Controller reading code2024-01-11T01:31:30Z<p>Rainwarrior: /* Standard Read for 2 Controllers and Famicom */ footnote about why the AND can't be skipped</p>
<hr />
<div>This page contains example code for reading the [[NES controller]].<br />
<br />
See also: [[Controller reading]]<br />
<br />
=== Basic Example ===<br />
<br />
This is a tutorial example of the bare minimum needed to read the controller.<br />
It will explain the basic principles in detail, but once understood, you may wish to continue to the [[#Standard Read for 2 Controllers and Famicom|Standard Read]] example that follows,<br />
as a more complete and ready-to-use code example.<br />
<br />
This code describes an efficient method of reading the [[standard controller]] using [http://cc65.github.io/cc65/ ca65] syntax.<br />
<br />
The result byte ''buttons'' should be placed in zero page to save a cycle each time through the loop.<br />
<pre><br />
; we reserve one byte for storing the data that is read from controller<br />
.zeropage<br />
buttons .res 1<br />
</pre><br />
<br />
When reading from ''JOYPAD*'' what is read might be different from $01/$00 for various reasons. (See [[Controller reading]].) In this code the only concern is bit 0 read from ''JOYPAD*.''.<br />
<pre><br />
JOYPAD1 = $4016<br />
JOYPAD2 = $4017<br />
</pre><br />
<br />
This is the end result that will be stored in ''buttons''. '''1''' if the button was pressed, '''0''' otherwise.<br />
<br />
{| class="wikitable" style="text-align:center;"<br />
|-<br />
! bit<br />
| &nbsp;&nbsp;&nbsp;&nbsp;7&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;6&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;5&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;4&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;3&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;2&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;1&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;&nbsp;<br />
|-<br />
! button<br />
| A<br />
| B<br />
| Select<br />
| Start<br />
| Up<br />
| Down<br />
| Left<br />
| Right<br />
|}<br />
<br />
This subroutine takes 132 cycles to execute but ignores the Famicom expansion controller.<br />
Many controller reading subroutines use the X or Y register to count 8 times through the loop.<br />
But this one uses a more clever [[wikipedia:Ring counter|ring counter]] technique: $01 is loaded into the result first, and once eight bits are shifted in, the 1 bit will be shifted out, terminating the loop.<br />
<pre><br />
; At the same time that we strobe bit 0, we initialize the ring counter<br />
; so we're hitting two birds with one stone here<br />
readjoy:<br />
lda #$01<br />
; While the strobe bit is set, buttons will be continuously reloaded.<br />
; This means that reading from JOYPAD1 will only return the state of the<br />
; first button: button A.<br />
sta JOYPAD1<br />
sta buttons<br />
lsr a ; now A is 0<br />
; By storing 0 into JOYPAD1, the strobe bit is cleared and the reloading stops.<br />
; This allows all 8 buttons (newly reloaded) to be read from JOYPAD1.<br />
sta JOYPAD1<br />
loop:<br />
lda JOYPAD1<br />
lsr a ; bit 0 -> Carry<br />
rol buttons ; Carry -> bit 0; bit 7 -> Carry<br />
bcc loop<br />
rts<br />
</pre><br />
<br />
Continue to the next example for a more complete read routine that handles both controllers and the standard Famicom expansion controllers.<br />
<br />
=== Standard Read for 2 Controllers and Famicom ===<br />
<br />
Adding support for controllers on the Famicom's DA15 expansion port and for player 2's controller is straightforward. Something similar to the following routine is used in most Famicom games.<br />
Even though the expansion port is unused on the NES, the unconnected bit will read as 0, so this solution works safely with both Famicom and NES hardware.<br />
<pre><br />
.zeropage<br />
buttons: .res 2 ; space for 2 reads<br />
<br />
.code<br />
readjoyx2:<br />
ldx #$00<br />
jsr readjoyx ; X=0: read controller 1<br />
inx<br />
; fall through to readjoyx below, X=1: read controller 2<br />
<br />
readjoyx: ; X register = 0 for controller 1, 1 for controller 2<br />
lda #$01<br />
sta JOYPAD1<br />
sta buttons, X<br />
lsr a<br />
sta JOYPAD1<br />
loop:<br />
lda JOYPAD1, X<br />
and #%00000011 ; ignore bits other than controller<br />
cmp #$01 ; Set carry if and only if nonzero<br />
rol buttons, X ; Carry -> bit 0; but 7 -> Carry<br />
bcc loop<br />
rts<br />
</pre><br />
<br />
If playing DPCM samples, there is an additional reread step to prevent errors ([[#DPCM Safety using Repeated Reads|see below]]).<br />
<br />
Note that the <tt>and</tt> to ignore bits is not optional, as the upper bits of <tt>JOYPAD1</tt> read are not guaranteed to be 1 or 0<ref>[[Controller_reading#Unconnected_data_lines_and_open_bus|Controller reading: Unconnected data lines and open bus]]</ref>.<br />
<br />
=== Alternative 2 Controllers Read ===<br />
<br />
Alternatively, we could combine both controller reads into 1 loop with a single strobe, though this routine is not safe to use with DPCM samples playing ([[#DPCM Safety using Repeated Reads|see below]]).<br />
<pre><br />
.zeropage<br />
buttons: .res 2<br />
<br />
.code<br />
readjoy2:<br />
lda #$01<br />
sta JOYPAD1<br />
sta buttons+1 ; player 2's buttons double as a ring counter<br />
lsr a<br />
sta JOYPAD1<br />
loop:<br />
lda JOYPAD1<br />
and #%00000011<br />
cmp #$01<br />
rol buttons+0<br />
lda JOYPAD2<br />
and #%00000011<br />
cmp #$01<br />
rol buttons+1<br />
bcc loop<br />
rts<br />
</pre><br />
<br />
=== DPCM Safety using Repeated Reads ===<br />
<br />
If your code is intended to be used with [[APU DMC]] playback, this code will need to be altered. The NES occasionally glitches the controller port twice in a row if sample playback is enabled, and games using samples need to work around this. The most common technique, as seen in ''Super Mario Bros. 3''<ref>[//forums.nesdev.org/viewtopic.php?p=151720#p151720 Super Mario Bros. 3 controller reread method]</ref> and other games, will read each controller twice, but in the event of a mismatch it will keep re-reading the controller until two results in a row are the same.<br />
<pre><br />
readjoy2_safe:<br />
ldx #$00<br />
jsr readjoyx_safe ; X=0: safe read controller 1<br />
inx<br />
; fall through to readjoyx_safe, X=1: safe read controller 2<br />
<br />
readjoyx_safe:<br />
jsr readjoyx<br />
reread:<br />
lda buttons, X<br />
pha<br />
jsr readjoyx<br />
pla<br />
cmp buttons, X<br />
bne reread<br />
rts<br />
</pre><br />
<br />
Note that the time between the start of one read and the end of the next read must be less than the length of the fastest DMC fetch period (432 cycles). For this reason, it is normal to read controllers one at a time with this method, rather than attempting both at once. (Note: <code>readjoy2</code> above takes too long to be suitable.) [[Game bugs|''Gimmick!'' has such a bug]] resulting from trying to read both at once.<br />
<br />
Most often a controller will be read 2 times, and 3 or 4 in the case of a DPCM corruption, or the player pressing a button during the read. With the assistance of tools, a malicious controller input could change the buttons on every read, holding it in this reread loop indefinitely<ref>[https://arstechnica.com/gaming/2016/07/how-to-beat-super-mario-bros-3-in-less-than-a-second/ Ars Technica: How to beat Super Mario Bros. 3 in less than a second</ref>, but this is generally not an important edge case to account for.<br />
<br />
=== DPCM Safety using OAM DMA ===<br />
<br />
Because halts for DPCM fetches normally only occur on an put cycles, it is possible to get glitch-free controller reads by timing all '''$4016''' and '''$4017''' reads to fall on get cycles. This is made possible by the behavior of OAM DMA: the first cycle after an OAM DMA is normally guaranteed to be a get cycle.<ref>[http://forums.nesdev.org/viewtopic.php?p=171971 Forum post:] Rahsennor's OAM-synchronized controller read</ref> This is a relatively new technique and is not supported by some emulators.<ref>[http://forums.nesdev.org/viewtopic.php?f=2&t=14319&start=15#p172099 Forum post:] as of May 2016, Nintendulator and Nestopia do not accurately emulate OAM-synchronized controller reading.</ref> In the following example code, the controller1 and controller2 labels must be in zeropage for the timing to work.<br />
<br />
<pre><br />
lda #OAM<br />
sta $4014 ; ------ OAM DMA ------<br />
ldx #1 ; get put <- strobe code must take an odd number of cycles total<br />
stx controller1 ; get put get <- controller1 and controller2 must be in the zeropage<br />
stx $4016 ; put get put get<br />
dex ; put get<br />
stx $4016 ; put get put get<br />
read_loop:<br />
lda $4017 ; put get put GET <- loop code must take an even number of cycles total<br />
and #3 ; put get<br />
cmp #1 ; put get<br />
rol controller2, x ; put get put get put get (X = 0; waste 1 cycle and 0 bytes for alignment)<br />
lda $4016 ; put get put GET<br />
and #3 ; put get<br />
cmp #1 ; put get<br />
rol controller1 ; put get put get put<br />
bcc read_loop ; get put [get] <- this branch must not be allowed to cross a page<br />
</pre><br />
<br />
Note that this example routine only reads two 8-bit controllers and does not take enough time to span more than one DPCM fetch. Routines longer than this must contend with two additional constraints:<br />
* When DMC DMA is delayed by an odd number of cycles, it takes 3 cycles instead of 4, changing the cycle parity. If extending this function to read more bits, care must be taken so that ''all'' CPU write cycles are aligned. Instructions with a single write cycle must align the write to avoid conflict with the DPCM fetch, and double-write instructions like ROL need to align both writes so that the DPCM fetch falls on the first write.<ref>[//forums.nesdev.org/viewtopic.php?p=231604#p231604 Forum post:] demonstration of how ROL instruction affects alignment for OAM DMA synchronized controller reading.</ref> If an interrupt can occur during the routine, it must be aligned so the fetch can only fall on the second of the three automatic stack writes.<br />
* When DMC DMA occurs near the end of OAM DMA, it only steals 1 or 3 cycles, inverting the cycle parity. Every DMC period after that, a misaligned DPCM fetch will occur. Care must be taken to ensure this does not land on a joypad read.<br />
<br />
See [[DMA]] for detailed information on DMA timing.<br />
<br />
=== Directional Safety ===<br />
<br />
To reject opposing presses (Up+Down and Left+Right), which are possible on a worn Control Pad:<br />
<pre><br />
lda buttons1,x<br />
and #%00001010 ; Compare Up and Left...<br />
lsr a<br />
and buttons1,x ; to Down and Right<br />
beq not_updown<br />
; Use previous frame's directions<br />
lda buttons1,x<br />
eor last_frame_buttons1,x<br />
and #%11110000<br />
eor last_frame_buttons1,x<br />
sta buttons1,x<br />
not_updown:<br />
</pre><br />
<br />
To instead reject all diagonal presses, simulating a 4-way joystick:<br />
<pre><br />
lda buttons1,x<br />
and #%00001111 ; If A & (A - 1) is nonzero, A has more than one bit set<br />
beq not_diagonal<br />
sec<br />
sbc #1<br />
and buttons1,x<br />
beq not_diagonal<br />
; Use previous frame's directions<br />
lda buttons1,x<br />
eor last_frame_buttons1,x<br />
and #%11110000<br />
eor last_frame_buttons1,x<br />
sta buttons1,x<br />
not_diagonal:<br />
</pre><br />
<br />
=== Calculating Presses and Releases ===<br />
<br />
To calculate newly pressed and newly released buttons:<br />
<pre><br />
lda buttons1,x<br />
eor #%11111111<br />
and last_frame_buttons1,x<br />
sta released_buttons1,x<br />
lda last_frame_buttons1,x<br />
eor #%11111111<br />
and buttons1,x<br />
sta pressed_buttons1,x<br />
</pre><br />
<br />
=== Button Flags ===<br />
<br />
It is helpful to define the buttons as a series of bit flags:<br />
<pre><br />
BUTTON_A = 1 << 7<br />
BUTTON_B = 1 << 6<br />
BUTTON_SELECT = 1 << 5<br />
BUTTON_START = 1 << 4<br />
BUTTON_UP = 1 << 3<br />
BUTTON_DOWN = 1 << 2<br />
BUTTON_LEFT = 1 << 1<br />
BUTTON_RIGHT = 1 << 0<br />
</pre><br />
<br />
And then buttons can be checked as follows:<br />
<pre><br />
lda buttons<br />
and #BUTTON_A | BUTTON_B<br />
beq notPressingAorB<br />
; Handle presses.<br />
notPressingAorB:<br />
</pre><br />
<br />
== External Examples ==<br />
<br />
* [http://forums.nesdev.org/viewtopic.php?t=4124 Forum post:] Blargg's DMC-fortified controller read routine<br />
* [http://forums.nesdev.org/viewtopic.php?p=171971 Forum post:] Rahsennor's OAM-synchronized controller read<br />
* [http://forums.nesdev.org/viewtopic.php?f=2&t=14197 Forum post:] Drag's bitwise DMC-safe controller reading<br />
<br />
== References ==<br />
<references/></div>Rainwarriorhttps://www.nesdev.org/w/index.php?title=Controller_reading_code&diff=21492Controller reading code2024-01-11T01:23:02Z<p>Rainwarrior: /* Standard Read for 2 Controllers and Famicom */ double bracket</p>
<hr />
<div>This page contains example code for reading the [[NES controller]].<br />
<br />
See also: [[Controller reading]]<br />
<br />
=== Basic Example ===<br />
<br />
This is a tutorial example of the bare minimum needed to read the controller.<br />
It will explain the basic principles in detail, but once understood, you may wish to continue to the [[#Standard Read for 2 Controllers and Famicom|Standard Read]] example that follows,<br />
as a more complete and ready-to-use code example.<br />
<br />
This code describes an efficient method of reading the [[standard controller]] using [http://cc65.github.io/cc65/ ca65] syntax.<br />
<br />
The result byte ''buttons'' should be placed in zero page to save a cycle each time through the loop.<br />
<pre><br />
; we reserve one byte for storing the data that is read from controller<br />
.zeropage<br />
buttons .res 1<br />
</pre><br />
<br />
When reading from ''JOYPAD*'' what is read might be different from $01/$00 for various reasons. (See [[Controller reading]].) In this code the only concern is bit 0 read from ''JOYPAD*.''.<br />
<pre><br />
JOYPAD1 = $4016<br />
JOYPAD2 = $4017<br />
</pre><br />
<br />
This is the end result that will be stored in ''buttons''. '''1''' if the button was pressed, '''0''' otherwise.<br />
<br />
{| class="wikitable" style="text-align:center;"<br />
|-<br />
! bit<br />
| &nbsp;&nbsp;&nbsp;&nbsp;7&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;6&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;5&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;4&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;3&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;2&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;1&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;&nbsp;<br />
|-<br />
! button<br />
| A<br />
| B<br />
| Select<br />
| Start<br />
| Up<br />
| Down<br />
| Left<br />
| Right<br />
|}<br />
<br />
This subroutine takes 132 cycles to execute but ignores the Famicom expansion controller.<br />
Many controller reading subroutines use the X or Y register to count 8 times through the loop.<br />
But this one uses a more clever [[wikipedia:Ring counter|ring counter]] technique: $01 is loaded into the result first, and once eight bits are shifted in, the 1 bit will be shifted out, terminating the loop.<br />
<pre><br />
; At the same time that we strobe bit 0, we initialize the ring counter<br />
; so we're hitting two birds with one stone here<br />
readjoy:<br />
lda #$01<br />
; While the strobe bit is set, buttons will be continuously reloaded.<br />
; This means that reading from JOYPAD1 will only return the state of the<br />
; first button: button A.<br />
sta JOYPAD1<br />
sta buttons<br />
lsr a ; now A is 0<br />
; By storing 0 into JOYPAD1, the strobe bit is cleared and the reloading stops.<br />
; This allows all 8 buttons (newly reloaded) to be read from JOYPAD1.<br />
sta JOYPAD1<br />
loop:<br />
lda JOYPAD1<br />
lsr a ; bit 0 -> Carry<br />
rol buttons ; Carry -> bit 0; bit 7 -> Carry<br />
bcc loop<br />
rts<br />
</pre><br />
<br />
Continue to the next example for a more complete read routine that handles both controllers and the standard Famicom expansion controllers.<br />
<br />
=== Standard Read for 2 Controllers and Famicom ===<br />
<br />
Adding support for controllers on the Famicom's DA15 expansion port and for player 2's controller is straightforward. Something similar to the following routine is used in most Famicom games.<br />
Even though the expansion port is unused on the NES, the unconnected bit will read as 0, so this solution works safely with both Famicom and NES hardware.<br />
<pre><br />
.zeropage<br />
buttons: .res 2 ; space for 2 reads<br />
<br />
.code<br />
readjoyx2:<br />
ldx #$00<br />
jsr readjoyx ; X=0: read controller 1<br />
inx<br />
; fall through to readjoyx below, X=1: read controller 2<br />
<br />
readjoyx: ; X register = 0 for controller 1, 1 for controller 2<br />
lda #$01<br />
sta JOYPAD1<br />
sta buttons, X<br />
lsr a<br />
sta JOYPAD1<br />
loop:<br />
lda JOYPAD1, X<br />
and #%00000011 ; ignore bits other than controller<br />
cmp #$01 ; Set carry if and only if nonzero<br />
rol buttons, X ; Carry -> bit 0; but 7 -> Carry<br />
bcc loop<br />
rts<br />
</pre><br />
<br />
If playing DPCM samples, there is an additional reread step to prevent errors ([[#DPCM Safety using Repeated Reads|see below]]).<br />
<br />
=== Alternative 2 Controllers Read ===<br />
<br />
Alternatively, we could combine both controller reads into 1 loop with a single strobe, though this routine is not safe to use with DPCM samples playing ([[#DPCM Safety using Repeated Reads|see below]]).<br />
<pre><br />
.zeropage<br />
buttons: .res 2<br />
<br />
.code<br />
readjoy2:<br />
lda #$01<br />
sta JOYPAD1<br />
sta buttons+1 ; player 2's buttons double as a ring counter<br />
lsr a<br />
sta JOYPAD1<br />
loop:<br />
lda JOYPAD1<br />
and #%00000011<br />
cmp #$01<br />
rol buttons+0<br />
lda JOYPAD2<br />
and #%00000011<br />
cmp #$01<br />
rol buttons+1<br />
bcc loop<br />
rts<br />
</pre><br />
<br />
=== DPCM Safety using Repeated Reads ===<br />
<br />
If your code is intended to be used with [[APU DMC]] playback, this code will need to be altered. The NES occasionally glitches the controller port twice in a row if sample playback is enabled, and games using samples need to work around this. The most common technique, as seen in ''Super Mario Bros. 3''<ref>[//forums.nesdev.org/viewtopic.php?p=151720#p151720 Super Mario Bros. 3 controller reread method]</ref> and other games, will read each controller twice, but in the event of a mismatch it will keep re-reading the controller until two results in a row are the same.<br />
<pre><br />
readjoy2_safe:<br />
ldx #$00<br />
jsr readjoyx_safe ; X=0: safe read controller 1<br />
inx<br />
; fall through to readjoyx_safe, X=1: safe read controller 2<br />
<br />
readjoyx_safe:<br />
jsr readjoyx<br />
reread:<br />
lda buttons, X<br />
pha<br />
jsr readjoyx<br />
pla<br />
cmp buttons, X<br />
bne reread<br />
rts<br />
</pre><br />
<br />
Note that the time between the start of one read and the end of the next read must be less than the length of the fastest DMC fetch period (432 cycles). For this reason, it is normal to read controllers one at a time with this method, rather than attempting both at once. (Note: <code>readjoy2</code> above takes too long to be suitable.) [[Game bugs|''Gimmick!'' has such a bug]] resulting from trying to read both at once.<br />
<br />
Most often a controller will be read 2 times, and 3 or 4 in the case of a DPCM corruption, or the player pressing a button during the read. With the assistance of tools, a malicious controller input could change the buttons on every read, holding it in this reread loop indefinitely<ref>[https://arstechnica.com/gaming/2016/07/how-to-beat-super-mario-bros-3-in-less-than-a-second/ Ars Technica: How to beat Super Mario Bros. 3 in less than a second</ref>, but this is generally not an important edge case to account for.<br />
<br />
=== DPCM Safety using OAM DMA ===<br />
<br />
Because halts for DPCM fetches normally only occur on an put cycles, it is possible to get glitch-free controller reads by timing all '''$4016''' and '''$4017''' reads to fall on get cycles. This is made possible by the behavior of OAM DMA: the first cycle after an OAM DMA is normally guaranteed to be a get cycle.<ref>[http://forums.nesdev.org/viewtopic.php?p=171971 Forum post:] Rahsennor's OAM-synchronized controller read</ref> This is a relatively new technique and is not supported by some emulators.<ref>[http://forums.nesdev.org/viewtopic.php?f=2&t=14319&start=15#p172099 Forum post:] as of May 2016, Nintendulator and Nestopia do not accurately emulate OAM-synchronized controller reading.</ref> In the following example code, the controller1 and controller2 labels must be in zeropage for the timing to work.<br />
<br />
<pre><br />
lda #OAM<br />
sta $4014 ; ------ OAM DMA ------<br />
ldx #1 ; get put <- strobe code must take an odd number of cycles total<br />
stx controller1 ; get put get <- controller1 and controller2 must be in the zeropage<br />
stx $4016 ; put get put get<br />
dex ; put get<br />
stx $4016 ; put get put get<br />
read_loop:<br />
lda $4017 ; put get put GET <- loop code must take an even number of cycles total<br />
and #3 ; put get<br />
cmp #1 ; put get<br />
rol controller2, x ; put get put get put get (X = 0; waste 1 cycle and 0 bytes for alignment)<br />
lda $4016 ; put get put GET<br />
and #3 ; put get<br />
cmp #1 ; put get<br />
rol controller1 ; put get put get put<br />
bcc read_loop ; get put [get] <- this branch must not be allowed to cross a page<br />
</pre><br />
<br />
Note that this example routine only reads two 8-bit controllers and does not take enough time to span more than one DPCM fetch. Routines longer than this must contend with two additional constraints:<br />
* When DMC DMA is delayed by an odd number of cycles, it takes 3 cycles instead of 4, changing the cycle parity. If extending this function to read more bits, care must be taken so that ''all'' CPU write cycles are aligned. Instructions with a single write cycle must align the write to avoid conflict with the DPCM fetch, and double-write instructions like ROL need to align both writes so that the DPCM fetch falls on the first write.<ref>[//forums.nesdev.org/viewtopic.php?p=231604#p231604 Forum post:] demonstration of how ROL instruction affects alignment for OAM DMA synchronized controller reading.</ref> If an interrupt can occur during the routine, it must be aligned so the fetch can only fall on the second of the three automatic stack writes.<br />
* When DMC DMA occurs near the end of OAM DMA, it only steals 1 or 3 cycles, inverting the cycle parity. Every DMC period after that, a misaligned DPCM fetch will occur. Care must be taken to ensure this does not land on a joypad read.<br />
<br />
See [[DMA]] for detailed information on DMA timing.<br />
<br />
=== Directional Safety ===<br />
<br />
To reject opposing presses (Up+Down and Left+Right), which are possible on a worn Control Pad:<br />
<pre><br />
lda buttons1,x<br />
and #%00001010 ; Compare Up and Left...<br />
lsr a<br />
and buttons1,x ; to Down and Right<br />
beq not_updown<br />
; Use previous frame's directions<br />
lda buttons1,x<br />
eor last_frame_buttons1,x<br />
and #%11110000<br />
eor last_frame_buttons1,x<br />
sta buttons1,x<br />
not_updown:<br />
</pre><br />
<br />
To instead reject all diagonal presses, simulating a 4-way joystick:<br />
<pre><br />
lda buttons1,x<br />
and #%00001111 ; If A & (A - 1) is nonzero, A has more than one bit set<br />
beq not_diagonal<br />
sec<br />
sbc #1<br />
and buttons1,x<br />
beq not_diagonal<br />
; Use previous frame's directions<br />
lda buttons1,x<br />
eor last_frame_buttons1,x<br />
and #%11110000<br />
eor last_frame_buttons1,x<br />
sta buttons1,x<br />
not_diagonal:<br />
</pre><br />
<br />
=== Calculating Presses and Releases ===<br />
<br />
To calculate newly pressed and newly released buttons:<br />
<pre><br />
lda buttons1,x<br />
eor #%11111111<br />
and last_frame_buttons1,x<br />
sta released_buttons1,x<br />
lda last_frame_buttons1,x<br />
eor #%11111111<br />
and buttons1,x<br />
sta pressed_buttons1,x<br />
</pre><br />
<br />
=== Button Flags ===<br />
<br />
It is helpful to define the buttons as a series of bit flags:<br />
<pre><br />
BUTTON_A = 1 << 7<br />
BUTTON_B = 1 << 6<br />
BUTTON_SELECT = 1 << 5<br />
BUTTON_START = 1 << 4<br />
BUTTON_UP = 1 << 3<br />
BUTTON_DOWN = 1 << 2<br />
BUTTON_LEFT = 1 << 1<br />
BUTTON_RIGHT = 1 << 0<br />
</pre><br />
<br />
And then buttons can be checked as follows:<br />
<pre><br />
lda buttons<br />
and #BUTTON_A | BUTTON_B<br />
beq notPressingAorB<br />
; Handle presses.<br />
notPressingAorB:<br />
</pre><br />
<br />
== External Examples ==<br />
<br />
* [http://forums.nesdev.org/viewtopic.php?t=4124 Forum post:] Blargg's DMC-fortified controller read routine<br />
* [http://forums.nesdev.org/viewtopic.php?p=171971 Forum post:] Rahsennor's OAM-synchronized controller read<br />
* [http://forums.nesdev.org/viewtopic.php?f=2&t=14197 Forum post:] Drag's bitwise DMC-safe controller reading<br />
<br />
== References ==<br />
<references/></div>Rainwarriorhttps://www.nesdev.org/w/index.php?title=Controller_reading_code&diff=21491Controller reading code2024-01-11T01:21:44Z<p>Rainwarrior: /* DPCM Safety using Repeated Reads */ use fall through</p>
<hr />
<div>This page contains example code for reading the [[NES controller]].<br />
<br />
See also: [[Controller reading]]<br />
<br />
=== Basic Example ===<br />
<br />
This is a tutorial example of the bare minimum needed to read the controller.<br />
It will explain the basic principles in detail, but once understood, you may wish to continue to the [[#Standard Read for 2 Controllers and Famicom|Standard Read]] example that follows,<br />
as a more complete and ready-to-use code example.<br />
<br />
This code describes an efficient method of reading the [[standard controller]] using [http://cc65.github.io/cc65/ ca65] syntax.<br />
<br />
The result byte ''buttons'' should be placed in zero page to save a cycle each time through the loop.<br />
<pre><br />
; we reserve one byte for storing the data that is read from controller<br />
.zeropage<br />
buttons .res 1<br />
</pre><br />
<br />
When reading from ''JOYPAD*'' what is read might be different from $01/$00 for various reasons. (See [[Controller reading]].) In this code the only concern is bit 0 read from ''JOYPAD*.''.<br />
<pre><br />
JOYPAD1 = $4016<br />
JOYPAD2 = $4017<br />
</pre><br />
<br />
This is the end result that will be stored in ''buttons''. '''1''' if the button was pressed, '''0''' otherwise.<br />
<br />
{| class="wikitable" style="text-align:center;"<br />
|-<br />
! bit<br />
| &nbsp;&nbsp;&nbsp;&nbsp;7&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;6&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;5&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;4&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;3&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;2&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;1&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;&nbsp;<br />
|-<br />
! button<br />
| A<br />
| B<br />
| Select<br />
| Start<br />
| Up<br />
| Down<br />
| Left<br />
| Right<br />
|}<br />
<br />
This subroutine takes 132 cycles to execute but ignores the Famicom expansion controller.<br />
Many controller reading subroutines use the X or Y register to count 8 times through the loop.<br />
But this one uses a more clever [[wikipedia:Ring counter|ring counter]] technique: $01 is loaded into the result first, and once eight bits are shifted in, the 1 bit will be shifted out, terminating the loop.<br />
<pre><br />
; At the same time that we strobe bit 0, we initialize the ring counter<br />
; so we're hitting two birds with one stone here<br />
readjoy:<br />
lda #$01<br />
; While the strobe bit is set, buttons will be continuously reloaded.<br />
; This means that reading from JOYPAD1 will only return the state of the<br />
; first button: button A.<br />
sta JOYPAD1<br />
sta buttons<br />
lsr a ; now A is 0<br />
; By storing 0 into JOYPAD1, the strobe bit is cleared and the reloading stops.<br />
; This allows all 8 buttons (newly reloaded) to be read from JOYPAD1.<br />
sta JOYPAD1<br />
loop:<br />
lda JOYPAD1<br />
lsr a ; bit 0 -> Carry<br />
rol buttons ; Carry -> bit 0; bit 7 -> Carry<br />
bcc loop<br />
rts<br />
</pre><br />
<br />
Continue to the next example for a more complete read routine that handles both controllers and the standard Famicom expansion controllers.<br />
<br />
=== Standard Read for 2 Controllers and Famicom ===<br />
<br />
Adding support for controllers on the Famicom's DA15 expansion port and for player 2's controller is straightforward. Something similar to the following routine is used in most Famicom games.<br />
Even though the expansion port is unused on the NES, the unconnected bit will read as 0, so this solution works safely with both Famicom and NES hardware.<br />
<pre><br />
.zeropage<br />
buttons: .res 2 ; space for 2 reads<br />
<br />
.code<br />
readjoyx2:<br />
ldx #$00<br />
jsr readjoyx ; X=0: read controller 1<br />
inx<br />
; fall through to readjoyx below, X=1: read controller 2<br />
<br />
readjoyx: ; X register = 0 for controller 1, 1 for controller 2<br />
lda #$01<br />
sta JOYPAD1<br />
sta buttons, X<br />
lsr a<br />
sta JOYPAD1<br />
loop:<br />
lda JOYPAD1, X<br />
and #%00000011 ; ignore bits other than controller<br />
cmp #$01 ; Set carry if and only if nonzero<br />
rol buttons, X ; Carry -> bit 0; but 7 -> Carry<br />
bcc loop<br />
rts<br />
</pre><br />
<br />
If playing DPCM samples, there is an additional reread step to prevent errors (([[#DPCM Safety using Repeated Reads|see below]]).<br />
<br />
=== Alternative 2 Controllers Read ===<br />
<br />
Alternatively, we could combine both controller reads into 1 loop with a single strobe, though this routine is not safe to use with DPCM samples playing ([[#DPCM Safety using Repeated Reads|see below]]).<br />
<pre><br />
.zeropage<br />
buttons: .res 2<br />
<br />
.code<br />
readjoy2:<br />
lda #$01<br />
sta JOYPAD1<br />
sta buttons+1 ; player 2's buttons double as a ring counter<br />
lsr a<br />
sta JOYPAD1<br />
loop:<br />
lda JOYPAD1<br />
and #%00000011<br />
cmp #$01<br />
rol buttons+0<br />
lda JOYPAD2<br />
and #%00000011<br />
cmp #$01<br />
rol buttons+1<br />
bcc loop<br />
rts<br />
</pre><br />
<br />
=== DPCM Safety using Repeated Reads ===<br />
<br />
If your code is intended to be used with [[APU DMC]] playback, this code will need to be altered. The NES occasionally glitches the controller port twice in a row if sample playback is enabled, and games using samples need to work around this. The most common technique, as seen in ''Super Mario Bros. 3''<ref>[//forums.nesdev.org/viewtopic.php?p=151720#p151720 Super Mario Bros. 3 controller reread method]</ref> and other games, will read each controller twice, but in the event of a mismatch it will keep re-reading the controller until two results in a row are the same.<br />
<pre><br />
readjoy2_safe:<br />
ldx #$00<br />
jsr readjoyx_safe ; X=0: safe read controller 1<br />
inx<br />
; fall through to readjoyx_safe, X=1: safe read controller 2<br />
<br />
readjoyx_safe:<br />
jsr readjoyx<br />
reread:<br />
lda buttons, X<br />
pha<br />
jsr readjoyx<br />
pla<br />
cmp buttons, X<br />
bne reread<br />
rts<br />
</pre><br />
<br />
Note that the time between the start of one read and the end of the next read must be less than the length of the fastest DMC fetch period (432 cycles). For this reason, it is normal to read controllers one at a time with this method, rather than attempting both at once. (Note: <code>readjoy2</code> above takes too long to be suitable.) [[Game bugs|''Gimmick!'' has such a bug]] resulting from trying to read both at once.<br />
<br />
Most often a controller will be read 2 times, and 3 or 4 in the case of a DPCM corruption, or the player pressing a button during the read. With the assistance of tools, a malicious controller input could change the buttons on every read, holding it in this reread loop indefinitely<ref>[https://arstechnica.com/gaming/2016/07/how-to-beat-super-mario-bros-3-in-less-than-a-second/ Ars Technica: How to beat Super Mario Bros. 3 in less than a second</ref>, but this is generally not an important edge case to account for.<br />
<br />
=== DPCM Safety using OAM DMA ===<br />
<br />
Because halts for DPCM fetches normally only occur on an put cycles, it is possible to get glitch-free controller reads by timing all '''$4016''' and '''$4017''' reads to fall on get cycles. This is made possible by the behavior of OAM DMA: the first cycle after an OAM DMA is normally guaranteed to be a get cycle.<ref>[http://forums.nesdev.org/viewtopic.php?p=171971 Forum post:] Rahsennor's OAM-synchronized controller read</ref> This is a relatively new technique and is not supported by some emulators.<ref>[http://forums.nesdev.org/viewtopic.php?f=2&t=14319&start=15#p172099 Forum post:] as of May 2016, Nintendulator and Nestopia do not accurately emulate OAM-synchronized controller reading.</ref> In the following example code, the controller1 and controller2 labels must be in zeropage for the timing to work.<br />
<br />
<pre><br />
lda #OAM<br />
sta $4014 ; ------ OAM DMA ------<br />
ldx #1 ; get put <- strobe code must take an odd number of cycles total<br />
stx controller1 ; get put get <- controller1 and controller2 must be in the zeropage<br />
stx $4016 ; put get put get<br />
dex ; put get<br />
stx $4016 ; put get put get<br />
read_loop:<br />
lda $4017 ; put get put GET <- loop code must take an even number of cycles total<br />
and #3 ; put get<br />
cmp #1 ; put get<br />
rol controller2, x ; put get put get put get (X = 0; waste 1 cycle and 0 bytes for alignment)<br />
lda $4016 ; put get put GET<br />
and #3 ; put get<br />
cmp #1 ; put get<br />
rol controller1 ; put get put get put<br />
bcc read_loop ; get put [get] <- this branch must not be allowed to cross a page<br />
</pre><br />
<br />
Note that this example routine only reads two 8-bit controllers and does not take enough time to span more than one DPCM fetch. Routines longer than this must contend with two additional constraints:<br />
* When DMC DMA is delayed by an odd number of cycles, it takes 3 cycles instead of 4, changing the cycle parity. If extending this function to read more bits, care must be taken so that ''all'' CPU write cycles are aligned. Instructions with a single write cycle must align the write to avoid conflict with the DPCM fetch, and double-write instructions like ROL need to align both writes so that the DPCM fetch falls on the first write.<ref>[//forums.nesdev.org/viewtopic.php?p=231604#p231604 Forum post:] demonstration of how ROL instruction affects alignment for OAM DMA synchronized controller reading.</ref> If an interrupt can occur during the routine, it must be aligned so the fetch can only fall on the second of the three automatic stack writes.<br />
* When DMC DMA occurs near the end of OAM DMA, it only steals 1 or 3 cycles, inverting the cycle parity. Every DMC period after that, a misaligned DPCM fetch will occur. Care must be taken to ensure this does not land on a joypad read.<br />
<br />
See [[DMA]] for detailed information on DMA timing.<br />
<br />
=== Directional Safety ===<br />
<br />
To reject opposing presses (Up+Down and Left+Right), which are possible on a worn Control Pad:<br />
<pre><br />
lda buttons1,x<br />
and #%00001010 ; Compare Up and Left...<br />
lsr a<br />
and buttons1,x ; to Down and Right<br />
beq not_updown<br />
; Use previous frame's directions<br />
lda buttons1,x<br />
eor last_frame_buttons1,x<br />
and #%11110000<br />
eor last_frame_buttons1,x<br />
sta buttons1,x<br />
not_updown:<br />
</pre><br />
<br />
To instead reject all diagonal presses, simulating a 4-way joystick:<br />
<pre><br />
lda buttons1,x<br />
and #%00001111 ; If A & (A - 1) is nonzero, A has more than one bit set<br />
beq not_diagonal<br />
sec<br />
sbc #1<br />
and buttons1,x<br />
beq not_diagonal<br />
; Use previous frame's directions<br />
lda buttons1,x<br />
eor last_frame_buttons1,x<br />
and #%11110000<br />
eor last_frame_buttons1,x<br />
sta buttons1,x<br />
not_diagonal:<br />
</pre><br />
<br />
=== Calculating Presses and Releases ===<br />
<br />
To calculate newly pressed and newly released buttons:<br />
<pre><br />
lda buttons1,x<br />
eor #%11111111<br />
and last_frame_buttons1,x<br />
sta released_buttons1,x<br />
lda last_frame_buttons1,x<br />
eor #%11111111<br />
and buttons1,x<br />
sta pressed_buttons1,x<br />
</pre><br />
<br />
=== Button Flags ===<br />
<br />
It is helpful to define the buttons as a series of bit flags:<br />
<pre><br />
BUTTON_A = 1 << 7<br />
BUTTON_B = 1 << 6<br />
BUTTON_SELECT = 1 << 5<br />
BUTTON_START = 1 << 4<br />
BUTTON_UP = 1 << 3<br />
BUTTON_DOWN = 1 << 2<br />
BUTTON_LEFT = 1 << 1<br />
BUTTON_RIGHT = 1 << 0<br />
</pre><br />
<br />
And then buttons can be checked as follows:<br />
<pre><br />
lda buttons<br />
and #BUTTON_A | BUTTON_B<br />
beq notPressingAorB<br />
; Handle presses.<br />
notPressingAorB:<br />
</pre><br />
<br />
== External Examples ==<br />
<br />
* [http://forums.nesdev.org/viewtopic.php?t=4124 Forum post:] Blargg's DMC-fortified controller read routine<br />
* [http://forums.nesdev.org/viewtopic.php?p=171971 Forum post:] Rahsennor's OAM-synchronized controller read<br />
* [http://forums.nesdev.org/viewtopic.php?f=2&t=14197 Forum post:] Drag's bitwise DMC-safe controller reading<br />
<br />
== References ==<br />
<references/></div>Rainwarriorhttps://www.nesdev.org/w/index.php?title=Controller_reading_code&diff=21490Controller reading code2024-01-11T01:19:52Z<p>Rainwarrior: /* Alternative 2 Controllers Read */ fix +9=+0 typo</p>
<hr />
<div>This page contains example code for reading the [[NES controller]].<br />
<br />
See also: [[Controller reading]]<br />
<br />
=== Basic Example ===<br />
<br />
This is a tutorial example of the bare minimum needed to read the controller.<br />
It will explain the basic principles in detail, but once understood, you may wish to continue to the [[#Standard Read for 2 Controllers and Famicom|Standard Read]] example that follows,<br />
as a more complete and ready-to-use code example.<br />
<br />
This code describes an efficient method of reading the [[standard controller]] using [http://cc65.github.io/cc65/ ca65] syntax.<br />
<br />
The result byte ''buttons'' should be placed in zero page to save a cycle each time through the loop.<br />
<pre><br />
; we reserve one byte for storing the data that is read from controller<br />
.zeropage<br />
buttons .res 1<br />
</pre><br />
<br />
When reading from ''JOYPAD*'' what is read might be different from $01/$00 for various reasons. (See [[Controller reading]].) In this code the only concern is bit 0 read from ''JOYPAD*.''.<br />
<pre><br />
JOYPAD1 = $4016<br />
JOYPAD2 = $4017<br />
</pre><br />
<br />
This is the end result that will be stored in ''buttons''. '''1''' if the button was pressed, '''0''' otherwise.<br />
<br />
{| class="wikitable" style="text-align:center;"<br />
|-<br />
! bit<br />
| &nbsp;&nbsp;&nbsp;&nbsp;7&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;6&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;5&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;4&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;3&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;2&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;1&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;&nbsp;<br />
|-<br />
! button<br />
| A<br />
| B<br />
| Select<br />
| Start<br />
| Up<br />
| Down<br />
| Left<br />
| Right<br />
|}<br />
<br />
This subroutine takes 132 cycles to execute but ignores the Famicom expansion controller.<br />
Many controller reading subroutines use the X or Y register to count 8 times through the loop.<br />
But this one uses a more clever [[wikipedia:Ring counter|ring counter]] technique: $01 is loaded into the result first, and once eight bits are shifted in, the 1 bit will be shifted out, terminating the loop.<br />
<pre><br />
; At the same time that we strobe bit 0, we initialize the ring counter<br />
; so we're hitting two birds with one stone here<br />
readjoy:<br />
lda #$01<br />
; While the strobe bit is set, buttons will be continuously reloaded.<br />
; This means that reading from JOYPAD1 will only return the state of the<br />
; first button: button A.<br />
sta JOYPAD1<br />
sta buttons<br />
lsr a ; now A is 0<br />
; By storing 0 into JOYPAD1, the strobe bit is cleared and the reloading stops.<br />
; This allows all 8 buttons (newly reloaded) to be read from JOYPAD1.<br />
sta JOYPAD1<br />
loop:<br />
lda JOYPAD1<br />
lsr a ; bit 0 -> Carry<br />
rol buttons ; Carry -> bit 0; bit 7 -> Carry<br />
bcc loop<br />
rts<br />
</pre><br />
<br />
Continue to the next example for a more complete read routine that handles both controllers and the standard Famicom expansion controllers.<br />
<br />
=== Standard Read for 2 Controllers and Famicom ===<br />
<br />
Adding support for controllers on the Famicom's DA15 expansion port and for player 2's controller is straightforward. Something similar to the following routine is used in most Famicom games.<br />
Even though the expansion port is unused on the NES, the unconnected bit will read as 0, so this solution works safely with both Famicom and NES hardware.<br />
<pre><br />
.zeropage<br />
buttons: .res 2 ; space for 2 reads<br />
<br />
.code<br />
readjoyx2:<br />
ldx #$00<br />
jsr readjoyx ; X=0: read controller 1<br />
inx<br />
; fall through to readjoyx below, X=1: read controller 2<br />
<br />
readjoyx: ; X register = 0 for controller 1, 1 for controller 2<br />
lda #$01<br />
sta JOYPAD1<br />
sta buttons, X<br />
lsr a<br />
sta JOYPAD1<br />
loop:<br />
lda JOYPAD1, X<br />
and #%00000011 ; ignore bits other than controller<br />
cmp #$01 ; Set carry if and only if nonzero<br />
rol buttons, X ; Carry -> bit 0; but 7 -> Carry<br />
bcc loop<br />
rts<br />
</pre><br />
<br />
If playing DPCM samples, there is an additional reread step to prevent errors (([[#DPCM Safety using Repeated Reads|see below]]).<br />
<br />
=== Alternative 2 Controllers Read ===<br />
<br />
Alternatively, we could combine both controller reads into 1 loop with a single strobe, though this routine is not safe to use with DPCM samples playing ([[#DPCM Safety using Repeated Reads|see below]]).<br />
<pre><br />
.zeropage<br />
buttons: .res 2<br />
<br />
.code<br />
readjoy2:<br />
lda #$01<br />
sta JOYPAD1<br />
sta buttons+1 ; player 2's buttons double as a ring counter<br />
lsr a<br />
sta JOYPAD1<br />
loop:<br />
lda JOYPAD1<br />
and #%00000011<br />
cmp #$01<br />
rol buttons+0<br />
lda JOYPAD2<br />
and #%00000011<br />
cmp #$01<br />
rol buttons+1<br />
bcc loop<br />
rts<br />
</pre><br />
<br />
=== DPCM Safety using Repeated Reads ===<br />
<br />
If your code is intended to be used with [[APU DMC]] playback, this code will need to be altered. The NES occasionally glitches the controller port twice in a row if sample playback is enabled, and games using samples need to work around this. The most common technique, as seen in ''Super Mario Bros. 3''<ref>[//forums.nesdev.org/viewtopic.php?p=151720#p151720 Super Mario Bros. 3 controller reread method]</ref> and other games, will read each controller twice, but in the event of a mismatch it will keep re-reading the controller until two results in a row are the same.<br />
<pre><br />
readjoyx_safe:<br />
jsr readjoyx<br />
reread:<br />
lda buttons, X<br />
pha<br />
jsr readjoyx<br />
pla<br />
cmp buttons, X<br />
bne reread<br />
rts<br />
<br />
readjoy2_safe:<br />
ldx #$00<br />
jsr readjoyx_safe ; X=0: safe read controller 1<br />
inx<br />
jmp readjoyx_safe ; X=1: safe read controller 2<br />
</pre><br />
<br />
Note that the time between the start of one read and the end of the next read must be less than the length of the fastest DMC fetch period (432 cycles). For this reason, it is normal to read controllers one at a time with this method, rather than attempting both at once. (Note: <code>readjoy2</code> above takes too long to be suitable.) [[Game bugs|''Gimmick!'' has such a bug]] resulting from trying to read both at once.<br />
<br />
Most often a controller will be read 2 times, and 3 or 4 in the case of a DPCM corruption, or the player pressing a button during the read. With the assistance of tools, a malicious controller input could change the buttons on every read, holding it in this reread loop indefinitely<ref>[https://arstechnica.com/gaming/2016/07/how-to-beat-super-mario-bros-3-in-less-than-a-second/ Ars Technica: How to beat Super Mario Bros. 3 in less than a second</ref>, but this is generally not an important edge case to account for.<br />
<br />
=== DPCM Safety using OAM DMA ===<br />
<br />
Because halts for DPCM fetches normally only occur on an put cycles, it is possible to get glitch-free controller reads by timing all '''$4016''' and '''$4017''' reads to fall on get cycles. This is made possible by the behavior of OAM DMA: the first cycle after an OAM DMA is normally guaranteed to be a get cycle.<ref>[http://forums.nesdev.org/viewtopic.php?p=171971 Forum post:] Rahsennor's OAM-synchronized controller read</ref> This is a relatively new technique and is not supported by some emulators.<ref>[http://forums.nesdev.org/viewtopic.php?f=2&t=14319&start=15#p172099 Forum post:] as of May 2016, Nintendulator and Nestopia do not accurately emulate OAM-synchronized controller reading.</ref> In the following example code, the controller1 and controller2 labels must be in zeropage for the timing to work.<br />
<br />
<pre><br />
lda #OAM<br />
sta $4014 ; ------ OAM DMA ------<br />
ldx #1 ; get put <- strobe code must take an odd number of cycles total<br />
stx controller1 ; get put get <- controller1 and controller2 must be in the zeropage<br />
stx $4016 ; put get put get<br />
dex ; put get<br />
stx $4016 ; put get put get<br />
read_loop:<br />
lda $4017 ; put get put GET <- loop code must take an even number of cycles total<br />
and #3 ; put get<br />
cmp #1 ; put get<br />
rol controller2, x ; put get put get put get (X = 0; waste 1 cycle and 0 bytes for alignment)<br />
lda $4016 ; put get put GET<br />
and #3 ; put get<br />
cmp #1 ; put get<br />
rol controller1 ; put get put get put<br />
bcc read_loop ; get put [get] <- this branch must not be allowed to cross a page<br />
</pre><br />
<br />
Note that this example routine only reads two 8-bit controllers and does not take enough time to span more than one DPCM fetch. Routines longer than this must contend with two additional constraints:<br />
* When DMC DMA is delayed by an odd number of cycles, it takes 3 cycles instead of 4, changing the cycle parity. If extending this function to read more bits, care must be taken so that ''all'' CPU write cycles are aligned. Instructions with a single write cycle must align the write to avoid conflict with the DPCM fetch, and double-write instructions like ROL need to align both writes so that the DPCM fetch falls on the first write.<ref>[//forums.nesdev.org/viewtopic.php?p=231604#p231604 Forum post:] demonstration of how ROL instruction affects alignment for OAM DMA synchronized controller reading.</ref> If an interrupt can occur during the routine, it must be aligned so the fetch can only fall on the second of the three automatic stack writes.<br />
* When DMC DMA occurs near the end of OAM DMA, it only steals 1 or 3 cycles, inverting the cycle parity. Every DMC period after that, a misaligned DPCM fetch will occur. Care must be taken to ensure this does not land on a joypad read.<br />
<br />
See [[DMA]] for detailed information on DMA timing.<br />
<br />
=== Directional Safety ===<br />
<br />
To reject opposing presses (Up+Down and Left+Right), which are possible on a worn Control Pad:<br />
<pre><br />
lda buttons1,x<br />
and #%00001010 ; Compare Up and Left...<br />
lsr a<br />
and buttons1,x ; to Down and Right<br />
beq not_updown<br />
; Use previous frame's directions<br />
lda buttons1,x<br />
eor last_frame_buttons1,x<br />
and #%11110000<br />
eor last_frame_buttons1,x<br />
sta buttons1,x<br />
not_updown:<br />
</pre><br />
<br />
To instead reject all diagonal presses, simulating a 4-way joystick:<br />
<pre><br />
lda buttons1,x<br />
and #%00001111 ; If A & (A - 1) is nonzero, A has more than one bit set<br />
beq not_diagonal<br />
sec<br />
sbc #1<br />
and buttons1,x<br />
beq not_diagonal<br />
; Use previous frame's directions<br />
lda buttons1,x<br />
eor last_frame_buttons1,x<br />
and #%11110000<br />
eor last_frame_buttons1,x<br />
sta buttons1,x<br />
not_diagonal:<br />
</pre><br />
<br />
=== Calculating Presses and Releases ===<br />
<br />
To calculate newly pressed and newly released buttons:<br />
<pre><br />
lda buttons1,x<br />
eor #%11111111<br />
and last_frame_buttons1,x<br />
sta released_buttons1,x<br />
lda last_frame_buttons1,x<br />
eor #%11111111<br />
and buttons1,x<br />
sta pressed_buttons1,x<br />
</pre><br />
<br />
=== Button Flags ===<br />
<br />
It is helpful to define the buttons as a series of bit flags:<br />
<pre><br />
BUTTON_A = 1 << 7<br />
BUTTON_B = 1 << 6<br />
BUTTON_SELECT = 1 << 5<br />
BUTTON_START = 1 << 4<br />
BUTTON_UP = 1 << 3<br />
BUTTON_DOWN = 1 << 2<br />
BUTTON_LEFT = 1 << 1<br />
BUTTON_RIGHT = 1 << 0<br />
</pre><br />
<br />
And then buttons can be checked as follows:<br />
<pre><br />
lda buttons<br />
and #BUTTON_A | BUTTON_B<br />
beq notPressingAorB<br />
; Handle presses.<br />
notPressingAorB:<br />
</pre><br />
<br />
== External Examples ==<br />
<br />
* [http://forums.nesdev.org/viewtopic.php?t=4124 Forum post:] Blargg's DMC-fortified controller read routine<br />
* [http://forums.nesdev.org/viewtopic.php?p=171971 Forum post:] Rahsennor's OAM-synchronized controller read<br />
* [http://forums.nesdev.org/viewtopic.php?f=2&t=14197 Forum post:] Drag's bitwise DMC-safe controller reading<br />
<br />
== References ==<br />
<references/></div>Rainwarriorhttps://www.nesdev.org/w/index.php?title=Controller_reading_code&diff=21489Controller reading code2024-01-11T01:19:02Z<p>Rainwarrior: /* DPCM Safety using Repeated Reads */ finishing note about SMB3, will resolve edit conflict in the next edit</p>
<hr />
<div>This page contains example code for reading the [[NES controller]].<br />
<br />
See also: [[Controller reading]]<br />
<br />
=== Basic Example ===<br />
<br />
This is a tutorial example of the bare minimum needed to read the controller.<br />
It will explain the basic principles in detail, but once understood, you may wish to continue to the [[#Standard Read for 2 Controllers and Famicom|Standard Read]] example that follows,<br />
as a more complete and ready-to-use code example.<br />
<br />
This code describes an efficient method of reading the [[standard controller]] using [http://cc65.github.io/cc65/ ca65] syntax.<br />
<br />
The result byte ''buttons'' should be placed in zero page to save a cycle each time through the loop.<br />
<pre><br />
; we reserve one byte for storing the data that is read from controller<br />
.zeropage<br />
buttons .res 1<br />
</pre><br />
<br />
When reading from ''JOYPAD*'' what is read might be different from $01/$00 for various reasons. (See [[Controller reading]].) In this code the only concern is bit 0 read from ''JOYPAD*.''.<br />
<pre><br />
JOYPAD1 = $4016<br />
JOYPAD2 = $4017<br />
</pre><br />
<br />
This is the end result that will be stored in ''buttons''. '''1''' if the button was pressed, '''0''' otherwise.<br />
<br />
{| class="wikitable" style="text-align:center;"<br />
|-<br />
! bit<br />
| &nbsp;&nbsp;&nbsp;&nbsp;7&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;6&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;5&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;4&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;3&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;2&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;1&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;&nbsp;<br />
|-<br />
! button<br />
| A<br />
| B<br />
| Select<br />
| Start<br />
| Up<br />
| Down<br />
| Left<br />
| Right<br />
|}<br />
<br />
This subroutine takes 132 cycles to execute but ignores the Famicom expansion controller.<br />
Many controller reading subroutines use the X or Y register to count 8 times through the loop.<br />
But this one uses a more clever [[wikipedia:Ring counter|ring counter]] technique: $01 is loaded into the result first, and once eight bits are shifted in, the 1 bit will be shifted out, terminating the loop.<br />
<pre><br />
; At the same time that we strobe bit 0, we initialize the ring counter<br />
; so we're hitting two birds with one stone here<br />
readjoy:<br />
lda #$01<br />
; While the strobe bit is set, buttons will be continuously reloaded.<br />
; This means that reading from JOYPAD1 will only return the state of the<br />
; first button: button A.<br />
sta JOYPAD1<br />
sta buttons<br />
lsr a ; now A is 0<br />
; By storing 0 into JOYPAD1, the strobe bit is cleared and the reloading stops.<br />
; This allows all 8 buttons (newly reloaded) to be read from JOYPAD1.<br />
sta JOYPAD1<br />
loop:<br />
lda JOYPAD1<br />
lsr a ; bit 0 -> Carry<br />
rol buttons ; Carry -> bit 0; bit 7 -> Carry<br />
bcc loop<br />
rts<br />
</pre><br />
<br />
Continue to the next example for a more complete read routine that handles both controllers and the standard Famicom expansion controllers.<br />
<br />
=== Standard Read for 2 Controllers and Famicom ===<br />
<br />
Adding support for controllers on the Famicom's DA15 expansion port and for player 2's controller is straightforward. Something similar to the following routine is used in most Famicom games.<br />
Even though the expansion port is unused on the NES, the unconnected bit will read as 0, so this solution works safely with both Famicom and NES hardware.<br />
<pre><br />
.zeropage<br />
buttons: .res 2 ; space for 2 reads<br />
<br />
.code<br />
readjoyx2:<br />
ldx #$00<br />
jsr readjoyx ; X=0: read controller 1<br />
inx<br />
; fall through to readjoyx below, X=1: read controller 2<br />
<br />
readjoyx: ; X register = 0 for controller 1, 1 for controller 2<br />
lda #$01<br />
sta JOYPAD1<br />
sta buttons, X<br />
lsr a<br />
sta JOYPAD1<br />
loop:<br />
lda JOYPAD1, X<br />
and #%00000011 ; ignore bits other than controller<br />
cmp #$01 ; Set carry if and only if nonzero<br />
rol buttons, X ; Carry -> bit 0; but 7 -> Carry<br />
bcc loop<br />
rts<br />
</pre><br />
<br />
If playing DPCM samples, there is an additional reread step to prevent errors (([[#DPCM Safety using Repeated Reads|see below]]).<br />
<br />
=== Alternative 2 Controllers Read ===<br />
<br />
Alternatively, we could combine both controller reads into 1 loop with a single strobe, though this routine is not safe to use with DPCM samples playing ([[#DPCM Safety using Repeated Reads|see below]]).<br />
<pre><br />
.zeropage<br />
buttons: .res 2<br />
<br />
.code<br />
readjoy2:<br />
lda #$01<br />
sta JOYPAD1<br />
sta buttons+1 ; player 2's buttons double as a ring counter<br />
lsr a<br />
sta JOYPAD1<br />
loop:<br />
lda JOYPAD1<br />
and #%00000011<br />
cmp #$01<br />
rol buttons+9<br />
lda JOYPAD2<br />
and #%00000011<br />
cmp #$01<br />
rol buttons+1<br />
bcc loop<br />
rts<br />
</pre><br />
<br />
=== DPCM Safety using Repeated Reads ===<br />
<br />
If your code is intended to be used with [[APU DMC]] playback, this code will need to be altered. The NES occasionally glitches the controller port twice in a row if sample playback is enabled, and games using samples need to work around this. The most common technique, as seen in ''Super Mario Bros. 3''<ref>[//forums.nesdev.org/viewtopic.php?p=151720#p151720 Super Mario Bros. 3 controller reread method]</ref> and other games, will read each controller twice, but in the event of a mismatch it will keep re-reading the controller until two results in a row are the same.<br />
<pre><br />
readjoyx_safe:<br />
jsr readjoyx<br />
reread:<br />
lda buttons, X<br />
pha<br />
jsr readjoyx<br />
pla<br />
cmp buttons, X<br />
bne reread<br />
rts<br />
<br />
readjoy2_safe:<br />
ldx #$00<br />
jsr readjoyx_safe ; X=0: safe read controller 1<br />
inx<br />
jmp readjoyx_safe ; X=1: safe read controller 2<br />
</pre><br />
<br />
Note that the time between the start of one read and the end of the next read must be less than the length of the fastest DMC fetch period (432 cycles). For this reason, it is normal to read controllers one at a time with this method, rather than attempting both at once. (Note: <code>readjoy2</code> above takes too long to be suitable.) [[Game bugs|''Gimmick!'' has such a bug]] resulting from trying to read both at once.<br />
<br />
Most often a controller will be read 2 times, and 3 or 4 in the case of a DPCM corruption, or the player pressing a button during the read. With the assistance of tools, a malicious controller input could change the buttons on every read, holding it in this reread loop indefinitely<ref>[https://arstechnica.com/gaming/2016/07/how-to-beat-super-mario-bros-3-in-less-than-a-second/ Ars Technica: How to beat Super Mario Bros. 3 in less than a second</ref>, but this is generally not an important edge case to account for.<br />
<br />
=== DPCM Safety using OAM DMA ===<br />
<br />
Because halts for DPCM fetches normally only occur on an put cycles, it is possible to get glitch-free controller reads by timing all '''$4016''' and '''$4017''' reads to fall on get cycles. This is made possible by the behavior of OAM DMA: the first cycle after an OAM DMA is normally guaranteed to be a get cycle.<ref>[http://forums.nesdev.org/viewtopic.php?p=171971 Forum post:] Rahsennor's OAM-synchronized controller read</ref> This is a relatively new technique and is not supported by some emulators.<ref>[http://forums.nesdev.org/viewtopic.php?f=2&t=14319&start=15#p172099 Forum post:] as of May 2016, Nintendulator and Nestopia do not accurately emulate OAM-synchronized controller reading.</ref> In the following example code, the controller1 and controller2 labels must be in zeropage for the timing to work.<br />
<br />
<pre><br />
lda #OAM<br />
sta $4014 ; ------ OAM DMA ------<br />
ldx #1 ; get put <- strobe code must take an odd number of cycles total<br />
stx controller1 ; get put get <- controller1 and controller2 must be in the zeropage<br />
stx $4016 ; put get put get<br />
dex ; put get<br />
stx $4016 ; put get put get<br />
read_loop:<br />
lda $4017 ; put get put GET <- loop code must take an even number of cycles total<br />
and #3 ; put get<br />
cmp #1 ; put get<br />
rol controller2, x ; put get put get put get (X = 0; waste 1 cycle and 0 bytes for alignment)<br />
lda $4016 ; put get put GET<br />
and #3 ; put get<br />
cmp #1 ; put get<br />
rol controller1 ; put get put get put<br />
bcc read_loop ; get put [get] <- this branch must not be allowed to cross a page<br />
</pre><br />
<br />
Note that this example routine only reads two 8-bit controllers and does not take enough time to span more than one DPCM fetch. Routines longer than this must contend with two additional constraints:<br />
* When DMC DMA is delayed by an odd number of cycles, it takes 3 cycles instead of 4, changing the cycle parity. If extending this function to read more bits, care must be taken so that ''all'' CPU write cycles are aligned. Instructions with a single write cycle must align the write to avoid conflict with the DPCM fetch, and double-write instructions like ROL need to align both writes so that the DPCM fetch falls on the first write.<ref>[//forums.nesdev.org/viewtopic.php?p=231604#p231604 Forum post:] demonstration of how ROL instruction affects alignment for OAM DMA synchronized controller reading.</ref> If an interrupt can occur during the routine, it must be aligned so the fetch can only fall on the second of the three automatic stack writes.<br />
* When DMC DMA occurs near the end of OAM DMA, it only steals 1 or 3 cycles, inverting the cycle parity. Every DMC period after that, a misaligned DPCM fetch will occur. Care must be taken to ensure this does not land on a joypad read.<br />
<br />
See [[DMA]] for detailed information on DMA timing.<br />
<br />
=== Directional Safety ===<br />
<br />
To reject opposing presses (Up+Down and Left+Right), which are possible on a worn Control Pad:<br />
<pre><br />
lda buttons1,x<br />
and #%00001010 ; Compare Up and Left...<br />
lsr a<br />
and buttons1,x ; to Down and Right<br />
beq not_updown<br />
; Use previous frame's directions<br />
lda buttons1,x<br />
eor last_frame_buttons1,x<br />
and #%11110000<br />
eor last_frame_buttons1,x<br />
sta buttons1,x<br />
not_updown:<br />
</pre><br />
<br />
To instead reject all diagonal presses, simulating a 4-way joystick:<br />
<pre><br />
lda buttons1,x<br />
and #%00001111 ; If A & (A - 1) is nonzero, A has more than one bit set<br />
beq not_diagonal<br />
sec<br />
sbc #1<br />
and buttons1,x<br />
beq not_diagonal<br />
; Use previous frame's directions<br />
lda buttons1,x<br />
eor last_frame_buttons1,x<br />
and #%11110000<br />
eor last_frame_buttons1,x<br />
sta buttons1,x<br />
not_diagonal:<br />
</pre><br />
<br />
=== Calculating Presses and Releases ===<br />
<br />
To calculate newly pressed and newly released buttons:<br />
<pre><br />
lda buttons1,x<br />
eor #%11111111<br />
and last_frame_buttons1,x<br />
sta released_buttons1,x<br />
lda last_frame_buttons1,x<br />
eor #%11111111<br />
and buttons1,x<br />
sta pressed_buttons1,x<br />
</pre><br />
<br />
=== Button Flags ===<br />
<br />
It is helpful to define the buttons as a series of bit flags:<br />
<pre><br />
BUTTON_A = 1 << 7<br />
BUTTON_B = 1 << 6<br />
BUTTON_SELECT = 1 << 5<br />
BUTTON_START = 1 << 4<br />
BUTTON_UP = 1 << 3<br />
BUTTON_DOWN = 1 << 2<br />
BUTTON_LEFT = 1 << 1<br />
BUTTON_RIGHT = 1 << 0<br />
</pre><br />
<br />
And then buttons can be checked as follows:<br />
<pre><br />
lda buttons<br />
and #BUTTON_A | BUTTON_B<br />
beq notPressingAorB<br />
; Handle presses.<br />
notPressingAorB:<br />
</pre><br />
<br />
== External Examples ==<br />
<br />
* [http://forums.nesdev.org/viewtopic.php?t=4124 Forum post:] Blargg's DMC-fortified controller read routine<br />
* [http://forums.nesdev.org/viewtopic.php?p=171971 Forum post:] Rahsennor's OAM-synchronized controller read<br />
* [http://forums.nesdev.org/viewtopic.php?f=2&t=14197 Forum post:] Drag's bitwise DMC-safe controller reading<br />
<br />
== References ==<br />
<references/></div>Rainwarriorhttps://www.nesdev.org/w/index.php?title=Controller_reading_code&diff=21486Controller reading code2024-01-11T01:01:24Z<p>Rainwarrior: /* DPCM Safety using Repeated Reads */ this is now a 2 controller example</p>
<hr />
<div>This page contains example code for reading the [[NES controller]].<br />
<br />
See also: [[Controller reading]]<br />
<br />
=== Basic Example ===<br />
<br />
This is a tutorial example of the bare minimum needed to read the controller.<br />
It will explain the basic principles in detail, but once understood, you may wish to continue to the [[#Standard Read for 2 Controllers and Famicom|Standard Read]] example that follows,<br />
as a more complete and ready-to-use code example.<br />
<br />
This code describes an efficient method of reading the [[standard controller]] using [http://cc65.github.io/cc65/ ca65] syntax.<br />
<br />
The result byte ''buttons'' should be placed in zero page to save a cycle each time through the loop.<br />
<pre><br />
; we reserve one byte for storing the data that is read from controller<br />
.zeropage<br />
buttons .res 1<br />
</pre><br />
<br />
When reading from ''JOYPAD*'' what is read might be different from $01/$00 for various reasons. (See [[Controller reading]].) In this code the only concern is bit 0 read from ''JOYPAD*.''.<br />
<pre><br />
JOYPAD1 = $4016<br />
JOYPAD2 = $4017<br />
</pre><br />
<br />
This is the end result that will be stored in ''buttons''. '''1''' if the button was pressed, '''0''' otherwise.<br />
<br />
{| class="wikitable" style="text-align:center;"<br />
|-<br />
! bit<br />
| &nbsp;&nbsp;&nbsp;&nbsp;7&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;6&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;5&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;4&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;3&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;2&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;1&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;&nbsp;<br />
|-<br />
! button<br />
| A<br />
| B<br />
| Select<br />
| Start<br />
| Up<br />
| Down<br />
| Left<br />
| Right<br />
|}<br />
<br />
This subroutine takes 132 cycles to execute but ignores the Famicom expansion controller.<br />
Many controller reading subroutines use the X or Y register to count 8 times through the loop.<br />
But this one uses a more clever [[wikipedia:Ring counter|ring counter]] technique: $01 is loaded into the result first, and once eight bits are shifted in, the 1 bit will be shifted out, terminating the loop.<br />
<pre><br />
; At the same time that we strobe bit 0, we initialize the ring counter<br />
; so we're hitting two birds with one stone here<br />
readjoy:<br />
lda #$01<br />
; While the strobe bit is set, buttons will be continuously reloaded.<br />
; This means that reading from JOYPAD1 will only return the state of the<br />
; first button: button A.<br />
sta JOYPAD1<br />
sta buttons<br />
lsr a ; now A is 0<br />
; By storing 0 into JOYPAD1, the strobe bit is cleared and the reloading stops.<br />
; This allows all 8 buttons (newly reloaded) to be read from JOYPAD1.<br />
sta JOYPAD1<br />
loop:<br />
lda JOYPAD1<br />
lsr a ; bit 0 -> Carry<br />
rol buttons ; Carry -> bit 0; bit 7 -> Carry<br />
bcc loop<br />
rts<br />
</pre><br />
<br />
Continue to the next example for a more complete read routine that handles both controllers and the standard Famicom expansion controllers.<br />
<br />
=== Standard Read for 2 Controllers and Famicom ===<br />
<br />
Adding support for controllers on the Famicom's DA15 expansion port and for player 2's controller is straightforward. Something similar to the following routine is used in most Famicom games.<br />
Even though the expansion port is unused on the NES, the unconnected bit will read as 0, so this solution works safely with both Famicom and NES hardware.<br />
<pre><br />
.zeropage<br />
buttons: .res 2 ; space for 2 reads<br />
<br />
.code<br />
readjoyx2:<br />
ldx #$00<br />
jsr readjoyx ; X=0: read controller 1<br />
inx<br />
; fall through to readjoyx below, X=1: read controller 2<br />
<br />
readjoyx: ; X register = 0 for controller 1, 1 for controller 2<br />
lda #$01<br />
sta JOYPAD1<br />
sta buttons, X<br />
lsr a<br />
sta JOYPAD1<br />
loop:<br />
lda JOYPAD1, X<br />
and #%00000011 ; ignore bits other than controller<br />
cmp #$01 ; Set carry if and only if nonzero<br />
rol buttons, X ; Carry -> bit 0; but 7 -> Carry<br />
bcc loop<br />
rts<br />
</pre><br />
<br />
If playing DPCM samples, there is an additional reread step to prevent errors (([[#DPCM Safety using Repeated Reads|see below]]).<br />
<br />
=== Alternative 2 Controllers Read ===<br />
<br />
Alternatively, we could combine both controller reads into 1 loop with a single strobe, though this routine is not safe to use with DPCM samples playing ([[#DPCM Safety using Repeated Reads|see below]]).<br />
<pre><br />
.zeropage<br />
buttons: .res 2<br />
<br />
.code<br />
readjoy2:<br />
lda #$01<br />
sta JOYPAD1<br />
sta buttons+1 ; player 2's buttons double as a ring counter<br />
lsr a<br />
sta JOYPAD1<br />
loop:<br />
lda JOYPAD1<br />
and #%00000011<br />
cmp #$01<br />
rol buttons+9<br />
lda JOYPAD2<br />
and #%00000011<br />
cmp #$01<br />
rol buttons+1<br />
bcc loop<br />
rts<br />
</pre><br />
<br />
=== DPCM Safety using Repeated Reads ===<br />
<br />
If your code is intended to be used with [[APU DMC]] playback, this code will need to be altered. The NES occasionally glitches the controller port twice in a row if sample playback is enabled, and games using samples need to work around this. For example, ''Super Mario Bros. 3'' reads each controller's data at least two times each frame. First it reads it as normal, then it reads it again. If the two results differ, it does the procedure all over.<ref>[//forums.nesdev.org/viewtopic.php?p=151720#p151720 Super Mario Bros. 3 controller reread method]</ref><br />
<pre><br />
readjoyx_safe:<br />
jsr readjoyx<br />
reread:<br />
lda buttons, X<br />
pha<br />
jsr readjoyx<br />
pla<br />
cmp buttons, X<br />
bne reread<br />
rts<br />
<br />
readjoy2_safe:<br />
ldx #$00<br />
jsr readjoyx_safe ; X=0: safe read controller 1<br />
inx<br />
jmp readjoyx_safe ; X=1: safe read controller 2<br />
</pre><br />
<br />
Note that the time between the start of one read and the end of the next read must be less than the length of the fastest DMC fetch period (432 cycles). For this reason, it is normal to read controllers one at a time with this method, rather than attempting both at once. (Note: <code>readjoy2</code> above takes too long to be suitable.) [[Game bugs|''Gimmick!'' has such a bug]] resulting from trying to read both at once.<br />
<br />
=== DPCM Safety using OAM DMA ===<br />
<br />
Because halts for DPCM fetches normally only occur on an put cycles, it is possible to get glitch-free controller reads by timing all '''$4016''' and '''$4017''' reads to fall on get cycles. This is made possible by the behavior of OAM DMA: the first cycle after an OAM DMA is normally guaranteed to be a get cycle.<ref>[http://forums.nesdev.org/viewtopic.php?p=171971 Forum post:] Rahsennor's OAM-synchronized controller read</ref> This is a relatively new technique and is not supported by some emulators.<ref>[http://forums.nesdev.org/viewtopic.php?f=2&t=14319&start=15#p172099 Forum post:] as of May 2016, Nintendulator and Nestopia do not accurately emulate OAM-synchronized controller reading.</ref> In the following example code, the controller1 and controller2 labels must be in zeropage for the timing to work.<br />
<br />
<pre><br />
lda #OAM<br />
sta $4014 ; ------ OAM DMA ------<br />
ldx #1 ; get put <- strobe code must take an odd number of cycles total<br />
stx controller1 ; get put get <- controller1 and controller2 must be in the zeropage<br />
stx $4016 ; put get put get<br />
dex ; put get<br />
stx $4016 ; put get put get<br />
read_loop:<br />
lda $4017 ; put get put GET <- loop code must take an even number of cycles total<br />
and #3 ; put get<br />
cmp #1 ; put get<br />
rol controller2, x ; put get put get put get (X = 0; waste 1 cycle and 0 bytes for alignment)<br />
lda $4016 ; put get put GET<br />
and #3 ; put get<br />
cmp #1 ; put get<br />
rol controller1 ; put get put get put<br />
bcc read_loop ; get put [get] <- this branch must not be allowed to cross a page<br />
</pre><br />
<br />
Note that this example routine only reads two 8-bit controllers and does not take enough time to span more than one DPCM fetch. Routines longer than this must contend with two additional constraints:<br />
* When DMC DMA is delayed by an odd number of cycles, it takes 3 cycles instead of 4, changing the cycle parity. If extending this function to read more bits, care must be taken so that ''all'' CPU write cycles are aligned. Instructions with a single write cycle must align the write to avoid conflict with the DPCM fetch, and double-write instructions like ROL need to align both writes so that the DPCM fetch falls on the first write.<ref>[//forums.nesdev.org/viewtopic.php?p=231604#p231604 Forum post:] demonstration of how ROL instruction affects alignment for OAM DMA synchronized controller reading.</ref> If an interrupt can occur during the routine, it must be aligned so the fetch can only fall on the second of the three automatic stack writes.<br />
* When DMC DMA occurs near the end of OAM DMA, it only steals 1 or 3 cycles, inverting the cycle parity. Every DMC period after that, a misaligned DPCM fetch will occur. Care must be taken to ensure this does not land on a joypad read.<br />
<br />
See [[DMA]] for detailed information on DMA timing.<br />
<br />
=== Directional Safety ===<br />
<br />
To reject opposing presses (Up+Down and Left+Right), which are possible on a worn Control Pad:<br />
<pre><br />
lda buttons1,x<br />
and #%00001010 ; Compare Up and Left...<br />
lsr a<br />
and buttons1,x ; to Down and Right<br />
beq not_updown<br />
; Use previous frame's directions<br />
lda buttons1,x<br />
eor last_frame_buttons1,x<br />
and #%11110000<br />
eor last_frame_buttons1,x<br />
sta buttons1,x<br />
not_updown:<br />
</pre><br />
<br />
To instead reject all diagonal presses, simulating a 4-way joystick:<br />
<pre><br />
lda buttons1,x<br />
and #%00001111 ; If A & (A - 1) is nonzero, A has more than one bit set<br />
beq not_diagonal<br />
sec<br />
sbc #1<br />
and buttons1,x<br />
beq not_diagonal<br />
; Use previous frame's directions<br />
lda buttons1,x<br />
eor last_frame_buttons1,x<br />
and #%11110000<br />
eor last_frame_buttons1,x<br />
sta buttons1,x<br />
not_diagonal:<br />
</pre><br />
<br />
=== Calculating Presses and Releases ===<br />
<br />
To calculate newly pressed and newly released buttons:<br />
<pre><br />
lda buttons1,x<br />
eor #%11111111<br />
and last_frame_buttons1,x<br />
sta released_buttons1,x<br />
lda last_frame_buttons1,x<br />
eor #%11111111<br />
and buttons1,x<br />
sta pressed_buttons1,x<br />
</pre><br />
<br />
=== Button Flags ===<br />
<br />
It is helpful to define the buttons as a series of bit flags:<br />
<pre><br />
BUTTON_A = 1 << 7<br />
BUTTON_B = 1 << 6<br />
BUTTON_SELECT = 1 << 5<br />
BUTTON_START = 1 << 4<br />
BUTTON_UP = 1 << 3<br />
BUTTON_DOWN = 1 << 2<br />
BUTTON_LEFT = 1 << 1<br />
BUTTON_RIGHT = 1 << 0<br />
</pre><br />
<br />
And then buttons can be checked as follows:<br />
<pre><br />
lda buttons<br />
and #BUTTON_A | BUTTON_B<br />
beq notPressingAorB<br />
; Handle presses.<br />
notPressingAorB:<br />
</pre><br />
<br />
== External Examples ==<br />
<br />
* [http://forums.nesdev.org/viewtopic.php?t=4124 Forum post:] Blargg's DMC-fortified controller read routine<br />
* [http://forums.nesdev.org/viewtopic.php?p=171971 Forum post:] Rahsennor's OAM-synchronized controller read<br />
* [http://forums.nesdev.org/viewtopic.php?f=2&t=14197 Forum post:] Drag's bitwise DMC-safe controller reading<br />
<br />
== References ==<br />
<references/></div>Rainwarriorhttps://www.nesdev.org/w/index.php?title=Controller_reading_code&diff=21485Controller reading code2024-01-11T00:56:50Z<p>Rainwarrior: /* Basic Example */ fix link</p>
<hr />
<div>This page contains example code for reading the [[NES controller]].<br />
<br />
See also: [[Controller reading]]<br />
<br />
=== Basic Example ===<br />
<br />
This is a tutorial example of the bare minimum needed to read the controller.<br />
It will explain the basic principles in detail, but once understood, you may wish to continue to the [[#Standard Read for 2 Controllers and Famicom|Standard Read]] example that follows,<br />
as a more complete and ready-to-use code example.<br />
<br />
This code describes an efficient method of reading the [[standard controller]] using [http://cc65.github.io/cc65/ ca65] syntax.<br />
<br />
The result byte ''buttons'' should be placed in zero page to save a cycle each time through the loop.<br />
<pre><br />
; we reserve one byte for storing the data that is read from controller<br />
.zeropage<br />
buttons .res 1<br />
</pre><br />
<br />
When reading from ''JOYPAD*'' what is read might be different from $01/$00 for various reasons. (See [[Controller reading]].) In this code the only concern is bit 0 read from ''JOYPAD*.''.<br />
<pre><br />
JOYPAD1 = $4016<br />
JOYPAD2 = $4017<br />
</pre><br />
<br />
This is the end result that will be stored in ''buttons''. '''1''' if the button was pressed, '''0''' otherwise.<br />
<br />
{| class="wikitable" style="text-align:center;"<br />
|-<br />
! bit<br />
| &nbsp;&nbsp;&nbsp;&nbsp;7&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;6&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;5&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;4&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;3&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;2&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;1&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;&nbsp;<br />
|-<br />
! button<br />
| A<br />
| B<br />
| Select<br />
| Start<br />
| Up<br />
| Down<br />
| Left<br />
| Right<br />
|}<br />
<br />
This subroutine takes 132 cycles to execute but ignores the Famicom expansion controller.<br />
Many controller reading subroutines use the X or Y register to count 8 times through the loop.<br />
But this one uses a more clever [[wikipedia:Ring counter|ring counter]] technique: $01 is loaded into the result first, and once eight bits are shifted in, the 1 bit will be shifted out, terminating the loop.<br />
<pre><br />
; At the same time that we strobe bit 0, we initialize the ring counter<br />
; so we're hitting two birds with one stone here<br />
readjoy:<br />
lda #$01<br />
; While the strobe bit is set, buttons will be continuously reloaded.<br />
; This means that reading from JOYPAD1 will only return the state of the<br />
; first button: button A.<br />
sta JOYPAD1<br />
sta buttons<br />
lsr a ; now A is 0<br />
; By storing 0 into JOYPAD1, the strobe bit is cleared and the reloading stops.<br />
; This allows all 8 buttons (newly reloaded) to be read from JOYPAD1.<br />
sta JOYPAD1<br />
loop:<br />
lda JOYPAD1<br />
lsr a ; bit 0 -> Carry<br />
rol buttons ; Carry -> bit 0; bit 7 -> Carry<br />
bcc loop<br />
rts<br />
</pre><br />
<br />
Continue to the next example for a more complete read routine that handles both controllers and the standard Famicom expansion controllers.<br />
<br />
=== Standard Read for 2 Controllers and Famicom ===<br />
<br />
Adding support for controllers on the Famicom's DA15 expansion port and for player 2's controller is straightforward. Something similar to the following routine is used in most Famicom games.<br />
Even though the expansion port is unused on the NES, the unconnected bit will read as 0, so this solution works safely with both Famicom and NES hardware.<br />
<pre><br />
.zeropage<br />
buttons: .res 2 ; space for 2 reads<br />
<br />
.code<br />
readjoyx2:<br />
ldx #$00<br />
jsr readjoyx ; X=0: read controller 1<br />
inx<br />
; fall through to readjoyx below, X=1: read controller 2<br />
<br />
readjoyx: ; X register = 0 for controller 1, 1 for controller 2<br />
lda #$01<br />
sta JOYPAD1<br />
sta buttons, X<br />
lsr a<br />
sta JOYPAD1<br />
loop:<br />
lda JOYPAD1, X<br />
and #%00000011 ; ignore bits other than controller<br />
cmp #$01 ; Set carry if and only if nonzero<br />
rol buttons, X ; Carry -> bit 0; but 7 -> Carry<br />
bcc loop<br />
rts<br />
</pre><br />
<br />
If playing DPCM samples, there is an additional reread step to prevent errors (([[#DPCM Safety using Repeated Reads|see below]]).<br />
<br />
=== Alternative 2 Controllers Read ===<br />
<br />
Alternatively, we could combine both controller reads into 1 loop with a single strobe, though this routine is not safe to use with DPCM samples playing ([[#DPCM Safety using Repeated Reads|see below]]).<br />
<pre><br />
.zeropage<br />
buttons: .res 2<br />
<br />
.code<br />
readjoy2:<br />
lda #$01<br />
sta JOYPAD1<br />
sta buttons+1 ; player 2's buttons double as a ring counter<br />
lsr a<br />
sta JOYPAD1<br />
loop:<br />
lda JOYPAD1<br />
and #%00000011<br />
cmp #$01<br />
rol buttons+9<br />
lda JOYPAD2<br />
and #%00000011<br />
cmp #$01<br />
rol buttons+1<br />
bcc loop<br />
rts<br />
</pre><br />
<br />
=== DPCM Safety using Repeated Reads ===<br />
<br />
If your code is intended to be used with [[APU DMC]] playback, this code will need to be altered. The NES occasionally glitches the controller port twice in a row if sample playback is enabled, and games using samples need to work around this. For example, ''Super Mario Bros. 3'' reads each controller's data at least two times each frame. First it reads it as normal, then it reads it again. If the two results differ, it does the procedure all over.<br />
<br />
One controller example:<ref>[//forums.nesdev.org/viewtopic.php?p=151720#p151720 Super Mario Bros. 3 controller reread method]</ref><br />
<pre><br />
readjoyx_safe:<br />
jsr readjoyx<br />
reread:<br />
lda buttons, X<br />
pha<br />
jsr readjoyx<br />
pla<br />
cmp buttons, X<br />
bne reread<br />
rts<br />
<br />
readjoy2_safe:<br />
ldx #$00<br />
jsr readjoyx_safe ; X=0: safe read controller 1<br />
inx<br />
jmp readjoyx_safe ; X=1: safe read controller 2<br />
</pre><br />
<br />
Note that the time between the start of one read and the end of the next read must be less than the length of the fastest DMC fetch period (432 cycles). For this reason, it is normal to read controllers one at a time with this method, rather than attempting both at once. (Note: <code>readjoy2</code> above takes too long to be suitable.) [[Game bugs|''Gimmick!'' has such a bug]] resulting from trying to read both at once.<br />
<br />
=== DPCM Safety using OAM DMA ===<br />
<br />
Because halts for DPCM fetches normally only occur on an put cycles, it is possible to get glitch-free controller reads by timing all '''$4016''' and '''$4017''' reads to fall on get cycles. This is made possible by the behavior of OAM DMA: the first cycle after an OAM DMA is normally guaranteed to be a get cycle.<ref>[http://forums.nesdev.org/viewtopic.php?p=171971 Forum post:] Rahsennor's OAM-synchronized controller read</ref> This is a relatively new technique and is not supported by some emulators.<ref>[http://forums.nesdev.org/viewtopic.php?f=2&t=14319&start=15#p172099 Forum post:] as of May 2016, Nintendulator and Nestopia do not accurately emulate OAM-synchronized controller reading.</ref> In the following example code, the controller1 and controller2 labels must be in zeropage for the timing to work.<br />
<br />
<pre><br />
lda #OAM<br />
sta $4014 ; ------ OAM DMA ------<br />
ldx #1 ; get put <- strobe code must take an odd number of cycles total<br />
stx controller1 ; get put get <- controller1 and controller2 must be in the zeropage<br />
stx $4016 ; put get put get<br />
dex ; put get<br />
stx $4016 ; put get put get<br />
read_loop:<br />
lda $4017 ; put get put GET <- loop code must take an even number of cycles total<br />
and #3 ; put get<br />
cmp #1 ; put get<br />
rol controller2, x ; put get put get put get (X = 0; waste 1 cycle and 0 bytes for alignment)<br />
lda $4016 ; put get put GET<br />
and #3 ; put get<br />
cmp #1 ; put get<br />
rol controller1 ; put get put get put<br />
bcc read_loop ; get put [get] <- this branch must not be allowed to cross a page<br />
</pre><br />
<br />
Note that this example routine only reads two 8-bit controllers and does not take enough time to span more than one DPCM fetch. Routines longer than this must contend with two additional constraints:<br />
* When DMC DMA is delayed by an odd number of cycles, it takes 3 cycles instead of 4, changing the cycle parity. If extending this function to read more bits, care must be taken so that ''all'' CPU write cycles are aligned. Instructions with a single write cycle must align the write to avoid conflict with the DPCM fetch, and double-write instructions like ROL need to align both writes so that the DPCM fetch falls on the first write.<ref>[//forums.nesdev.org/viewtopic.php?p=231604#p231604 Forum post:] demonstration of how ROL instruction affects alignment for OAM DMA synchronized controller reading.</ref> If an interrupt can occur during the routine, it must be aligned so the fetch can only fall on the second of the three automatic stack writes.<br />
* When DMC DMA occurs near the end of OAM DMA, it only steals 1 or 3 cycles, inverting the cycle parity. Every DMC period after that, a misaligned DPCM fetch will occur. Care must be taken to ensure this does not land on a joypad read.<br />
<br />
See [[DMA]] for detailed information on DMA timing.<br />
<br />
=== Directional Safety ===<br />
<br />
To reject opposing presses (Up+Down and Left+Right), which are possible on a worn Control Pad:<br />
<pre><br />
lda buttons1,x<br />
and #%00001010 ; Compare Up and Left...<br />
lsr a<br />
and buttons1,x ; to Down and Right<br />
beq not_updown<br />
; Use previous frame's directions<br />
lda buttons1,x<br />
eor last_frame_buttons1,x<br />
and #%11110000<br />
eor last_frame_buttons1,x<br />
sta buttons1,x<br />
not_updown:<br />
</pre><br />
<br />
To instead reject all diagonal presses, simulating a 4-way joystick:<br />
<pre><br />
lda buttons1,x<br />
and #%00001111 ; If A & (A - 1) is nonzero, A has more than one bit set<br />
beq not_diagonal<br />
sec<br />
sbc #1<br />
and buttons1,x<br />
beq not_diagonal<br />
; Use previous frame's directions<br />
lda buttons1,x<br />
eor last_frame_buttons1,x<br />
and #%11110000<br />
eor last_frame_buttons1,x<br />
sta buttons1,x<br />
not_diagonal:<br />
</pre><br />
<br />
=== Calculating Presses and Releases ===<br />
<br />
To calculate newly pressed and newly released buttons:<br />
<pre><br />
lda buttons1,x<br />
eor #%11111111<br />
and last_frame_buttons1,x<br />
sta released_buttons1,x<br />
lda last_frame_buttons1,x<br />
eor #%11111111<br />
and buttons1,x<br />
sta pressed_buttons1,x<br />
</pre><br />
<br />
=== Button Flags ===<br />
<br />
It is helpful to define the buttons as a series of bit flags:<br />
<pre><br />
BUTTON_A = 1 << 7<br />
BUTTON_B = 1 << 6<br />
BUTTON_SELECT = 1 << 5<br />
BUTTON_START = 1 << 4<br />
BUTTON_UP = 1 << 3<br />
BUTTON_DOWN = 1 << 2<br />
BUTTON_LEFT = 1 << 1<br />
BUTTON_RIGHT = 1 << 0<br />
</pre><br />
<br />
And then buttons can be checked as follows:<br />
<pre><br />
lda buttons<br />
and #BUTTON_A | BUTTON_B<br />
beq notPressingAorB<br />
; Handle presses.<br />
notPressingAorB:<br />
</pre><br />
<br />
== External Examples ==<br />
<br />
* [http://forums.nesdev.org/viewtopic.php?t=4124 Forum post:] Blargg's DMC-fortified controller read routine<br />
* [http://forums.nesdev.org/viewtopic.php?p=171971 Forum post:] Rahsennor's OAM-synchronized controller read<br />
* [http://forums.nesdev.org/viewtopic.php?f=2&t=14197 Forum post:] Drag's bitwise DMC-safe controller reading<br />
<br />
== References ==<br />
<references/></div>Rainwarriorhttps://www.nesdev.org/w/index.php?title=Controller_reading_code&diff=21484Controller reading code2024-01-11T00:56:20Z<p>Rainwarrior: Break up the 3 examples to make them easier to follow</p>
<hr />
<div>This page contains example code for reading the [[NES controller]].<br />
<br />
See also: [[Controller reading]]<br />
<br />
=== Basic Example ===<br />
<br />
This is a tutorial example of the bare minimum needed to read the controller.<br />
It will explain the basic principles in detail, but once understood, you may wish to continue to the [[Standard Read for 2 Controllers and Famicom#Standard Read]] example that follows,<br />
as a more complete and ready-to-use code example.<br />
<br />
This code describes an efficient method of reading the [[standard controller]] using [http://cc65.github.io/cc65/ ca65] syntax.<br />
<br />
The result byte ''buttons'' should be placed in zero page to save a cycle each time through the loop.<br />
<pre><br />
; we reserve one byte for storing the data that is read from controller<br />
.zeropage<br />
buttons .res 1<br />
</pre><br />
<br />
When reading from ''JOYPAD*'' what is read might be different from $01/$00 for various reasons. (See [[Controller reading]].) In this code the only concern is bit 0 read from ''JOYPAD*.''.<br />
<pre><br />
JOYPAD1 = $4016<br />
JOYPAD2 = $4017<br />
</pre><br />
<br />
This is the end result that will be stored in ''buttons''. '''1''' if the button was pressed, '''0''' otherwise.<br />
<br />
{| class="wikitable" style="text-align:center;"<br />
|-<br />
! bit<br />
| &nbsp;&nbsp;&nbsp;&nbsp;7&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;6&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;5&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;4&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;3&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;2&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;1&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;&nbsp;<br />
|-<br />
! button<br />
| A<br />
| B<br />
| Select<br />
| Start<br />
| Up<br />
| Down<br />
| Left<br />
| Right<br />
|}<br />
<br />
This subroutine takes 132 cycles to execute but ignores the Famicom expansion controller.<br />
Many controller reading subroutines use the X or Y register to count 8 times through the loop.<br />
But this one uses a more clever [[wikipedia:Ring counter|ring counter]] technique: $01 is loaded into the result first, and once eight bits are shifted in, the 1 bit will be shifted out, terminating the loop.<br />
<pre><br />
; At the same time that we strobe bit 0, we initialize the ring counter<br />
; so we're hitting two birds with one stone here<br />
readjoy:<br />
lda #$01<br />
; While the strobe bit is set, buttons will be continuously reloaded.<br />
; This means that reading from JOYPAD1 will only return the state of the<br />
; first button: button A.<br />
sta JOYPAD1<br />
sta buttons<br />
lsr a ; now A is 0<br />
; By storing 0 into JOYPAD1, the strobe bit is cleared and the reloading stops.<br />
; This allows all 8 buttons (newly reloaded) to be read from JOYPAD1.<br />
sta JOYPAD1<br />
loop:<br />
lda JOYPAD1<br />
lsr a ; bit 0 -> Carry<br />
rol buttons ; Carry -> bit 0; bit 7 -> Carry<br />
bcc loop<br />
rts<br />
</pre><br />
<br />
Continue to the next example for a more complete read routine that handles both controllers and the standard Famicom expansion controllers.<br />
<br />
=== Standard Read for 2 Controllers and Famicom ===<br />
<br />
Adding support for controllers on the Famicom's DA15 expansion port and for player 2's controller is straightforward. Something similar to the following routine is used in most Famicom games.<br />
Even though the expansion port is unused on the NES, the unconnected bit will read as 0, so this solution works safely with both Famicom and NES hardware.<br />
<pre><br />
.zeropage<br />
buttons: .res 2 ; space for 2 reads<br />
<br />
.code<br />
readjoyx2:<br />
ldx #$00<br />
jsr readjoyx ; X=0: read controller 1<br />
inx<br />
; fall through to readjoyx below, X=1: read controller 2<br />
<br />
readjoyx: ; X register = 0 for controller 1, 1 for controller 2<br />
lda #$01<br />
sta JOYPAD1<br />
sta buttons, X<br />
lsr a<br />
sta JOYPAD1<br />
loop:<br />
lda JOYPAD1, X<br />
and #%00000011 ; ignore bits other than controller<br />
cmp #$01 ; Set carry if and only if nonzero<br />
rol buttons, X ; Carry -> bit 0; but 7 -> Carry<br />
bcc loop<br />
rts<br />
</pre><br />
<br />
If playing DPCM samples, there is an additional reread step to prevent errors (([[#DPCM Safety using Repeated Reads|see below]]).<br />
<br />
=== Alternative 2 Controllers Read ===<br />
<br />
Alternatively, we could combine both controller reads into 1 loop with a single strobe, though this routine is not safe to use with DPCM samples playing ([[#DPCM Safety using Repeated Reads|see below]]).<br />
<pre><br />
.zeropage<br />
buttons: .res 2<br />
<br />
.code<br />
readjoy2:<br />
lda #$01<br />
sta JOYPAD1<br />
sta buttons+1 ; player 2's buttons double as a ring counter<br />
lsr a<br />
sta JOYPAD1<br />
loop:<br />
lda JOYPAD1<br />
and #%00000011<br />
cmp #$01<br />
rol buttons+9<br />
lda JOYPAD2<br />
and #%00000011<br />
cmp #$01<br />
rol buttons+1<br />
bcc loop<br />
rts<br />
</pre><br />
<br />
=== DPCM Safety using Repeated Reads ===<br />
<br />
If your code is intended to be used with [[APU DMC]] playback, this code will need to be altered. The NES occasionally glitches the controller port twice in a row if sample playback is enabled, and games using samples need to work around this. For example, ''Super Mario Bros. 3'' reads each controller's data at least two times each frame. First it reads it as normal, then it reads it again. If the two results differ, it does the procedure all over.<br />
<br />
One controller example:<ref>[//forums.nesdev.org/viewtopic.php?p=151720#p151720 Super Mario Bros. 3 controller reread method]</ref><br />
<pre><br />
readjoyx_safe:<br />
jsr readjoyx<br />
reread:<br />
lda buttons, X<br />
pha<br />
jsr readjoyx<br />
pla<br />
cmp buttons, X<br />
bne reread<br />
rts<br />
<br />
readjoy2_safe:<br />
ldx #$00<br />
jsr readjoyx_safe ; X=0: safe read controller 1<br />
inx<br />
jmp readjoyx_safe ; X=1: safe read controller 2<br />
</pre><br />
<br />
Note that the time between the start of one read and the end of the next read must be less than the length of the fastest DMC fetch period (432 cycles). For this reason, it is normal to read controllers one at a time with this method, rather than attempting both at once. (Note: <code>readjoy2</code> above takes too long to be suitable.) [[Game bugs|''Gimmick!'' has such a bug]] resulting from trying to read both at once.<br />
<br />
=== DPCM Safety using OAM DMA ===<br />
<br />
Because halts for DPCM fetches normally only occur on an put cycles, it is possible to get glitch-free controller reads by timing all '''$4016''' and '''$4017''' reads to fall on get cycles. This is made possible by the behavior of OAM DMA: the first cycle after an OAM DMA is normally guaranteed to be a get cycle.<ref>[http://forums.nesdev.org/viewtopic.php?p=171971 Forum post:] Rahsennor's OAM-synchronized controller read</ref> This is a relatively new technique and is not supported by some emulators.<ref>[http://forums.nesdev.org/viewtopic.php?f=2&t=14319&start=15#p172099 Forum post:] as of May 2016, Nintendulator and Nestopia do not accurately emulate OAM-synchronized controller reading.</ref> In the following example code, the controller1 and controller2 labels must be in zeropage for the timing to work.<br />
<br />
<pre><br />
lda #OAM<br />
sta $4014 ; ------ OAM DMA ------<br />
ldx #1 ; get put <- strobe code must take an odd number of cycles total<br />
stx controller1 ; get put get <- controller1 and controller2 must be in the zeropage<br />
stx $4016 ; put get put get<br />
dex ; put get<br />
stx $4016 ; put get put get<br />
read_loop:<br />
lda $4017 ; put get put GET <- loop code must take an even number of cycles total<br />
and #3 ; put get<br />
cmp #1 ; put get<br />
rol controller2, x ; put get put get put get (X = 0; waste 1 cycle and 0 bytes for alignment)<br />
lda $4016 ; put get put GET<br />
and #3 ; put get<br />
cmp #1 ; put get<br />
rol controller1 ; put get put get put<br />
bcc read_loop ; get put [get] <- this branch must not be allowed to cross a page<br />
</pre><br />
<br />
Note that this example routine only reads two 8-bit controllers and does not take enough time to span more than one DPCM fetch. Routines longer than this must contend with two additional constraints:<br />
* When DMC DMA is delayed by an odd number of cycles, it takes 3 cycles instead of 4, changing the cycle parity. If extending this function to read more bits, care must be taken so that ''all'' CPU write cycles are aligned. Instructions with a single write cycle must align the write to avoid conflict with the DPCM fetch, and double-write instructions like ROL need to align both writes so that the DPCM fetch falls on the first write.<ref>[//forums.nesdev.org/viewtopic.php?p=231604#p231604 Forum post:] demonstration of how ROL instruction affects alignment for OAM DMA synchronized controller reading.</ref> If an interrupt can occur during the routine, it must be aligned so the fetch can only fall on the second of the three automatic stack writes.<br />
* When DMC DMA occurs near the end of OAM DMA, it only steals 1 or 3 cycles, inverting the cycle parity. Every DMC period after that, a misaligned DPCM fetch will occur. Care must be taken to ensure this does not land on a joypad read.<br />
<br />
See [[DMA]] for detailed information on DMA timing.<br />
<br />
=== Directional Safety ===<br />
<br />
To reject opposing presses (Up+Down and Left+Right), which are possible on a worn Control Pad:<br />
<pre><br />
lda buttons1,x<br />
and #%00001010 ; Compare Up and Left...<br />
lsr a<br />
and buttons1,x ; to Down and Right<br />
beq not_updown<br />
; Use previous frame's directions<br />
lda buttons1,x<br />
eor last_frame_buttons1,x<br />
and #%11110000<br />
eor last_frame_buttons1,x<br />
sta buttons1,x<br />
not_updown:<br />
</pre><br />
<br />
To instead reject all diagonal presses, simulating a 4-way joystick:<br />
<pre><br />
lda buttons1,x<br />
and #%00001111 ; If A & (A - 1) is nonzero, A has more than one bit set<br />
beq not_diagonal<br />
sec<br />
sbc #1<br />
and buttons1,x<br />
beq not_diagonal<br />
; Use previous frame's directions<br />
lda buttons1,x<br />
eor last_frame_buttons1,x<br />
and #%11110000<br />
eor last_frame_buttons1,x<br />
sta buttons1,x<br />
not_diagonal:<br />
</pre><br />
<br />
=== Calculating Presses and Releases ===<br />
<br />
To calculate newly pressed and newly released buttons:<br />
<pre><br />
lda buttons1,x<br />
eor #%11111111<br />
and last_frame_buttons1,x<br />
sta released_buttons1,x<br />
lda last_frame_buttons1,x<br />
eor #%11111111<br />
and buttons1,x<br />
sta pressed_buttons1,x<br />
</pre><br />
<br />
=== Button Flags ===<br />
<br />
It is helpful to define the buttons as a series of bit flags:<br />
<pre><br />
BUTTON_A = 1 << 7<br />
BUTTON_B = 1 << 6<br />
BUTTON_SELECT = 1 << 5<br />
BUTTON_START = 1 << 4<br />
BUTTON_UP = 1 << 3<br />
BUTTON_DOWN = 1 << 2<br />
BUTTON_LEFT = 1 << 1<br />
BUTTON_RIGHT = 1 << 0<br />
</pre><br />
<br />
And then buttons can be checked as follows:<br />
<pre><br />
lda buttons<br />
and #BUTTON_A | BUTTON_B<br />
beq notPressingAorB<br />
; Handle presses.<br />
notPressingAorB:<br />
</pre><br />
<br />
== External Examples ==<br />
<br />
* [http://forums.nesdev.org/viewtopic.php?t=4124 Forum post:] Blargg's DMC-fortified controller read routine<br />
* [http://forums.nesdev.org/viewtopic.php?p=171971 Forum post:] Rahsennor's OAM-synchronized controller read<br />
* [http://forums.nesdev.org/viewtopic.php?f=2&t=14197 Forum post:] Drag's bitwise DMC-safe controller reading<br />
<br />
== References ==<br />
<references/></div>Rainwarriorhttps://www.nesdev.org/w/index.php?title=Controller_reading_code&diff=21483Controller reading code2024-01-11T00:43:08Z<p>Rainwarrior: /* DPCM Safety using Repeated Reads */ use readjoyx to make 2 controllers simple</p>
<hr />
<div>This page contains example code for reading the [[NES controller]].<br />
<br />
See also: [[Controller reading]]<br />
<br />
=== Basic Example ===<br />
<br />
This describes an efficient method of reading the [[standard controller]] using [http://cc65.github.io/cc65/ ca65] syntax.<br />
<br />
The result byte ''buttons'' should be placed in zero page to save a cycle each time through the loop.<br />
<pre><br />
; we reserve one byte for storing the data that is read from controller<br />
.zeropage<br />
buttons .res 1<br />
</pre><br />
<br />
When reading from ''JOYPAD*'' what is read might be different from $01/$00 for various reasons. (See [[Controller reading]].) In this code the only concern is bit 0 read from ''JOYPAD*.''.<br />
<pre><br />
JOYPAD1 = $4016<br />
JOYPAD2 = $4017<br />
</pre><br />
<br />
This is the end result that will be stored in ''buttons''. '''1''' if the button was pressed, '''0''' otherwise.<br />
<br />
{| class="wikitable" style="text-align:center;"<br />
|-<br />
! bit<br />
| &nbsp;&nbsp;&nbsp;&nbsp;7&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;6&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;5&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;4&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;3&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;2&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;1&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;&nbsp;<br />
|-<br />
! button<br />
| A<br />
| B<br />
| Select<br />
| Start<br />
| Up<br />
| Down<br />
| Left<br />
| Right<br />
|}<br />
<br />
This subroutine takes 132 cycles to execute but ignores the Famicom expansion controller.<br />
Many controller reading subroutines use the X or Y register to count 8 times through the loop.<br />
But this one uses a more clever [[wikipedia:Ring counter|ring counter]] technique: $01 is loaded into the result first, and once eight bits are shifted in, the 1 bit will be shifted out, terminating the loop.<br />
<pre><br />
; At the same time that we strobe bit 0, we initialize the ring counter<br />
; so we're hitting two birds with one stone here<br />
readjoy:<br />
lda #$01<br />
; While the strobe bit is set, buttons will be continuously reloaded.<br />
; This means that reading from JOYPAD1 will only return the state of the<br />
; first button: button A.<br />
sta JOYPAD1<br />
sta buttons<br />
lsr a ; now A is 0<br />
; By storing 0 into JOYPAD1, the strobe bit is cleared and the reloading stops.<br />
; This allows all 8 buttons (newly reloaded) to be read from JOYPAD1.<br />
sta JOYPAD1<br />
loop:<br />
lda JOYPAD1<br />
lsr a ; bit 0 -> Carry<br />
rol buttons ; Carry -> bit 0; bit 7 -> Carry<br />
bcc loop<br />
rts<br />
</pre><br />
<br />
Adding support for controllers on the Famicom's DA15 expansion port and for player 2's controller is straightforward. Something similar to the following routine is used in most Famicom games.<br />
Even though the expansion port is unused on the NES, the expansion port bit will always read as 0, so this solution works safely with both Famicom and NES hardware.<br />
<pre><br />
.zeropage<br />
buttons: .res 2 ; space for 2 reads<br />
<br />
.code<br />
readjoyx: ; X register = 0 for controller 1, 1 for controller 2<br />
lda #$01<br />
sta JOYPAD1<br />
sta buttons, X<br />
lsr a<br />
sta JOYPAD1<br />
loop:<br />
lda JOYPAD1, X<br />
and #%00000011 ; ignore bits other than controller<br />
cmp #$01 ; Set carry if and only if nonzero<br />
rol buttons, X ; Carry -> bit 0; but 7 -> Carry<br />
bcc loop<br />
rts<br />
</pre><br />
<br />
Alternatively, we could combine both controller reads into 1 loop with a single strobe, though this routine is not safe to use with DPCM samples playing (see below).<br />
<pre><br />
.zeropage<br />
buttons: .res 2<br />
<br />
.code<br />
readjoy2:<br />
lda #$01<br />
sta JOYPAD1<br />
sta buttons+1 ; player 2's buttons double as a ring counter<br />
lsr a<br />
sta JOYPAD1<br />
loop:<br />
lda JOYPAD1<br />
and #%00000011<br />
cmp #$01<br />
rol buttons+9<br />
lda JOYPAD2<br />
and #%00000011<br />
cmp #$01<br />
rol buttons+1<br />
bcc loop<br />
rts<br />
</pre><br />
<br />
=== DPCM Safety using Repeated Reads ===<br />
<br />
If your code is intended to be used with [[APU DMC]] playback, this code will need to be altered. The NES occasionally glitches the controller port twice in a row if sample playback is enabled, and games using samples need to work around this. For example, ''Super Mario Bros. 3'' reads each controller's data at least two times each frame. First it reads it as normal, then it reads it again. If the two results differ, it does the procedure all over.<br />
<br />
One controller example:<ref>[//forums.nesdev.org/viewtopic.php?p=151720#p151720 Super Mario Bros. 3 controller reread method]</ref><br />
<pre><br />
readjoyx_safe:<br />
jsr readjoyx<br />
reread:<br />
lda buttons, X<br />
pha<br />
jsr readjoyx<br />
pla<br />
cmp buttons, X<br />
bne reread<br />
rts<br />
<br />
readjoy2_safe:<br />
lda #0<br />
jsr readjoyx_safe ; X=0: safe read controller 1<br />
inx<br />
jmp readjoyx_safe ; X=1: safe read controller 2<br />
</pre><br />
<br />
Note that the time between the start of one read and the end of the next read must be less than the length of the fastest DMC fetch period (432 cycles). For this reason, it is normal to read controllers one at a time with this method, rather than attempting both at once. (Note: <code>readjoy2</code> above takes too long to be suitable.) [[Game bugs|''Gimmick!'' has such a bug]] resulting from trying to read both at once.<br />
<br />
=== DPCM Safety using OAM DMA ===<br />
<br />
Because halts for DPCM fetches normally only occur on an put cycles, it is possible to get glitch-free controller reads by timing all '''$4016''' and '''$4017''' reads to fall on get cycles. This is made possible by the behavior of OAM DMA: the first cycle after an OAM DMA is normally guaranteed to be a get cycle.<ref>[http://forums.nesdev.org/viewtopic.php?p=171971 Forum post:] Rahsennor's OAM-synchronized controller read</ref> This is a relatively new technique and is not supported by some emulators.<ref>[http://forums.nesdev.org/viewtopic.php?f=2&t=14319&start=15#p172099 Forum post:] as of May 2016, Nintendulator and Nestopia do not accurately emulate OAM-synchronized controller reading.</ref> In the following example code, the controller1 and controller2 labels must be in zeropage for the timing to work.<br />
<br />
<pre><br />
lda #OAM<br />
sta $4014 ; ------ OAM DMA ------<br />
ldx #1 ; get put <- strobe code must take an odd number of cycles total<br />
stx controller1 ; get put get <- controller1 and controller2 must be in the zeropage<br />
stx $4016 ; put get put get<br />
dex ; put get<br />
stx $4016 ; put get put get<br />
read_loop:<br />
lda $4017 ; put get put GET <- loop code must take an even number of cycles total<br />
and #3 ; put get<br />
cmp #1 ; put get<br />
rol controller2, x ; put get put get put get (X = 0; waste 1 cycle and 0 bytes for alignment)<br />
lda $4016 ; put get put GET<br />
and #3 ; put get<br />
cmp #1 ; put get<br />
rol controller1 ; put get put get put<br />
bcc read_loop ; get put [get] <- this branch must not be allowed to cross a page<br />
</pre><br />
<br />
Note that this example routine only reads two 8-bit controllers and does not take enough time to span more than one DPCM fetch. Routines longer than this must contend with two additional constraints:<br />
* When DMC DMA is delayed by an odd number of cycles, it takes 3 cycles instead of 4, changing the cycle parity. If extending this function to read more bits, care must be taken so that ''all'' CPU write cycles are aligned. Instructions with a single write cycle must align the write to avoid conflict with the DPCM fetch, and double-write instructions like ROL need to align both writes so that the DPCM fetch falls on the first write.<ref>[//forums.nesdev.org/viewtopic.php?p=231604#p231604 Forum post:] demonstration of how ROL instruction affects alignment for OAM DMA synchronized controller reading.</ref> If an interrupt can occur during the routine, it must be aligned so the fetch can only fall on the second of the three automatic stack writes.<br />
* When DMC DMA occurs near the end of OAM DMA, it only steals 1 or 3 cycles, inverting the cycle parity. Every DMC period after that, a misaligned DPCM fetch will occur. Care must be taken to ensure this does not land on a joypad read.<br />
<br />
See [[DMA]] for detailed information on DMA timing.<br />
<br />
=== Directional Safety ===<br />
<br />
To reject opposing presses (Up+Down and Left+Right), which are possible on a worn Control Pad:<br />
<pre><br />
lda buttons1,x<br />
and #%00001010 ; Compare Up and Left...<br />
lsr a<br />
and buttons1,x ; to Down and Right<br />
beq not_updown<br />
; Use previous frame's directions<br />
lda buttons1,x<br />
eor last_frame_buttons1,x<br />
and #%11110000<br />
eor last_frame_buttons1,x<br />
sta buttons1,x<br />
not_updown:<br />
</pre><br />
<br />
To instead reject all diagonal presses, simulating a 4-way joystick:<br />
<pre><br />
lda buttons1,x<br />
and #%00001111 ; If A & (A - 1) is nonzero, A has more than one bit set<br />
beq not_diagonal<br />
sec<br />
sbc #1<br />
and buttons1,x<br />
beq not_diagonal<br />
; Use previous frame's directions<br />
lda buttons1,x<br />
eor last_frame_buttons1,x<br />
and #%11110000<br />
eor last_frame_buttons1,x<br />
sta buttons1,x<br />
not_diagonal:<br />
</pre><br />
<br />
=== Calculating Presses and Releases ===<br />
<br />
To calculate newly pressed and newly released buttons:<br />
<pre><br />
lda buttons1,x<br />
eor #%11111111<br />
and last_frame_buttons1,x<br />
sta released_buttons1,x<br />
lda last_frame_buttons1,x<br />
eor #%11111111<br />
and buttons1,x<br />
sta pressed_buttons1,x<br />
</pre><br />
<br />
=== Button Flags ===<br />
<br />
It is helpful to define the buttons as a series of bit flags:<br />
<pre><br />
BUTTON_A = 1 << 7<br />
BUTTON_B = 1 << 6<br />
BUTTON_SELECT = 1 << 5<br />
BUTTON_START = 1 << 4<br />
BUTTON_UP = 1 << 3<br />
BUTTON_DOWN = 1 << 2<br />
BUTTON_LEFT = 1 << 1<br />
BUTTON_RIGHT = 1 << 0<br />
</pre><br />
<br />
And then buttons can be checked as follows:<br />
<pre><br />
lda buttons<br />
and #BUTTON_A | BUTTON_B<br />
beq notPressingAorB<br />
; Handle presses.<br />
notPressingAorB:<br />
</pre><br />
<br />
== External Examples ==<br />
<br />
* [http://forums.nesdev.org/viewtopic.php?t=4124 Forum post:] Blargg's DMC-fortified controller read routine<br />
* [http://forums.nesdev.org/viewtopic.php?p=171971 Forum post:] Rahsennor's OAM-synchronized controller read<br />
* [http://forums.nesdev.org/viewtopic.php?f=2&t=14197 Forum post:] Drag's bitwise DMC-safe controller reading<br />
<br />
== References ==<br />
<references/></div>Rainwarriorhttps://www.nesdev.org/w/index.php?title=Controller_reading_code&diff=21482Controller reading code2024-01-11T00:40:12Z<p>Rainwarrior: /* Basic Example */ note that this second routine is safe for NES too</p>
<hr />
<div>This page contains example code for reading the [[NES controller]].<br />
<br />
See also: [[Controller reading]]<br />
<br />
=== Basic Example ===<br />
<br />
This describes an efficient method of reading the [[standard controller]] using [http://cc65.github.io/cc65/ ca65] syntax.<br />
<br />
The result byte ''buttons'' should be placed in zero page to save a cycle each time through the loop.<br />
<pre><br />
; we reserve one byte for storing the data that is read from controller<br />
.zeropage<br />
buttons .res 1<br />
</pre><br />
<br />
When reading from ''JOYPAD*'' what is read might be different from $01/$00 for various reasons. (See [[Controller reading]].) In this code the only concern is bit 0 read from ''JOYPAD*.''.<br />
<pre><br />
JOYPAD1 = $4016<br />
JOYPAD2 = $4017<br />
</pre><br />
<br />
This is the end result that will be stored in ''buttons''. '''1''' if the button was pressed, '''0''' otherwise.<br />
<br />
{| class="wikitable" style="text-align:center;"<br />
|-<br />
! bit<br />
| &nbsp;&nbsp;&nbsp;&nbsp;7&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;6&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;5&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;4&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;3&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;2&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;1&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;&nbsp;<br />
|-<br />
! button<br />
| A<br />
| B<br />
| Select<br />
| Start<br />
| Up<br />
| Down<br />
| Left<br />
| Right<br />
|}<br />
<br />
This subroutine takes 132 cycles to execute but ignores the Famicom expansion controller.<br />
Many controller reading subroutines use the X or Y register to count 8 times through the loop.<br />
But this one uses a more clever [[wikipedia:Ring counter|ring counter]] technique: $01 is loaded into the result first, and once eight bits are shifted in, the 1 bit will be shifted out, terminating the loop.<br />
<pre><br />
; At the same time that we strobe bit 0, we initialize the ring counter<br />
; so we're hitting two birds with one stone here<br />
readjoy:<br />
lda #$01<br />
; While the strobe bit is set, buttons will be continuously reloaded.<br />
; This means that reading from JOYPAD1 will only return the state of the<br />
; first button: button A.<br />
sta JOYPAD1<br />
sta buttons<br />
lsr a ; now A is 0<br />
; By storing 0 into JOYPAD1, the strobe bit is cleared and the reloading stops.<br />
; This allows all 8 buttons (newly reloaded) to be read from JOYPAD1.<br />
sta JOYPAD1<br />
loop:<br />
lda JOYPAD1<br />
lsr a ; bit 0 -> Carry<br />
rol buttons ; Carry -> bit 0; bit 7 -> Carry<br />
bcc loop<br />
rts<br />
</pre><br />
<br />
Adding support for controllers on the Famicom's DA15 expansion port and for player 2's controller is straightforward. Something similar to the following routine is used in most Famicom games.<br />
Even though the expansion port is unused on the NES, the expansion port bit will always read as 0, so this solution works safely with both Famicom and NES hardware.<br />
<pre><br />
.zeropage<br />
buttons: .res 2 ; space for 2 reads<br />
<br />
.code<br />
readjoyx: ; X register = 0 for controller 1, 1 for controller 2<br />
lda #$01<br />
sta JOYPAD1<br />
sta buttons, X<br />
lsr a<br />
sta JOYPAD1<br />
loop:<br />
lda JOYPAD1, X<br />
and #%00000011 ; ignore bits other than controller<br />
cmp #$01 ; Set carry if and only if nonzero<br />
rol buttons, X ; Carry -> bit 0; but 7 -> Carry<br />
bcc loop<br />
rts<br />
</pre><br />
<br />
Alternatively, we could combine both controller reads into 1 loop with a single strobe, though this routine is not safe to use with DPCM samples playing (see below).<br />
<pre><br />
.zeropage<br />
buttons: .res 2<br />
<br />
.code<br />
readjoy2:<br />
lda #$01<br />
sta JOYPAD1<br />
sta buttons+1 ; player 2's buttons double as a ring counter<br />
lsr a<br />
sta JOYPAD1<br />
loop:<br />
lda JOYPAD1<br />
and #%00000011<br />
cmp #$01<br />
rol buttons+9<br />
lda JOYPAD2<br />
and #%00000011<br />
cmp #$01<br />
rol buttons+1<br />
bcc loop<br />
rts<br />
</pre><br />
<br />
=== DPCM Safety using Repeated Reads ===<br />
<br />
If your code is intended to be used with [[APU DMC]] playback, this code will need to be altered. The NES occasionally glitches the controller port twice in a row if sample playback is enabled, and games using samples need to work around this. For example, ''Super Mario Bros. 3'' reads each controller's data at least two times each frame. First it reads it as normal, then it reads it again. If the two results differ, it does the procedure all over.<br />
<br />
One controller example:<ref>[//forums.nesdev.org/viewtopic.php?p=151720#p151720 Super Mario Bros. 3 controller reread method]</ref><br />
<pre><br />
readjoy_safe:<br />
jsr readjoy<br />
reread:<br />
lda buttons<br />
pha<br />
jsr readjoy<br />
pla<br />
cmp buttons<br />
bne reread<br />
rts<br />
</pre><br />
<br />
Note that the time between the start of one read and the end of the next read must be less than the length of the fastest DMC fetch period (432 cycles). For this reason, it is normal to read controllers one at a time with this method, rather than attempting both at once. (Note: <code>readjoy2</code> above takes too long to be suitable.) [[Game bugs|''Gimmick!'' has such a bug]] resulting from trying to read both at once.<br />
<br />
=== DPCM Safety using OAM DMA ===<br />
<br />
Because halts for DPCM fetches normally only occur on an put cycles, it is possible to get glitch-free controller reads by timing all '''$4016''' and '''$4017''' reads to fall on get cycles. This is made possible by the behavior of OAM DMA: the first cycle after an OAM DMA is normally guaranteed to be a get cycle.<ref>[http://forums.nesdev.org/viewtopic.php?p=171971 Forum post:] Rahsennor's OAM-synchronized controller read</ref> This is a relatively new technique and is not supported by some emulators.<ref>[http://forums.nesdev.org/viewtopic.php?f=2&t=14319&start=15#p172099 Forum post:] as of May 2016, Nintendulator and Nestopia do not accurately emulate OAM-synchronized controller reading.</ref> In the following example code, the controller1 and controller2 labels must be in zeropage for the timing to work.<br />
<br />
<pre><br />
lda #OAM<br />
sta $4014 ; ------ OAM DMA ------<br />
ldx #1 ; get put <- strobe code must take an odd number of cycles total<br />
stx controller1 ; get put get <- controller1 and controller2 must be in the zeropage<br />
stx $4016 ; put get put get<br />
dex ; put get<br />
stx $4016 ; put get put get<br />
read_loop:<br />
lda $4017 ; put get put GET <- loop code must take an even number of cycles total<br />
and #3 ; put get<br />
cmp #1 ; put get<br />
rol controller2, x ; put get put get put get (X = 0; waste 1 cycle and 0 bytes for alignment)<br />
lda $4016 ; put get put GET<br />
and #3 ; put get<br />
cmp #1 ; put get<br />
rol controller1 ; put get put get put<br />
bcc read_loop ; get put [get] <- this branch must not be allowed to cross a page<br />
</pre><br />
<br />
Note that this example routine only reads two 8-bit controllers and does not take enough time to span more than one DPCM fetch. Routines longer than this must contend with two additional constraints:<br />
* When DMC DMA is delayed by an odd number of cycles, it takes 3 cycles instead of 4, changing the cycle parity. If extending this function to read more bits, care must be taken so that ''all'' CPU write cycles are aligned. Instructions with a single write cycle must align the write to avoid conflict with the DPCM fetch, and double-write instructions like ROL need to align both writes so that the DPCM fetch falls on the first write.<ref>[//forums.nesdev.org/viewtopic.php?p=231604#p231604 Forum post:] demonstration of how ROL instruction affects alignment for OAM DMA synchronized controller reading.</ref> If an interrupt can occur during the routine, it must be aligned so the fetch can only fall on the second of the three automatic stack writes.<br />
* When DMC DMA occurs near the end of OAM DMA, it only steals 1 or 3 cycles, inverting the cycle parity. Every DMC period after that, a misaligned DPCM fetch will occur. Care must be taken to ensure this does not land on a joypad read.<br />
<br />
See [[DMA]] for detailed information on DMA timing.<br />
<br />
=== Directional Safety ===<br />
<br />
To reject opposing presses (Up+Down and Left+Right), which are possible on a worn Control Pad:<br />
<pre><br />
lda buttons1,x<br />
and #%00001010 ; Compare Up and Left...<br />
lsr a<br />
and buttons1,x ; to Down and Right<br />
beq not_updown<br />
; Use previous frame's directions<br />
lda buttons1,x<br />
eor last_frame_buttons1,x<br />
and #%11110000<br />
eor last_frame_buttons1,x<br />
sta buttons1,x<br />
not_updown:<br />
</pre><br />
<br />
To instead reject all diagonal presses, simulating a 4-way joystick:<br />
<pre><br />
lda buttons1,x<br />
and #%00001111 ; If A & (A - 1) is nonzero, A has more than one bit set<br />
beq not_diagonal<br />
sec<br />
sbc #1<br />
and buttons1,x<br />
beq not_diagonal<br />
; Use previous frame's directions<br />
lda buttons1,x<br />
eor last_frame_buttons1,x<br />
and #%11110000<br />
eor last_frame_buttons1,x<br />
sta buttons1,x<br />
not_diagonal:<br />
</pre><br />
<br />
=== Calculating Presses and Releases ===<br />
<br />
To calculate newly pressed and newly released buttons:<br />
<pre><br />
lda buttons1,x<br />
eor #%11111111<br />
and last_frame_buttons1,x<br />
sta released_buttons1,x<br />
lda last_frame_buttons1,x<br />
eor #%11111111<br />
and buttons1,x<br />
sta pressed_buttons1,x<br />
</pre><br />
<br />
=== Button Flags ===<br />
<br />
It is helpful to define the buttons as a series of bit flags:<br />
<pre><br />
BUTTON_A = 1 << 7<br />
BUTTON_B = 1 << 6<br />
BUTTON_SELECT = 1 << 5<br />
BUTTON_START = 1 << 4<br />
BUTTON_UP = 1 << 3<br />
BUTTON_DOWN = 1 << 2<br />
BUTTON_LEFT = 1 << 1<br />
BUTTON_RIGHT = 1 << 0<br />
</pre><br />
<br />
And then buttons can be checked as follows:<br />
<pre><br />
lda buttons<br />
and #BUTTON_A | BUTTON_B<br />
beq notPressingAorB<br />
; Handle presses.<br />
notPressingAorB:<br />
</pre><br />
<br />
== External Examples ==<br />
<br />
* [http://forums.nesdev.org/viewtopic.php?t=4124 Forum post:] Blargg's DMC-fortified controller read routine<br />
* [http://forums.nesdev.org/viewtopic.php?p=171971 Forum post:] Rahsennor's OAM-synchronized controller read<br />
* [http://forums.nesdev.org/viewtopic.php?f=2&t=14197 Forum post:] Drag's bitwise DMC-safe controller reading<br />
<br />
== References ==<br />
<references/></div>Rainwarriorhttps://www.nesdev.org/w/index.php?title=Controller_reading_code&diff=21481Controller reading code2024-01-11T00:37:38Z<p>Rainwarrior: /* Basic Example */ create a more standard example to read one controller at a time via index</p>
<hr />
<div>This page contains example code for reading the [[NES controller]].<br />
<br />
See also: [[Controller reading]]<br />
<br />
=== Basic Example ===<br />
<br />
This describes an efficient method of reading the [[standard controller]] using [http://cc65.github.io/cc65/ ca65] syntax.<br />
<br />
The result byte ''buttons'' should be placed in zero page to save a cycle each time through the loop.<br />
<pre><br />
; we reserve one byte for storing the data that is read from controller<br />
.zeropage<br />
buttons .res 1<br />
</pre><br />
<br />
When reading from ''JOYPAD*'' what is read might be different from $01/$00 for various reasons. (See [[Controller reading]].) In this code the only concern is bit 0 read from ''JOYPAD*.''.<br />
<pre><br />
JOYPAD1 = $4016<br />
JOYPAD2 = $4017<br />
</pre><br />
<br />
This is the end result that will be stored in ''buttons''. '''1''' if the button was pressed, '''0''' otherwise.<br />
<br />
{| class="wikitable" style="text-align:center;"<br />
|-<br />
! bit<br />
| &nbsp;&nbsp;&nbsp;&nbsp;7&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;6&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;5&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;4&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;3&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;2&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;1&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;&nbsp;<br />
|-<br />
! button<br />
| A<br />
| B<br />
| Select<br />
| Start<br />
| Up<br />
| Down<br />
| Left<br />
| Right<br />
|}<br />
<br />
This subroutine takes 132 cycles to execute but ignores the Famicom expansion controller.<br />
Many controller reading subroutines use the X or Y register to count 8 times through the loop.<br />
But this one uses a more clever [[wikipedia:Ring counter|ring counter]] technique: $01 is loaded into the result first, and once eight bits are shifted in, the 1 bit will be shifted out, terminating the loop.<br />
<pre><br />
; At the same time that we strobe bit 0, we initialize the ring counter<br />
; so we're hitting two birds with one stone here<br />
readjoy:<br />
lda #$01<br />
; While the strobe bit is set, buttons will be continuously reloaded.<br />
; This means that reading from JOYPAD1 will only return the state of the<br />
; first button: button A.<br />
sta JOYPAD1<br />
sta buttons<br />
lsr a ; now A is 0<br />
; By storing 0 into JOYPAD1, the strobe bit is cleared and the reloading stops.<br />
; This allows all 8 buttons (newly reloaded) to be read from JOYPAD1.<br />
sta JOYPAD1<br />
loop:<br />
lda JOYPAD1<br />
lsr a ; bit 0 -> Carry<br />
rol buttons ; Carry -> bit 0; bit 7 -> Carry<br />
bcc loop<br />
rts<br />
</pre><br />
<br />
Adding support for controllers on the Famicom's DA15 expansion port and for player 2's controller is straightforward.<br />
<pre><br />
.zeropage<br />
buttons: .res 2 ; space for 2 reads<br />
<br />
.code<br />
readjoyx: ; X register = 0 for controller 1, 1 for controller 2<br />
lda #$01<br />
sta JOYPAD1<br />
sta buttons, X<br />
lsr a<br />
sta JOYPAD1<br />
loop:<br />
lda JOYPAD1, X<br />
and #%00000011 ; ignore bits other than controller<br />
cmp #$01 ; Set carry if and only if nonzero<br />
rol buttons, X ; Carry -> bit 0; but 7 -> Carry<br />
bcc loop<br />
rts<br />
</pre><br />
<br />
Alternatively, we could combine both controller reads into 1 loop with a single strobe, though this routine is not safe to use with DPCM samples playing (see below).<br />
<pre><br />
.zeropage<br />
buttons: .res 2<br />
<br />
.code<br />
readjoy2:<br />
lda #$01<br />
sta JOYPAD1<br />
sta buttons+1 ; player 2's buttons double as a ring counter<br />
lsr a<br />
sta JOYPAD1<br />
loop:<br />
lda JOYPAD1<br />
and #%00000011<br />
cmp #$01<br />
rol buttons+9<br />
lda JOYPAD2<br />
and #%00000011<br />
cmp #$01<br />
rol buttons+1<br />
bcc loop<br />
rts<br />
</pre><br />
<br />
=== DPCM Safety using Repeated Reads ===<br />
<br />
If your code is intended to be used with [[APU DMC]] playback, this code will need to be altered. The NES occasionally glitches the controller port twice in a row if sample playback is enabled, and games using samples need to work around this. For example, ''Super Mario Bros. 3'' reads each controller's data at least two times each frame. First it reads it as normal, then it reads it again. If the two results differ, it does the procedure all over.<br />
<br />
One controller example:<ref>[//forums.nesdev.org/viewtopic.php?p=151720#p151720 Super Mario Bros. 3 controller reread method]</ref><br />
<pre><br />
readjoy_safe:<br />
jsr readjoy<br />
reread:<br />
lda buttons<br />
pha<br />
jsr readjoy<br />
pla<br />
cmp buttons<br />
bne reread<br />
rts<br />
</pre><br />
<br />
Note that the time between the start of one read and the end of the next read must be less than the length of the fastest DMC fetch period (432 cycles). For this reason, it is normal to read controllers one at a time with this method, rather than attempting both at once. (Note: <code>readjoy2</code> above takes too long to be suitable.) [[Game bugs|''Gimmick!'' has such a bug]] resulting from trying to read both at once.<br />
<br />
=== DPCM Safety using OAM DMA ===<br />
<br />
Because halts for DPCM fetches normally only occur on an put cycles, it is possible to get glitch-free controller reads by timing all '''$4016''' and '''$4017''' reads to fall on get cycles. This is made possible by the behavior of OAM DMA: the first cycle after an OAM DMA is normally guaranteed to be a get cycle.<ref>[http://forums.nesdev.org/viewtopic.php?p=171971 Forum post:] Rahsennor's OAM-synchronized controller read</ref> This is a relatively new technique and is not supported by some emulators.<ref>[http://forums.nesdev.org/viewtopic.php?f=2&t=14319&start=15#p172099 Forum post:] as of May 2016, Nintendulator and Nestopia do not accurately emulate OAM-synchronized controller reading.</ref> In the following example code, the controller1 and controller2 labels must be in zeropage for the timing to work.<br />
<br />
<pre><br />
lda #OAM<br />
sta $4014 ; ------ OAM DMA ------<br />
ldx #1 ; get put <- strobe code must take an odd number of cycles total<br />
stx controller1 ; get put get <- controller1 and controller2 must be in the zeropage<br />
stx $4016 ; put get put get<br />
dex ; put get<br />
stx $4016 ; put get put get<br />
read_loop:<br />
lda $4017 ; put get put GET <- loop code must take an even number of cycles total<br />
and #3 ; put get<br />
cmp #1 ; put get<br />
rol controller2, x ; put get put get put get (X = 0; waste 1 cycle and 0 bytes for alignment)<br />
lda $4016 ; put get put GET<br />
and #3 ; put get<br />
cmp #1 ; put get<br />
rol controller1 ; put get put get put<br />
bcc read_loop ; get put [get] <- this branch must not be allowed to cross a page<br />
</pre><br />
<br />
Note that this example routine only reads two 8-bit controllers and does not take enough time to span more than one DPCM fetch. Routines longer than this must contend with two additional constraints:<br />
* When DMC DMA is delayed by an odd number of cycles, it takes 3 cycles instead of 4, changing the cycle parity. If extending this function to read more bits, care must be taken so that ''all'' CPU write cycles are aligned. Instructions with a single write cycle must align the write to avoid conflict with the DPCM fetch, and double-write instructions like ROL need to align both writes so that the DPCM fetch falls on the first write.<ref>[//forums.nesdev.org/viewtopic.php?p=231604#p231604 Forum post:] demonstration of how ROL instruction affects alignment for OAM DMA synchronized controller reading.</ref> If an interrupt can occur during the routine, it must be aligned so the fetch can only fall on the second of the three automatic stack writes.<br />
* When DMC DMA occurs near the end of OAM DMA, it only steals 1 or 3 cycles, inverting the cycle parity. Every DMC period after that, a misaligned DPCM fetch will occur. Care must be taken to ensure this does not land on a joypad read.<br />
<br />
See [[DMA]] for detailed information on DMA timing.<br />
<br />
=== Directional Safety ===<br />
<br />
To reject opposing presses (Up+Down and Left+Right), which are possible on a worn Control Pad:<br />
<pre><br />
lda buttons1,x<br />
and #%00001010 ; Compare Up and Left...<br />
lsr a<br />
and buttons1,x ; to Down and Right<br />
beq not_updown<br />
; Use previous frame's directions<br />
lda buttons1,x<br />
eor last_frame_buttons1,x<br />
and #%11110000<br />
eor last_frame_buttons1,x<br />
sta buttons1,x<br />
not_updown:<br />
</pre><br />
<br />
To instead reject all diagonal presses, simulating a 4-way joystick:<br />
<pre><br />
lda buttons1,x<br />
and #%00001111 ; If A & (A - 1) is nonzero, A has more than one bit set<br />
beq not_diagonal<br />
sec<br />
sbc #1<br />
and buttons1,x<br />
beq not_diagonal<br />
; Use previous frame's directions<br />
lda buttons1,x<br />
eor last_frame_buttons1,x<br />
and #%11110000<br />
eor last_frame_buttons1,x<br />
sta buttons1,x<br />
not_diagonal:<br />
</pre><br />
<br />
=== Calculating Presses and Releases ===<br />
<br />
To calculate newly pressed and newly released buttons:<br />
<pre><br />
lda buttons1,x<br />
eor #%11111111<br />
and last_frame_buttons1,x<br />
sta released_buttons1,x<br />
lda last_frame_buttons1,x<br />
eor #%11111111<br />
and buttons1,x<br />
sta pressed_buttons1,x<br />
</pre><br />
<br />
=== Button Flags ===<br />
<br />
It is helpful to define the buttons as a series of bit flags:<br />
<pre><br />
BUTTON_A = 1 << 7<br />
BUTTON_B = 1 << 6<br />
BUTTON_SELECT = 1 << 5<br />
BUTTON_START = 1 << 4<br />
BUTTON_UP = 1 << 3<br />
BUTTON_DOWN = 1 << 2<br />
BUTTON_LEFT = 1 << 1<br />
BUTTON_RIGHT = 1 << 0<br />
</pre><br />
<br />
And then buttons can be checked as follows:<br />
<pre><br />
lda buttons<br />
and #BUTTON_A | BUTTON_B<br />
beq notPressingAorB<br />
; Handle presses.<br />
notPressingAorB:<br />
</pre><br />
<br />
== External Examples ==<br />
<br />
* [http://forums.nesdev.org/viewtopic.php?t=4124 Forum post:] Blargg's DMC-fortified controller read routine<br />
* [http://forums.nesdev.org/viewtopic.php?p=171971 Forum post:] Rahsennor's OAM-synchronized controller read<br />
* [http://forums.nesdev.org/viewtopic.php?f=2&t=14197 Forum post:] Drag's bitwise DMC-safe controller reading<br />
<br />
== References ==<br />
<references/></div>Rainwarriorhttps://www.nesdev.org/w/index.php?title=Talk:Controller_reading_code&diff=21480Talk:Controller reading code2024-01-11T00:27:50Z<p>Rainwarrior: /* Removed last-frame compromise */ follow-up, it was determined unsafe against DPCM in 2023</p>
<hr />
<div>== Reorganization needed with [[Standard controller]] ==<br />
<br />
See: [[Talk:Standard_controller#Reorganization_needed_with_Controller_Reading]]<br />
<br />
== Removed last-frame compromise ==<br />
<br />
This code appeared in the [[Controller Reading#DPCM Safety using Repeated Reads|DPCM Safety using Repeated Reads]] section.<br />
I have removed it, because I think it hurts comprehension for new readers who may not understand<br />
what they are trading away to save a few cycles they may not need.<br />
There's probably a place for this code somewhere, but I don't think it belongs in the middle of the article,<br />
and certainly not in lieu of a simpler and more standard example.<br />
<br />
I left a description of the technique, but not the code. - [[User:Rainwarrior|Rainwarrior]] ([[User talk:Rainwarrior|talk]]) 13:14, 16 April 2019 (MDT)<br />
<br />
Code:<br />
<pre><br />
last_frame_buttons1 = $00<br />
last_frame_buttons2 = $01<br />
first_read_buttons1 = $02<br />
first_read_buttons2 = $03<br />
<br />
readjoy_safe:<br />
lda buttons2<br />
sta last_frame_buttons2<br />
lda buttons1<br />
sta last_frame_buttons1<br />
<br />
; Read the controllers once and stash the result<br />
jsr readjoy<br />
lda buttons2<br />
sta first_read_buttons2<br />
lda buttons1<br />
sta first_read_buttons1<br />
<br />
; Read the controllers again and compare<br />
jsr readjoy<br />
ldx #1<br />
cleanup_loop:<br />
; Ignore read values if a bit deletion occurred<br />
lda buttons1,x<br />
cmp first_read_buttons1,x<br />
beq not_glitched<br />
lda last_frame_buttons,x<br />
sta buttons1,x<br />
not_glitched:<br />
<br />
dex<br />
bpl cleanup_loop<br />
<br />
rts<br />
</pre><br />
<br />
:In november 2023 it was demonstrated that this is still subject to DPCM errors because the readjoy loop does not complete fast enough (allowing 2 matching corruptions of the same controller). So, aside from the compromise of 1 frame of lag, it wasn't completely DPCM error free either. Note that tepples has since replaced this code with the OAMDMA sync solution in his NROM template ([https://github.com/pinobatch/nrom-template/commit/5656fc285aaa92f34a9b56246362c145aeaef930 gitub: pinobatch/nrom-template changes]). So, perhaps this code may just be retired here for eternity. - [[User:Rainwarrior|Rainwarrior]] ([[User talk:Rainwarrior|talk]]) 00:27, 11 January 2024 (UTC)</div>Rainwarriorhttps://www.nesdev.org/w/index.php?title=Controller_reading_code&diff=21398Controller reading code2023-11-16T04:28:00Z<p>Rainwarrior: /* DPCM Safety using Repeated Reads */ note the timing restrictions, reference the gimmick bug as a cautionary example</p>
<hr />
<div>This page contains example code for reading the [[NES controller]].<br />
<br />
See also: [[Controller reading]]<br />
<br />
=== Basic Example ===<br />
<br />
This describes an efficient method of reading the [[standard controller]] using [http://cc65.github.io/cc65/ ca65] syntax.<br />
<br />
The result byte ''buttons'' should be placed in zero page to save a cycle each time through the loop.<br />
<pre><br />
; we reserve one byte for storing the data that is read from controller<br />
.zeropage<br />
buttons .res 1<br />
</pre><br />
<br />
When reading from ''JOYPAD*'' what is read might be different from $01/$00 for various reasons. (See [[Controller reading]].) In this code the only concern is bit 0 read from ''JOYPAD*.''.<br />
<pre><br />
JOYPAD1 = $4016<br />
JOYPAD2 = $4017<br />
</pre><br />
<br />
This is the end result that will be stored in ''buttons''. '''1''' if the button was pressed, '''0''' otherwise.<br />
<br />
{| class="wikitable" style="text-align:center;"<br />
|-<br />
! bit<br />
| &nbsp;&nbsp;&nbsp;&nbsp;7&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;6&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;5&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;4&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;3&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;2&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;1&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;&nbsp;<br />
|-<br />
! button<br />
| A<br />
| B<br />
| Select<br />
| Start<br />
| Up<br />
| Down<br />
| Left<br />
| Right<br />
|}<br />
<br />
This subroutine takes 132 cycles to execute but ignores the Famicom expansion controller.<br />
Many controller reading subroutines use the X or Y register to count 8 times through the loop.<br />
But this one uses a more clever [[wikipedia:Ring counter|ring counter]] technique: $01 is loaded into the result first, and once eight bits are shifted in, the 1 bit will be shifted out, terminating the loop.<br />
<pre><br />
; At the same time that we strobe bit 0, we initialize the ring counter<br />
; so we're hitting two birds with one stone here<br />
readjoy:<br />
lda #$01<br />
; While the strobe bit is set, buttons will be continuously reloaded.<br />
; This means that reading from JOYPAD1 will only return the state of the<br />
; first button: button A.<br />
sta JOYPAD1<br />
sta buttons<br />
lsr a ; now A is 0<br />
; By storing 0 into JOYPAD1, the strobe bit is cleared and the reloading stops.<br />
; This allows all 8 buttons (newly reloaded) to be read from JOYPAD1.<br />
sta JOYPAD1<br />
loop:<br />
lda JOYPAD1<br />
lsr a ; bit 0 -> Carry<br />
rol buttons ; Carry -> bit 0; bit 7 -> Carry<br />
bcc loop<br />
rts<br />
</pre><br />
<br />
Adding support for controllers on the Famicom's DA15 expansion port and for player 2's controller is straightforward.<br />
<pre><br />
.zeropage<br />
buttons1: .res 1<br />
buttons2: .res 1<br />
<br />
.code<br />
readjoy2:<br />
lda #$01<br />
sta JOYPAD1<br />
sta buttons2 ; player 2's buttons double as a ring counter<br />
lsr a ; now A is 0<br />
sta JOYPAD1<br />
loop:<br />
lda JOYPAD1<br />
and #%00000011 ; ignore bits other than controller<br />
cmp #$01 ; Set carry if and only if nonzero<br />
rol buttons1 ; Carry -> bit 0; bit 7 -> Carry<br />
lda JOYPAD2 ; Repeat<br />
and #%00000011<br />
cmp #$01<br />
rol buttons2 ; Carry -> bit 0; bit 7 -> Carry<br />
bcc loop<br />
rts<br />
</pre><br />
<br />
=== DPCM Safety using Repeated Reads ===<br />
<br />
If your code is intended to be used with [[APU DMC]] playback, this code will need to be altered. The NES occasionally glitches the controller port twice in a row if sample playback is enabled, and games using samples need to work around this. For example, ''Super Mario Bros. 3'' reads each controller's data at least two times each frame. First it reads it as normal, then it reads it again. If the two results differ, it does the procedure all over.<br />
<br />
One controller example:<ref>[//forums.nesdev.org/viewtopic.php?p=151720#p151720 Super Mario Bros. 3 controller reread method]</ref><br />
<pre><br />
readjoy_safe:<br />
jsr readjoy<br />
reread:<br />
lda buttons<br />
pha<br />
jsr readjoy<br />
pla<br />
cmp buttons<br />
bne reread<br />
rts<br />
</pre><br />
<br />
Note that the time between the start of one read and the end of the next read must be less than the length of the fastest DMC fetch period (432 cycles). For this reason, it is normal to read controllers one at a time with this method, rather than attempting both at once. (Note: <code>readjoy2</code> above takes too long to be suitable.) [[Game bugs|''Gimmick!'' has such a bug]] resulting from trying to read both at once.<br />
<br />
=== DPCM Safety using OAM DMA ===<br />
<br />
Because halts for DPCM fetches normally only occur on an put cycles, it is possible to get glitch-free controller reads by timing all '''$4016''' and '''$4017''' reads to fall on get cycles. This is made possible by the behavior of OAM DMA: the first cycle after an OAM DMA is normally guaranteed to be a get cycle.<ref>[http://forums.nesdev.org/viewtopic.php?p=171971 Forum post:] Rahsennor's OAM-synchronized controller read</ref> This is a relatively new technique and is not supported by some emulators.<ref>[http://forums.nesdev.org/viewtopic.php?f=2&t=14319&start=15#p172099 Forum post:] as of May 2016, Nintendulator and Nestopia do not accurately emulate OAM-synchronized controller reading.</ref> In the following example code, the controller1 and controller2 labels must be in zeropage for the timing to work.<br />
<br />
<pre><br />
lda #OAM<br />
sta $4014 ; ------ OAM DMA ------<br />
ldx #1 ; get put <- strobe code must take an odd number of cycles total<br />
stx controller1 ; get put get <- controller1 and controller2 must be in the zeropage<br />
stx $4016 ; put get put get<br />
dex ; put get<br />
stx $4016 ; put get put get<br />
read_loop:<br />
lda $4017 ; put get put GET <- loop code must take an even number of cycles total<br />
and #3 ; put get<br />
cmp #1 ; put get<br />
rol controller2, x ; put get put get put get (X = 0; waste 1 cycle and 0 bytes for alignment)<br />
lda $4016 ; put get put GET<br />
and #3 ; put get<br />
cmp #1 ; put get<br />
rol controller1 ; put get put get put<br />
bcc read_loop ; get put [get] <- this branch must not be allowed to cross a page<br />
</pre><br />
<br />
Note that this example routine only reads two 8-bit controllers and does not take enough time to span more than one DPCM fetch. Routines longer than this must contend with two additional constraints:<br />
* When DMC DMA is delayed by an odd number of cycles, it takes 3 cycles instead of 4, changing the cycle parity. If extending this function to read more bits, care must be taken so that ''all'' CPU write cycles are aligned. Instructions with a single write cycle must align the write to avoid conflict with the DPCM fetch, and double-write instructions like ROL need to align both writes so that the DPCM fetch falls on the first write.<ref>[//forums.nesdev.org/viewtopic.php?p=231604#p231604 Forum post:] demonstration of how ROL instruction affects alignment for OAM DMA synchronized controller reading.</ref> If an interrupt can occur during the routine, it must be aligned so the fetch can only fall on the second of the three automatic stack writes.<br />
* When DMC DMA occurs near the end of OAM DMA, it only steals 1 or 3 cycles, inverting the cycle parity. Every DMC period after that, a misaligned DPCM fetch will occur. Care must be taken to ensure this does not land on a joypad read.<br />
<br />
See [[DMA]] for detailed information on DMA timing.<br />
<br />
=== Directional Safety ===<br />
<br />
To reject opposing presses (Up+Down and Left+Right), which are possible on a worn Control Pad:<br />
<pre><br />
lda buttons1,x<br />
and #%00001010 ; Compare Up and Left...<br />
lsr a<br />
and buttons1,x ; to Down and Right<br />
beq not_updown<br />
; Use previous frame's directions<br />
lda buttons1,x<br />
eor last_frame_buttons1,x<br />
and #%11110000<br />
eor last_frame_buttons1,x<br />
sta buttons1,x<br />
not_updown:<br />
</pre><br />
<br />
To instead reject all diagonal presses, simulating a 4-way joystick:<br />
<pre><br />
lda buttons1,x<br />
and #%00001111 ; If A & (A - 1) is nonzero, A has more than one bit set<br />
beq not_diagonal<br />
sec<br />
sbc #1<br />
and buttons1,x<br />
beq not_diagonal<br />
; Use previous frame's directions<br />
lda buttons1,x<br />
eor last_frame_buttons1,x<br />
and #%11110000<br />
eor last_frame_buttons1,x<br />
sta buttons1,x<br />
not_diagonal:<br />
</pre><br />
<br />
=== Calculating Presses and Releases ===<br />
<br />
To calculate newly pressed and newly released buttons:<br />
<pre><br />
lda buttons1,x<br />
eor #%11111111<br />
and last_frame_buttons1,x<br />
sta released_buttons1,x<br />
lda last_frame_buttons1,x<br />
eor #%11111111<br />
and buttons1,x<br />
sta pressed_buttons1,x<br />
</pre><br />
<br />
=== Button Flags ===<br />
<br />
It is helpful to define the buttons as a series of bit flags:<br />
<pre><br />
BUTTON_A = 1 << 7<br />
BUTTON_B = 1 << 6<br />
BUTTON_SELECT = 1 << 5<br />
BUTTON_START = 1 << 4<br />
BUTTON_UP = 1 << 3<br />
BUTTON_DOWN = 1 << 2<br />
BUTTON_LEFT = 1 << 1<br />
BUTTON_RIGHT = 1 << 0<br />
</pre><br />
<br />
And then buttons can be checked as follows:<br />
<pre><br />
lda buttons<br />
and #BUTTON_A | BUTTON_B<br />
beq notPressingAorB<br />
; Handle presses.<br />
notPressingAorB:<br />
</pre><br />
<br />
== External Examples ==<br />
<br />
* [http://forums.nesdev.org/viewtopic.php?t=4124 Forum post:] Blargg's DMC-fortified controller read routine<br />
* [http://forums.nesdev.org/viewtopic.php?p=171971 Forum post:] Rahsennor's OAM-synchronized controller read<br />
* [http://forums.nesdev.org/viewtopic.php?f=2&t=14197 Forum post:] Drag's bitwise DMC-safe controller reading<br />
<br />
== References ==<br />
<references/></div>Rainwarriorhttps://www.nesdev.org/w/index.php?title=Controller_reading_code&diff=21397Controller reading code2023-11-16T04:21:16Z<p>Rainwarrior: /* Basic Example */ readjoy is referred to below and having two non-equivalent functions with the same name makes this confusing, renaming the double read to readjoy2</p>
<hr />
<div>This page contains example code for reading the [[NES controller]].<br />
<br />
See also: [[Controller reading]]<br />
<br />
=== Basic Example ===<br />
<br />
This describes an efficient method of reading the [[standard controller]] using [http://cc65.github.io/cc65/ ca65] syntax.<br />
<br />
The result byte ''buttons'' should be placed in zero page to save a cycle each time through the loop.<br />
<pre><br />
; we reserve one byte for storing the data that is read from controller<br />
.zeropage<br />
buttons .res 1<br />
</pre><br />
<br />
When reading from ''JOYPAD*'' what is read might be different from $01/$00 for various reasons. (See [[Controller reading]].) In this code the only concern is bit 0 read from ''JOYPAD*.''.<br />
<pre><br />
JOYPAD1 = $4016<br />
JOYPAD2 = $4017<br />
</pre><br />
<br />
This is the end result that will be stored in ''buttons''. '''1''' if the button was pressed, '''0''' otherwise.<br />
<br />
{| class="wikitable" style="text-align:center;"<br />
|-<br />
! bit<br />
| &nbsp;&nbsp;&nbsp;&nbsp;7&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;6&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;5&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;4&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;3&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;2&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;1&nbsp;&nbsp;&nbsp;&nbsp;<br />
| &nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;&nbsp;<br />
|-<br />
! button<br />
| A<br />
| B<br />
| Select<br />
| Start<br />
| Up<br />
| Down<br />
| Left<br />
| Right<br />
|}<br />
<br />
This subroutine takes 132 cycles to execute but ignores the Famicom expansion controller.<br />
Many controller reading subroutines use the X or Y register to count 8 times through the loop.<br />
But this one uses a more clever [[wikipedia:Ring counter|ring counter]] technique: $01 is loaded into the result first, and once eight bits are shifted in, the 1 bit will be shifted out, terminating the loop.<br />
<pre><br />
; At the same time that we strobe bit 0, we initialize the ring counter<br />
; so we're hitting two birds with one stone here<br />
readjoy:<br />
lda #$01<br />
; While the strobe bit is set, buttons will be continuously reloaded.<br />
; This means that reading from JOYPAD1 will only return the state of the<br />
; first button: button A.<br />
sta JOYPAD1<br />
sta buttons<br />
lsr a ; now A is 0<br />
; By storing 0 into JOYPAD1, the strobe bit is cleared and the reloading stops.<br />
; This allows all 8 buttons (newly reloaded) to be read from JOYPAD1.<br />
sta JOYPAD1<br />
loop:<br />
lda JOYPAD1<br />
lsr a ; bit 0 -> Carry<br />
rol buttons ; Carry -> bit 0; bit 7 -> Carry<br />
bcc loop<br />
rts<br />
</pre><br />
<br />
Adding support for controllers on the Famicom's DA15 expansion port and for player 2's controller is straightforward.<br />
<pre><br />
.zeropage<br />
buttons1: .res 1<br />
buttons2: .res 1<br />
<br />
.code<br />
readjoy2:<br />
lda #$01<br />
sta JOYPAD1<br />
sta buttons2 ; player 2's buttons double as a ring counter<br />
lsr a ; now A is 0<br />
sta JOYPAD1<br />
loop:<br />
lda JOYPAD1<br />
and #%00000011 ; ignore bits other than controller<br />
cmp #$01 ; Set carry if and only if nonzero<br />
rol buttons1 ; Carry -> bit 0; bit 7 -> Carry<br />
lda JOYPAD2 ; Repeat<br />
and #%00000011<br />
cmp #$01<br />
rol buttons2 ; Carry -> bit 0; bit 7 -> Carry<br />
bcc loop<br />
rts<br />
</pre><br />
<br />
=== DPCM Safety using Repeated Reads ===<br />
<br />
If your code is intended to be used with [[APU DMC]] playback, this code will need to be altered. The NES occasionally glitches the controller port twice in a row if sample playback is enabled, and games using samples need to work around this. For example, ''Super Mario Bros. 3'' reads each controller's data at least two times each frame. First it reads it as normal, then it reads it again. If the two results differ, it does the procedure all over.<br />
<br />
One controller example:<ref>[//forums.nesdev.org/viewtopic.php?p=151720#p151720 Super Mario Bros. 3 controller reread method]</ref><br />
<pre><br />
readjoy_safe:<br />
jsr readjoy<br />
reread:<br />
lda buttons<br />
pha<br />
jsr readjoy<br />
pla<br />
cmp buttons<br />
bne reread<br />
rts<br />
</pre><br />
<br />
=== DPCM Safety using OAM DMA ===<br />
<br />
Because halts for DPCM fetches normally only occur on an put cycles, it is possible to get glitch-free controller reads by timing all '''$4016''' and '''$4017''' reads to fall on get cycles. This is made possible by the behavior of OAM DMA: the first cycle after an OAM DMA is normally guaranteed to be a get cycle.<ref>[http://forums.nesdev.org/viewtopic.php?p=171971 Forum post:] Rahsennor's OAM-synchronized controller read</ref> This is a relatively new technique and is not supported by some emulators.<ref>[http://forums.nesdev.org/viewtopic.php?f=2&t=14319&start=15#p172099 Forum post:] as of May 2016, Nintendulator and Nestopia do not accurately emulate OAM-synchronized controller reading.</ref> In the following example code, the controller1 and controller2 labels must be in zeropage for the timing to work.<br />
<br />
<pre><br />
lda #OAM<br />
sta $4014 ; ------ OAM DMA ------<br />
ldx #1 ; get put <- strobe code must take an odd number of cycles total<br />
stx controller1 ; get put get <- controller1 and controller2 must be in the zeropage<br />
stx $4016 ; put get put get<br />
dex ; put get<br />
stx $4016 ; put get put get<br />
read_loop:<br />
lda $4017 ; put get put GET <- loop code must take an even number of cycles total<br />
and #3 ; put get<br />
cmp #1 ; put get<br />
rol controller2, x ; put get put get put get (X = 0; waste 1 cycle and 0 bytes for alignment)<br />
lda $4016 ; put get put GET<br />
and #3 ; put get<br />
cmp #1 ; put get<br />
rol controller1 ; put get put get put<br />
bcc read_loop ; get put [get] <- this branch must not be allowed to cross a page<br />
</pre><br />
<br />
Note that this example routine only reads two 8-bit controllers and does not take enough time to span more than one DPCM fetch. Routines longer than this must contend with two additional constraints:<br />
* When DMC DMA is delayed by an odd number of cycles, it takes 3 cycles instead of 4, changing the cycle parity. If extending this function to read more bits, care must be taken so that ''all'' CPU write cycles are aligned. Instructions with a single write cycle must align the write to avoid conflict with the DPCM fetch, and double-write instructions like ROL need to align both writes so that the DPCM fetch falls on the first write.<ref>[//forums.nesdev.org/viewtopic.php?p=231604#p231604 Forum post:] demonstration of how ROL instruction affects alignment for OAM DMA synchronized controller reading.</ref> If an interrupt can occur during the routine, it must be aligned so the fetch can only fall on the second of the three automatic stack writes.<br />
* When DMC DMA occurs near the end of OAM DMA, it only steals 1 or 3 cycles, inverting the cycle parity. Every DMC period after that, a misaligned DPCM fetch will occur. Care must be taken to ensure this does not land on a joypad read.<br />
<br />
See [[DMA]] for detailed information on DMA timing.<br />
<br />
=== Directional Safety ===<br />
<br />
To reject opposing presses (Up+Down and Left+Right), which are possible on a worn Control Pad:<br />
<pre><br />
lda buttons1,x<br />
and #%00001010 ; Compare Up and Left...<br />
lsr a<br />
and buttons1,x ; to Down and Right<br />
beq not_updown<br />
; Use previous frame's directions<br />
lda buttons1,x<br />
eor last_frame_buttons1,x<br />
and #%11110000<br />
eor last_frame_buttons1,x<br />
sta buttons1,x<br />
not_updown:<br />
</pre><br />
<br />
To instead reject all diagonal presses, simulating a 4-way joystick:<br />
<pre><br />
lda buttons1,x<br />
and #%00001111 ; If A & (A - 1) is nonzero, A has more than one bit set<br />
beq not_diagonal<br />
sec<br />
sbc #1<br />
and buttons1,x<br />
beq not_diagonal<br />
; Use previous frame's directions<br />
lda buttons1,x<br />
eor last_frame_buttons1,x<br />
and #%11110000<br />
eor last_frame_buttons1,x<br />
sta buttons1,x<br />
not_diagonal:<br />
</pre><br />
<br />
=== Calculating Presses and Releases ===<br />
<br />
To calculate newly pressed and newly released buttons:<br />
<pre><br />
lda buttons1,x<br />
eor #%11111111<br />
and last_frame_buttons1,x<br />
sta released_buttons1,x<br />
lda last_frame_buttons1,x<br />
eor #%11111111<br />
and buttons1,x<br />
sta pressed_buttons1,x<br />
</pre><br />
<br />
=== Button Flags ===<br />
<br />
It is helpful to define the buttons as a series of bit flags:<br />
<pre><br />
BUTTON_A = 1 << 7<br />
BUTTON_B = 1 << 6<br />
BUTTON_SELECT = 1 << 5<br />
BUTTON_START = 1 << 4<br />
BUTTON_UP = 1 << 3<br />
BUTTON_DOWN = 1 << 2<br />
BUTTON_LEFT = 1 << 1<br />
BUTTON_RIGHT = 1 << 0<br />
</pre><br />
<br />
And then buttons can be checked as follows:<br />
<pre><br />
lda buttons<br />
and #BUTTON_A | BUTTON_B<br />
beq notPressingAorB<br />
; Handle presses.<br />
notPressingAorB:<br />
</pre><br />
<br />
== External Examples ==<br />
<br />
* [http://forums.nesdev.org/viewtopic.php?t=4124 Forum post:] Blargg's DMC-fortified controller read routine<br />
* [http://forums.nesdev.org/viewtopic.php?p=171971 Forum post:] Rahsennor's OAM-synchronized controller read<br />
* [http://forums.nesdev.org/viewtopic.php?f=2&t=14197 Forum post:] Drag's bitwise DMC-safe controller reading<br />
<br />
== References ==<br />
<references/></div>Rainwarriorhttps://www.nesdev.org/w/index.php?title=CPU_memory_map&diff=21313CPU memory map2023-09-20T16:52:12Z<p>Rainwarrior: clarify that both WRAM and PRG-RAM are common terms for the memory at $6000</p>
<hr />
<div>{| class="tabular"<br />
! Address range || Size || Device<br />
|-<br />
| $0000–$07FF || $0800 || 2 KB internal RAM<br />
|-<br />
| $0800–$0FFF || $0800 ||rowspan=3| [[Mirroring#Memory Mirroring|Mirrors]] of $0000–$07FF<br />
|-<br />
| $1000–$17FF || $0800<br />
|-<br />
| $1800–$1FFF || $0800<br />
|-<br />
| $2000–$2007 || $0008 || [[PPU registers|NES PPU registers]]<br />
|-<br />
| $2008–$3FFF || $1FF8 || Mirrors of $2000–$2007 (repeats every 8 bytes)<br />
|-<br />
| $4000–$4017 || $0018 || [[APU|NES APU]] and [[2A03|I/O registers]]<br />
|-<br />
| $4018–$401F || $0008 || APU and I/O functionality that is normally disabled. See [[CPU Test Mode]].<br />
|-<br />
| $4020–$FFFF || $BFE0 || Cartridge space: PRG ROM, PRG RAM, and [[mapper]] registers<br />
|}<br />
<br />
* Some parts of the 2 KiB of internal RAM at $0000–$07FF have predefined purposes dictated by the 6502 architecture:<br />
** $0000-$00FF: The zero page, which can be accessed with fewer bytes and cycles than other addresses<br />
** $0100–$01FF: The page containing the stack, which can be located anywhere here, but typically starts at $01FF<br />
: Games may divide up the rest however the programmer deems useful. See [[Sample RAM map]] for an example allocation strategy for this RAM. Most commonly, $0200-$02FF is used for the OAM buffer to be copied to PPU OAM during vblank.<br />
<br />
* The cartridge space at $4020-$FFFF can be used by cartridges for any purpose, such as ROM, RAM, and registers. Many common mappers place ROM and save/work RAM in these locations:<br />
** $6000–$7FFF: Battery-backed save or work RAM (usually referred to as WRAM or PRG-RAM)<br />
** $8000–$FFFF: ROM and mapper registers (see [[MMC1]] and [[UxROM]] for examples)<br />
: The cartridge is able to passively observe reads from and writes to any address in the CPU address space, even outside this cartridge space, except for reads from $4015, the only readable register that is internal to the CPU. The cartridge can map writable registers anywhere, but its readable memory can only be placed where it does not interfere with other readable hardware, which would produce a [[bus conflict]]. While cartridges can map readable memory at $4000-$4014 and $4018-$401F, a quirk in the 2A03's register decoding can cause DMA to misbehave if the CPU is halted while reading from $4000-$401F, so it is recommended that cartridges only map readable memory from $4020-$FFFF.<br />
<br />
* If using [[APU DMC|DPCM playback]], samples are limited to the following practical range:<br />
** $C000–$FFF1: DPCM sample data<br />
: Sample playback wraps around from $FFFF to $8000. The highest sample starting address is $FFC0 and longest sample is $FF1 bytes, so the full DPCM range is $C000-$FFFF and $8000-$8FB0, but making use of the wraparound is challenging because of banking and the presence of the CPU vectors.<br />
<br />
* The CPU expects interrupt vectors in a fixed place at the end of the cartridge space:<br />
** $FFFA–$FFFB: NMI vector<br />
** $FFFC–$FFFD: Reset vector<br />
** $FFFE–$FFFF: IRQ/BRK vector<br />
: If a mapper doesn't fix $FFFA–$FFFF to some known bank (normally by fixing an entire bank-sized region at the top of the address space, such as $C000-$FFFF, to a specific bank) nor use some sort of reset detection, the vectors need to be stored in all banks.<br />
<br />
* Reading from memory that is not mapped to anything normally returns [[Open bus behavior|open bus]]. The cartridge hardware may affect open bus behavior across the entire CPU address space, such as by pulling bits high or low.</div>Rainwarriorhttps://www.nesdev.org/w/index.php?title=CPU_memory_map&diff=21312CPU memory map2023-09-20T16:38:59Z<p>Rainwarrior: list WRAM as common acronym for $6000 work RAM</p>
<hr />
<div>{| class="tabular"<br />
! Address range || Size || Device<br />
|-<br />
| $0000–$07FF || $0800 || 2 KB internal RAM<br />
|-<br />
| $0800–$0FFF || $0800 ||rowspan=3| [[Mirroring#Memory Mirroring|Mirrors]] of $0000–$07FF<br />
|-<br />
| $1000–$17FF || $0800<br />
|-<br />
| $1800–$1FFF || $0800<br />
|-<br />
| $2000–$2007 || $0008 || [[PPU registers|NES PPU registers]]<br />
|-<br />
| $2008–$3FFF || $1FF8 || Mirrors of $2000–$2007 (repeats every 8 bytes)<br />
|-<br />
| $4000–$4017 || $0018 || [[APU|NES APU]] and [[2A03|I/O registers]]<br />
|-<br />
| $4018–$401F || $0008 || APU and I/O functionality that is normally disabled. See [[CPU Test Mode]].<br />
|-<br />
| $4020–$FFFF || $BFE0 || Cartridge space: PRG ROM, PRG RAM, and [[mapper]] registers<br />
|}<br />
<br />
* Some parts of the 2 KiB of internal RAM at $0000–$07FF have predefined purposes dictated by the 6502 architecture:<br />
** $0000-$00FF: The zero page, which can be accessed with fewer bytes and cycles than other addresses<br />
** $0100–$01FF: The page containing the stack, which can be located anywhere here, but typically starts at $01FF<br />
: Games may divide up the rest however the programmer deems useful. See [[Sample RAM map]] for an example allocation strategy for this RAM. Most commonly, $0200-$02FF is used for the OAM buffer to be copied to PPU OAM during vblank.<br />
<br />
* The cartridge space at $4020-$FFFF can be used by cartridges for any purpose, such as ROM, RAM, and registers. Many common mappers place ROM and save/work RAM in these locations:<br />
** $6000–$7FFF: Battery-backed save or work RAM (WRAM)<br />
** $8000–$FFFF: ROM and mapper registers (see [[MMC1]] and [[UxROM]] for examples)<br />
: The cartridge is able to passively observe reads from and writes to any address in the CPU address space, even outside this cartridge space, except for reads from $4015, the only readable register that is internal to the CPU. The cartridge can map writable registers anywhere, but its readable memory can only be placed where it does not interfere with other readable hardware, which would produce a [[bus conflict]]. While cartridges can map readable memory at $4000-$4014 and $4018-$401F, a quirk in the 2A03's register decoding can cause DMA to misbehave if the CPU is halted while reading from $4000-$401F, so it is recommended that cartridges only map readable memory from $4020-$FFFF.<br />
<br />
* If using [[APU DMC|DPCM playback]], samples are limited to the following practical range:<br />
** $C000–$FFF1: DPCM sample data<br />
: Sample playback wraps around from $FFFF to $8000. The highest sample starting address is $FFC0 and longest sample is $FF1 bytes, so the full DPCM range is $C000-$FFFF and $8000-$8FB0, but making use of the wraparound is challenging because of banking and the presence of the CPU vectors.<br />
<br />
* The CPU expects interrupt vectors in a fixed place at the end of the cartridge space:<br />
** $FFFA–$FFFB: NMI vector<br />
** $FFFC–$FFFD: Reset vector<br />
** $FFFE–$FFFF: IRQ/BRK vector<br />
: If a mapper doesn't fix $FFFA–$FFFF to some known bank (normally by fixing an entire bank-sized region at the top of the address space, such as $C000-$FFFF, to a specific bank) nor use some sort of reset detection, the vectors need to be stored in all banks.<br />
<br />
* Reading from memory that is not mapped to anything normally returns [[Open bus behavior|open bus]]. The cartridge hardware may affect open bus behavior across the entire CPU address space, such as by pulling bits high or low.</div>Rainwarriorhttps://www.nesdev.org/w/index.php?title=Jump_table&diff=21231Jump table2023-08-16T06:40:40Z<p>Rainwarrior: /* Indirect jumping */ revise this "downsides" section as they are not really significant downsides, and it fails to mention that it's actually more efficient</p>
<hr />
<div>A jump table is a table of code addresses, meant to be indexed by a selector value. The program uses the selector to look up an address in the table, then jumps to that address.<br />
<br />
The alternative to a jump table is a long string of comparisons with each possible selector value. This approach is tedious to set up and slow in comparison to jump tables.<br />
<br />
Jump tables are similar to "switch" statements found in other programming languages.<br />
<br />
== Indirect jumping ==<br />
The NES supports JMP (addr), an indirect jump instruction, so a jump table can be implemented by copying the address to a temporary variable and jumping to it:<br />
<br />
<pre><br />
; Jumps to the subroutine indexed by 'A'.<br />
do_action:<br />
asl<br />
tax<br />
lda table,x<br />
sta ptr<br />
lda table+1,x<br />
sta ptr+1<br />
jmp (ptr)<br />
</pre><br />
<br />
While there is no indirect version of JSR, the behavior can be imitated by combining regular JSR with JMP (addr):<br />
<br />
<pre><br />
do_action:<br />
asl<br />
tax<br />
lda table,x<br />
sta ptr<br />
lda table+1,x<br />
sta ptr+1<br />
jsr callSubroutineInPtr<br />
; Do other stuff here once the called subroutine returns.<br />
rts<br />
<br />
callSubroutineInPtr:<br />
jmp (ptr)<br />
</pre><br />
<br />
Two things to ensure:<br />
* ''ptr'' must not lie on the edge of a page boundary (<code>$xxFF</code>), as a [[Errata#CPU|bug in the original 6502]] prevents it from being fetched properly. This is easy to avoid, especially if ''ptr'' is on the zero-page, but most assemblers should at least have a warning to catch the accidental case.<br />
* ''ptr'' must only be used by a single thread. If you need a jump table in both your main thread code, and within an interrupt/NMI, a separate variable must be used for the interrupt thread to prevent conflicting use.<br />
<br />
A stack-based alternative can avoid the need to use a ''ptr'' variable, at the expense of 1 extra cycle for RTS vs JMP (assuming ''ptr'' was zero-page). See below.<br />
<br />
== Stack-based dispatch ==<br />
{{main|RTS Trick}}<br />
Like JMP (addr), the RTS and RTI instructions also perform indirect jumps. Rather than jumping to a pointer variable stored in zero page memory, RTS and RTI jump to the address on top of the stack.<br />
<br />
To use RTI for indirect jumps, first push the address and then push the processor flags. Executing RTI will pop these values and jump.<br />
<pre><br />
do_action:<br />
asl a<br />
tax<br />
lda table+1,x ; high byte first<br />
pha<br />
lda table,x<br />
pha<br />
php ; RTI expects processor flags on top.<br />
rti<br />
</pre><br />
<br />
RTS is slightly more tricky, because it adds one to the address it pulls from the stack. This requires that every entry in the jump table have one subtracted from it. This could be done by the code, but it's tedious because the low byte must be decremented first, while the high byte needs to be pushed first. Thus, it's preferable to simply subtract one from each entry in the assembly source text:<br />
<br />
<pre><br />
do_action:<br />
asl a<br />
tax<br />
lda table+1,x<br />
pha<br />
lda table,x<br />
pha<br />
rts<br />
<br />
table:<br />
.word action0-1, action1-1, action2-1 ; ...<br />
</pre><br />
<br />
The benefit of the RTS version is that it's three clock cycles faster than the RTI version, due to not having to push the flags. The disadvantage is that you must adjust every table entry by -1.<br />
<br />
== Split Tables ==<br />
<br />
The previous examples have used a single table storing two-byte addresses, but on the 6502 it is slightly more efficient to split the table into a table of low bytes and a table of high bytes:<br />
<br />
<pre><br />
table_lo:<br />
.lobyte(addr1)<br />
.lobyte(addr2)<br />
.lobyte(addr3)<br />
table_hi:<br />
.hibyte(addr1)<br />
.hibyte(addr2)<br />
.hibyte(addr3)<br />
<br />
; Jumps to the subroutine indexed by 'A'.<br />
do_action:<br />
tax<br />
lda table_lo,x<br />
sta ptr<br />
lda table_hi,x<br />
sta ptr+1<br />
jmp (ptr)<br />
</pre><br />
<br />
256 addresses can be contained in both tables this way as opposed to 128 using a single table.</div>Rainwarriorhttps://www.nesdev.org/w/index.php?title=NTSC_video&diff=21198NTSC video2023-07-26T09:48:12Z<p>Rainwarrior: /* Emulating in C++ code */ refer to first and second images rather than left and right (to cover case of wrap)</p>
<hr />
<div>Unlike many other game consoles, the NES does not generate RGB or YUV and then encode that to composite.<br />
Instead, it generates '''NTSC video''' directly in the composite domain, which leads to interesting artifacts.<br />
<br />
==Scanline Timing==<br />
The NTSC master clock is 21.47727273 MHz and each PPU pixel lasts four of these clocks: 186ns. (PAL is different. See [[PAL video]].)<br />
<br />
The values in this section are measured in PPU pixels, with 341 total per scanline.<br />
<br />
The video output of the PPU is delayed by 1 pixel clock; this means that cycle 0, scanline 0 according to the [https://www.nesdev.org/wiki/File:Ppu.svg PPU Frame Timing Diagram] is marked by the black pixel.<br />
<br />
The start times of each entry are thus relative to cycle 0, taking into account the delay. Timings based on Breaking NES Wiki reverse engineered horizontal<ref>[https://github.com/emu-russia/breaks/blob/master/BreakingNESWiki_DeepL/PPU/hv_decoder.md#h-decoder Breaking NES Wiki article on H counter decoder]</ref> and vertical <ref>[https://github.com/emu-russia/breaks/blob/master/BreakingNESWiki_DeepL/PPU/hv_decoder.md#v-decoder Breaking NES Wiki article on V counter decoder]</ref> decoder functions.<br />
<br />
[[File:Ntsc video timing.png|right|frame|A visualization of the tables to the left, starts with cyan for horizontal sync]]<br />
<br />
Rendering scanlines (n=240):<br />
<br />
{| class="wikitable"<br />
! ■ || name || start || duration || row || notes<br />
|-<br />
| style="color:#00ffff" | ■ || horizontal sync || 277 || 25 || 0-239<br />
|-<br />
| style="color:#0000ff" | ■ || back porch (black) || 302 || 4 || 0-239<br />
|-<br />
| style="color:#ffff00" | ■ || colorburst || 306 || 15 || 0-239<br />
|-<br />
| style="color:#0000ff" | ■ || back porch, continued (black) || 321 || 5 || 0-239<br />
|-<br />
| style="color:#00ff00" | ■ || pulse ([[Glossary#B|backdrop]] in grayscale) || 326 || 1 || 0-239 || one scanline earlier<br />
|-<br />
| style="color:#7f0000" | ■ || left border (backdrop) || 327 || 15 || 0-239 || one scanline earlier; 14 pixels on end of row 261 for odd frames, if either background or sprite rendering is enabled<br />
|-<br />
| style="color:#ff0000" | ■ || active || 1 || 256 || 0-239 || <br />
|-<br />
| style="color:#7f0000" | ■ || right border (backdrop) || 257 || 11 || 0-239<br />
|-<br />
| style="color:#ff8000" | ■ || front porch (black) || 268 || 9 || 0-239<br />
|}<br />
<br />
Post-render scanlines (n=2):<br />
<br />
{| class="wikitable"<br />
! ■ || name || start || duration || row || notes<br />
|-<br />
| style="color:#00ffff" | ■ || horizontal sync || 277 || 25 || 240-241<br />
|-<br />
| style="color:#0000ff" | ■ || back porch (black) || 303 || 4 || 240-241<br />
|-<br />
| style="color:#ffff00" | ■ || colorburst || 306 || 15 || 240-241<br />
|-<br />
| style="color:#0000ff" | ■ || back porch, continued (black) || 321 || 5 || 240-241<br />
|-<br />
| style="color:#00ff00" | ■ || pulse (backdrop in grayscale) || 326 || 1 || 240-241<br />
|-<br />
| style="color:#7f0000" | ■ || bottom border (backdrop) || 327 || 282 || 240-241 || VBlank flag is set on scanline 241<br />
|-<br />
| style="color:#ff8000" | ■ || front porch (black) || 268 || 9 || 240-241<br />
|}<br />
<br />
Post-render blanking scanlines (n=3):<br />
<br />
{| class="wikitable"<br />
! ■ || name || start || duration || row<br />
|-<br />
| style="color:#00ffff" | ■ || horizontal sync || 277 || 25 || 242-244<br />
|-<br />
| style="color:#0000ff" | ■ || back porch (black) || 303 || 4 || 242-244<br />
|-<br />
| style="color:#ffff00" | ■ || colorburst || 306 || 15 || 242-244<br />
|-<br />
| style="color:#0000ff" | ■ || back porch, continued (black) || 321 || 5 || 242-244<br />
|-<br />
| style="color:#007f00" | ■ || vertical blanking region (black) || 326 || 283 || 242-244<br />
|-<br />
| style="color:#ff8000" | ■ || front porch (black) || 268 || 9 || 242-244<br />
|}<br />
<br />
Vertical sync scanlines (n=3):<br />
<br />
{| class="wikitable"<br />
! ■ || name || start || duration || row<br />
|-<br />
| style="color:#ff00ff" | ■ || vertical blanking pulse || 277 || 318 || 245-247<br />
|-<br />
| style="color:#007f00" | ■ || vertical sync separator (black) || 254 || 14 || 245-247<br />
|-<br />
| style="color:#ff8000" | ■ || vertical sync separator (front porch, black) || 268 || 9 || 245-247<br />
|}<br />
<br />
Pre-render blanking scanlines (n=14):<br />
<br />
{| class="wikitable"<br />
! ■ || name || start || duration || row || notes<br />
|-<br />
| style="color:#00ffff" | ■ || horizontal sync || 277 || 25 || 248-261<br />
|-<br />
| style="color:#0000ff" | ■ || back porch (black) || 303 || 4 || 248-261<br />
|-<br />
| style="color:#ffff00" | ■ || colorburst || 306 || 15 || 248-261<br />
|-<br />
| style="color:#0000ff" | ■ || back porch, continued (black) || 321 || 5 || 248-261<br />
|-<br />
| style="color:#007f00" | ■ || vertical blanking region (black) || 326 || 283 || 248-261 || VBlank is cleared on scanline 261<br />
|-<br />
| style="color:#ff8000" | ■ || front porch (black) || 268 || 9 || 248-261<br />
|}<br />
<br />
This amounts to a total of 262 scanlines.<br />
<br />
In standard NTSC, a scanline is 227.5 subcarrier cycles long (equivalent to 341.25 NES pixels), and each field is 262.5 scanlines lines tall. Vertical sync "serrations" or "equalization pulses" use a brief period of 31kHz horizontal sync to be able to start vertical sync half-way through a scanline, which makes the TV draw the next field one half scanline higher, resulting in ''interlaced'' video.<br />
<br />
The video timing in the NES is non-standard - it both generates 341 pixels, making 227 1/3 subcarrier cycles per scanline, and always generates 262 scanlines. This causes the TV to draw the fields on top of each other, resulting in a non-standard low-definition "progressive" or "double struck" video mode sometimes called [http://junkerhq.net/xrgb/index.php/240p_video 240p].<br />
<br />
Some high-definition displays and upscalers cannot handle 240p video, instead introducing artifacts that make the video appear as if it were interlaced. Artemio Urbina's [http://junkerhq.net/xrgb/index.php/240p_test_suite 240p test suite], which has been [https://forums.nesdev.org/viewtopic.php?p=157634#p157634 ported to NES] by [[User:Tepples|Damian Yerrick]], contains a set of test patterns to diagnose problems with decoding 240p composite video.<br />
<br />
Note that emulators usually crop the top and bottom 8 lines from the picture, as most televisions will hide at least part of the picture in a similar way. See: [[Overscan]]<br />
<br />
==Brightness Levels==<br />
The [[PPU palettes|NES's PPU's palette]] holds a set of 6-bit numbers, one for each simultaneous color displayable. In this section, we divide each palette entry into two halves, $xy. $x controls the brightness, and $y mostly controls the hue.<br />
<br />
$xE/$xF output the same voltage as $1D. $x1-$xC output a square wave alternating between levels for $xD and $x0. Colors $20 and $30 are exactly the same.<br />
<br />
When grayscale is active, all colors between $x1-$xD are treated as $x0. Notably this behavior extends to the first pixel of the border color, which acts as a sync pulse on every visible scanline.<br />
<br />
=== Terminated measurement ===<br />
<br />
Standard video (not NES) looks like this:<br />
{| class="wikitable"<br />
! Type || IRE level || Voltage (mV)<br />
|-<br />
| Peak white || 120 ||<br />
|-<br />
| White || 100 || 714<br />
|-<br />
| Colorburst H || 20 || 143<br />
|-<br />
| Black || 7.5 || 53.6<br />
|-<br />
| Blanking || 0 || 0<br />
|-<br />
| Colorburst L || -20 || -143<br />
|-<br />
| Sync || -40 || -286<br />
|}<br />
<br />
The following [http://forums.nesdev.org/viewtopic.php?p=159266#p159266 measurements by lidnariq] into a properly terminated (75 Ω) TV have about 10 mV of noise and 4 mV of quantization error, which implies an error of ±2 IRE:<br />
{| class="wikitable"<br />
! Signal || Potential || IRE<br />
|-<br />
| SYNC || 48 mV || -37 IRE<br />
|-<br />
| CBL || 148 mV || -23 IRE<br />
|-<br />
| 0D || 228 mV || -12 IRE<br />
|-<br />
| 1D || 312 mV || ≡ 0 IRE<br />
|-<br />
| CBH || 524 mV || 30 IRE<br />
|-<br />
| 2D || 552 mV || 34 IRE<br />
|-<br />
| 00 || 616 mV || 43 IRE<br />
|-<br />
| 10 || 840 mV || 74 IRE<br />
|-<br />
| 3D || 880 mV || 80 IRE<br />
|-<br />
| 20 || 1100 mV || 110 IRE<br />
|-<br />
| 0Dem || 192 mV || -17 IRE<br />
|-<br />
| 1Dem || 256 mV || -8 IRE<br />
|-<br />
| 2Dem || 448 mV || 19 IRE<br />
|-<br />
| 00em || 500 mV || 26 IRE<br />
|-<br />
| 10em || 676 mV || 51 IRE<br />
|-<br />
| 3Dem || 712 mV || 56 IRE<br />
|-<br />
| 20em || 896 mV || 82 IRE<br />
|}<br />
US NTSC is supposed to have a "setup", a difference between blanking and black level. Japanese NTSC does not. This means the exact same console will display slightly darker and with greater contrast on a US TV set than on a Japanese TV set.<br />
<br />
=== Old measurement ===<br />
<br />
This measurment table was added to the wiki in 2009. Its source is unknown, and its results differ from the terminated measurements above. This was used for Bisqwit's example C++ implementation below.<br />
<br />
Voltage levels used by the PPU are as follows - absolute, relative to synch, and normalized between black level and white:<br />
{| class="wikitable"<br />
! Type || Absolute || Relative || Normalized<br />
|-<br />
| Synch || 0.781 || 0.000 || -0.359<br />
|-<br />
| Colorburst L || 1.000 || 0.218 || -0.208<br />
|-<br />
| Colorburst H || 1.712 || 0.931 || 0.286<br />
|-<br />
|Color 0D || 1.131 || 0.350 || -0.117<br />
|-<br />
|Color 1D (black) || 1.300 || 0.518 || 0.000<br />
|-<br />
|Color 2D || 1.743 || 0.962 || 0.308<br />
|-<br />
|Color 3D || 2.331 || 1.550 || 0.715<br />
|-<br />
|Color 00 || 1.875 || 1.090 || 0.397<br />
|-<br />
|Color 10 || 2.287 || 1.500 || 0.681<br />
|-<br />
|Color 20 || 2.743 || 1.960 || 1.000<br />
|-<br />
|Color 30 || 2.743 || 1.960 || 1.000<br />
|}<br />
<br />
These levels don't quite match the standard levels.<br />
Ideally, the composite signal is 1000 millivolts from peak to peak (1.0 Vp-p) when loaded with a 75 Ω output impedance.<br />
(Unloaded levels may be twice that amount, which may explain the levels seen above.)<br />
Levels are commonly measured in units called IRE.<ref>[https://www.maximintegrated.com/en/app-notes/index.mvp/id/1184 Tutorial 1184: Understanding Analog Video Signals]</ref><ref>[http://www.ni.com/white-paper/4750/en/ Analog Video 101]</ref><br />
<br />
==Color Phases==<br />
111111------<br />
22222------2<br />
3333------33<br />
444------444<br />
55------5555<br />
6------66666<br />
------777777<br />
-----888888-<br />
----999999--<br />
---AAAAAA---<br />
--BBBBBB----<br />
-CCCCCC-----<br />
<br />
The color generator is clocked by the rising ''and'' falling edges of the ~21.48 MHz clock, resulting in an effective ~42.95 MHz clock rate. There are 12 color square waves, spaced at regular phases. Each runs at the ~3.58 MHz [[wikipedia:colorburst|colorburst]] rate. Color $xY uses the wave numbered with Y in the table immediately above. NTSC colorburst (pure shade [[wikipedia:YUV|-U]]) is the same phase as phase 8.<br />
<br />
PAL specifics are on [[PAL video]].<br />
<br />
=== Differential Phase Distortion ===<br />
The output is subject to a [[wikipedia:Differential phase|differential phase distortion]] effect<ref>[https://forums.nesdev.org/viewtopic.php?p=287241#p287241 Re: In search of a PAL region reference palette] - Explanation of the differential phase distortion of the NES.</ref>. This causes a rotation of the NTSC signal's effective hue, proportional to the voltage, causing more shift for brighter colors. Current estimates approximate about 2.5° (2C02E) or 5° (2C02G) of additional rotation for each row of the palette.<br />
<br />
The reason for this distortion is that the output impedance of the PPU is dependent on the signal level. When combined with the board's capacitance, it slows level transitions, causes the edges at high signal levels to be less steep. The high frequency chroma signal is sensitive to this, and the delay to its phase causes the hue rotation.<br />
<br />
A [[PAL video|PAL NES]] is affected by the same differential phase distortion, but because of the alternating-line mechanism of PAL, the effect is mostly cancelled out on consecutive scanlines.<br />
<br />
=== Color Artifacts ===<br />
Though it takes 12 clocks of the color generator mentioned above to complete a color cycle, an NTSC pixel is only 8 clocks wide, and a PAL pixel is 10 clocks wide. This means that the effective resolution of color is lower than the pixel resolution, and some color information has to be shared with a neighbouring pixel. This produces color errors at horizontal edges where the color changes. These errors are known as artifacts. They are especially noticeable as "shimmering" when the screen scrolls slowly.<ref>[//forums.nesdev.org/viewtopic.php?t=24294 Effect of skipped dot on the picture] - Forum thread with commentary and diagrams on the nature of color artifacts, and the skipped dot.</ref><br />
<br />
The phase alignment of each pixel to the color cycle changes on every scanline, and this affects the hue of each color artifact. E.g. if the "red" part of the cycle is outside the pixel, its error artifact will be a distortion of the red color.<br />
<br />
An NTSC NES scanline is 227⅓ color cycles long, causing the alignment to shift by 4 clocks on each line. This creates a pattern of alignments that repeats every 3 lines. A vertical line may be seen to have a "rainbow" pattern of red, green, blue, red, green, blue... etc. The starting phase depends on a random alignment of the PPU to the picture which is determined on reset. (The scanline is shorter than standard NTSC, which has 227½ color cycles per line.)<br />
<br />
A PAL NES scanline is 284⅙ color cycles long, instead causing the alignment to shift by 2 clocks on each line, with an additional temporary -3 clocks every second line to provide the phase-alternating-line mechanism. This creates a [[:File:PAL signal 6538 53.2MHz.png|pattern of alignments]] that repeats every 6 lines. (The scanline is longer than standard PAL, which has 283¾ cycles per line.)<br />
<br />
Each frame of the NTSC NES picture also starts from a changing alignment. Normally every odd frame is 1 dot shorter than every even frame, resulting in 59560⅔ color cycles on odd frames, and 59561⅓ on even frames. This creates a 2-frame repeating pattern, shifting by 8 clocks after an odd frame, then by 4 after an even one. The missing dot may be suppressed if rendering is disabled during the pre-render scanline, so some games which force blank through the top of the frame (e.g. Battletoads) advance the color phase alignment by 4 clocks every frame. In this case, it creates a 3-frame repeating pattern, which creates a more noticeable shimmering. See: [[PPU frame timing]].<br />
<br />
PAL and Dendy instead have an even number of color cycles per frame, so the color phase alignment does not change from frame to frame.<br />
<br />
==Color Tint Bits==<br />
There are three color modulation channels controlled by the top three bits of [[PPUMASK]]. Each channel uses one of the color square waves (see above diagram) and enables attenuation of the video signal when the color square wave is high. A single attenuator is shared by all channels. It is active for 6 out of 12 half-clocks if one bit is set, 10 half-clocks if two bits are set, or all 12 if all three bits are set.<br />
<br />
{| class="wikitable"<br />
! PPUMASK || Active phase || Active diagram || Complement<br />
|-<br />
|| Bit 7 || Color 8 || <tt>-----888888-</tt> || Color 2 (blue)<br />
|-<br />
|| Bit 6 || Color 4 || <tt>444------444</tt> || Color A (green)<br />
|-<br />
|| Bit 5 || Color C || <tt>-CCCCCC-----</tt> || Color 6 (red)<br />
|}<br />
<br />
When attenuation is active and the current pixel is a color other than $xE/$xF (black), the signal is attenuated.<br />
<br />
For example, when PPUMASK bit 6 is true, the attenuator will be active during the phases of color 4.<br />
This means the attenuator is not active during its complement (color A), and the screen appears to have a tint of color A, which is green.<br />
<br />
Note that on the Dendy and PAL NES, the green and red bits swap meaning.<br />
<br />
[http://forums.nesdev.org/viewtopic.php?p=160669#p160669 Tests performed on NTSC NES] show that emphasis does not affect the black colors in columns $E or $F, but it does affect all other columns, including the blacks and greys in column $D.<br />
<br />
The terminated measurements above suggest that resulting attenuated absolute voltage is approximately '''0.81 times''' the un-attenuated absolute voltage.<br />
<br />
The old measurement suggested a different approximation, applied to its relative or normalized values. This does not agree with the terminated measurements:<br />
attenuated relative = relative * 0.746<br />
attenuated normalized = normalized * 0.746 - 0.0912<br />
<br />
==Example Waveform==<br />
<br />
This waveform steps through various grays and then stops on a color.<br />
[[File:Composite_waveform_example.gif|center|frame|The composite signal steps through 6 gray colors ($0D, $0F, $2D, $00, $10, $30) then continues through with color $11. ]]<br />
<br />
The PPU's shortcut method of NTSC modulation often produces artifacts in which vertical lines appear slightly ragged, as the chroma spills over into luma.<br />
[[File:NTSC video ragged box animated.gif|right|frame|Generation and demodulation of a red corner]]<br />
<br clear="all"/><br />
<br />
== Composite decoding ==<br />
<br />
Normal composite video encodes chroma and luma information into one composite analog signal. In order to convert composite into an RGB signal, it firsts needs to be decoded into YUV, before converting the resulting YUV into RGB.<br />
<br />
The NES PPU does not encode anything into composite; instead, directly drawing the composite waveform itself. In order to convert the NES's composite signal into an RGB signal, it is decoded under the "assumption" that it was encoded under YUV.<br />
<br />
YUV in this article refers to and will continue to refer to the equiband encoding of composite video as Y, b-y and r-y respectively. YIQ refers to the non-equiband encoding of composite, which has much more additional considerations regarding bandlimiting.<br />
<br />
In practice, YIQ decoding is not used by any modern TV receiver and composite decoder, instead using YUV decoding as it is much simpler and less mathematically intensive to decode.<ref>[https://www.itu.int/rec/R-REC-BT.1700-0-200502-I/en S170m-2004.pdf: Composite Analog Video Signal NTSC for Studio Applications. Page 17.]</ref><ref>SMPTE EG 27-2004: Supplemental Information for SMPTE 170M and Background on the Development of NTSC Color Standards. Page 5.</ref><br />
<br />
=== Decoding composite video into YUV ===<br />
<br />
Although encoding composite is somewhat standardized, the methods of decoding composite may vary from TV to TV. This article shows one way to decode composite.<br />
<br />
==== Decoding luma information (Y) ====<br />
<br />
To get the luma (Y) component, the base signal is filtered by a lowpass or comb filter. Some TVs use more complex methods to decode luma, some TVs do not filter at all.<br />
<br />
==== Decoding chroma information (UV) ====<br />
<br />
Decoding chroma information requires a subcarrier reference sine wave to determine the hue, whose phase is "locked" (or aligned as best as possible) to the colorburst of the composite scanline.<br />
<br />
The subcarrier reference is used to demodulate the U component. A copy (or a phase offset) of the reference is delayed by 90 degrees, which is then used to demodulate the V component.<br />
<br />
The U/V component is demodulated by multiplying the subcarrier reference to the composite waveform. The resulting waveform is then filtered typically by a lowpass filter. A comb filter can also be used if desired.<br />
<br />
Since demodulation involves multiplying each chroma component by sin(2π·Fsc·t) and the integral of sin(2πx)² over a cycle is 0.5, a factor of 2 must be applied to the demodulator to achieve correct chroma amplitudes and therefore saturation.<br />
=== Converting YUV to signal RGB ===<br />
<br />
To convert YUV to signal RGB, we multiply the components to the following inversed matrix:<br />
<br />
R = Y + V*1.14<br />
G = Y - (R*0.299 - B*0.114) / 0.587<br />
B = Y + U*2.03<br />
<br />
Or, in terms of YUV only:<br />
<br />
R = Y + V*1.14<br />
G = Y - U*0.394242... - V*0.580681...<br />
B = Y + U*2.03<br />
<br />
The matrices above are derived from the NTSC base matrix<ref>[https://www.itu.int/rec/R-REC-BT.1700-0-200502-I/en S170m-2004.pdf: Composite Analog Video Signal NTSC for Studio Applications. Page 4.]</ref> of luminance and color-difference:<br />
<br />
Y = R*0.299 + G*0.587 + B*0.114<br />
B-Y = -R*0.299 - G*0.587 + B*0.886<br />
R-Y = R*0.701 - G*0.587 - B*0.114<br />
<br />
Which, when applied with the approximate color reduction factors 1/2.03 and 1/1.14 for B-Y and R-Y respectively<ref>[https://www.itu.int/rec/R-REC-BT.1700-0-200502-I/en S170m-2004.pdf: Composite Analog Video Signal NTSC for Studio Applications. Page 16.]</ref>, results in the definition of the linear RGB to YUV matrix equation:<br />
<br />
Y = R*0.299 + G*0.587 + B*0.114<br />
U = (-R*0.299 - G*0.587 + B*0.886) / 2.03<br />
V = ( R*0.701 - G*0.587 - B*0.114) / 1.14<br />
<br />
In YIQ, the IQ component's chroma hue is just the UV component's chroma hue rotated by 33 degrees. Note that this is not precisely the same as properly decoding YIQ with different bandwidths for the I and Q component.<br />
<br />
The following conversion is optional, and might match the look of other composite decoders:<br />
<br />
U = -(I * sin(-33 deg)) + (Q * cos(-33 deg))<br />
V = (I * cos(-33 deg)) + (Q * sin(-33 deg))<br />
<br />
==== Normalizing signals ====<br />
<br />
After decoding, it is important to normalize the decoded RGB signals within the range of [0, 1].<br />
<br />
Most TVs use the range 7.5 IRE to 100 IRE for normalizing the signal:<br />
<br />
C = R, G, or B channel<br />
<br />
signal_black_point = <voltage level $0F> + (7.5 / 140.0)<br />
signal_white_point = <voltage level $0F> + (100. / 140.0)<br />
<br />
C -= signal_black_point<br />
C /= (signal_white_point - signal_black_point)<br />
<br />
The 100 IRE white point may be substituted with voltage level $20 because on analog CRT TVs, the luma voltage does not strictly clip at a given level, with only the luminosity of the phosphors being the upper limit.<br />
<br />
signal_white_point = <voltage level $20><br />
<br />
Similarly, some TVs do not use the 7.5 IRE setup black level, instead directly using the blank level.<br />
<br />
signal_black_point = <voltage level $0F><br />
<br />
Finally, the signals must be clipped or normalized to [0, 1] to avoid values outside of the valid range.<br />
<br />
C_raw = R, G, or B channel<br />
C_clip = clipped or normalized R, G, or B channel<br />
<br />
C_clip = max(0, min(1, C_raw))<br />
<br />
=== Converting signal RGB to display RGB ===<br />
<br />
The final step is to convert signal RGB into the output colorspace, typically sRGB for most monitors.<br />
<br />
==== Signal RGB into sRGB ====<br />
<br />
Assuming no colorimetry involved, the resulting R, G and B values can directly be quantized into 8 bits per channel:<br />
<br />
C' = R, G or B signal<br />
C8bpc = quantized R, G, or B channel<br />
<br />
C8bpc = (int)(C' * 255)<br />
<br />
However, if the signal RGB is assumed to be fed a reference display with different color primaries, then a correction matrix must be applied to the signal before quantization.<br />
<br />
==Emulating in C++ code==<br />
<br />
For efficient, ready to use implementations, see [[#Libraries|Libraries]] below. The following is an illustrative example. The values used are based on the "old" measurements given above.<br />
<br />
Calculating the momentary NTSC signal level can be done as follows in C++:<br />
<br />
<nowiki><br />
// pixel = Pixel color (9-bit) given as input. Bitmask format: "eeellcccc".<br />
// phase = Signal phase (0..11). It is a variable that increases by 8 each pixel.<br />
float NTSCsignal(int pixel, int phase)<br />
{<br />
// Voltage levels, relative to synch voltage<br />
static const float black=.518f, white=1.962f, attenuation=.746f,<br />
levels[8] = {.350f, .518f, .962f,1.550f, // Signal low<br />
1.094f,1.506f,1.962f,1.962f}; // Signal high<br />
<br />
// Decode the NES color.<br />
int color = (pixel & 0x0F); // 0..15 "cccc"<br />
int level = (pixel >> 4) & 3; // 0..3 "ll"<br />
int emphasis = (pixel >> 6); // 0..7 "eee"<br />
if(color > 13) { level = 1; } // For colors 14..15, level 1 is forced.<br />
<br />
// The square wave for this color alternates between these two voltages:<br />
float low = levels[0 + level];<br />
float high = levels[4 + level];<br />
if(color == 0) { low = high; } // For color 0, only high level is emitted<br />
if(color > 12) { high = low; } // For colors 13..15, only low level is emitted<br />
<br />
// Generate the square wave<br />
auto InColorPhase = [=](int color) { return (color + phase) % 12 < 6; }; // Inline function<br />
float signal = InColorPhase(color) ? high : low;<br />
<br />
// When de-emphasis bits are set, some parts of the signal are attenuated:<br />
if( ((emphasis & 1) && InColorPhase(0))<br />
|| ((emphasis & 2) && InColorPhase(4))<br />
|| ((emphasis & 4) && InColorPhase(8)) ) signal = signal * attenuation;<br />
<br />
return signal;<br />
}</nowiki><br />
<br />
The process of generating NTSC signal for a single pixel can be simulated with the following C++ code:<br />
<br />
<nowiki><br />
void RenderNTSCpixel(unsigned x, int pixel, int PPU_cycle_counter)<br />
{<br />
int phase = PPU_cycle_counter * 8;<br />
for(int p=0; p<8; ++p) // Each pixel produces distinct 8 samples of NTSC signal.<br />
{<br />
float signal = NTSCsignal(pixel, phase + p); // Calculated as above<br />
// Optionally apply some lowpass-filtering to the signal here.<br />
// Optionally normalize the signal to 0..1 range:<br />
static const float black=.518f, white=1.962f;<br />
signal = (signal-black) / (white-black);<br />
// Save the signal for this pixel.<br />
signal_levels[ x*8 + p ] = signal;<br />
}<br />
}</nowiki><br />
<br />
It is important to note that while the NES only generates eight (8) samples of NTSC signal per pixel, the wavelength for chroma is 12 samples long. This means that the colors of adjacent pixels get mandatorily mixed up to some degree. For the same reason, narrow black&white details can be interpreted as colors.<br />
<br />
Because the scanline length is uneven (341*8 is not an even multiple of 12), the color mixing shifts a little each scanline. This appears visually as a sawtooth effect at the edges of colors at high resolution. The sawtooth cycles every 3 scanlines.<br />
<br />
Because also the frame length is uneven (neither 262*341*8 nor (262*341-1)*8 is an even multiple of 12), the color mixing also changes a little every frame. When rendering is normally enabled, the screen is alternatingly 89342 and 89341 cycles long. The combination of these (89342+89341)*8 <i>is</i> an even multiple of 12, which means that the artifact pattern cycles every 2 frames. The pattern of cycling can be changed by disabling rendering during the end of the pre-render scanline; it forces the screen length to 89342 cycles, even if would be 89341 otherwise.<br />
<br />
The process of decoding NTSC signal (convert it into RGB) is subject to a lot of study, and there are many patents and different techniques for it. A simple method suitable for emulation is covered below. It is not accurate, because in reality the chroma is blurred much more than is done here (the region of signal sampled for I and Q is wider than 12 samples), and the filter used here is a simple box FIR filter rather than an IIR filter, but it already produces a quite authentic looking picture. In addition, the border region (total of 26 pixels of background color around the 256-pixel scanline) is not sampled.<br />
<br />
<nowiki><br />
float signal_levels[256*8] = {...}; // Eight signal levels for each pixel, normalized to 0..1 range. <br />
Calculated as above.<br />
<br />
unsigned Width; // Input: Screen width. Can be not only 256, but anything up to 2048.<br />
float phase; // Input: This should the value that was PPU_cycle_counter * 8 + 3.9<br />
// at the BEGINNING of this scanline. It should be modulo 12.<br />
// It can additionally include a floating-point hue offset.<br />
for(unsigned x = 0; x < Width; ++x)<br />
{<br />
// Determine the region of scanline signal to sample. Take 12 samples.<br />
int center = x * (256*8) / Width + 0;<br />
int begin = center - 6; if(begin < 0) begin = 0;<br />
int end = center + 6; if(end > 256*8) end = 256*8;<br />
float y = 0.f, i = 0.f, q = 0.f; // Calculate the color in YIQ.<br />
for(int p = begin; p < end; ++p) // Collect and accumulate samples<br />
{<br />
float level = signal_levels[p] / 12.f;<br />
y = y + level;<br />
i = i + level * cos( M_PI * (phase+p) / 6 );<br />
q = q + level * sin( M_PI * (phase+p) / 6 );<br />
}<br />
render_pixel(y,i,q); // Send the YIQ color for rendering.<br />
}</nowiki><br />
<br />
The NTSC decoder here produces pixels in YIQ color space.<br />
<br />
If you want more saturated colors, just multiply <code>i</code> and <code>q</code> with a factor of your choosing, such as 1.7. If you want brighter colors, just multiply <code>y</code>, <code>i</code> and <code>q</code> with a factor of your choosing, such as 1.1. If you want to adjust the hue, just add or subtract a value from/to <code>phase</code>. If you want to see so called chroma dots, change the begin and end in such manner that you collect a number of samples that is not divisible with 12. If you want to blur the video horizontally, change the begin and end in such manner that the samples are collected from a wider region.<br />
<br />
The YIQ colors can be converted into sRGB colors with the following formula, using the [https://www.govinfo.gov/content/pkg/CFR-2013-title47-vol4/pdf/CFR-2013-title47-vol4-sec73-682.pdf#page=2 FCC-sanctioned] YIQ-to-RGB conversion matrix. This produces a value that can be saved to e.g. framebuffer:<br />
<br />
<nowiki><br />
float gamma = 2.0f; // Assumed display gamma<br />
auto gammafix = [=](float f) { return f <= 0.f ? 0.f : pow(f, 2.2f / gamma); };<br />
auto clamp = [](int v) { return v>255 ? 255 : v; };<br />
unsigned rgb =<br />
0x10000*clamp(255.95 * gammafix(y + 0.946882f*i + 0.623557f*q))<br />
+ 0x00100*clamp(255.95 * gammafix(y + -0.274788f*i + -0.635691f*q))<br />
+ 0x00001*clamp(255.95 * gammafix(y + -1.108545f*i + 1.709007f*q));</nowiki><br />
<br />
The two images below illustrate the NTSC artifacts.<br />
In the first image, 12 samples of NTSC signal were generated for each NES pixel,<br />
and each display pixel was separately rendered by decoding that 12-sample signal.<br />
In the second image, 8 samples of NTSC signal were generated for each NES pixel,<br />
and each display pixel was rendered by decoding 12 samples of NTSC signal from the<br />
corresponding location within the scanline.<br clear="all" /><br />
<br />
<div style="display:flex; flex-flow:row wrap;"><br />
[[File:nes_ntsc_perpixel.png|left|frame|Per-pixel rendering: 12 samples of NTSC signal per input pixel; the same 12 samples are decoded for each output pixel]]<br />
[[File:nes_ntsc_perscanline.gif|left|frame|Per-scanline rendering: 8 samples of NTSC signal per input pixel; 12 samples are decoded for each output pixel]]<br />
</div><br />
<div style="display:flex; flex-flow:row wrap;"><br />
[[File:nes_ntsc_perpixel_small.png|left|frame|Same as above, but rendered at 256x240 without upscaling]]<br />
[[File:nes_ntsc_perpixel_small_bw.png|left|frame|Same in grayscale (zero saturation). This illustrates well how the different color values have exactly the same luminosity; only the chroma phase differs.]]<br />
[[File:nes_ntsc_perscanline_small.gif|left|frame|Same as above, but rendered at 256x240 rather than at 2048x240 and then downscaled]]<br />
[[File:nes_ntsc_perscanline_small_bw.gif|left|frame|Same in grayscale]]<br />
</div><br />
<br />
The source code of the program that generated both images can be read here: [https://bisqwit.iki.fi/jutut/kuvat/programming_examples/nesemu1/ntsc-small.cc ntsc-small.cc]. Note that even though the image resembles the well-known Philips PM5544 test card, it is not the same; the exact same<br />
colors could not be reproduced with NES colors. In addition, some parts were changed to better test NES features. For example, the backgrounds for the "station ID" regions (the black rectangles at the top and at the bottom inside the circle) are generated using the various blacks within the NES palette.<br />
<br />
Later, Bisqwit made a generic [http://forums.nesdev.org/viewtopic.php?p=172329#p172329 integer-based decoder in C++]. This takes a signal at 12 times color burst and can be used to emulate other systems that use shortcuts when generating NTSC video, such as Apple II (where ''every'' color in <code>HGR</code> is an artifact color) and Atari 7800 (whose game ''Tower Toppler'' seriously exploits artifact colors).<br />
<br />
==Libraries==<br />
<br />
* [http://slack.net/~ant/libs/ntsc.html blargg's nes_ntsc library]<br />
* [//forums.nesdev.org/viewtopic.php?f=21&t=11947 blargg's NTSC demo windows executable]<br />
* [//forums.nesdev.org/viewtopic.php?f=2&t=14338 Forum thread]: New NTSC decoder with integer-only math (short C++ code) - by Bisqwit<br />
* [https://github.com/LMP88959/NTSC-CRT/ LMP88959 (EMMIR)'s NTSC decoder]<br />
<br />
== See also ==<br />
* [[Cycle reference chart]]<br />
* [[PAL video]]<br />
* [[PPU palettes]]<br />
<br />
== References ==<br />
<references /></div>Rainwarriorhttps://www.nesdev.org/w/index.php?title=NTSC_video&diff=21197NTSC video2023-07-26T08:23:07Z<p>Rainwarrior: /* Emulating in C++ code */ use flexible rows instead of tables so a narrower browser is allowed to wrap these huge images instead of forced to make a horizontal scrolling view to accomodate</p>
<hr />
<div>Unlike many other game consoles, the NES does not generate RGB or YUV and then encode that to composite.<br />
Instead, it generates '''NTSC video''' directly in the composite domain, which leads to interesting artifacts.<br />
<br />
==Scanline Timing==<br />
The NTSC master clock is 21.47727273 MHz and each PPU pixel lasts four of these clocks: 186ns. (PAL is different. See [[PAL video]].)<br />
<br />
The values in this section are measured in PPU pixels, with 341 total per scanline.<br />
<br />
The video output of the PPU is delayed by 1 pixel clock; this means that cycle 0, scanline 0 according to the [https://www.nesdev.org/wiki/File:Ppu.svg PPU Frame Timing Diagram] is marked by the black pixel.<br />
<br />
The start times of each entry are thus relative to cycle 0, taking into account the delay. Timings based on Breaking NES Wiki reverse engineered horizontal<ref>[https://github.com/emu-russia/breaks/blob/master/BreakingNESWiki_DeepL/PPU/hv_decoder.md#h-decoder Breaking NES Wiki article on H counter decoder]</ref> and vertical <ref>[https://github.com/emu-russia/breaks/blob/master/BreakingNESWiki_DeepL/PPU/hv_decoder.md#v-decoder Breaking NES Wiki article on V counter decoder]</ref> decoder functions.<br />
<br />
[[File:Ntsc video timing.png|right|frame|A visualization of the tables to the left, starts with cyan for horizontal sync]]<br />
<br />
Rendering scanlines (n=240):<br />
<br />
{| class="wikitable"<br />
! ■ || name || start || duration || row || notes<br />
|-<br />
| style="color:#00ffff" | ■ || horizontal sync || 277 || 25 || 0-239<br />
|-<br />
| style="color:#0000ff" | ■ || back porch (black) || 302 || 4 || 0-239<br />
|-<br />
| style="color:#ffff00" | ■ || colorburst || 306 || 15 || 0-239<br />
|-<br />
| style="color:#0000ff" | ■ || back porch, continued (black) || 321 || 5 || 0-239<br />
|-<br />
| style="color:#00ff00" | ■ || pulse ([[Glossary#B|backdrop]] in grayscale) || 326 || 1 || 0-239 || one scanline earlier<br />
|-<br />
| style="color:#7f0000" | ■ || left border (backdrop) || 327 || 15 || 0-239 || one scanline earlier; 14 pixels on end of row 261 for odd frames, if either background or sprite rendering is enabled<br />
|-<br />
| style="color:#ff0000" | ■ || active || 1 || 256 || 0-239 || <br />
|-<br />
| style="color:#7f0000" | ■ || right border (backdrop) || 257 || 11 || 0-239<br />
|-<br />
| style="color:#ff8000" | ■ || front porch (black) || 268 || 9 || 0-239<br />
|}<br />
<br />
Post-render scanlines (n=2):<br />
<br />
{| class="wikitable"<br />
! ■ || name || start || duration || row || notes<br />
|-<br />
| style="color:#00ffff" | ■ || horizontal sync || 277 || 25 || 240-241<br />
|-<br />
| style="color:#0000ff" | ■ || back porch (black) || 303 || 4 || 240-241<br />
|-<br />
| style="color:#ffff00" | ■ || colorburst || 306 || 15 || 240-241<br />
|-<br />
| style="color:#0000ff" | ■ || back porch, continued (black) || 321 || 5 || 240-241<br />
|-<br />
| style="color:#00ff00" | ■ || pulse (backdrop in grayscale) || 326 || 1 || 240-241<br />
|-<br />
| style="color:#7f0000" | ■ || bottom border (backdrop) || 327 || 282 || 240-241 || VBlank flag is set on scanline 241<br />
|-<br />
| style="color:#ff8000" | ■ || front porch (black) || 268 || 9 || 240-241<br />
|}<br />
<br />
Post-render blanking scanlines (n=3):<br />
<br />
{| class="wikitable"<br />
! ■ || name || start || duration || row<br />
|-<br />
| style="color:#00ffff" | ■ || horizontal sync || 277 || 25 || 242-244<br />
|-<br />
| style="color:#0000ff" | ■ || back porch (black) || 303 || 4 || 242-244<br />
|-<br />
| style="color:#ffff00" | ■ || colorburst || 306 || 15 || 242-244<br />
|-<br />
| style="color:#0000ff" | ■ || back porch, continued (black) || 321 || 5 || 242-244<br />
|-<br />
| style="color:#007f00" | ■ || vertical blanking region (black) || 326 || 283 || 242-244<br />
|-<br />
| style="color:#ff8000" | ■ || front porch (black) || 268 || 9 || 242-244<br />
|}<br />
<br />
Vertical sync scanlines (n=3):<br />
<br />
{| class="wikitable"<br />
! ■ || name || start || duration || row<br />
|-<br />
| style="color:#ff00ff" | ■ || vertical blanking pulse || 277 || 318 || 245-247<br />
|-<br />
| style="color:#007f00" | ■ || vertical sync separator (black) || 254 || 14 || 245-247<br />
|-<br />
| style="color:#ff8000" | ■ || vertical sync separator (front porch, black) || 268 || 9 || 245-247<br />
|}<br />
<br />
Pre-render blanking scanlines (n=14):<br />
<br />
{| class="wikitable"<br />
! ■ || name || start || duration || row || notes<br />
|-<br />
| style="color:#00ffff" | ■ || horizontal sync || 277 || 25 || 248-261<br />
|-<br />
| style="color:#0000ff" | ■ || back porch (black) || 303 || 4 || 248-261<br />
|-<br />
| style="color:#ffff00" | ■ || colorburst || 306 || 15 || 248-261<br />
|-<br />
| style="color:#0000ff" | ■ || back porch, continued (black) || 321 || 5 || 248-261<br />
|-<br />
| style="color:#007f00" | ■ || vertical blanking region (black) || 326 || 283 || 248-261 || VBlank is cleared on scanline 261<br />
|-<br />
| style="color:#ff8000" | ■ || front porch (black) || 268 || 9 || 248-261<br />
|}<br />
<br />
This amounts to a total of 262 scanlines.<br />
<br />
In standard NTSC, a scanline is 227.5 subcarrier cycles long (equivalent to 341.25 NES pixels), and each field is 262.5 scanlines lines tall. Vertical sync "serrations" or "equalization pulses" use a brief period of 31kHz horizontal sync to be able to start vertical sync half-way through a scanline, which makes the TV draw the next field one half scanline higher, resulting in ''interlaced'' video.<br />
<br />
The video timing in the NES is non-standard - it both generates 341 pixels, making 227 1/3 subcarrier cycles per scanline, and always generates 262 scanlines. This causes the TV to draw the fields on top of each other, resulting in a non-standard low-definition "progressive" or "double struck" video mode sometimes called [http://junkerhq.net/xrgb/index.php/240p_video 240p].<br />
<br />
Some high-definition displays and upscalers cannot handle 240p video, instead introducing artifacts that make the video appear as if it were interlaced. Artemio Urbina's [http://junkerhq.net/xrgb/index.php/240p_test_suite 240p test suite], which has been [https://forums.nesdev.org/viewtopic.php?p=157634#p157634 ported to NES] by [[User:Tepples|Damian Yerrick]], contains a set of test patterns to diagnose problems with decoding 240p composite video.<br />
<br />
Note that emulators usually crop the top and bottom 8 lines from the picture, as most televisions will hide at least part of the picture in a similar way. See: [[Overscan]]<br />
<br />
==Brightness Levels==<br />
The [[PPU palettes|NES's PPU's palette]] holds a set of 6-bit numbers, one for each simultaneous color displayable. In this section, we divide each palette entry into two halves, $xy. $x controls the brightness, and $y mostly controls the hue.<br />
<br />
$xE/$xF output the same voltage as $1D. $x1-$xC output a square wave alternating between levels for $xD and $x0. Colors $20 and $30 are exactly the same.<br />
<br />
When grayscale is active, all colors between $x1-$xD are treated as $x0. Notably this behavior extends to the first pixel of the border color, which acts as a sync pulse on every visible scanline.<br />
<br />
=== Terminated measurement ===<br />
<br />
Standard video (not NES) looks like this:<br />
{| class="wikitable"<br />
! Type || IRE level || Voltage (mV)<br />
|-<br />
| Peak white || 120 ||<br />
|-<br />
| White || 100 || 714<br />
|-<br />
| Colorburst H || 20 || 143<br />
|-<br />
| Black || 7.5 || 53.6<br />
|-<br />
| Blanking || 0 || 0<br />
|-<br />
| Colorburst L || -20 || -143<br />
|-<br />
| Sync || -40 || -286<br />
|}<br />
<br />
The following [http://forums.nesdev.org/viewtopic.php?p=159266#p159266 measurements by lidnariq] into a properly terminated (75 Ω) TV have about 10 mV of noise and 4 mV of quantization error, which implies an error of ±2 IRE:<br />
{| class="wikitable"<br />
! Signal || Potential || IRE<br />
|-<br />
| SYNC || 48 mV || -37 IRE<br />
|-<br />
| CBL || 148 mV || -23 IRE<br />
|-<br />
| 0D || 228 mV || -12 IRE<br />
|-<br />
| 1D || 312 mV || ≡ 0 IRE<br />
|-<br />
| CBH || 524 mV || 30 IRE<br />
|-<br />
| 2D || 552 mV || 34 IRE<br />
|-<br />
| 00 || 616 mV || 43 IRE<br />
|-<br />
| 10 || 840 mV || 74 IRE<br />
|-<br />
| 3D || 880 mV || 80 IRE<br />
|-<br />
| 20 || 1100 mV || 110 IRE<br />
|-<br />
| 0Dem || 192 mV || -17 IRE<br />
|-<br />
| 1Dem || 256 mV || -8 IRE<br />
|-<br />
| 2Dem || 448 mV || 19 IRE<br />
|-<br />
| 00em || 500 mV || 26 IRE<br />
|-<br />
| 10em || 676 mV || 51 IRE<br />
|-<br />
| 3Dem || 712 mV || 56 IRE<br />
|-<br />
| 20em || 896 mV || 82 IRE<br />
|}<br />
US NTSC is supposed to have a "setup", a difference between blanking and black level. Japanese NTSC does not. This means the exact same console will display slightly darker and with greater contrast on a US TV set than on a Japanese TV set.<br />
<br />
=== Old measurement ===<br />
<br />
This measurment table was added to the wiki in 2009. Its source is unknown, and its results differ from the terminated measurements above. This was used for Bisqwit's example C++ implementation below.<br />
<br />
Voltage levels used by the PPU are as follows - absolute, relative to synch, and normalized between black level and white:<br />
{| class="wikitable"<br />
! Type || Absolute || Relative || Normalized<br />
|-<br />
| Synch || 0.781 || 0.000 || -0.359<br />
|-<br />
| Colorburst L || 1.000 || 0.218 || -0.208<br />
|-<br />
| Colorburst H || 1.712 || 0.931 || 0.286<br />
|-<br />
|Color 0D || 1.131 || 0.350 || -0.117<br />
|-<br />
|Color 1D (black) || 1.300 || 0.518 || 0.000<br />
|-<br />
|Color 2D || 1.743 || 0.962 || 0.308<br />
|-<br />
|Color 3D || 2.331 || 1.550 || 0.715<br />
|-<br />
|Color 00 || 1.875 || 1.090 || 0.397<br />
|-<br />
|Color 10 || 2.287 || 1.500 || 0.681<br />
|-<br />
|Color 20 || 2.743 || 1.960 || 1.000<br />
|-<br />
|Color 30 || 2.743 || 1.960 || 1.000<br />
|}<br />
<br />
These levels don't quite match the standard levels.<br />
Ideally, the composite signal is 1000 millivolts from peak to peak (1.0 Vp-p) when loaded with a 75 Ω output impedance.<br />
(Unloaded levels may be twice that amount, which may explain the levels seen above.)<br />
Levels are commonly measured in units called IRE.<ref>[https://www.maximintegrated.com/en/app-notes/index.mvp/id/1184 Tutorial 1184: Understanding Analog Video Signals]</ref><ref>[http://www.ni.com/white-paper/4750/en/ Analog Video 101]</ref><br />
<br />
==Color Phases==<br />
111111------<br />
22222------2<br />
3333------33<br />
444------444<br />
55------5555<br />
6------66666<br />
------777777<br />
-----888888-<br />
----999999--<br />
---AAAAAA---<br />
--BBBBBB----<br />
-CCCCCC-----<br />
<br />
The color generator is clocked by the rising ''and'' falling edges of the ~21.48 MHz clock, resulting in an effective ~42.95 MHz clock rate. There are 12 color square waves, spaced at regular phases. Each runs at the ~3.58 MHz [[wikipedia:colorburst|colorburst]] rate. Color $xY uses the wave numbered with Y in the table immediately above. NTSC colorburst (pure shade [[wikipedia:YUV|-U]]) is the same phase as phase 8.<br />
<br />
PAL specifics are on [[PAL video]].<br />
<br />
=== Differential Phase Distortion ===<br />
The output is subject to a [[wikipedia:Differential phase|differential phase distortion]] effect<ref>[https://forums.nesdev.org/viewtopic.php?p=287241#p287241 Re: In search of a PAL region reference palette] - Explanation of the differential phase distortion of the NES.</ref>. This causes a rotation of the NTSC signal's effective hue, proportional to the voltage, causing more shift for brighter colors. Current estimates approximate about 2.5° (2C02E) or 5° (2C02G) of additional rotation for each row of the palette.<br />
<br />
The reason for this distortion is that the output impedance of the PPU is dependent on the signal level. When combined with the board's capacitance, it slows level transitions, causes the edges at high signal levels to be less steep. The high frequency chroma signal is sensitive to this, and the delay to its phase causes the hue rotation.<br />
<br />
A [[PAL video|PAL NES]] is affected by the same differential phase distortion, but because of the alternating-line mechanism of PAL, the effect is mostly cancelled out on consecutive scanlines.<br />
<br />
=== Color Artifacts ===<br />
Though it takes 12 clocks of the color generator mentioned above to complete a color cycle, an NTSC pixel is only 8 clocks wide, and a PAL pixel is 10 clocks wide. This means that the effective resolution of color is lower than the pixel resolution, and some color information has to be shared with a neighbouring pixel. This produces color errors at horizontal edges where the color changes. These errors are known as artifacts. They are especially noticeable as "shimmering" when the screen scrolls slowly.<ref>[//forums.nesdev.org/viewtopic.php?t=24294 Effect of skipped dot on the picture] - Forum thread with commentary and diagrams on the nature of color artifacts, and the skipped dot.</ref><br />
<br />
The phase alignment of each pixel to the color cycle changes on every scanline, and this affects the hue of each color artifact. E.g. if the "red" part of the cycle is outside the pixel, its error artifact will be a distortion of the red color.<br />
<br />
An NTSC NES scanline is 227⅓ color cycles long, causing the alignment to shift by 4 clocks on each line. This creates a pattern of alignments that repeats every 3 lines. A vertical line may be seen to have a "rainbow" pattern of red, green, blue, red, green, blue... etc. The starting phase depends on a random alignment of the PPU to the picture which is determined on reset. (The scanline is shorter than standard NTSC, which has 227½ color cycles per line.)<br />
<br />
A PAL NES scanline is 284⅙ color cycles long, instead causing the alignment to shift by 2 clocks on each line, with an additional temporary -3 clocks every second line to provide the phase-alternating-line mechanism. This creates a [[:File:PAL signal 6538 53.2MHz.png|pattern of alignments]] that repeats every 6 lines. (The scanline is longer than standard PAL, which has 283¾ cycles per line.)<br />
<br />
Each frame of the NTSC NES picture also starts from a changing alignment. Normally every odd frame is 1 dot shorter than every even frame, resulting in 59560⅔ color cycles on odd frames, and 59561⅓ on even frames. This creates a 2-frame repeating pattern, shifting by 8 clocks after an odd frame, then by 4 after an even one. The missing dot may be suppressed if rendering is disabled during the pre-render scanline, so some games which force blank through the top of the frame (e.g. Battletoads) advance the color phase alignment by 4 clocks every frame. In this case, it creates a 3-frame repeating pattern, which creates a more noticeable shimmering. See: [[PPU frame timing]].<br />
<br />
PAL and Dendy instead have an even number of color cycles per frame, so the color phase alignment does not change from frame to frame.<br />
<br />
==Color Tint Bits==<br />
There are three color modulation channels controlled by the top three bits of [[PPUMASK]]. Each channel uses one of the color square waves (see above diagram) and enables attenuation of the video signal when the color square wave is high. A single attenuator is shared by all channels. It is active for 6 out of 12 half-clocks if one bit is set, 10 half-clocks if two bits are set, or all 12 if all three bits are set.<br />
<br />
{| class="wikitable"<br />
! PPUMASK || Active phase || Active diagram || Complement<br />
|-<br />
|| Bit 7 || Color 8 || <tt>-----888888-</tt> || Color 2 (blue)<br />
|-<br />
|| Bit 6 || Color 4 || <tt>444------444</tt> || Color A (green)<br />
|-<br />
|| Bit 5 || Color C || <tt>-CCCCCC-----</tt> || Color 6 (red)<br />
|}<br />
<br />
When attenuation is active and the current pixel is a color other than $xE/$xF (black), the signal is attenuated.<br />
<br />
For example, when PPUMASK bit 6 is true, the attenuator will be active during the phases of color 4.<br />
This means the attenuator is not active during its complement (color A), and the screen appears to have a tint of color A, which is green.<br />
<br />
Note that on the Dendy and PAL NES, the green and red bits swap meaning.<br />
<br />
[http://forums.nesdev.org/viewtopic.php?p=160669#p160669 Tests performed on NTSC NES] show that emphasis does not affect the black colors in columns $E or $F, but it does affect all other columns, including the blacks and greys in column $D.<br />
<br />
The terminated measurements above suggest that resulting attenuated absolute voltage is approximately '''0.81 times''' the un-attenuated absolute voltage.<br />
<br />
The old measurement suggested a different approximation, applied to its relative or normalized values. This does not agree with the terminated measurements:<br />
attenuated relative = relative * 0.746<br />
attenuated normalized = normalized * 0.746 - 0.0912<br />
<br />
==Example Waveform==<br />
<br />
This waveform steps through various grays and then stops on a color.<br />
[[File:Composite_waveform_example.gif|center|frame|The composite signal steps through 6 gray colors ($0D, $0F, $2D, $00, $10, $30) then continues through with color $11. ]]<br />
<br />
The PPU's shortcut method of NTSC modulation often produces artifacts in which vertical lines appear slightly ragged, as the chroma spills over into luma.<br />
[[File:NTSC video ragged box animated.gif|right|frame|Generation and demodulation of a red corner]]<br />
<br clear="all"/><br />
<br />
== Composite decoding ==<br />
<br />
Normal composite video encodes chroma and luma information into one composite analog signal. In order to convert composite into an RGB signal, it firsts needs to be decoded into YUV, before converting the resulting YUV into RGB.<br />
<br />
The NES PPU does not encode anything into composite; instead, directly drawing the composite waveform itself. In order to convert the NES's composite signal into an RGB signal, it is decoded under the "assumption" that it was encoded under YUV.<br />
<br />
YUV in this article refers to and will continue to refer to the equiband encoding of composite video as Y, b-y and r-y respectively. YIQ refers to the non-equiband encoding of composite, which has much more additional considerations regarding bandlimiting.<br />
<br />
In practice, YIQ decoding is not used by any modern TV receiver and composite decoder, instead using YUV decoding as it is much simpler and less mathematically intensive to decode.<ref>[https://www.itu.int/rec/R-REC-BT.1700-0-200502-I/en S170m-2004.pdf: Composite Analog Video Signal NTSC for Studio Applications. Page 17.]</ref><ref>SMPTE EG 27-2004: Supplemental Information for SMPTE 170M and Background on the Development of NTSC Color Standards. Page 5.</ref><br />
<br />
=== Decoding composite video into YUV ===<br />
<br />
Although encoding composite is somewhat standardized, the methods of decoding composite may vary from TV to TV. This article shows one way to decode composite.<br />
<br />
==== Decoding luma information (Y) ====<br />
<br />
To get the luma (Y) component, the base signal is filtered by a lowpass or comb filter. Some TVs use more complex methods to decode luma, some TVs do not filter at all.<br />
<br />
==== Decoding chroma information (UV) ====<br />
<br />
Decoding chroma information requires a subcarrier reference sine wave to determine the hue, whose phase is "locked" (or aligned as best as possible) to the colorburst of the composite scanline.<br />
<br />
The subcarrier reference is used to demodulate the U component. A copy (or a phase offset) of the reference is delayed by 90 degrees, which is then used to demodulate the V component.<br />
<br />
The U/V component is demodulated by multiplying the subcarrier reference to the composite waveform. The resulting waveform is then filtered typically by a lowpass filter. A comb filter can also be used if desired.<br />
<br />
Since demodulation involves multiplying each chroma component by sin(2π·Fsc·t) and the integral of sin(2πx)² over a cycle is 0.5, a factor of 2 must be applied to the demodulator to achieve correct chroma amplitudes and therefore saturation.<br />
=== Converting YUV to signal RGB ===<br />
<br />
To convert YUV to signal RGB, we multiply the components to the following inversed matrix:<br />
<br />
R = Y + V*1.14<br />
G = Y - (R*0.299 - B*0.114) / 0.587<br />
B = Y + U*2.03<br />
<br />
Or, in terms of YUV only:<br />
<br />
R = Y + V*1.14<br />
G = Y - U*0.394242... - V*0.580681...<br />
B = Y + U*2.03<br />
<br />
The matrices above are derived from the NTSC base matrix<ref>[https://www.itu.int/rec/R-REC-BT.1700-0-200502-I/en S170m-2004.pdf: Composite Analog Video Signal NTSC for Studio Applications. Page 4.]</ref> of luminance and color-difference:<br />
<br />
Y = R*0.299 + G*0.587 + B*0.114<br />
B-Y = -R*0.299 - G*0.587 + B*0.886<br />
R-Y = R*0.701 - G*0.587 - B*0.114<br />
<br />
Which, when applied with the approximate color reduction factors 1/2.03 and 1/1.14 for B-Y and R-Y respectively<ref>[https://www.itu.int/rec/R-REC-BT.1700-0-200502-I/en S170m-2004.pdf: Composite Analog Video Signal NTSC for Studio Applications. Page 16.]</ref>, results in the definition of the linear RGB to YUV matrix equation:<br />
<br />
Y = R*0.299 + G*0.587 + B*0.114<br />
U = (-R*0.299 - G*0.587 + B*0.886) / 2.03<br />
V = ( R*0.701 - G*0.587 - B*0.114) / 1.14<br />
<br />
In YIQ, the IQ component's chroma hue is just the UV component's chroma hue rotated by 33 degrees. Note that this is not precisely the same as properly decoding YIQ with different bandwidths for the I and Q component.<br />
<br />
The following conversion is optional, and might match the look of other composite decoders:<br />
<br />
U = -(I * sin(-33 deg)) + (Q * cos(-33 deg))<br />
V = (I * cos(-33 deg)) + (Q * sin(-33 deg))<br />
<br />
==== Normalizing signals ====<br />
<br />
After decoding, it is important to normalize the decoded RGB signals within the range of [0, 1].<br />
<br />
Most TVs use the range 7.5 IRE to 100 IRE for normalizing the signal:<br />
<br />
C = R, G, or B channel<br />
<br />
signal_black_point = <voltage level $0F> + (7.5 / 140.0)<br />
signal_white_point = <voltage level $0F> + (100. / 140.0)<br />
<br />
C -= signal_black_point<br />
C /= (signal_white_point - signal_black_point)<br />
<br />
The 100 IRE white point may be substituted with voltage level $20 because on analog CRT TVs, the luma voltage does not strictly clip at a given level, with only the luminosity of the phosphors being the upper limit.<br />
<br />
signal_white_point = <voltage level $20><br />
<br />
Similarly, some TVs do not use the 7.5 IRE setup black level, instead directly using the blank level.<br />
<br />
signal_black_point = <voltage level $0F><br />
<br />
Finally, the signals must be clipped or normalized to [0, 1] to avoid values outside of the valid range.<br />
<br />
C_raw = R, G, or B channel<br />
C_clip = clipped or normalized R, G, or B channel<br />
<br />
C_clip = max(0, min(1, C_raw))<br />
<br />
=== Converting signal RGB to display RGB ===<br />
<br />
The final step is to convert signal RGB into the output colorspace, typically sRGB for most monitors.<br />
<br />
==== Signal RGB into sRGB ====<br />
<br />
Assuming no colorimetry involved, the resulting R, G and B values can directly be quantized into 8 bits per channel:<br />
<br />
C' = R, G or B signal<br />
C8bpc = quantized R, G, or B channel<br />
<br />
C8bpc = (int)(C' * 255)<br />
<br />
However, if the signal RGB is assumed to be fed a reference display with different color primaries, then a correction matrix must be applied to the signal before quantization.<br />
<br />
==Emulating in C++ code==<br />
<br />
For efficient, ready to use implementations, see [[#Libraries|Libraries]] below. The following is an illustrative example. The values used are based on the "old" measurements given above.<br />
<br />
Calculating the momentary NTSC signal level can be done as follows in C++:<br />
<br />
<nowiki><br />
// pixel = Pixel color (9-bit) given as input. Bitmask format: "eeellcccc".<br />
// phase = Signal phase (0..11). It is a variable that increases by 8 each pixel.<br />
float NTSCsignal(int pixel, int phase)<br />
{<br />
// Voltage levels, relative to synch voltage<br />
static const float black=.518f, white=1.962f, attenuation=.746f,<br />
levels[8] = {.350f, .518f, .962f,1.550f, // Signal low<br />
1.094f,1.506f,1.962f,1.962f}; // Signal high<br />
<br />
// Decode the NES color.<br />
int color = (pixel & 0x0F); // 0..15 "cccc"<br />
int level = (pixel >> 4) & 3; // 0..3 "ll"<br />
int emphasis = (pixel >> 6); // 0..7 "eee"<br />
if(color > 13) { level = 1; } // For colors 14..15, level 1 is forced.<br />
<br />
// The square wave for this color alternates between these two voltages:<br />
float low = levels[0 + level];<br />
float high = levels[4 + level];<br />
if(color == 0) { low = high; } // For color 0, only high level is emitted<br />
if(color > 12) { high = low; } // For colors 13..15, only low level is emitted<br />
<br />
// Generate the square wave<br />
auto InColorPhase = [=](int color) { return (color + phase) % 12 < 6; }; // Inline function<br />
float signal = InColorPhase(color) ? high : low;<br />
<br />
// When de-emphasis bits are set, some parts of the signal are attenuated:<br />
if( ((emphasis & 1) && InColorPhase(0))<br />
|| ((emphasis & 2) && InColorPhase(4))<br />
|| ((emphasis & 4) && InColorPhase(8)) ) signal = signal * attenuation;<br />
<br />
return signal;<br />
}</nowiki><br />
<br />
The process of generating NTSC signal for a single pixel can be simulated with the following C++ code:<br />
<br />
<nowiki><br />
void RenderNTSCpixel(unsigned x, int pixel, int PPU_cycle_counter)<br />
{<br />
int phase = PPU_cycle_counter * 8;<br />
for(int p=0; p<8; ++p) // Each pixel produces distinct 8 samples of NTSC signal.<br />
{<br />
float signal = NTSCsignal(pixel, phase + p); // Calculated as above<br />
// Optionally apply some lowpass-filtering to the signal here.<br />
// Optionally normalize the signal to 0..1 range:<br />
static const float black=.518f, white=1.962f;<br />
signal = (signal-black) / (white-black);<br />
// Save the signal for this pixel.<br />
signal_levels[ x*8 + p ] = signal;<br />
}<br />
}</nowiki><br />
<br />
It is important to note that while the NES only generates eight (8) samples of NTSC signal per pixel, the wavelength for chroma is 12 samples long. This means that the colors of adjacent pixels get mandatorily mixed up to some degree. For the same reason, narrow black&white details can be interpreted as colors.<br />
<br />
Because the scanline length is uneven (341*8 is not an even multiple of 12), the color mixing shifts a little each scanline. This appears visually as a sawtooth effect at the edges of colors at high resolution. The sawtooth cycles every 3 scanlines.<br />
<br />
Because also the frame length is uneven (neither 262*341*8 nor (262*341-1)*8 is an even multiple of 12), the color mixing also changes a little every frame. When rendering is normally enabled, the screen is alternatingly 89342 and 89341 cycles long. The combination of these (89342+89341)*8 <i>is</i> an even multiple of 12, which means that the artifact pattern cycles every 2 frames. The pattern of cycling can be changed by disabling rendering during the end of the pre-render scanline; it forces the screen length to 89342 cycles, even if would be 89341 otherwise.<br />
<br />
The process of decoding NTSC signal (convert it into RGB) is subject to a lot of study, and there are many patents and different techniques for it. A simple method suitable for emulation is covered below. It is not accurate, because in reality the chroma is blurred much more than is done here (the region of signal sampled for I and Q is wider than 12 samples), and the filter used here is a simple box FIR filter rather than an IIR filter, but it already produces a quite authentic looking picture. In addition, the border region (total of 26 pixels of background color around the 256-pixel scanline) is not sampled.<br />
<br />
<nowiki><br />
float signal_levels[256*8] = {...}; // Eight signal levels for each pixel, normalized to 0..1 range. <br />
Calculated as above.<br />
<br />
unsigned Width; // Input: Screen width. Can be not only 256, but anything up to 2048.<br />
float phase; // Input: This should the value that was PPU_cycle_counter * 8 + 3.9<br />
// at the BEGINNING of this scanline. It should be modulo 12.<br />
// It can additionally include a floating-point hue offset.<br />
for(unsigned x = 0; x < Width; ++x)<br />
{<br />
// Determine the region of scanline signal to sample. Take 12 samples.<br />
int center = x * (256*8) / Width + 0;<br />
int begin = center - 6; if(begin < 0) begin = 0;<br />
int end = center + 6; if(end > 256*8) end = 256*8;<br />
float y = 0.f, i = 0.f, q = 0.f; // Calculate the color in YIQ.<br />
for(int p = begin; p < end; ++p) // Collect and accumulate samples<br />
{<br />
float level = signal_levels[p] / 12.f;<br />
y = y + level;<br />
i = i + level * cos( M_PI * (phase+p) / 6 );<br />
q = q + level * sin( M_PI * (phase+p) / 6 );<br />
}<br />
render_pixel(y,i,q); // Send the YIQ color for rendering.<br />
}</nowiki><br />
<br />
The NTSC decoder here produces pixels in YIQ color space.<br />
<br />
If you want more saturated colors, just multiply <code>i</code> and <code>q</code> with a factor of your choosing, such as 1.7. If you want brighter colors, just multiply <code>y</code>, <code>i</code> and <code>q</code> with a factor of your choosing, such as 1.1. If you want to adjust the hue, just add or subtract a value from/to <code>phase</code>. If you want to see so called chroma dots, change the begin and end in such manner that you collect a number of samples that is not divisible with 12. If you want to blur the video horizontally, change the begin and end in such manner that the samples are collected from a wider region.<br />
<br />
The YIQ colors can be converted into sRGB colors with the following formula, using the [https://www.govinfo.gov/content/pkg/CFR-2013-title47-vol4/pdf/CFR-2013-title47-vol4-sec73-682.pdf#page=2 FCC-sanctioned] YIQ-to-RGB conversion matrix. This produces a value that can be saved to e.g. framebuffer:<br />
<br />
<nowiki><br />
float gamma = 2.0f; // Assumed display gamma<br />
auto gammafix = [=](float f) { return f <= 0.f ? 0.f : pow(f, 2.2f / gamma); };<br />
auto clamp = [](int v) { return v>255 ? 255 : v; };<br />
unsigned rgb =<br />
0x10000*clamp(255.95 * gammafix(y + 0.946882f*i + 0.623557f*q))<br />
+ 0x00100*clamp(255.95 * gammafix(y + -0.274788f*i + -0.635691f*q))<br />
+ 0x00001*clamp(255.95 * gammafix(y + -1.108545f*i + 1.709007f*q));</nowiki><br />
<br />
The two images below illustrate the NTSC artifacts.<br />
In the left side image, 12 samples of NTSC signal were generated for each NES pixel,<br />
and each display pixel was separately rendered by decoding that 12-sample signal.<br />
In the right side image, 8 samples of NTSC signal were generated for each NES pixel,<br />
and each display pixel was rendered by decoding 12 samples of NTSC signal from the<br />
corresponding location within the scanline.<br clear="all" /><br />
<br />
<div style="display:flex; flex-direction:row; flex-wrap: wrap;"><br />
[[File:nes_ntsc_perpixel.png|left|frame|Per-pixel rendering: 12 samples of NTSC signal per input pixel; the same 12 samples are decoded for each output pixel]]<br />
[[File:nes_ntsc_perscanline.gif|left|frame|Per-scanline rendering: 8 samples of NTSC signal per input pixel; 12 samples are decoded for each output pixel]]<br />
</div><br />
<div style="display:flex; flex-direction:row; flex-wrap: wrap;"><br />
[[File:nes_ntsc_perpixel_small.png|left|frame|Same as above, but rendered at 256x240 without upscaling]]<br />
[[File:nes_ntsc_perpixel_small_bw.png|left|frame|Same in grayscale (zero saturation). This illustrates well how the different color values have exactly the same luminosity; only the chroma phase differs.]]<br />
[[File:nes_ntsc_perscanline_small.gif|left|frame|Same as above, but rendered at 256x240 rather than at 2048x240 and then downscaled]]<br />
[[File:nes_ntsc_perscanline_small_bw.gif|left|frame|Same in grayscale]]<br />
</div><br />
<br />
The source code of the program that generated both images can be read here: [https://bisqwit.iki.fi/jutut/kuvat/programming_examples/nesemu1/ntsc-small.cc ntsc-small.cc]. Note that even though the image resembles the well-known Philips PM5544 test card, it is not the same; the exact same<br />
colors could not be reproduced with NES colors. In addition, some parts were changed to better test NES features. For example, the backgrounds for the "station ID" regions (the black rectangles at the top and at the bottom inside the circle) are generated using the various blacks within the NES palette.<br />
<br />
Later, Bisqwit made a generic [http://forums.nesdev.org/viewtopic.php?p=172329#p172329 integer-based decoder in C++]. This takes a signal at 12 times color burst and can be used to emulate other systems that use shortcuts when generating NTSC video, such as Apple II (where ''every'' color in <code>HGR</code> is an artifact color) and Atari 7800 (whose game ''Tower Toppler'' seriously exploits artifact colors).<br />
<br />
==Libraries==<br />
<br />
* [http://slack.net/~ant/libs/ntsc.html blargg's nes_ntsc library]<br />
* [//forums.nesdev.org/viewtopic.php?f=21&t=11947 blargg's NTSC demo windows executable]<br />
* [//forums.nesdev.org/viewtopic.php?f=2&t=14338 Forum thread]: New NTSC decoder with integer-only math (short C++ code) - by Bisqwit<br />
* [https://github.com/LMP88959/NTSC-CRT/ LMP88959 (EMMIR)'s NTSC decoder]<br />
<br />
== See also ==<br />
* [[Cycle reference chart]]<br />
* [[PAL video]]<br />
* [[PPU palettes]]<br />
<br />
== References ==<br />
<references /></div>Rainwarriorhttps://www.nesdev.org/w/index.php?title=NSF&diff=21164NSF2023-06-22T06:18:32Z<p>Rainwarrior: /* Header Overview */ more information about frequency of extended character encodings, Shift-JIS is the more common, used by many Famicompo participants. 1252 Latin I don't have any ready examples for.</p>
<hr />
<div>[[Category:Audio]]<br />
[[Category:File formats]]<br />
The NES Sound Format (.nsf) is used for storing and playing music from the NES and related systems. It is similar to the PSID file format for C64 music/sound, where one rips the music/sound code from an NES game and prepends a small header to the data. An NSF player puts the music code into memory at the proper place, based on the header, prepares sound hardware, then runs it to make music. An NSF can be played on NES/Famicom hardware or in an emulator (NSF player or NES emulator).<br />
<br />
There are two extensions of the NSF format:<br />
* [[NSFe]] - Allows a playlist with track titles and times, as well as other metadata.<br />
* [[NSF2]] - A backward compatible extension including NSFe's metadata, IRQ and other features.<br />
<br />
== Header Overview ==<br />
<br />
All 2-byte address and period values are little endian. For example, an NTSC play speed of <code>FF 40</code> means $40FF, or 16639 microseconds.<br />
<br />
offset # of bytes Function<br />
----------------------------<br />
$000 5 STRING 'N','E','S','M',$1A (denotes an NES sound format file)<br />
$005 1 BYTE Version number $01 (or $02 for [[NSF2]])<br />
$006 1 BYTE Total songs (1=1 song, 2=2 songs, etc)<br />
$007 1 BYTE Starting song (1=1st song, 2=2nd song, etc)<br />
$008 2 WORD (lo, hi) load address of data ($8000-FFFF)<br />
$00A 2 WORD (lo, hi) init address of data ($8000-FFFF)<br />
$00C 2 WORD (lo, hi) play address of data ($8000-FFFF)<br />
$00E 32 STRING The name of the song, null terminated<br />
$02E 32 STRING The artist, if known, null terminated<br />
$04E 32 STRING The copyright holder, null terminated<br />
$06E 2 WORD (lo, hi) Play speed, in 1/1000000th sec ticks, NTSC (see text)<br />
$070 8 BYTE Bankswitch init values (see text, and FDS section)<br />
$078 2 WORD (lo, hi) Play speed, in 1/1000000th sec ticks, PAL (see text)<br />
$07A 1 BYTE PAL/NTSC bits<br />
bit 0: if clear, this is an NTSC tune<br />
bit 0: if set, this is a PAL tune<br />
bit 1: if set, this is a dual PAL/NTSC tune<br />
bits 2-7: reserved, must be 0<br />
$07B 1 BYTE Extra Sound Chip Support<br />
bit 0: if set, this song uses [[VRC6 audio]]<br />
bit 1: if set, this song uses [[VRC7 audio]]<br />
bit 2: if set, this song uses [[FDS audio]]<br />
bit 3: if set, this song uses [[MMC5 audio]]<br />
bit 4: if set, this song uses [[Namco 163 audio]]<br />
bit 5: if set, this song uses [[Sunsoft 5B audio]]<br />
bit 6: if set, this song uses [[VT02+_Sound|VT02+ audio]]<br />
bit 7: reserved, must be zero<br />
$07C 1 BYTE Reserved for [[NSF2]]<br />
$07D 3 BYTES 24-bit length of contained program data.<br />
If 0, all data until end of file is part of the program.<br />
If used, can be used to provide [[NSF2#Metadata|NSF2 metadata]]<br />
in a backward compatible way.<br />
$080 nnn ---- The music program/data follows<br />
<br />
Strings are usually encoded in plain ASCII. In most game rips Japanese titles have been romanized into plain ASCII. More rarely NSFs have also used extended characters, the most common of which is [https://en.wikipedia.org/wiki/Code_page_932_(Microsoft_Windows) Windows CP-932] (Shift-JIS) for Japanese titles. [https://en.wikipedia.org/wiki/Windows-1252 Windows CP-1252] (Latin) encoding examples may also exist.<br />
<br />
[[NSF2]] and [[NSFe]] should use UTF-8 instead, or plain ASCII for backward compatibility.<br />
<br />
== Loading a tune into RAM ==<br />
<br />
If file offsets $070 to $077 have $00 in them, then bank switching is ''not''<br />
used. Data should be read from the file beginning at $080 and loaded contiguously<br />
into the 6502 address space beginning at the load address until the end of file is reached.<br />
<br />
Some FDS NSFs use a load address below $8000 to fill in the $6000-7FFF range. It is recommended to use bankswitching to accomplish this instead, because it is not universally supported.<br />
<br />
=== Bank Switching ===<br />
<br />
If any of the bytes from $070 to $077 in the file header are nonzero then bank switching<br />
is used. In this case, take the logical AND of the load address with $0FFF, and the result<br />
specifies the number of bytes of padding at the start of the ROM image. The ROM image should<br />
consist of a contiguous set of 4k banks, read directly from the NSF file beginning at $080 after<br />
inserting the requested number of pad bytes. If the file does not have enough data to fill the<br />
last bank completely, it may be padded out.<br />
<br />
The 6502's address space is divided into 8 4k bank switchable blocks.<br />
For each block the current bank is controlled by writing the bank number to<br />
at corresponding register at $5FF8 through $5FFF. The initial bank assignment<br />
is determined by bytes $070 through $077 in the file.<br />
<br />
NSF Address Register<br />
==== ========== ========<br />
$070 $8000-8FFF $5FF8<br />
$071 $9000-9FFF $5FF9<br />
$072 $A000-AFFF $5FFA<br />
$073 $B000-BFFF $5FFB<br />
$074 $C000-CFFF $5FFC<br />
$075 $D000-DFFF $5FFD<br />
$076 $E000-EFFF $5FFE<br />
$077 $F000-FFFF $5FFF<br />
<br />
The initial bank assignment should be done before any call to the ''INIT'' routine.<br />
Once the ROM image has been built from the NSF file, this can be set up simply<br />
by writing the 8 values from the file header $070-077 to the corresponding<br />
registers $5FF8-$5FFF.<br />
<br />
If the ''INIT'' routine needs to change the bank assignments based on the<br />
selected song, it may do so by writing the bank control registers.<br />
<br />
==== FDS Bankswitching ====<br />
<br />
If the FDS expansion is enabled, bank switching operates slightly differently. Two additional registers at $5FF6 and $5FF7 control the banks $6000-6FFF and $7000-7FFF respectively, and the initial load values at $076 and $077 now specify the banks used for $6000-7FFF as well as $E000-FFFF (these regions will both be set up to use the same banks before ''INIT'' is called).<br />
<br />
Because the FDS has a RAM area at $8000-DFFF for the disk image to be loaded to, that means this area is writable when the FDS expansion is enabled. Some NSF player implementations will treat this like bankswitched RAM, and some players will treat an FDS bank switch operation as a copy into RAM. Hardware players are more likely to use bankswitched RAM.<br />
<br />
This has a number of caveats:<br />
<br />
* Writes may be mirrored if the same bank is used in multiple places. Care should be taken to avoid accidental overwrites when the same bank appears more than once in the bankswitch table. In particular, unique banks should be used for memory regions that must be written to.<br />
* Since the FDS itself was incapable of mirrored writes like this and many players will not have them, mirrored writes should not intentionally be used to store the same data in two memory locations. It is a side effect, not a supported feature.<br />
* Writes to the area may or may not persist in the bank written to if it is switched out and then switched back in. This is another side effect that should be accounted for, but not relied upon.<br />
* Writes may or may not persist between songs, depending on whether the NSF player reloads the NSF image when the song is changed. Hardware players are not likely to reload, but software players may.<br />
<br />
See also the notes on [[#Multi-chip tunes|multi-chip tunes]] below.<br />
<br />
==== Example ====<br />
<br />
METROID.NSF will be used for the following explanation.<br />
<br />
The file is set up like so: (starting at $070 in the file)<br />
<br />
$070: 05 05 05 05 05 05 05 05<br />
$078: 00 00 00 00 00 00 00 00<br />
$080: ... music data goes here...<br />
<br />
Since $070-$077 are something other than $00, this NSF is using bank switching.<br />
The load address given is $8000. The load address AND $0FFF specifies 0 bytes of padding,<br />
so we set up our ROM image with contiguous data starting from $080 in the file.<br />
<br />
This NSF has 6 4k banks in it, numbered 0 through 5. It specifies that each of the 8 memory regions should be switched<br />
to bank 5, which begins at $05 * $1000 bytes in the ROM image.<br />
<br />
== Initializing a tune ==<br />
<br />
The desired song number is loaded into the accumulator register A,<br />
and the X register is set to specify specify PAL (X=1) or NTSC (X=0).<br />
<br />
Valid song numbers are 0 to one less than the number of songs (specified at $006 in the header).<br />
The first selected song is in the header at $007. The NSF player should display<br />
to the user song numbers from 1 up to and including the number of songs, and these should<br />
correspond to the same number - 1 loaded into register A. Note that when choosing the first song<br />
from the value in $007, subtract 1 from it before loading that value into register A.<br />
<br />
# Write $00 to all RAM at $0000-$07FF and $6000-$7FFF.<br />
# Initialize the sound registers by writing $00 to $4000-$4013, and $00 then $0F to $4015.<br />
# Initialize the [[APU Frame Counter|frame counter]] to 4-step mode ($40 to $4017).<br />
# If the tune is bank switched, load the bank values from $070-$077 into $5FF8-$5FFF.<br />
# Set the A register for the desired song.<br />
# Set the X register for PAL or NTSC.<br />
# Call the music ''INIT'' routine.<br />
<br />
The ''INIT'' routine MUST finish with an RTS instruction before music playback will begin.<br />
At this point, the NSF player will begin executing the ''PLAY'' routine at the specified interval.<br />
<br />
If this is a single standard tune (PAL or NTSC but not both) the ''INIT'' routine MAY ignore the X register.<br />
Otherwise, it SHOULD use this value to determine how to set pitches and tempo for the appropriate platform.<br />
<br />
The use of the $4017 register is not well supported by existing NSF players. The NSF should not normally clear bit 6 (the IRQ disable bit), though the [[#Pseudo-IRQ Technique|Pseudo-IRQ Technique]] relies on being able to do this.<br />
<br />
While the NSF1 specification never guaranteed anything for Y on entry to INIT,<br />
for better forward compatibility with [[NSF2#Non-Returning INIT|NSF2's non-returning INIT]] feature,<br />
it is recommended that the player set Y to 0, or at least some value that is not $80 or $81, before calling INIT.<br />
<br />
== Playing a tune ==<br />
<br />
Once the tune has been initialized, it can now be played.<br />
To do this, simply call the routine at the ''PLAY'' address at the rate <br />
determined by the file header at $06E-06F (NTSC) or $078-079 (PAL).<br />
<br />
The playback rate is determined by this formula:<br />
<br />
1000000 1000000<br />
rate = --------- period = ---------<br />
period speed<br />
<br />
Where period is the value you place at $06E-$06F in the file, and<br />
rate is how often the ''PLAY'' routine should be called in Hz.<br />
<br />
The following playback rates are common:<br />
* 60.002 Hz (recommended by the original NSF specification, close to APU timer IRQ rate): 16666 ($411A)<br />
* 60.099 Hz (actual NTSC NES [[Cycle_reference_chart#Clock_rates|frame rate]]): 16639 ($40FF)<br />
* 50.007 Hz (suggested PAL NES frame rate): 19997 ($4E1D)<br />
<br />
Nonstandard rates may be difficult for hardware players. If the rate is much faster the ''PLAY'' routine may not be short enough to execute in the specified amount of time.<br />
<br />
The ''PLAY'' routine will be called at the specified interval. If the X register passed to ''INIT'' was 1 (PAL), it will be called at the rate specified by $078-079, and if 0 (NTSC), it will use the rate at $06E-06F.<br />
<br />
A ''PLAY'' routine should normally finish with an RTS instruction, but is not required to do so.<br />
A non-returning ''PLAY'' will cause problems for NSF players that use the same CPU to control the user interface and to run the NSF, such as NSF players that run on an NES.<br />
It is strongly recommended to return every few frames if at all possible, such as when no PCM is playing.<br />
If ''PLAY'' takes longer to finish than the specified interval, that interval may be skipped and ''PLAY'' may not be called again until the next one.<br />
<br />
Some popular modern NSF engines use a non-returning ''PLAY'' to implement an output stream of PCM sound (e.g. SuperNSF, MUSE, Deflemask), and this can also be combined with a [[#Pseudo-IRQ Technique|Pseudo-IRQ technique]].<br />
<br />
== Sound Chip Support ==<br />
Byte $07B of the file stores the sound chip flags. If a particular flag is set, those sound registers should be enabled. If the flag is clear, then those registers should be disabled. All I/O registers within $8000-FFFF are ''write only'' and must not disrupt music code that happens to be stored there. Some audio register addresses have mirrors in their original hardware mappers, but NSF code should use only the lowest address for each register, listed here.<br />
<br />
=== APU ===<br />
* Uses registers $4000-4013, and $4015. See [[APU]] for more information.<br />
* $4015 is set to 0F on reset by most players. It is better if the NSF does not assume this and initializes this register itself, but there are several existing NSF files that require it (Battletoads, Castlevania and Gremlins 2 are examples).<br />
* The APU interrupts that can be generated via $4015 and $4017 are not reliably available across NSF players, and have usually been considered out of bounds for NSF rips. [[NSF2]] can explicitly allow them, however.<br />
* $4017 has other features that are not consistently supported across NSF players.<br />
<br />
=== VRCVI ===<br />
* Uses registers $9000-9003, $A000-A002, and $B000-B002, write only. See [[VRC6_audio|VRC6 Audio]] for more information.<br />
* The A0 and A1 lines are flipped on a few games. If you rip the music and it sounds all funny, flip around the xxx1 and xxx2 register pairs. (i.e. 9001 and 9002) Esper2 and Madara will need this change, while Castlevania 3j will not.<br />
<br />
=== VRCVII ===<br />
* Uses registers $9010 and $9030, write only. See [[VRC7_audio|VRC7 Audio]] for more information.<br />
<br />
=== FDS Sound ===<br />
* Uses registers from $4040 through $4092. See [[FDS_audio|FDS Audio]] for more information.<br />
<br />
Notes:<br />
* $6000-DFFF is assumed to be RAM, since $6000-DFFF is RAM on the FDS. $E000-FFFF is usually not included in FDS games because it is the BIOS ROM. However, it can be used on FDS rips to help the ripper (for modified ''PLAY''/''INIT'' addresses).<br />
* Bank switching is different if FDS is enabled. $5FF6 and $5FF7 control banks at $6000-6FFF and $7000-7FFF, and the NSF header $076-$077 initialized both $6000-7FFF and $E000-FFFF. See above.<br />
<br />
=== MMC5 Sound ===<br />
* Uses registers $5000-5015, write only as well as $5205 and $5206, and $5C00-5FF5. see [[MMC5_audio|MMC5 Audio]] for more information.<br />
<br />
Notes:<br />
* $5205 and $5206 are a hardware 8 * 8 multiplier. The idea being you write your two bytes to be multiplied into 5205 and 5206 and after doing so, you read the result back out.<br />
* $5C00-5FF5 should be RAM to emulate EXRAM while in MMC5 mode.<br />
<br />
=== Namco 163 Sound ===<br />
* Uses registers $4800 and $F800. See [[Namco 163 audio]] for more information.<br />
<br />
=== Sunsoft 5B Sound ===<br />
* Audio in the Sunsoft 5B mapper, a variant of the [[FME-7]], uses registers $C000 and $E000. See [[Sunsoft audio]].<br />
* Many players do not implement the noise or envelope capabilities of the 5B, as they were not used in the only 5B game, Gimmick.<br />
<br />
=== Multi-chip tunes ===<br />
<br />
Multiple expansion chips can be used at the same time, but because this was not something that was ever supported by an original Famicom games, actual practice with multi-expansion NSF varies.<br />
<br />
Some mappers mirror their audio registers at addresses that would conflict. Many NSF players only support the lowest address, which avoids these conflicts, but the following conflicts may need resolution in an attempted hardware multi-chip implementation:<br />
<br />
* N163's address port $F800 overlaps a mirror of Sunsoft 5B's data port $E000. This can be avoided by setting Sunsoft 5B's address port $C000 to $0E or $0F (unused internal registers) before writing to the N163.<br />
* VRC6 and VRC7 have a conflict at ports $9010 and $9030, where the VRC6's pulse 1 control port is mirrored.<br />
* VRC7 and N163 each have a mute or reset register at $E000, which conflicts with Sunsoft 5B's data port. Since writing $E000 with bit 6 set will silence either of these, an emulator may wish to ignore writes to $E000 for VRC7/N163 if 5B is also present.<br />
* FDS will make the normally read-only area from $8000-$DFFF writable. This may cause corruption of these areas when writing to VRC6, VRC7, or 5B audio registers. The safest way to avoid this is to make sure your code and data do not fall within these addresses, so that you may safely write to them. NSF player implementations may wish to disable memory writes at these addresses to avoid the conflict.<br />
<br />
== Caveats ==<br />
* The starting song number and maximum song numbers start counting at 1, while the ''INIT'' address of the tune starts counting at 0. Remember to pass the desired song number ''minus 1'' to the ''INIT'' routine.<br />
* The NTSC speed word is used ''only'' for NTSC tunes and dual PAL/NTSC tunes. The PAL speed word is used ''only'' for PAL tunes and dual PAL/NTSC tunes.<br />
* If bit 1 of the PAL/NTSC is set, indicating a dual PAL/NTSC NSF, bit 0 may be interpreted as a preference for PAL or NTSC. Most players do not support this, however, and some older players may have problems if bit 0 is set.<br />
* The length of the text in the name, artist, and copyright fields must be 31 characters or less. There has to be at least a single NULL byte ($00) after the text, between fields.<br />
* If a field is not known (name, artist, copyright) then the field must contain the string "<?>" (without quotes). <br />
* There should be 8K of RAM present at $6000-7FFF. MMC5 tunes need RAM at $5C00-5FF7 to emulate its $EXRAM. $8000-FFFF should be read-only (not writable) after a tune has loaded. The only time this area should be writable is if an FDS tune is being played.<br />
* Do not assume the state of ''anything'' on entry to the ''INIT'' routine except A and X. Y can be anything, as can the flags.<br />
* Do not assume the state of ''anything'' on entry to the ''PLAY'' routine. Flags, X, A, and Y could be at any state.<br />
* The stack sits at $01FF and grows down. The precise position of the stack on ''INIT'' or ''PLAY'' is not guaranteed, as the NSF player may need to use the top area of the stack for its own internal purpose. Make sure the tune does not attempt to modify $01F0-01FF directly. (Armed Dragon Villigust did, and was relocated to 2xx for its NSF.)<br />
* The NSF should not initialize the stack pointer in ''INIT'' or ''PLAY''. These subroutines are called from the player; some software emulators may not have a problem with this, but it will almost certainly cause an error on a hardware player. It is the player's job to initialize the stack pointer, and some hardware players (e.g. [[PowerPak]]) will place their own variables on the stack.<br />
* RAM should be addressed from $0000-07FF, and should not expect mirror addresses to work. If the tune writes outside this range, e.g. $1400 it should be relocated. (Terminator 3 did this and was relocated to 04xx for NSF.)<br />
* The vector table at $FFFA-FFFF should not be filled with code or data by the NSF. These can be overridden by hardware NSF players.<br />
* Instructions which modify the stack, PLP, PHP, and TXS must be used with great care, as a player may need to rely on being able to store data at the end of the stack. An NSF should use the stack pointer given; the stack past this pointer should remain intact, as it may be needed by the player.<br />
* Instructions CLI, SEI, and BRK are problematic, and should usually be avoided. The NSF itself should generally not attempt to interfere with IRQs, as many NSF players do not have an IRQ implementation. One notable exception is using SEI in a non-returning ''PLAY'' routine for a [[#Pseudo-IRQ Technique|pseudo-IRQ technique]]. BRK should generally not be used, as it reads the IRQ routine address from the vector table which is reserved for the player's use.<br />
* PowerPak's NSF play incorrectly does not restore the startup banks when switching tracks, so unless the PLAY routine always leaves with the INIT routine in its starting bank, switching tracks will fail on it.<br />
<br />
== Summary of Addresses ==<br />
<br />
These lists all the addresses which should be readable by the code in the NSF; no other addresses should ever be accessed for reading:<br />
* $0000-$01EF<br />
* $01F0-$01FF (may be used internally by NSF player)<br />
* $0200-$07FF<br />
* $4015<br />
* $4040-$407F (if FDS is enabled)<br />
* $4090 (if FDS is enabled)<br />
* $4092 (if FDS is enabled)<br />
* $4800 (if Namco 163 is enabled)<br />
* $5205-$5206 (if MMC5 is enabled)<br />
* $5C00-$5FF5 (if MMC5 is enabled)<br />
* $6000-$FFF9<br />
<br />
These lists all the addresses which should be writable by the code in the NSF; no other addresses should ever be accessed for writing:<br />
* $0000-$01EF<br />
* $01F0-$01FF (may be used internally by NSF player; do not use for non-stack variables)<br />
* $0200-$07FF<br />
* $4000-$4013 (always clear bit7 of $4010)<br />
* $4015<br />
* $4040-$4080 (if FDS is enabled)<br />
* $4082-$408A (if FDS is enabled)<br />
* $4800 (if Namco 163 is enabled)<br />
* $5205-$5206 (if MMC5 is enabled)<br />
* $5C00-$5FF5 (if MMC5 is enabled)<br />
* $5FF6-$5FF7 (if bankswitching and FDS is enabled)<br />
* $5FF8-$5FFF (if bankswitching is enabled)<br />
* $6000-$7FFF<br />
* $8000-$DFFF (if FDS is enabled)<br />
* $9000-$9003 (if VRC6 is enabled)<br />
* $9010 (if VRC7 is enabled)<br />
* $9030 (if VRC7 is enabled)<br />
* $A000-$A002 (if VRC6 is enabled)<br />
* $B000-$B002 (if VRC6 is enabled)<br />
* $F800 (if Namco 163 is enabled)<br />
<br />
Reading/writing anything other than specified here results in undefined behaviour.<br />
<br />
== Pseudo-IRQ Technique ==<br />
<br />
Some modern NSFs use a trick<ref>[http://forums.nesdev.org/viewtopic.php?f=6&t=9296 NSF PCM technique (via Deflemask)] forum post</ref> first made popular by [http://www.delek.com.ar/deflemask Deflemask], primarily intended to support PCM sample playback. This technique is not universally supported, because it may rely on a lack of conflict with the player's implementation. Some hardware implementations do support it correctly (e.g. [[PowerPak]]), and it also works with several software NSF players.<br />
<br />
The technique uses a non-returning ''PLAY'' in the following way:<br />
<br />
# Use SEI to mask interrupts.<br />
# Enable the APU interrupt by writing to $4017.<br />
# Enter a sample playback loop, polling $4015 to see if an APU IRQ is pending.<br />
# When the poll registers the APU IRQ flag (occurring at 60 hz on NTSC), temporarily exit the sample playback loop to do other tasks.<br />
# Return to step 3, never returning from ''PLAY''.<br />
<br />
== See also ==<br />
*[[List of NES music composers]]<br />
*[[Emulation Libraries#NSF Players|Emulation Libraries: NSF Players]]<br />
*[[iNES Mapper 031]]: Cart mapper with NSF-inspired bankswitching<br />
*[[NSFDRV]]<br />
<br />
== References ==<br />
* [http://kevtris.org/nes/nsfspec.txt Kevtris' Official NSF spec] - the original NSF specification<br />
* [http://kevtris.org/Projects/hardnes/index.html Kevtris' HardNES] - a hardware NSF player project<br />
<references/></div>Rainwarriorhttps://www.nesdev.org/w/index.php?title=PAL_video&diff=21009PAL video2023-04-10T21:56:51Z<p>Rainwarrior: /* See Also */ link forum thread with some odd PAL effects</p>
<hr />
<div>The 2C07 PPU in the PAL NES and the 6538 PPU in PAL famiclones generate composite '''PAL video''' in much the same way that the 2C02 generates [[NTSC video]]: as a square wave between "high" and "low" levels, offset by 0 to 5.5 master clock cycles from the phase of color burst.<br />
<br />
PAL NES video has several key differences from NTSC NES video:<br />
<br />
;[[wikipedia:PAL|Phase Alternating Line]]<br />
:The phase of the V subcarrier inverts between each scanline and the next. The color burst is ideally at 135 degrees relative to the [[wikipedia:YUV|UV plane]], not 180. This allows the TV to detect the phase of the V subcarrier by comparing the phase of color burst to that of the previous line. The PAL NES outputs a somewhat nonstandard 120 degree color burst.<br />
;Higher color subcarrier frequency<br />
:Pixels are 5 master clock cycles long (5/6 of a pixel), rather than 4 (4/6), increasing the chroma resolution slightly.<br />
;50 Hz<br />
:Each field contains 312 lines, not 262, producing vertical [[Overscan|underscan]] and a pixel aspect ratio close to 1.386:1, which is wider than 1.143:1 of NTSC.<br />
;No short line<br />
:The dot at the end of pre-render scanline is never skipped. This combined with the fact that 312 is a multiple of 6 causes the chroma dot pattern not to vary from one field to the next, producing dirty stills but OK movement.<br />
;Phase per line<br />
:The PAL NES scanline has 284⅙ chroma cycles, rather than the standard 283¾. This results in a 6-line pattern of color artifacts, as the phase changes by 60° on each line. NTSC by comparison has 227⅓ chroma cycles per line, giving a 3-line pattern.<br />
;Larger border<br />
:The border, including the area outside the picture, is always black rather than using the background color at $3F00, and it covers the top scanline and the left and right 2 pixels of each remaining scanline.<br />
;Hue shift<br />
:The color hue is slightly different relative to NTSC. There is a 15 degree shift due to the color burst effectively using color phase "7.5" instead of 8, but this difference may be mitigated for brighter colors by PAL's cancellation of differential phase distortion effects (see below), which on NTSC appear to cause a similar shift but only for brighter colors.<br />
;Differential phase distortion<br />
:The output is subject to differential phase distortion like the NTSC PPU, and on individual scanlines the effect may be even more severe on PAL<ref>[//forums.nesdev.org/viewtopic.php?p=133640#p133640 Re: PAL chroma merging?] TheFox observes a ~60° hue difference between even and odd scanlines.</ref>, but because the alternating-line mechanism causes the hue distortion to be opposite on consecutive lines, the color error can cancel out vertically when it's not on isolated rows. (See: [[NTSC video#Color phases|NTSC video: Color phases]])<br />
<br />
The 2C07 and 6538 additionally have minor timing differences related to post-render length and OAM refresh; see [[Cycle_reference_chart#Clock_rates|Clock rate]].<br />
<br />
There are two different ways that a TV can ''decode'' PAL video.<br />
The simple way treats PAL as if it were NTSC, modulo the five differences above.<br />
If the television signal is subject to phase distortion, this produces an artifact called [[wikipedia:Hanover bars|Hanover bars]].<br />
The other way is a comb filter: average the received scanline's chroma (U and V channels) with the chroma from the received scanline immediately above it in the same field and use that.<br />
This method, invented by an engineer at Telefunken, eliminates Hanover bars at the expense of a 64 microsecond quartz delay line, a royalty payable to Telefunken, and blurred vertical color detail.<br />
Less expensive PAL TVs used the simple method and relied on the change in color burst phase over time to cancel out the Hanover bars, though this technique may not be effective with the slightly nonstandard scanline length in the PAL signal from an NES.<br />
<br />
Emulator developers planning to simulate PAL video decoding can use a signal captured from a 6538 to test the decoder:<br />
* [[:File:PAL signal 6538 250MHz.png|250 MHz capture]]<br />
* [[:File:PAL signal 6538 53.2MHz.png|Same capture downsampled to twelve times the subcarrier frequency (53.2 MHz)]], with one pixel per rise or fall of the master clock<br />
<br />
== Libraries ==<br />
* [https://github.com/LMP88959/PAL-CRT/ LMP88959 (EMMIR)'s PAL decoder]<br />
<br />
== See Also ==<br />
* [[NTSC video]]<br />
<br />
== References ==<br />
<References/><br />
* [//forums.nesdev.org/viewtopic.php?t=18406 What is the cause of these three effects?] - Some strange decoding effects observed on a PAL television.</div>Rainwarriorhttps://www.nesdev.org/w/index.php?title=NES_2.0&diff=21008NES 2.02023-04-10T21:23:33Z<p>Rainwarrior: /* Hard-Wired Mirroring */ retracting mapper UxROM (no 4-screen release yet)</p>
<hr />
<div>'''NES 2.0''' extends the [[iNES]] single file cart format to better describe NES/Famicom-compatible cartridge hardware. Some of its purpose include:<br />
* Removing the need to use ROM checksums, or other information outside the header, to disambiguate emulation behavior not encoded by iNES.<br />
* Making room for new mapper allocation.<br />
* Allowing for larger ROM sizes.<br />
* Supporting other than standard NES/Famicom console types such as the Nintendo Vs. System and enhanced Famiclones.<br />
* Providing additional information such as the region-specific CPU/PPU type and default expansion port devices.<br />
* Replaces the deprecated [[UNIF]] format.<br />
<br />
The format is [[#Backwards Compatibility to iNES|backwards-compatible]] to iNES, so that ROM images with a NES 2.0 header run in non-NES-2.0-compliant emulators as long as they do not require NES-2.0-exclusive features.<br />
<br />
=Identification=<br />
A file is a NES 2.0 ROM image file if it begins with "NES<EOF>" (same as iNES) and, additionally, the byte at offset 7 has bit 2 clear and bit 3 set:<br />
bool iNESFormat=false;<br />
if (header[0]=='N' && header[1]=='E' && header[2]=='S' && header[3]==0x1A)<br />
iNESFormat=true;<br />
<br />
bool NES20Format=false;<br />
if (iNESFormat==true && (header[7]&0x0C)==0x08)<br />
NES20Format=true;<br />
=File Structure=<br />
A NES 2.0 file contains a sixteen-byte header, followed by Trainer, PRG-ROM, CHR-ROM and Miscellaneous ROM data.<br />
<br />
==Header==<br />
Offset Meaning<br />
--------------<br />
0-3 Identification String. Must be "NES<EOF>".<br />
<br />
4 [[#PRG-ROM Area|PRG-ROM]] size LSB<br />
5 [[#CHR-ROM Area|CHR-ROM]] size LSB<br />
<br />
6 Flags 6<br />
D~7654 3210<br />
---------<br />
NNNN FTBM<br />
|||| |||+-- [[#Hard-Wired Mirroring|Hard-wired nametable mirroring type]]<br />
|||| ||| 0: Horizontal (vertical arrangement) or mapper-controlled<br />
|||| ||| 1: Vertical (horizontal arrangement)<br />
|||| ||+--- "Battery" and other non-volatile memory<br />
|||| || 0: Not present<br />
|||| || 1: Present<br />
|||| |+--- 512-byte [[#Trainer Area|Trainer]]<br />
|||| | 0: Not present<br />
|||| | 1: Present between Header and PRG-ROM data<br />
|||| +---- [[#Hard-Wired Mirroring|Hard-wired four-screen mode]]<br />
|||| 0: No<br />
|||| 1: Yes<br />
++++------ Mapper Number D0..D3<br />
<br />
7 Flags 7<br />
D~7654 3210<br />
---------<br />
NNNN 10TT<br />
|||| ||++- Console type<br />
|||| || 0: Nintendo Entertainment System/Family Computer<br />
|||| || 1: Nintendo [[Vs. System]]<br />
|||| || 2: Nintendo [[PC10 ROM-Images|Playchoice 10]]<br />
|||| || 3: [[#Extended Console Type|Extended Console Type]]<br />
|||| ++--- NES 2.0 identifier<br />
++++------ Mapper Number D4..D7<br />
<br />
8 [[Mapper]] MSB/[[Submapper]]<br />
D~7654 3210<br />
---------<br />
SSSS NNNN<br />
|||| ++++- Mapper number D8..D11<br />
++++------ Submapper number<br />
<br />
9 [[#PRG-ROM Area|PRG-ROM]]/[[#CHR-ROM Area|CHR-ROM]] size MSB<br />
D~7654 3210<br />
---------<br />
CCCC PPPP<br />
|||| ++++- PRG-ROM size MSB<br />
++++------ CHR-ROM size MSB<br />
<br />
10 [[#PRG-(NV)RAM/EEPROM|PRG-RAM/EEPROM]] size<br />
D~7654 3210<br />
---------<br />
pppp PPPP<br />
|||| ++++- PRG-RAM (volatile) shift count<br />
++++------ PRG-NVRAM/EEPROM (non-volatile) shift count<br />
If the shift count is zero, there is no PRG-(NV)RAM.<br />
If the shift count is non-zero, the actual size is<br />
"64 << shift count" bytes, i.e. 8192 bytes for a shift count of 7.<br />
<br />
11 [[#CHR-(NV)RAM|CHR-RAM]] size<br />
D~7654 3210<br />
---------<br />
cccc CCCC<br />
|||| ++++- CHR-RAM size (volatile) shift count<br />
++++------ [[:Category:Mappers with battery-backed CHR-RAM|CHR-NVRAM]] size (non-volatile) shift count<br />
If the shift count is zero, there is no CHR-(NV)RAM.<br />
If the shift count is non-zero, the actual size is<br />
"64 << shift count" bytes, i.e. 8192 bytes for a shift count of 7.<br />
<br />
12 [[#CPU/PPU Timing|CPU/PPU Timing]]<br />
D~7654 3210<br />
---------<br />
.... ..VV<br />
++- CPU/PPU timing mode<br />
0: RP2C02 ("NTSC NES")<br />
1: RP2C07 ("Licensed PAL NES")<br />
2: Multiple-region<br />
3: UA6538 ("Dendy")<br />
<br />
13 When Byte 7 AND 3 =1: [[#Vs. System Type|Vs. System Type]]<br />
D~7654 3210<br />
---------<br />
MMMM PPPP<br />
|||| ++++- Vs. PPU Type<br />
++++------ Vs. Hardware Type<br />
<br />
When Byte 7 AND 3 =3: [[#Extended Console Type|Extended Console Type]]<br />
D~7654 3210<br />
---------<br />
.... CCCC<br />
++++- Extended Console Type<br />
<br />
14 [[#Miscellaneous ROM Area|Miscellaneous ROMs]]<br />
D~7654 3210<br />
---------<br />
.... ..RR<br />
++- Number of miscellaneous ROMs present<br />
<br />
15 [[#Default Expansion Device|Default Expansion Device]]<br />
D~7654 3210<br />
---------<br />
..DD DDDD<br />
++-++++- Default Expansion Device<br />
<br />
==Trainer Area==<br />
The Trainer Area follows the 16-byte Header and precedes the PRG-ROM area if bit 2 of Header byte 6 is set. It is always 512 bytes in size if present,<br />
and contains data to be loaded into CPU memory at $7000. It is only used by some games that were modified to run on different hardware from the original cartridges,<br />
such as early RAM cartridges and emulators, and which put some additional compatibility code into those address ranges.<br />
==PRG-ROM Area==<br />
The PRG-ROM Area follows the 16-byte Header and the Trainer Area and precedes the CHR-ROM Area. Header byte 4 (LSB) and bits 0-3 of Header byte 9 (MSB) together specify its size.<br />
If the MSB nibble is $0-E, LSB and MSB together simply specify the PRG-ROM size in 16 KiB units:<br />
++++----------- Header byte 9 D0..D3<br />
|||| ++++-++++- Header byte 4<br />
D~BA98 7654 3210<br />
--------------<br />
BBBB BBBB BBBB<br />
++++-++++-++++- PRG-ROM size in 16 KiB units,<br />
values $000-$EFF for 0..62,898,176 bytes<br />
If the MSB nibble is $F, an exponent-multiplier notation is used:<br />
++++----------- Header byte 9 D0..D3<br />
|||| ++++-++++- Header byte 4<br />
D~BA98 7654 3210<br />
--------------<br />
1111 EEEE EEMM<br />
|||| ||++- Multiplier, actual value is MM*2+1 (1,3,5,7)<br />
++++-++--- Exponent (2^E), 0-63<br />
<br />
The actual PRG-ROM size is 2^E *(MM*2+1) bytes.<br />
The exponent-multiplier form may only be used if the PRG-ROM size cannot be specified correctly using the simpler notation. If the PRG-ROM data has an odd size that cannot<br />
be represented in either notation, the data must be padded to a size that can be represented.<br />
<br />
In Vs. Dual System ROM images, the first half block of the specified PRG-ROM size belongs to the first unit, and the second half block of PRG-ROM belongs to the the second unit.<br />
24 KiB (half-)blocks are mapped to $A000-$FFFF both in Vs. Unisystem and Vs. Dual System.<br />
An exception is granted for two oddly-sized Vs. System ROM images with a total of 40 KiB PRG-ROM, which are defined to represent 32 KiB +8 KiB instead:<br />
* ''Vs. Gumshoe'', [[#Vs. System Type|Vs. Hardware type]] #0:<br />
** First 32 KiB represent the entire CPU $8000-$FFFF area, including the CPU $8000-$9FFF area with $4016 D2=0;<br />
** Second 8 KiB represent the CPU $8000-$9FFF area with $4016 D2=1.<br />
* ''Vs. Raid on Bungeling Bay'', [[#Vs. System Type|Vs. Hardware type]] #6:<br />
** First 32 KiB represent the first unit's PRG-ROM at CPU $8000-$FFFF;<br />
** Second 8 KiB represent the second unit's PRG-ROM at CPU $E000-$FFFF.<br />
** The second unit only executes a dummy program that does nothing except set a flag in the shared WRAM at $6000-$67FF.<br />
<br />
==CHR-ROM Area==<br />
The CHR-ROM Area, if present, follows the Trainer and PRG-ROM Areas and precedes the Miscellaneous ROM Area. Header byte 5 (LSB) and bits 4-7 of Header byte 9 (MSB)<br />
specify its size. If the MSB nibble is $0-E, LSB and MSB together simply specify the CHR-ROM size in 8 KiB units:<br />
++++----------- Header byte 9 D4..D7<br />
|||| ++++-++++- Header byte 5<br />
D~BA98 7654 3210<br />
--------------<br />
BBBB BBBB BBBB<br />
++++-++++-++++- CHR-ROM size in 8 KiB units,<br />
values $000-$EFF for 0..31,449,088 bytes<br />
If the MSB nibble is $F, an exponent-multiplier notation is used:<br />
++++----------- Header byte 9 D4..D7<br />
|||| ++++-++++- Header byte 5<br />
D~BA98 7654 3210<br />
--------------<br />
1111 EEEE EEMM<br />
|||| ||++- Multiplier, actual value is MM*2+1 (1,3,5,7)<br />
++++-++--- Exponent (2^E), 0-63<br />
<br />
The actual CHR-ROM size therefore becomes 2^E * (MM*2+1).<br />
The exponent-multiplier form may only be used if the CHR-ROM size cannot be specified correctly using the simpler notation. If the CHR-ROM data has an odd size that cannot<br />
be represented by either notation, the data must be padded to a size that can be represented.<br />
<br />
For Vs. Dual System ROM images, if the CHR-ROM size is 32 KiB, the first 16 KiB belong to the first unit, and the second 16 KiB of CHR-ROM belong to the second unit.<br />
If the CHR-ROM size is 16 KiB, the both units use the same bank-switched 16 KiB CHR-ROM data.<br />
<br />
==Miscellaneous ROM Area==<br />
The Miscellaneous ROM Area, if present, follows the CHR-ROM area and occupies the remainder of the file. Its size is not explicitly denoted in the header, and can be deduced<br />
by subtracting the 16-byte Header, Trainer, PRG-ROM and CHR-ROM Area sizes from the total file size. The meaning of this data depends on the console type and mapper type; Header<br />
byte 14 is used to denote the presence of the Miscellaneous ROM Area and the number of ROM chips in case any disambiguation is needed. Currently, miscellaneous ROMs are defined<br />
for the following situations:<br />
* on console type [[PC10 ROM-Images|Playchoice 10]], an 8 KiB INST ROM, 16 bytes of PROM Data, 16 bytes of PROM Counter Out data, for a total of "3" miscellaneous ROMs;<br />
* on console type [[VT369]], 4 KiB of ROM that is embedded into the NES-on-a-chip itself;<br />
* on [[INES Mapper 086]] submapper 1, a single miscellaneous ROM containing speech data;<br />
* on [[NES 2.0 Mapper 355]], the embedded ROM of the PIC16C54 microcontroller that the games use for protection purposes.<br />
* on [[NES 2.0 Mapper 561]] and [[NES 2.0 Mapper 562]] to deliver trainers that do not match the iNES trainer conventions in size (512 byte) or location ($7000).<br />
<br />
=Notes=<br />
==Backwards Compatibility to iNES==<br />
* Bytes 0-7 have the same meaning as in [[iNES]], so that NES-2.0-headered games will still run in emulators that do not support NES 2.0 unless the header specifies features that those older emulators did not support anyway.<br />
* The NES 2.0 identifier (Byte 7 D2..D3) has been chosen so that it does not collide with any valid iNES header nor with any known ROM image that has garbage in bytes 7-15 such as "DiskDude!".<br />
==Hard-Wired Mirroring==<br />
Byte 6 (Flags 6) contains two bits to describe the [[Mirroring#Nametable Mirroring|nametable mirroring]] capabilities of the cartridge.<br />
<br />
D~7654 3210<br />
---------<br />
.... F..M<br />
| +-- Horizontal/vertical hard-wired mirroring.<br />
+----- 4-screen nametables.<br />
<br />
* Bit 0 is normally relevant only if the mapper does not allow the mirroring type to be switched. It should be set to zero otherwise.<br />
* The standard meaning of bit 3 is that 4 KiB of RAM are present at PPU $2000-2FFF, exclusive to that region, and cannot be banked, replaced, or rearranged. This applies to:<br />
** [[INES Mapper 004|Mapper 4]] (MMC3)<br />
** [[INES Mapper 206|Mapper 206]] (DxROM, etc. MMC3-like subset)<br />
** [[INES Mapper 077|Mapper 77]] (Napoleon Senki)<br />
** [[NES 2.0 Mapper 262|Mapper 262]] (Street Heroes)<br />
* Three mappers use these bits in a nonstandard way:<br />
** [[INES Mapper 030#Nametable Configuration|Mapper 30]] (UNROM 512) - This board can be wired for H/V fixed, 1-screen, or 4-screen.<br />
** [[INES Mapper 218|Mapper 218]] (Magic Floor) - This experimental board had 4 configurations that allowed the internal 2k CIRAM to be used for both CHR and nametables at once.<br />
** [[INES Mapper 078|Mapper 78]] (Holy Diver, Cosmo Carrier) - This board had two different mapper-controlled nametable configurations. Bit 3 was used to select between them in the past, but NES 2.0 has assigned [[NES 2.0 submappers#078: Cosmo Carrier / Holy Diver|submappers for this]] instead.<br />
* Some emulators allow bit 3 in its standard meaning to be used with a wide variety of mappers, replacing the fixed or mapper-controlled nametable mirroring with exclusive RAM. Support for this is inconsistent across emulators.<br />
<br />
==PRG-(NV)RAM/EEPROM==<br />
The PRG-(NV)RAM/EEPROM fields specify the sizes of...<br />
* Memory that is mapped into CPU address space, regardless of whether that memory is internal to a mapper chip or in a separate RAM chip;<br />
* EEPROM even if it is not mapped into CPU address space.<br />
They do not specify the sizes of...<br />
* Mapper-chip-internal memory that is not mapped into CPU address space, even if battery-backed, such as the [[Namco 163]]'s wavetable RAM which some games use to store saved game data. The size of such memory is part of the Mapper definition instead. The Battery bit (Header byte 6 bit 1) denotes whether such memory is battery-backed. The [[MMC5]]'s EXRAM is not included in the PRG-RAM size, as it can be mapped by software to CPU, PPU, or no address space at all;<br />
* self-flashable PRG-ROM;<br />
* external storage such as cassette tape or the ASCII Turbo File.<br />
When the upper nibble (PRG-NVRAM/EEPROM) has a non-zero value, the Battery bit (Header byte 6 bit 1) must always be set for compatibility with [[iNES]]. Conversely, if the Battery bit is set, the upper nibble must have a non-zero value, unless the only battery-backed memory is either mapper-chip-internal memory that is not mapped into CPU address space, such as the [[Namco 163]]'s wavetable RAM, or the PRG-ROM is self-flashable.<br />
<br />
==CHR-(NV)RAM==<br />
* In the presence of a NES 2.0 Header, an emulator must not assume that if a ROM image specifies no CHR-ROM, the game will automatically have 8 KiB of CHR-RAM; all CHR-RAM must instead be explicitly specified in Header byte 11.<br />
* Memory that is permanently mapped into the nametable address space (PPU $2000-$2FFF) is not included in the CHR-RAM size. Setting the hard-wired four-screen mode bit in Header byte 6 bit 3 therefore does not entail a 4 KiB increase of the CHR-RAM size.<br />
* The [[MMC5]]'s EXRAM is not included in the CHR-RAM size, as it can be mapped by software to CPU, PPU, or no address space at all.<br />
<br />
==CPU/PPU Timing==<br />
For non-homebrew NES/Famicom games, this field's value is always a function of the region in which a game was released:<br />
Value Meaning Regions<br />
0 RP2C02 North America, Japan, South Korea, Taiwan<br />
1 RP2C07 Western Europe, Australia<br />
2 Multiple Multiple<br />
3 UA6538 Eastern Europe, Russia, Mainland China, India, Africa<br />
Value 2 ("multiple-region") is used either if a game was released with identical ROM content in both NTSC and PAL countries, such as Nintendo's early games, or if the game detects the console's timing and adjusts itself. Emulators should implement this value by either switching to a user-specified "Default Region" or by keeping the previously-set region.<br />
<br />
[[VTxx|V.R. Technology Famiclones]] only come with RP2C02 or UA6538 timing, so games with such a console type can only bear values 0 or 3.<br />
<br />
==Vs. System Type==<br />
When the console type in Header byte 7 D0..D1 is 1 (Vs. System), the lower nibble of Header byte 13 specifies the Vs. PPU type, and the upper nibble the non-PPU-based protection<br />
type and whether the ROM is for the Vs. Unisystem or the Vs. Dual System.<br />
Vs. PPU types (Header byte 13 D0..D3):<br />
$0: RP2C03B<br />
$1: RP2C03G<br />
$2: RP2C04-0001<br />
$3: RP2C04-0002<br />
$4: RP2C04-0003<br />
$5: RP2C04-0004<br />
$6: RC2C03B<br />
$7: RC2C03C<br />
$8: RC2C05-01 ($2002 AND $?? =$1B)<br />
$9: RC2C05-02 ($2002 AND $3F =$3D)<br />
$A: RC2C05-03 ($2002 AND $1F =$1C)<br />
$B: RC2C05-04 ($2002 AND $1F =$1B)<br />
$C: RC2C05-05 ($2002 AND $1F =unknown)<br />
$D-F: reserved<br />
For copy protection purposes, these PPU types have different [[PPU palettes|palettes]]; the RC2C05 PPUs furthermore swap [[PPU registers]] $2000 and $2001 and return a signature in the lower bits of $2002. If a game uses the DIP switches to select different PPU models, this field represents the correct PPU model when those DIP switches are all set to zero.<br />
Vs. Hardware type (Header byte 13 D4..D7):<br />
$0: Vs. Unisystem (normal)<br />
$1: Vs. Unisystem (RBI Baseball protection)<br />
$2: Vs. Unisystem (TKO Boxing protection)<br />
$3: Vs. Unisystem (Super Xevious protection)<br />
$4: Vs. Unisystem (Vs. Ice Climber Japan protection)<br />
$5: Vs. Dual System (normal)<br />
$6: Vs. Dual System (Raid on Bungeling Bay protection)<br />
Refer to the [[Vs. System]] entry for more information.<br />
==Extended Console Type==<br />
When the console type in Header byte 7 D0..D1 is 3 (Extended), the lower nibble of Header byte 13 specifies the type of console on which the ROM image is supposed to be run.<br />
$0 [Regular NES/Famicom/Dendy]<br />
$1 [Nintendo Vs. System]<br />
$2 [Playchoice 10]<br />
$3 Regular Famiclone, but with CPU that supports Decimal Mode<br />
$4 Regular NES/Famicom with [[EPSM]] module or plug-through cartridge<br />
$5 [[VT01 STN_Palette|V.R. Technology VT01 with red/cyan STN palette]]<br />
$6 [[VTxx|V.R. Technology VT02]]<br />
$7 [[VTxx|V.R. Technology VT03]]<br />
$8 [[VTxx|V.R. Technology VT09]]<br />
$9 V.R. Technology VT32<br />
$A V.R. Technology VT369<br />
$B UMC UM6578<br />
$C [[Famicom Network System]]<br />
$D-$F reserved<br />
Values $0-$2 are not used for the extended console type, as they can be expressed by only using Header byte 7 D0..D1. They are reserved here so that emulators<br />
can fold the information in Header Byte 7 D0..D1 and Header byte 13 into one "console type" variable without recoding the values.<br />
<br />
==Default Expansion Device==<br />
Header byte 15 indicates that the ROM expects a specific set of devices accessible at CPU $4016/$4017. For an emulator that wishes to automatically provide selection of needed peripherals, this gives the required information directly within the header.<br />
<br />
Value $00 is reserved for compatibility with older versions of this specification and indicates no information on the default input device.<br />
<br />
In almost all cases, this byte will specify ''the'' device without which the game cannot be played at all, such as the NES Zapper or Power Pad. If a game supports an ''optional'' expansion port device, and having that device connected does not preclude using the normal controllers with that game, this byte will specify that device, such as the ASCII Turbo File or the Arkanoid Vaus Controller. For games that support multiple combinations of expansion devices, this byte will denote the game's default selection.<br />
<br />
This byte does not denote devices that connect to a cartridge; such devices are part of the respective Mapper's definition.<br />
$00 Unspecified<br />
$01 [[Standard controller|Standard NES/Famicom controllers]]<br />
$02 NES [[Four Score]]/Satellite with two additional standard controllers<br />
$03 Famicom Four Players Adapter with two additional standard controllers using the [[Four player adapters#"Simple" Famicom adapters|"simple"]] protocol<br />
$04 [[Vs. System]] (1P via $4016)<br />
$05 Vs. System (1P via $4017)<br />
$06 Reserved<br />
$07 Vs. [[Zapper]]<br />
$08 [[Zapper]] ($4017)<br />
$09 Two Zappers<br />
$0A Bandai Hyper Shot Lightgun<br />
$0B [[Power Pad]] Side A<br />
$0C [[Power Pad]] Side B<br />
$0D [[Power Pad#Family Trainer Mat|Family Trainer]] Side A<br />
$0E [[Power Pad#Family Trainer Mat|Family Trainer]] Side B<br />
$0F [[Arkanoid controller|Arkanoid Vaus Controller (NES)]]<br />
$10 [[Arkanoid controller|Arkanoid Vaus Controller (Famicom)]]<br />
$11 Two Vaus Controllers plus [[Family BASIC Data Recorder|Famicom Data Recorder]]<br />
$12 [[Konami Hyper Shot]] Controller<br />
$13 [[Coconuts Pachinko]] Controller<br />
$14 [[Exciting Boxing Punching Bag]] (Blowup Doll)<br />
$15 [[Jissen Mahjong controller|Jissen Mahjong Controller]]<br />
$16 [[Partytap|Party Tap]] <br />
$17 [[Oeka Kids tablet|Oeka Kids Tablet]]<br />
$18 Sunsoft Barcode Battler<br />
$19 [[Miracle_Piano|Miracle Piano Keyboard]]<br />
$1A Pokkun Moguraa (Whack-a-Mole Mat and Mallet)<br />
$1B Top Rider (Inflatable Bicycle)<br />
$1C Double-Fisted (Requires or allows use of two controllers by one player)<br />
$1D [[Famicom 3D glasses|Famicom 3D System]]<br />
$1E Doremikko Keyboard<br />
$1F R.O.B. Gyro Set<br />
$20 [[Family BASIC Data Recorder|Famicom Data Recorder]] ("silent" keyboard)<br />
$21 ASCII Turbo File<br />
$22 IGS Storage Battle Box<br />
$23 [[Family BASIC Keyboard]] plus Famicom Data Recorder<br />
$24 Dongda PEC-586 Keyboard<br />
$25 Bit Corp. Bit-79 Keyboard<br />
$26 Subor Keyboard<br />
$27 Subor Keyboard plus [[Mouse#Subor Mouse|mouse]] (3x8-bit protocol)<br />
$28 Subor Keyboard plus mouse (24-bit protocol via $4016)<br />
$29 [[Mouse#SNES Mouse|SNES Mouse]] ($4017.d0)<br />
$2A Multicart<br />
$2B Two [[SNES_controller|SNES controllers]] replacing the two standard NES controllers<br />
$2C RacerMate Bicycle<br />
$2D U-Force<br />
$2E R.O.B. Stack-Up<br />
$2F City Patrolman Lightgun<br />
$30 Sharp C1 Cassette Interface<br />
$31 Standard Controller with swapped Left-Right/Up-Down/B-A<br />
$32 Excalibor Sudoku Pad<br />
$33 ABL Pinball<br />
$34 Golden Nugget Casino extra buttons<br />
$35 Unknown famiclone keyboard used by the "Golden Key" educational cartridge<br />
$36 Subor Keyboard plus mouse (24-bit protocol via $4017)<br />
$37 [[Port test controller]]<br />
Notes:<br />
* The Famicom Four Players Adapter ($03) is denoted only if the additional controllers provide ''independent'' 3P/4P input, not if they just alias the built-in 1P/2P controllers.<br />
* So far, there have been no games that provide independent 3P/4P input solely through the [[Four player adapters#Hori 4 Players Adapter|"Hori"]] protocol, which is why there has been no value assigned for it yet.<br />
* For Vs. System games that do not care which stick is used and therefore could be denoted either with value $04 or $05, use value $04.<br />
* Value $06 originally denoted "Pinball (Japan)" and was thought to represent a unique wiring variant, but was since found to represent a peculiar MAME behavior that MAME has since removed.<br />
* "Two Vaus Controllers plus Famicom Data Recorder" ($11) can be trivially emulated as just connecting a Famicom Vaus controller, or sophisticatedly emulated as "Connect two daisy-chained Vaus controllers on startup, disconnect them and connect Family BASIC keyboard with Data Recorder when the user selects Tape Playback or Tape Record from the emulator's user interface; detach these and re-connect the two Vaus controllers when the user selects Tape Stop".<br />
* "Double-Fisted" ($1C) assumes a Four Score is connected, which allows two players to use two controllers at once (Smash T.V.) if the game supports two players.<br />
* The difference between "Famicom Data Recorder" ($20) and "Family BASIC Keyboard" ($23) is that although $20 emulates the Family BASIC keyboard's response to strobe, no actual emulated keyboard input is registered ("silent" keyboard), allowing desktop emulators to keep allowing the use of the host's keyboard for other purposes (such as D-Pad input), and not necessitating the display of an on-screen keyboard on mobile emulators.<br />
* "Multicart" ($2A) is only used if any game on that multicart actually uses expansion port devices. As these will be mostly Zapper games, emulating an expansion port Zapper together with two standard controllers is the simplest way of implementing this value.<br />
* The [[PowerPak]] official loader considers any .NES with a non-zero byte 15 to be invalid, and will fail to load the ROM. A [https://forums.nesdev.org/viewtopic.php?p=283943#p283943 patched N.MAP loader] is available.<br />
<br />
==Version History==<br />
* 2006-09-18 - Original version of specification by kevtris.<br />
** [https://forums.nesdev.org/viewtopic.php?p=17727#p17727 NES 2.0 "Official" Specification]<br />
* 2019-01-02 - Additions by NewRisingSun.<br />
** [https://forums.nesdev.org/viewtopic.php?f=3&t=17213&start=45#p220624 Additions proposal by NewRisingSun]<br />
** Flags 7: adds [[#Extended Console Type|Extended Console Type]] value<br />
** Flags 12: adds [[#CPU/PPU Timing|Dendy]] value<br />
** Flags 13: adds [[#Extended Console Type|Extended Console Type]] field<br />
** Flags 14: adds [[#Miscellaneous ROM Area|miscellaneous ROM]] specifier<br />
** Flags 15: adds [[#Default Expansion Device|Default Expansion Device]]<br />
<br />
==See Also==<br />
* [[NES 2.0 submappers]] - disambiguation for mappers that were under-specified in iNES 1<br />
* [[NES 2.0 header for ca65]] - macro header generator for ca65 assembly<br />
* [[NES 2.0 header for cc65]] - macro header generator for cc65 C code<br />
<br />
==References==<br />
* [https://forums.nesdev.org/viewtopic.php?p=17727#p17727 Original proposal by kevtris]<br />
* [https://forums.nesdev.org/viewtopic.php?f=3&t=17213&start=45#p220624 Additions proposal by NewRisingSun]<br />
* [https://forums.nesdev.org/viewtopic.php?t=19940 NES 2.0 XML Database, with link to Python script for applying it to a ROM files collection]<br />
<references/><br />
[[Category:File formats]]</div>Rainwarriorhttps://www.nesdev.org/w/index.php?title=NTSC_video&diff=21006NTSC video2023-04-08T07:07:48Z<p>Rainwarrior: /* Color Artifacts */ linking a good forum thread as reference</p>
<hr />
<div>Unlike many other game consoles, the NES does not generate RGB or YUV and then encode that to composite.<br />
Instead, it generates '''NTSC video''' directly in the composite domain, which leads to interesting artifacts.<br />
<br />
NTSC Master clock is 21.47727273 MHz and each PPU pixel lasts four clocks; PAL master clock is 26.6017125 MHz, and each PPU pixel lasts five clocks. $xy refers to a palette color in the range $00 to $3F.<br />
<br />
==Scanline Timing==<br />
Values in PPU pixels (341 total per scanline).<br />
[[File:Ntsc video timing.png|right|frame|A visualization of the tables to the left, starts with Cyan for short sync]]<br />
<br />
Rendering scanlines (n=240):<br />
<br />
{| class="wikitable"<br />
! name || start || duration || row || notes<br />
|-<br />
| short sync || 280 || 25 || 0-239 ||<br />
|-<br />
| black (back porch) || 305 || 4 || 0-239 ||<br />
|-<br />
| colorburst || 309 || 15 || 0-239 ||<br />
|-<br />
| black (the rest of back porch) || 324 || 5 || 0-239 ||<br />
|-<br />
| pulse (background color in grayscale) || 329 || 1 || 0-239 ||<br />
|-<br />
| left border (background color) || 330 || 15 || 0-239 ||<br />
|-<br />
| active || 4 || 256 || 0-239 || if background rendering is disabled, border will be rendered instead<br />
|-<br />
| right border (background color) || 260 || 11 || 0-239 ||<br />
|-<br />
| black (front porch) || 271 || 9 || 0-239 ||<br />
|}<br />
<br />
Post-render scanlines (n=2):<br />
<br />
{| class="wikitable"<br />
! name || start || duration || row<br />
|-<br />
| short sync || 280 || 25 || 240-241<br />
|-<br />
| black (back porch) || 305 || 4 || 240-241<br />
|-<br />
| colorburst || 309 || 15 || 240-241<br />
|-<br />
| black (the rest of back porch) || 324 || 5 || 240-241<br />
|-<br />
| pulse (background color in grayscale) || 329 || 1 || 240-241<br />
|-<br />
| bottom border (background color) || 330 || 282 || 240-241<br />
|-<br />
| black (front porch) || 271 || 9 || 240-241<br />
|}<br />
<br />
Post-render blanking scanlines (n=3):<br />
<br />
{| class="wikitable"<br />
! name || start || duration || row<br />
|-<br />
| short sync || 280 || 25 || 242-244<br />
|-<br />
| black (back porch) || 305 || 4 || 242-244<br />
|-<br />
| colorburst || 309 || 15 || 242-244<br />
|-<br />
| black || 324 || 297 || 242-244<br />
|}<br />
<br />
Vertical sync scanlines (n=3):<br />
<br />
{| class="wikitable"<br />
! name || start || duration || row<br />
|-<br />
| long sync || 280 || 318 || 245-247<br />
|-<br />
| black (sync separator) || 257 || 23 || 245-247<br />
|}<br />
<br />
Pre-render blanking scanlines (n=14):<br />
<br />
{| class="wikitable"<br />
! name || start || duration || row || notes<br />
|-<br />
| short sync || 280 || 25 || 248-261 ||<br />
|-<br />
| black (back porch) || 305 || 4 || 248-261 ||<br />
|-<br />
| colorburst || 309 || 15 || 248-261 || 14 columns on end of row 261 for odd frames, if either background or sprite rendering is enabled<br />
|-<br />
| black || 324 || 297 || 248-261 ||<br />
|}<br />
<br />
This amounts to a total of 262 scanlines.<br />
<br />
In standard NTSC, a scanline is 227.5 subcarrier cycles long (equivalent to 341.25 NES pixels), and each field is 262.5 scanlines lines tall. Vertical sync "serrations" or "equalization pulses" use a brief period of 31kHz horizontal sync to be able to start vertical sync half-way through a scanline, which makes the TV draw the next field one half scanline higher, resulting in ''interlaced'' video.<br />
<br />
The video timing in the NES is non-standard - it both generates 341 pixels, making 227 1/3 subcarrier cycles per scanline, and always generates 262 scanlines. This causes the TV to draw the fields on top of each other, resulting in a non-standard low-definition "progressive" or "double struck" video mode sometimes called [http://junkerhq.net/xrgb/index.php/240p_video 240p].<br />
<br />
Some high-definition displays and upscalers cannot handle 240p video, instead introducing artifacts that make the video appear as if it were interlaced. Artemio Urbina's [http://junkerhq.net/xrgb/index.php/240p_test_suite 240p test suite], which has been [https://forums.nesdev.org/viewtopic.php?p=157634#p157634 ported to NES] by [[User:Tepples|Damian Yerrick]], contains a set of test patterns to diagnose problems with decoding 240p composite video.<br />
<br />
Note that emulators usually crop the top and bottom 8 lines from the picture, as most televisions will hide at least part of the picture in a similar way. See: [[Overscan]]<br />
<br />
==Brightness Levels==<br />
<br />
$xE/$xF output the same voltage as $1D. $x1-$xC output a square wave alternating between levels for $xD and $x0. Colors $20 and $30 are exactly the same.<br />
<br />
When grayscale is active, all colors between $x1-$xD are treated as $x0. Notably this behavior extends to the first pixel of the border color, which acts as a sync pulse on every visible scanline.<br />
<br />
=== Terminated measurement ===<br />
<br />
Standard video (not NES) looks like this:<br />
{| class="wikitable"<br />
! Type || IRE level || Voltage (mV)<br />
|-<br />
| Peak white || 120 ||<br />
|-<br />
| White || 100 || 714<br />
|-<br />
| Colorburst H || 20 || 143<br />
|-<br />
| Black || 7.5 || 53.6<br />
|-<br />
| Blanking || 0 || 0<br />
|-<br />
| Colorburst L || -20 || -143<br />
|-<br />
| Sync || -40 || -286<br />
|}<br />
<br />
The following [http://forums.nesdev.org/viewtopic.php?p=159266#p159266 measurements by lidnariq] into a properly terminated (75 Ω) TV have about 10 mV of noise and 4 mV of quantization error, which implies an error of ±2 IRE:<br />
{| class="wikitable"<br />
! Signal || Potential || IRE<br />
|-<br />
| SYNC || 48 mV || -37 IRE<br />
|-<br />
| CBL || 148 mV || -23 IRE<br />
|-<br />
| 0D || 228 mV || -12 IRE<br />
|-<br />
| 1D || 312 mV || ≡ 0 IRE<br />
|-<br />
| CBH || 524 mV || 30 IRE<br />
|-<br />
| 2D || 552 mV || 34 IRE<br />
|-<br />
| 00 || 616 mV || 43 IRE<br />
|-<br />
| 10 || 840 mV || 74 IRE<br />
|-<br />
| 3D || 880 mV || 80 IRE<br />
|-<br />
| 20 || 1100 mV || 110 IRE<br />
|-<br />
| 0Dem || 192 mV || -17 IRE<br />
|-<br />
| 1Dem || 256 mV || -8 IRE<br />
|-<br />
| 2Dem || 448 mV || 19 IRE<br />
|-<br />
| 00em || 500 mV || 26 IRE<br />
|-<br />
| 10em || 676 mV || 51 IRE<br />
|-<br />
| 3Dem || 712 mV || 56 IRE<br />
|-<br />
| 20em || 896 mV || 82 IRE<br />
|}<br />
Unlike PAL, US NTSC is supposed to have a "setup", a difference between blanking and black level. Japanese NTSC does not make this distinction.<br />
<br />
=== Old measurement ===<br />
<br />
This measurment table was added to the wiki in 2009. Its source is unknown, and its results differ from the terminated measurements above. This was used for Bisqwit's example C++ implementation below.<br />
<br />
Voltage levels used by the PPU are as follows - absolute, relative to synch, and normalized between black level and white:<br />
{| class="wikitable"<br />
! Type || Absolute || Relative || Normalized<br />
|-<br />
| Synch || 0.781 || 0.000 || -0.359<br />
|-<br />
| Colorburst L || 1.000 || 0.218 || -0.208<br />
|-<br />
| Colorburst H || 1.712 || 0.931 || 0.286<br />
|-<br />
|Color 0D || 1.131 || 0.350 || -0.117<br />
|-<br />
|Color 1D (black) || 1.300 || 0.518 || 0.000<br />
|-<br />
|Color 2D || 1.743 || 0.962 || 0.308<br />
|-<br />
|Color 3D || 2.331 || 1.550 || 0.715<br />
|-<br />
|Color 00 || 1.875 || 1.090 || 0.397<br />
|-<br />
|Color 10 || 2.287 || 1.500 || 0.681<br />
|-<br />
|Color 20 || 2.743 || 1.960 || 1.000<br />
|-<br />
|Color 30 || 2.743 || 1.960 || 1.000<br />
|}<br />
<br />
These levels don't quite match the standard levels.<br />
Ideally, the composite signal is 1000 millivolts from peak to peak (1.0 Vp-p) when loaded with a 75 Ω output impedance.<br />
(Unloaded levels may be twice that amount, which may explain the levels seen above.)<br />
Levels are commonly measured in units called IRE.<ref>[https://www.maximintegrated.com/en/app-notes/index.mvp/id/1184 Tutorial 1184: Understanding Analog Video Signals]</ref><ref>[http://www.ni.com/white-paper/4750/en/ Analog Video 101]</ref><br />
<br />
==Color Phases==<br />
111111------<br />
22222------2<br />
3333------33<br />
444------444<br />
55------5555<br />
6------66666<br />
------777777<br />
-----888888-<br />
----999999--<br />
---AAAAAA---<br />
--BBBBBB----<br />
-CCCCCC-----<br />
<br />
The color generator is clocked by the rising ''and'' falling edges of the ~21.48 MHz clock, resulting in an effective ~42.95 MHz clock rate. There are 12 color square waves, spaced at regular phases. Each runs at the ~3.58 MHz colorburst rate. On NTSC, color $xY uses the wave shown in row Y from the table. NTSC color burst (pure shade -U) uses color phase 8 (with voltages listed above); PAL color burst is believed to alternate between 6 (-U+V) and 9 (-U-V), so hue is rotated by 15° from NTSC. [[wikipedia:PAL|PAL]] alternates the broadcast sign of the V component, so on PAL every odd scanline will use the appropriate opposite phase—e.g. phases 5-C are respectively replaced with C-5.<br />
<br />
=== Differential Phase Distortion ===<br />
The output is subject to a [[wikipedia:Differential phase|differential phase distortion]] effect<ref>[https://forums.nesdev.org/viewtopic.php?p=287241#p287241 Re: In search of a PAL region reference palette] - Explanation of the differential phase distortion of the NES.</ref>. This causes a rotation of the NTSC signal's effective hue, proportional to the voltage, causing more shift for brighter colors. Current estimates approximate about 2.5° (2C02E) or 5° (2C02G) of additional rotation for each row of the palette.<br />
<br />
The reason for this distortion is that the output impedance of the PPU is dependent on the signal level. When combined with the board's capacitance, it slows level transitions, causes the edges at high signal levels to be less steep. The high frequency chroma signal is sensitive to this, and the delay to its phase causes the hue rotation.<br />
<br />
A [[PAL video|PAL NES]] is affected by the same differential phase distortion, but because of the alternating-line mechanism of PAL, the effect is mostly cancelled out on consecutive scanlines.<br />
<br />
=== Color Artifacts ===<br />
Thought it takes 12 clocks of the generator to complete a color cycle, an NTSC pixel is only 8 clocks wide, or 10 on PAL. This means that the effective resolution of colour is lower than the pixel resolution, and some color information has to be shared with a neighbouring pixel. This produces color errors at horizontal edges where the color changes. These errors are known as artifacts. They are especially noticeable as "shimmering" when the screen scrolls slowly.<ref>[//forums.nesdev.org/viewtopic.php?t=24294 Effect of skipped dot on the picture] - Forum thread with commentary and diagrams on the nature of color artifacts, and the skipped dot.</ref><br />
<br />
The phase alignment of each pixel to the color cycle changes on every scanline, and this affects the hue of each color artifact. E.g. if the "red" part of the cycle is outside the pixel, its error artifact will be a distortion of the red color.<br />
<br />
An NTSC NES scanline is 227⅓ color cycles long, causing the alignment to shift by 4 clocks on each line. This creates a pattern of alignments that repeats every 3 lines. A vertical line may be seen to have a "rainbow" pattern of red, green, blue, red, green, blue... etc. The starting phase depends on a random alignment of the PPU to the picture which is determined on reset. (The scanline is shorter than standard NTSC, which has 227½ color cycles per line.)<br />
<br />
A PAL NES scanline is 284⅙ color cycles long, instead causing the alignment to shift by 2 clocks on each line, with an additional temporary -3 clocks every second line to provide the phase-alternating-line mechanism. This creates a [[:File:PAL signal 6538 53.2MHz.png|pattern of alignments]] that repeats every 6 lines. (The scanline is longer than standard PAL, which has 283¾ cycles per line.)<br />
<br />
Each frame of the NTSC NES picture also starts from a changing alignment. Normally every odd frame is 1 dot shorter than every even frame, resulting in 59560⅔ color cycles on odd frames, and 59561⅓ on even frames. This creates a 2-frame repeating pattern, shifting by 8 clocks after an odd frame, then by 4 after an even one. The missing dot may be suppressed if rendering is disabled during the pre-render scanline, so some games which force blank through the top of the frame (e.g. Battletoads) advance the color phase alignment by 4 clocks every frame. In this case, it creates a 3-frame repeating pattern, which creates a more noticeable shimmering. See: [[PPU frame timing]].<br />
<br />
PAL and Dendy instead have an even number of color cycles per frame, so the color phase alignment does not change from frame to frame.<br />
<br />
==Color Tint Bits==<br />
There are three color modulation channels controlled by the top three bits of $2001. Each channel uses one of the color square waves (see above diagram) and enables attenuation of the video signal when the color square wave is high. A single attenuator is shared by all channels. It is active for 6 out of 12 half-clocks if one bit is set, 10 half-clocks if two bits are set, or all 12 if all three bits are set.<br />
<br />
{| class="wikitable"<br />
! $2001 || Active phase || Active diagram || Complement<br />
|-<br />
|| Bit 7 || Color 8 || <tt>-----888888-</tt> || Color 2 (blue)<br />
|-<br />
|| Bit 6 || Color 4 || <tt>444------444</tt> || Color A (green)<br />
|-<br />
|| Bit 5 || Color C || <tt>-CCCCCC-----</tt> || Color 6 (red)<br />
|}<br />
<br />
When attenuation is active and the current pixel is a color other than $xE/$xF (black), the signal is attenuated.<br />
<br />
For example, when $2001 bit 6 is true, the attenuator will be active during the phases of color 4.<br />
This means the attenuator is not active during its complement (color A), and the screen appears to have a tint of color A, which is green.<br />
<br />
Note that on the Dendy and PAL NES, the green and red bits swap meaning.<br />
<br />
[http://forums.nesdev.org/viewtopic.php?p=160669#p160669 Tests performed on NTSC NES] show that emphasis does not affect the black colours in columns $E or $F, but it does affect all other columns, including the blacks and greys in column $D.<br />
<br />
The terminated measurements above suggest that resulting attenuated absolute voltage is approximately '''0.81 times''' the un-attenuated absolute voltage.<br />
<br />
The old measurement suggested a different approximation, applied to its relative or normalized values. This does not agree with the terminated measurements:<br />
attenuated relative = relative * 0.746<br />
attenuated normalized = normalized * 0.746 - 0.0912<br />
<br />
==Example Waveform==<br />
<br />
This waveform steps through various grays and then stops on a color.<br />
[[File:Composite_waveform_example.gif|center|frame|The composite signal steps through 6 gray colors ($0D, $0F, $2D, $00, $10, $30) then continues through with color $11. ]]<br />
<br />
The PPU's shortcut method of NTSC modulation often produces artifacts in which vertical lines appear slightly ragged, as the chroma spills over into luma.<br />
[[File:NTSC video ragged box animated.gif|right|frame|Generation and demodulation of a red corner]]<br />
<br clear="all"/><br />
<br />
== Composite decoding ==<br />
<br />
Normal composite video encodes chroma and luma information into one composite analog signal. In order to convert composite into an RGB signal, it firsts needs to be decoded into YUV, before converting the resulting YUV into RGB.<br />
<br />
The NES PPU does not encode anything into composite; instead, directly drawing the composite waveform itself. In order to convert the NES's composite signal into an RGB signal, it is decoded under the "assumption" that it was encoded under YUV.<br />
<br />
YUV in this article refers to and will continue to refer to the equiband encoding of composite video as Y, b-y and r-y respectively. YIQ refers to the non-equiband encoding of composite, which has much more additional considerations regarding bandlimiting.<br />
<br />
In practice, YIQ decoding is not used by any modern TV receiver and composite decoder, instead using YUV decoding as it is much simpler and less mathematically intensive to decode.<ref>[https://www.itu.int/rec/R-REC-BT.1700-0-200502-I/en S170m-2004.pdf: Composite Analog Video Signal NTSC for Studio Applications. Page 17.]</ref><ref>SMPTE EG 27-2004: Supplemental Information for SMPTE 170M and Background on the Development of NTSC Color Standards. Page 5.</ref><br />
<br />
=== Decoding composite video into YUV ===<br />
<br />
Although encoding composite is somewhat standardized, the methods of decoding composite may vary from TV to TV. This article shows one way to decode composite.<br />
<br />
==== Decoding chroma information (UV) ====<br />
<br />
Decoding chroma information requires a subcarrier reference sine wave to determine the hue, whose phase is "locked" (or aligned as best as possible) to the colorburst of the composite scanline.<br />
<br />
The subcarrier reference is used to demodulate the U component. A copy (or a phase offset) of the reference is delayed by 90 degrees, which is then used to demodulate the V component.<br />
<br />
The U/V component is demodulated by multiplying the subcarrier reference to the composite waveform. The resulting waveform is then filtered typically by a lowpass filter. A comb filter can also be used if desired.<br />
<br />
==== Decoding luma information (Y) ====<br />
<br />
To get the luma (Y) component, the base signal is filtered by a lowpass or comb filter. Some TVs use more complex methods to decode luma, some TVs do not filter at all.<br />
<br />
=== Converting YUV to linear RGB ===<br />
<br />
To convert YUV to linear RGB, we multiply the components to the following inversed matrix:<br />
<br />
<nowiki><br />
R = Y + V*1.14<br />
G = Y - (R*0.299 - B*0.114) / 0.587<br />
B = Y + U*2.03</nowiki><br />
<br />
Or, in terms of YUV only:<br />
<br />
<nowiki><br />
R = Y + V*1.14<br />
G = Y - U*0.394242... - V*0.580681...<br />
B = Y + U*2.03</nowiki><br />
<br />
The matrices above is derived from the NTSC base matrix<ref>[https://www.itu.int/rec/R-REC-BT.1700-0-200502-I/en S170m-2004.pdf: Composite Analog Video Signal NTSC for Studio Applications. Page 4.]</ref> of luminance and color-difference:<br />
<br />
<nowiki><br />
Y = R*0.299 + G*0.587 + B*0.114<br />
B-Y = -R*0.299 - G*0.587 + B*0.886<br />
R-Y = R*0.701 - G*0.587 - B*0.114</nowiki><br />
<br />
Which, when applied with the approximate color reduction factors 1/2.03 and 1/1.14 for B-Y and R-Y respectively<ref>[https://www.itu.int/rec/R-REC-BT.1700-0-200502-I/en S170m-2004.pdf: Composite Analog Video Signal NTSC for Studio Applications. Page 16.]</ref>, results in the definition of the linear RGB to YUV matrix equation:<br />
<br />
<nowiki><br />
Y = R*0.299 + G*0.587 + B*0.114<br />
U = (-R*0.299 - G*0.587 + B*0.886) / 2.03<br />
V = ( R*0.701 - G*0.587 - B*0.114) / 1.14</nowiki><br />
<br />
In YIQ, the IQ component's chroma hue is just the UV component's chroma hue rotated by 33 degrees. Note that this is not precisely the same as properly decoding YIQ with different bandwidths for the I and Q component.<br />
<br />
The following conversion is optional, and might match the look of other composite decoders:<br />
<br />
<nowiki><br />
U = -(I * sin(-33 deg)) + (Q * cos(-33 deg))<br />
V = (I * cos(-33 deg)) + (Q * sin(-33 deg))</nowiki><br />
<br />
=== Converting linear RGB to output colorspace ===<br />
<br />
The final step is to convert linear RGB into the output colorspace, typically sRGB for most monitors.<br />
<br />
==== Linear RGB into sRGB ====<br />
<br />
According to IEC 61966-2-1:1999, a gamma curve correction must be applied to the R, G and B signals before they are displayed.<ref>[https://www.color.org/chardata/rgb/srgb.xalter ICC page on sRGB]</ref> The transfer function for sRGB is:<br />
<br />
<nowiki><br />
C = linear R, G, or B signal<br />
C' = gamma corrected R, G or B signal<br />
<br />
C' = 12.92 * C if C <= 0.0031308<br />
C' = 1.055 * C^(1/2.4) - 0.055 if C > 0.0031308</nowiki><br />
<br />
The resulting R, G and B values can then be quantized into 8 bits per channel:<br />
<br />
<nowiki><br />
C8bpc = quantized R, G, or B channel<br />
C' = gamma corrected R, G or B signal<br />
<br />
C8bpc = (int)(C` * 255)</nowiki><br />
<br />
==Emulating in C++ code==<br />
<br />
For efficient, ready to use implementations, see [[#Libraries|Libraries]] below. The following is an illustrative example. The values used are based on the "old" measurements given above.<br />
<br />
Calculating the momentary NTSC signal level can be done as follows in C++:<br />
<br />
<nowiki><br />
// pixel = Pixel color (9-bit) given as input. Bitmask format: "eeellcccc".<br />
// phase = Signal phase (0..11). It is a variable that increases by 8 each pixel.<br />
float NTSCsignal(int pixel, int phase)<br />
{<br />
// Voltage levels, relative to synch voltage<br />
static const float black=.518f, white=1.962f, attenuation=.746f,<br />
levels[8] = {.350f, .518f, .962f,1.550f, // Signal low<br />
1.094f,1.506f,1.962f,1.962f}; // Signal high<br />
<br />
// Decode the NES color.<br />
int color = (pixel & 0x0F); // 0..15 "cccc"<br />
int level = (pixel >> 4) & 3; // 0..3 "ll"<br />
int emphasis = (pixel >> 6); // 0..7 "eee"<br />
if(color > 13) { level = 1; } // For colors 14..15, level 1 is forced.<br />
<br />
// The square wave for this color alternates between these two voltages:<br />
float low = levels[0 + level];<br />
float high = levels[4 + level];<br />
if(color == 0) { low = high; } // For color 0, only high level is emitted<br />
if(color > 12) { high = low; } // For colors 13..15, only low level is emitted<br />
<br />
// Generate the square wave<br />
auto InColorPhase = [=](int color) { return (color + phase) % 12 < 6; }; // Inline function<br />
float signal = InColorPhase(color) ? high : low;<br />
<br />
// When de-emphasis bits are set, some parts of the signal are attenuated:<br />
if( ((emphasis & 1) && InColorPhase(0))<br />
|| ((emphasis & 2) && InColorPhase(4))<br />
|| ((emphasis & 4) && InColorPhase(8)) ) signal = signal * attenuation;<br />
<br />
return signal;<br />
}</nowiki><br />
<br />
The process of generating NTSC signal for a single pixel can be simulated with the following C++ code:<br />
<br />
<nowiki><br />
void RenderNTSCpixel(unsigned x, int pixel, int PPU_cycle_counter)<br />
{<br />
int phase = PPU_cycle_counter * 8;<br />
for(int p=0; p<8; ++p) // Each pixel produces distinct 8 samples of NTSC signal.<br />
{<br />
float signal = NTSCsignal(pixel, phase + p); // Calculated as above<br />
// Optionally apply some lowpass-filtering to the signal here.<br />
// Optionally normalize the signal to 0..1 range:<br />
static const float black=.518f, white=1.962f;<br />
signal = (signal-black) / (white-black);<br />
// Save the signal for this pixel.<br />
signal_levels[ x*8 + p ] = signal;<br />
}<br />
}</nowiki><br />
<br />
It is important to note that while the NES only generates eight (8) samples of NTSC signal per pixel, the wavelength for chroma is 12 samples long. This means that the colors of adjacent pixels get mandatorily mixed up to some degree. For the same reason, narrow black&white details can be interpreted as colors.<br />
<br />
Because the scanline length is uneven (341*8 is not an even multiple of 12), the color mixing shifts a little each scanline. This appears visually as a sawtooth effect at the edges of colors at high resolution. The sawtooth cycles every 3 scanlines.<br />
<br />
Because also the frame length is uneven (neither 262*341*8 nor (262*341-1)*8 is an even multiple of 12), the color mixing also changes a little every frame. When rendering is normally enabled, the screen is alternatingly 89342 and 89341 cycles long. The combination of these (89342+89341)*8 <i>is</i> an even multiple of 12, which means that the artifact pattern cycles every 2 frames. The pattern of cycling can be changed by disabling rendering during the end of the pre-render scanline; it forces the screen length to 89342 cycles, even if would be 89341 otherwise.<br />
<br />
The process of decoding NTSC signal (convert it into RGB) is subject to a lot of study, and there are many patents and different techniques for it. A simple method suitable for emulation is covered below. It is not accurate, because in reality the chroma is blurred much more than is done here (the region of signal sampled for I and Q is wider than 12 samples), and the filter used here is a simple box FIR filter rather than an IIR filter, but it already produces a quite authentic looking picture. In addition, the border region (total of 26 pixels of background color around the 256-pixel scanline) is not sampled.<br />
<br />
<nowiki><br />
float signal_levels[256*8] = {...}; // Eight signal levels for each pixel, normalized to 0..1 range. <br />
Calculated as above.<br />
<br />
unsigned Width; // Input: Screen width. Can be not only 256, but anything up to 2048.<br />
float phase; // Input: This should the value that was PPU_cycle_counter * 8 + 3.9<br />
// at the BEGINNING of this scanline. It should be modulo 12.<br />
// It can additionally include a floating-point hue offset.<br />
for(unsigned x = 0; x < Width; ++x)<br />
{<br />
// Determine the region of scanline signal to sample. Take 12 samples.<br />
int center = x * (256*8) / Width + 0;<br />
int begin = center - 6; if(begin < 0) begin = 0;<br />
int end = center + 6; if(end > 256*8) end = 256*8;<br />
float y = 0.f, i = 0.f, q = 0.f; // Calculate the color in YIQ.<br />
for(int p = begin; p < end; ++p) // Collect and accumulate samples<br />
{<br />
float level = signal_levels[p] / 12.f;<br />
y = y + level;<br />
i = i + level * cos( M_PI * (phase+p) / 6 );<br />
q = q + level * sin( M_PI * (phase+p) / 6 );<br />
}<br />
render_pixel(y,i,q); // Send the YIQ color for rendering.<br />
}</nowiki><br />
<br />
The NTSC decoder here produces pixels in YIQ color space.<br />
<br />
If you want more saturated colors, just multiply <code>i</code> and <code>q</code> with a factor of your choosing, such as 1.7. If you want brighter colors, just multiply <code>y</code>, <code>i</code> and <code>q</code> with a factor of your choosing, such as 1.1. If you want to adjust the hue, just add or subtract a value from/to <code>phase</code>. If you want to see so called chroma dots, change the begin and end in such manner that you collect a number of samples that is not divisible with 12. If you want to blur the video horizontally, change the begin and end in such manner that the samples are collected from a wider region.<br />
<br />
The YIQ colors can be converted into sRGB colors with the following formula, using the [https://www.govinfo.gov/content/pkg/CFR-2013-title47-vol4/pdf/CFR-2013-title47-vol4-sec73-682.pdf#page=2 FCC-sanctioned] YIQ-to-RGB conversion matrix. This produces a value that can be saved to e.g. framebuffer:<br />
<br />
<nowiki><br />
float gamma = 2.0f; // Assumed display gamma<br />
auto gammafix = [=](float f) { return f <= 0.f ? 0.f : pow(f, 2.2f / gamma); };<br />
auto clamp = [](int v) { return v>255 ? 255 : v; };<br />
unsigned rgb =<br />
0x10000*clamp(255.95 * gammafix(y + 0.946882f*i + 0.623557f*q))<br />
+ 0x00100*clamp(255.95 * gammafix(y + -0.274788f*i + -0.635691f*q))<br />
+ 0x00001*clamp(255.95 * gammafix(y + -1.108545f*i + 1.709007f*q));</nowiki><br />
<br />
The two images below illustrate the NTSC artifacts.<br />
In the left side image, 12 samples of NTSC signal were generated for each NES pixel,<br />
and each display pixel was separately rendered by decoding that 12-sample signal.<br />
In the right side image, 8 samples of NTSC signal were generated for each NES pixel,<br />
and each display pixel was rendered by decoding 12 samples of NTSC signal from the<br />
corresponding location within the scanline.<br clear="all" /><br />
<table cellspacing=0 cellpadding=0><br />
<tr><td colspan=2>[[File:nes_ntsc_perpixel.png|left|frame|Per-pixel rendering: 12 samples of NTSC signal per input pixel; the same 12 samples are decoded for each output pixel]]</td><br />
<td colspan=2>[[File:nes_ntsc_perscanline.gif|left|frame|Per-scanline rendering: 8 samples of NTSC signal per input pixel; 12 samples are decoded for each output pixel]]</td></tr><br />
<tr><td>[[File:nes_ntsc_perpixel_small.png|left|frame|Same as above, but rendered at 256x240 without upscaling]]</td><br />
<td>[[File:nes_ntsc_perpixel_small_bw.png|left|frame|Same in grayscale (zero saturation). This illustrates well how the different color values have exactly the same luminosity; only the chroma phase differs.]]</td><br />
<td>[[File:nes_ntsc_perscanline_small.gif|left|frame|Same as above, but rendered at 256x240 rather than at 2048x240 and then downscaled]]</td><br />
<td>[[File:nes_ntsc_perscanline_small_bw.gif|left|frame|Same in grayscale]]</td></tr></table><br />
<br />
The source code of the program that generated both images can be read here: [https://bisqwit.iki.fi/jutut/kuvat/programming_examples/nesemu1/ntsc-small.cc ntsc-small.cc]. Note that even though the image resembles the well-known Philips PM5544 test card, it is not the same; the exact same<br />
colors could not be reproduced with NES colors. In addition, some parts were changed to better test NES features. For example, the backgrounds for the "station ID" regions (the black rectangles at the top and at the bottom inside the circle) are generated using the various blacks within the NES palette.<br />
<br />
Later, Bisqwit made a generic [http://forums.nesdev.org/viewtopic.php?p=172329#p172329 integer-based decoder in C++]. This takes a signal at 12 times color burst and can be used to emulate other systems that use shortcuts when generating NTSC video, such as Apple II (where ''every'' color in <code>HGR</code> is an artifact color) and Atari 7800 (whose game ''Tower Toppler'' seriously exploits artifact colors).<br />
<br />
==Libraries==<br />
<br />
* [http://slack.net/~ant/libs/ntsc.html blargg's nes_ntsc library]<br />
* [//forums.nesdev.org/viewtopic.php?f=21&t=11947 blargg's NTSC demo windows executable]<br />
* [//forums.nesdev.org/viewtopic.php?f=2&t=14338 Forum thread]: New NTSC decoder with integer-only math (short C++ code) - by Bisqwit<br />
* [https://github.com/LMP88959/NTSC-CRT/ LMP88959 (EMMIR)'s NTSC decoder]<br />
<br />
== See also ==<br />
* [[Cycle reference chart]]<br />
* [[PAL video]]<br />
* [[PPU palettes]]<br />
<br />
== References ==<br />
<references /></div>Rainwarriorhttps://www.nesdev.org/w/index.php?title=NTSC_video&diff=21005NTSC video2023-04-08T06:40:00Z<p>Rainwarrior: /* Color Phases */ describe the colour artifacts</p>
<hr />
<div>Unlike many other game consoles, the NES does not generate RGB or YUV and then encode that to composite.<br />
Instead, it generates '''NTSC video''' directly in the composite domain, which leads to interesting artifacts.<br />
<br />
NTSC Master clock is 21.47727273 MHz and each PPU pixel lasts four clocks; PAL master clock is 26.6017125 MHz, and each PPU pixel lasts five clocks. $xy refers to a palette color in the range $00 to $3F.<br />
<br />
==Scanline Timing==<br />
Values in PPU pixels (341 total per scanline).<br />
[[File:Ntsc video timing.png|right|frame|A visualization of the tables to the left, starts with Cyan for short sync]]<br />
<br />
Rendering scanlines (n=240):<br />
<br />
{| class="wikitable"<br />
! name || start || duration || row || notes<br />
|-<br />
| short sync || 280 || 25 || 0-239 ||<br />
|-<br />
| black (back porch) || 305 || 4 || 0-239 ||<br />
|-<br />
| colorburst || 309 || 15 || 0-239 ||<br />
|-<br />
| black (the rest of back porch) || 324 || 5 || 0-239 ||<br />
|-<br />
| pulse (background color in grayscale) || 329 || 1 || 0-239 ||<br />
|-<br />
| left border (background color) || 330 || 15 || 0-239 ||<br />
|-<br />
| active || 4 || 256 || 0-239 || if background rendering is disabled, border will be rendered instead<br />
|-<br />
| right border (background color) || 260 || 11 || 0-239 ||<br />
|-<br />
| black (front porch) || 271 || 9 || 0-239 ||<br />
|}<br />
<br />
Post-render scanlines (n=2):<br />
<br />
{| class="wikitable"<br />
! name || start || duration || row<br />
|-<br />
| short sync || 280 || 25 || 240-241<br />
|-<br />
| black (back porch) || 305 || 4 || 240-241<br />
|-<br />
| colorburst || 309 || 15 || 240-241<br />
|-<br />
| black (the rest of back porch) || 324 || 5 || 240-241<br />
|-<br />
| pulse (background color in grayscale) || 329 || 1 || 240-241<br />
|-<br />
| bottom border (background color) || 330 || 282 || 240-241<br />
|-<br />
| black (front porch) || 271 || 9 || 240-241<br />
|}<br />
<br />
Post-render blanking scanlines (n=3):<br />
<br />
{| class="wikitable"<br />
! name || start || duration || row<br />
|-<br />
| short sync || 280 || 25 || 242-244<br />
|-<br />
| black (back porch) || 305 || 4 || 242-244<br />
|-<br />
| colorburst || 309 || 15 || 242-244<br />
|-<br />
| black || 324 || 297 || 242-244<br />
|}<br />
<br />
Vertical sync scanlines (n=3):<br />
<br />
{| class="wikitable"<br />
! name || start || duration || row<br />
|-<br />
| long sync || 280 || 318 || 245-247<br />
|-<br />
| black (sync separator) || 257 || 23 || 245-247<br />
|}<br />
<br />
Pre-render blanking scanlines (n=14):<br />
<br />
{| class="wikitable"<br />
! name || start || duration || row || notes<br />
|-<br />
| short sync || 280 || 25 || 248-261 ||<br />
|-<br />
| black (back porch) || 305 || 4 || 248-261 ||<br />
|-<br />
| colorburst || 309 || 15 || 248-261 || 14 columns on end of row 261 for odd frames, if either background or sprite rendering is enabled<br />
|-<br />
| black || 324 || 297 || 248-261 ||<br />
|}<br />
<br />
This amounts to a total of 262 scanlines.<br />
<br />
In standard NTSC, a scanline is 227.5 subcarrier cycles long (equivalent to 341.25 NES pixels), and each field is 262.5 scanlines lines tall. Vertical sync "serrations" or "equalization pulses" use a brief period of 31kHz horizontal sync to be able to start vertical sync half-way through a scanline, which makes the TV draw the next field one half scanline higher, resulting in ''interlaced'' video.<br />
<br />
The video timing in the NES is non-standard - it both generates 341 pixels, making 227 1/3 subcarrier cycles per scanline, and always generates 262 scanlines. This causes the TV to draw the fields on top of each other, resulting in a non-standard low-definition "progressive" or "double struck" video mode sometimes called [http://junkerhq.net/xrgb/index.php/240p_video 240p].<br />
<br />
Some high-definition displays and upscalers cannot handle 240p video, instead introducing artifacts that make the video appear as if it were interlaced. Artemio Urbina's [http://junkerhq.net/xrgb/index.php/240p_test_suite 240p test suite], which has been [https://forums.nesdev.org/viewtopic.php?p=157634#p157634 ported to NES] by [[User:Tepples|Damian Yerrick]], contains a set of test patterns to diagnose problems with decoding 240p composite video.<br />
<br />
Note that emulators usually crop the top and bottom 8 lines from the picture, as most televisions will hide at least part of the picture in a similar way. See: [[Overscan]]<br />
<br />
==Brightness Levels==<br />
<br />
$xE/$xF output the same voltage as $1D. $x1-$xC output a square wave alternating between levels for $xD and $x0. Colors $20 and $30 are exactly the same.<br />
<br />
When grayscale is active, all colors between $x1-$xD are treated as $x0. Notably this behavior extends to the first pixel of the border color, which acts as a sync pulse on every visible scanline.<br />
<br />
=== Terminated measurement ===<br />
<br />
Standard video (not NES) looks like this:<br />
{| class="wikitable"<br />
! Type || IRE level || Voltage (mV)<br />
|-<br />
| Peak white || 120 ||<br />
|-<br />
| White || 100 || 714<br />
|-<br />
| Colorburst H || 20 || 143<br />
|-<br />
| Black || 7.5 || 53.6<br />
|-<br />
| Blanking || 0 || 0<br />
|-<br />
| Colorburst L || -20 || -143<br />
|-<br />
| Sync || -40 || -286<br />
|}<br />
<br />
The following [http://forums.nesdev.org/viewtopic.php?p=159266#p159266 measurements by lidnariq] into a properly terminated (75 Ω) TV have about 10 mV of noise and 4 mV of quantization error, which implies an error of ±2 IRE:<br />
{| class="wikitable"<br />
! Signal || Potential || IRE<br />
|-<br />
| SYNC || 48 mV || -37 IRE<br />
|-<br />
| CBL || 148 mV || -23 IRE<br />
|-<br />
| 0D || 228 mV || -12 IRE<br />
|-<br />
| 1D || 312 mV || ≡ 0 IRE<br />
|-<br />
| CBH || 524 mV || 30 IRE<br />
|-<br />
| 2D || 552 mV || 34 IRE<br />
|-<br />
| 00 || 616 mV || 43 IRE<br />
|-<br />
| 10 || 840 mV || 74 IRE<br />
|-<br />
| 3D || 880 mV || 80 IRE<br />
|-<br />
| 20 || 1100 mV || 110 IRE<br />
|-<br />
| 0Dem || 192 mV || -17 IRE<br />
|-<br />
| 1Dem || 256 mV || -8 IRE<br />
|-<br />
| 2Dem || 448 mV || 19 IRE<br />
|-<br />
| 00em || 500 mV || 26 IRE<br />
|-<br />
| 10em || 676 mV || 51 IRE<br />
|-<br />
| 3Dem || 712 mV || 56 IRE<br />
|-<br />
| 20em || 896 mV || 82 IRE<br />
|}<br />
Unlike PAL, US NTSC is supposed to have a "setup", a difference between blanking and black level. Japanese NTSC does not make this distinction.<br />
<br />
=== Old measurement ===<br />
<br />
This measurment table was added to the wiki in 2009. Its source is unknown, and its results differ from the terminated measurements above. This was used for Bisqwit's example C++ implementation below.<br />
<br />
Voltage levels used by the PPU are as follows - absolute, relative to synch, and normalized between black level and white:<br />
{| class="wikitable"<br />
! Type || Absolute || Relative || Normalized<br />
|-<br />
| Synch || 0.781 || 0.000 || -0.359<br />
|-<br />
| Colorburst L || 1.000 || 0.218 || -0.208<br />
|-<br />
| Colorburst H || 1.712 || 0.931 || 0.286<br />
|-<br />
|Color 0D || 1.131 || 0.350 || -0.117<br />
|-<br />
|Color 1D (black) || 1.300 || 0.518 || 0.000<br />
|-<br />
|Color 2D || 1.743 || 0.962 || 0.308<br />
|-<br />
|Color 3D || 2.331 || 1.550 || 0.715<br />
|-<br />
|Color 00 || 1.875 || 1.090 || 0.397<br />
|-<br />
|Color 10 || 2.287 || 1.500 || 0.681<br />
|-<br />
|Color 20 || 2.743 || 1.960 || 1.000<br />
|-<br />
|Color 30 || 2.743 || 1.960 || 1.000<br />
|}<br />
<br />
These levels don't quite match the standard levels.<br />
Ideally, the composite signal is 1000 millivolts from peak to peak (1.0 Vp-p) when loaded with a 75 Ω output impedance.<br />
(Unloaded levels may be twice that amount, which may explain the levels seen above.)<br />
Levels are commonly measured in units called IRE.<ref>[https://www.maximintegrated.com/en/app-notes/index.mvp/id/1184 Tutorial 1184: Understanding Analog Video Signals]</ref><ref>[http://www.ni.com/white-paper/4750/en/ Analog Video 101]</ref><br />
<br />
==Color Phases==<br />
111111------<br />
22222------2<br />
3333------33<br />
444------444<br />
55------5555<br />
6------66666<br />
------777777<br />
-----888888-<br />
----999999--<br />
---AAAAAA---<br />
--BBBBBB----<br />
-CCCCCC-----<br />
<br />
The color generator is clocked by the rising ''and'' falling edges of the ~21.48 MHz clock, resulting in an effective ~42.95 MHz clock rate. There are 12 color square waves, spaced at regular phases. Each runs at the ~3.58 MHz colorburst rate. On NTSC, color $xY uses the wave shown in row Y from the table. NTSC color burst (pure shade -U) uses color phase 8 (with voltages listed above); PAL color burst is believed to alternate between 6 (-U+V) and 9 (-U-V), so hue is rotated by 15° from NTSC. [[wikipedia:PAL|PAL]] alternates the broadcast sign of the V component, so on PAL every odd scanline will use the appropriate opposite phase—e.g. phases 5-C are respectively replaced with C-5.<br />
<br />
=== Differential Phase Distortion ===<br />
The output is subject to a [[wikipedia:Differential phase|differential phase distortion]] effect<ref>[https://forums.nesdev.org/viewtopic.php?p=287241#p287241 Re: In search of a PAL region reference palette] - Explanation of the differential phase distortion of the NES.</ref>. This causes a rotation of the NTSC signal's effective hue, proportional to the voltage, causing more shift for brighter colors. Current estimates approximate about 2.5° (2C02E) or 5° (2C02G) of additional rotation for each row of the palette.<br />
<br />
The reason for this distortion is that the output impedance of the PPU is dependent on the signal level. When combined with the board's capacitance, it slows level transitions, causes the edges at high signal levels to be less steep. The high frequency chroma signal is sensitive to this, and the delay to its phase causes the hue rotation.<br />
<br />
A [[PAL video|PAL NES]] is affected by the same differential phase distortion, but because of the alternating-line mechanism of PAL, the effect is mostly cancelled out on consecutive scanlines.<br />
<br />
=== Color Artifacts ===<br />
Thought it takes 12 clocks of the generator to complete a color cycle, an NTSC pixel is only 8 clocks wide, or 10 on PAL. This means that the effective resolution of colour is lower than the pixel resolution, and some color information has to be shared with a neighbouring pixel. This produces color errors at horizontal edges where the color changes. These errors are known as artifacts. They are especially noticeable as "shimmering" when the screen scrolls slowly.<br />
<br />
The phase alignment of each pixel to the color cycle changes on every scanline, and this affects the hue of each color artifact. E.g. if the "red" part of the cycle is outside the pixel, its error artifact will be a distortion of the red color.<br />
<br />
An NTSC NES scanline is 227⅓ color cycles long, causing the alignment to shift by 4 clocks on each line. This creates a pattern of alignments that repeats every 3 lines. A vertical line may be seen to have a "rainbow" pattern of red, green, blue, red, green, blue... etc. The starting phase depends on a random alignment of the PPU to the picture which is determined on reset. (The scanline is shorter than standard NTSC, which has 227½ color cycles per line.)<br />
<br />
A PAL NES scanline is 284⅙ color cycles long, instead causing the alignment to shift by 2 clocks on each line, with an additional temporary -3 clocks every second line to provide the phase-alternating-line mechanism. This creates a [[:File:PAL signal 6538 53.2MHz.png|pattern of alignments]] that repeats every 6 lines. (The scanline is longer than standard PAL, which has 283¾ cycles per line.)<br />
<br />
Each frame of the NTSC NES picture also starts from a changing alignment. Normally every odd frame is 1 dot shorter than every even frame, resulting in 59560⅔ color cycles on odd frames, and 59561⅓ on even frames. This creates a 2-frame repeating pattern, shifting by 8 clocks after an odd frame, then by 4 after an even one. The missing dot may be suppressed if rendering is disabled during the pre-render scanline, so some games which force blank through the top of the frame (e.g. Battletoads) advance the color phase alignment by 4 clocks every frame. In this case, it creates a 3-frame repeating pattern, which creates a more noticeable shimmering. See: [[PPU frame timing]].<br />
<br />
PAL and Dendy instead have an even number of color cycles per frame, so the color phase alignment does not change from frame to frame.<br />
<br />
==Color Tint Bits==<br />
There are three color modulation channels controlled by the top three bits of $2001. Each channel uses one of the color square waves (see above diagram) and enables attenuation of the video signal when the color square wave is high. A single attenuator is shared by all channels. It is active for 6 out of 12 half-clocks if one bit is set, 10 half-clocks if two bits are set, or all 12 if all three bits are set.<br />
<br />
{| class="wikitable"<br />
! $2001 || Active phase || Active diagram || Complement<br />
|-<br />
|| Bit 7 || Color 8 || <tt>-----888888-</tt> || Color 2 (blue)<br />
|-<br />
|| Bit 6 || Color 4 || <tt>444------444</tt> || Color A (green)<br />
|-<br />
|| Bit 5 || Color C || <tt>-CCCCCC-----</tt> || Color 6 (red)<br />
|}<br />
<br />
When attenuation is active and the current pixel is a color other than $xE/$xF (black), the signal is attenuated.<br />
<br />
For example, when $2001 bit 6 is true, the attenuator will be active during the phases of color 4.<br />
This means the attenuator is not active during its complement (color A), and the screen appears to have a tint of color A, which is green.<br />
<br />
Note that on the Dendy and PAL NES, the green and red bits swap meaning.<br />
<br />
[http://forums.nesdev.org/viewtopic.php?p=160669#p160669 Tests performed on NTSC NES] show that emphasis does not affect the black colours in columns $E or $F, but it does affect all other columns, including the blacks and greys in column $D.<br />
<br />
The terminated measurements above suggest that resulting attenuated absolute voltage is approximately '''0.81 times''' the un-attenuated absolute voltage.<br />
<br />
The old measurement suggested a different approximation, applied to its relative or normalized values. This does not agree with the terminated measurements:<br />
attenuated relative = relative * 0.746<br />
attenuated normalized = normalized * 0.746 - 0.0912<br />
<br />
==Example Waveform==<br />
<br />
This waveform steps through various grays and then stops on a color.<br />
[[File:Composite_waveform_example.gif|center|frame|The composite signal steps through 6 gray colors ($0D, $0F, $2D, $00, $10, $30) then continues through with color $11. ]]<br />
<br />
The PPU's shortcut method of NTSC modulation often produces artifacts in which vertical lines appear slightly ragged, as the chroma spills over into luma.<br />
[[File:NTSC video ragged box animated.gif|right|frame|Generation and demodulation of a red corner]]<br />
<br clear="all"/><br />
<br />
== Composite decoding ==<br />
<br />
Normal composite video encodes chroma and luma information into one composite analog signal. In order to convert composite into an RGB signal, it firsts needs to be decoded into YUV, before converting the resulting YUV into RGB.<br />
<br />
The NES PPU does not encode anything into composite; instead, directly drawing the composite waveform itself. In order to convert the NES's composite signal into an RGB signal, it is decoded under the "assumption" that it was encoded under YUV.<br />
<br />
YUV in this article refers to and will continue to refer to the equiband encoding of composite video as Y, b-y and r-y respectively. YIQ refers to the non-equiband encoding of composite, which has much more additional considerations regarding bandlimiting.<br />
<br />
In practice, YIQ decoding is not used by any modern TV receiver and composite decoder, instead using YUV decoding as it is much simpler and less mathematically intensive to decode.<ref>[https://www.itu.int/rec/R-REC-BT.1700-0-200502-I/en S170m-2004.pdf: Composite Analog Video Signal NTSC for Studio Applications. Page 17.]</ref><ref>SMPTE EG 27-2004: Supplemental Information for SMPTE 170M and Background on the Development of NTSC Color Standards. Page 5.</ref><br />
<br />
=== Decoding composite video into YUV ===<br />
<br />
Although encoding composite is somewhat standardized, the methods of decoding composite may vary from TV to TV. This article shows one way to decode composite.<br />
<br />
==== Decoding chroma information (UV) ====<br />
<br />
Decoding chroma information requires a subcarrier reference sine wave to determine the hue, whose phase is "locked" (or aligned as best as possible) to the colorburst of the composite scanline.<br />
<br />
The subcarrier reference is used to demodulate the U component. A copy (or a phase offset) of the reference is delayed by 90 degrees, which is then used to demodulate the V component.<br />
<br />
The U/V component is demodulated by multiplying the subcarrier reference to the composite waveform. The resulting waveform is then filtered typically by a lowpass filter. A comb filter can also be used if desired.<br />
<br />
==== Decoding luma information (Y) ====<br />
<br />
To get the luma (Y) component, the base signal is filtered by a lowpass or comb filter. Some TVs use more complex methods to decode luma, some TVs do not filter at all.<br />
<br />
=== Converting YUV to linear RGB ===<br />
<br />
To convert YUV to linear RGB, we multiply the components to the following inversed matrix:<br />
<br />
<nowiki><br />
R = Y + V*1.14<br />
G = Y - (R*0.299 - B*0.114) / 0.587<br />
B = Y + U*2.03</nowiki><br />
<br />
Or, in terms of YUV only:<br />
<br />
<nowiki><br />
R = Y + V*1.14<br />
G = Y - U*0.394242... - V*0.580681...<br />
B = Y + U*2.03</nowiki><br />
<br />
The matrices above is derived from the NTSC base matrix<ref>[https://www.itu.int/rec/R-REC-BT.1700-0-200502-I/en S170m-2004.pdf: Composite Analog Video Signal NTSC for Studio Applications. Page 4.]</ref> of luminance and color-difference:<br />
<br />
<nowiki><br />
Y = R*0.299 + G*0.587 + B*0.114<br />
B-Y = -R*0.299 - G*0.587 + B*0.886<br />
R-Y = R*0.701 - G*0.587 - B*0.114</nowiki><br />
<br />
Which, when applied with the approximate color reduction factors 1/2.03 and 1/1.14 for B-Y and R-Y respectively<ref>[https://www.itu.int/rec/R-REC-BT.1700-0-200502-I/en S170m-2004.pdf: Composite Analog Video Signal NTSC for Studio Applications. Page 16.]</ref>, results in the definition of the linear RGB to YUV matrix equation:<br />
<br />
<nowiki><br />
Y = R*0.299 + G*0.587 + B*0.114<br />
U = (-R*0.299 - G*0.587 + B*0.886) / 2.03<br />
V = ( R*0.701 - G*0.587 - B*0.114) / 1.14</nowiki><br />
<br />
In YIQ, the IQ component's chroma hue is just the UV component's chroma hue rotated by 33 degrees. Note that this is not precisely the same as properly decoding YIQ with different bandwidths for the I and Q component.<br />
<br />
The following conversion is optional, and might match the look of other composite decoders:<br />
<br />
<nowiki><br />
U = -(I * sin(-33 deg)) + (Q * cos(-33 deg))<br />
V = (I * cos(-33 deg)) + (Q * sin(-33 deg))</nowiki><br />
<br />
=== Converting linear RGB to output colorspace ===<br />
<br />
The final step is to convert linear RGB into the output colorspace, typically sRGB for most monitors.<br />
<br />
==== Linear RGB into sRGB ====<br />
<br />
According to IEC 61966-2-1:1999, a gamma curve correction must be applied to the R, G and B signals before they are displayed.<ref>[https://www.color.org/chardata/rgb/srgb.xalter ICC page on sRGB]</ref> The transfer function for sRGB is:<br />
<br />
<nowiki><br />
C = linear R, G, or B signal<br />
C' = gamma corrected R, G or B signal<br />
<br />
C' = 12.92 * C if C <= 0.0031308<br />
C' = 1.055 * C^(1/2.4) - 0.055 if C > 0.0031308</nowiki><br />
<br />
The resulting R, G and B values can then be quantized into 8 bits per channel:<br />
<br />
<nowiki><br />
C8bpc = quantized R, G, or B channel<br />
C' = gamma corrected R, G or B signal<br />
<br />
C8bpc = (int)(C` * 255)</nowiki><br />
<br />
==Emulating in C++ code==<br />
<br />
For efficient, ready to use implementations, see [[#Libraries|Libraries]] below. The following is an illustrative example. The values used are based on the "old" measurements given above.<br />
<br />
Calculating the momentary NTSC signal level can be done as follows in C++:<br />
<br />
<nowiki><br />
// pixel = Pixel color (9-bit) given as input. Bitmask format: "eeellcccc".<br />
// phase = Signal phase (0..11). It is a variable that increases by 8 each pixel.<br />
float NTSCsignal(int pixel, int phase)<br />
{<br />
// Voltage levels, relative to synch voltage<br />
static const float black=.518f, white=1.962f, attenuation=.746f,<br />
levels[8] = {.350f, .518f, .962f,1.550f, // Signal low<br />
1.094f,1.506f,1.962f,1.962f}; // Signal high<br />
<br />
// Decode the NES color.<br />
int color = (pixel & 0x0F); // 0..15 "cccc"<br />
int level = (pixel >> 4) & 3; // 0..3 "ll"<br />
int emphasis = (pixel >> 6); // 0..7 "eee"<br />
if(color > 13) { level = 1; } // For colors 14..15, level 1 is forced.<br />
<br />
// The square wave for this color alternates between these two voltages:<br />
float low = levels[0 + level];<br />
float high = levels[4 + level];<br />
if(color == 0) { low = high; } // For color 0, only high level is emitted<br />
if(color > 12) { high = low; } // For colors 13..15, only low level is emitted<br />
<br />
// Generate the square wave<br />
auto InColorPhase = [=](int color) { return (color + phase) % 12 < 6; }; // Inline function<br />
float signal = InColorPhase(color) ? high : low;<br />
<br />
// When de-emphasis bits are set, some parts of the signal are attenuated:<br />
if( ((emphasis & 1) && InColorPhase(0))<br />
|| ((emphasis & 2) && InColorPhase(4))<br />
|| ((emphasis & 4) && InColorPhase(8)) ) signal = signal * attenuation;<br />
<br />
return signal;<br />
}</nowiki><br />
<br />
The process of generating NTSC signal for a single pixel can be simulated with the following C++ code:<br />
<br />
<nowiki><br />
void RenderNTSCpixel(unsigned x, int pixel, int PPU_cycle_counter)<br />
{<br />
int phase = PPU_cycle_counter * 8;<br />
for(int p=0; p<8; ++p) // Each pixel produces distinct 8 samples of NTSC signal.<br />
{<br />
float signal = NTSCsignal(pixel, phase + p); // Calculated as above<br />
// Optionally apply some lowpass-filtering to the signal here.<br />
// Optionally normalize the signal to 0..1 range:<br />
static const float black=.518f, white=1.962f;<br />
signal = (signal-black) / (white-black);<br />
// Save the signal for this pixel.<br />
signal_levels[ x*8 + p ] = signal;<br />
}<br />
}</nowiki><br />
<br />
It is important to note that while the NES only generates eight (8) samples of NTSC signal per pixel, the wavelength for chroma is 12 samples long. This means that the colors of adjacent pixels get mandatorily mixed up to some degree. For the same reason, narrow black&white details can be interpreted as colors.<br />
<br />
Because the scanline length is uneven (341*8 is not an even multiple of 12), the color mixing shifts a little each scanline. This appears visually as a sawtooth effect at the edges of colors at high resolution. The sawtooth cycles every 3 scanlines.<br />
<br />
Because also the frame length is uneven (neither 262*341*8 nor (262*341-1)*8 is an even multiple of 12), the color mixing also changes a little every frame. When rendering is normally enabled, the screen is alternatingly 89342 and 89341 cycles long. The combination of these (89342+89341)*8 <i>is</i> an even multiple of 12, which means that the artifact pattern cycles every 2 frames. The pattern of cycling can be changed by disabling rendering during the end of the pre-render scanline; it forces the screen length to 89342 cycles, even if would be 89341 otherwise.<br />
<br />
The process of decoding NTSC signal (convert it into RGB) is subject to a lot of study, and there are many patents and different techniques for it. A simple method suitable for emulation is covered below. It is not accurate, because in reality the chroma is blurred much more than is done here (the region of signal sampled for I and Q is wider than 12 samples), and the filter used here is a simple box FIR filter rather than an IIR filter, but it already produces a quite authentic looking picture. In addition, the border region (total of 26 pixels of background color around the 256-pixel scanline) is not sampled.<br />
<br />
<nowiki><br />
float signal_levels[256*8] = {...}; // Eight signal levels for each pixel, normalized to 0..1 range. <br />
Calculated as above.<br />
<br />
unsigned Width; // Input: Screen width. Can be not only 256, but anything up to 2048.<br />
float phase; // Input: This should the value that was PPU_cycle_counter * 8 + 3.9<br />
// at the BEGINNING of this scanline. It should be modulo 12.<br />
// It can additionally include a floating-point hue offset.<br />
for(unsigned x = 0; x < Width; ++x)<br />
{<br />
// Determine the region of scanline signal to sample. Take 12 samples.<br />
int center = x * (256*8) / Width + 0;<br />
int begin = center - 6; if(begin < 0) begin = 0;<br />
int end = center + 6; if(end > 256*8) end = 256*8;<br />
float y = 0.f, i = 0.f, q = 0.f; // Calculate the color in YIQ.<br />
for(int p = begin; p < end; ++p) // Collect and accumulate samples<br />
{<br />
float level = signal_levels[p] / 12.f;<br />
y = y + level;<br />
i = i + level * cos( M_PI * (phase+p) / 6 );<br />
q = q + level * sin( M_PI * (phase+p) / 6 );<br />
}<br />
render_pixel(y,i,q); // Send the YIQ color for rendering.<br />
}</nowiki><br />
<br />
The NTSC decoder here produces pixels in YIQ color space.<br />
<br />
If you want more saturated colors, just multiply <code>i</code> and <code>q</code> with a factor of your choosing, such as 1.7. If you want brighter colors, just multiply <code>y</code>, <code>i</code> and <code>q</code> with a factor of your choosing, such as 1.1. If you want to adjust the hue, just add or subtract a value from/to <code>phase</code>. If you want to see so called chroma dots, change the begin and end in such manner that you collect a number of samples that is not divisible with 12. If you want to blur the video horizontally, change the begin and end in such manner that the samples are collected from a wider region.<br />
<br />
The YIQ colors can be converted into sRGB colors with the following formula, using the [https://www.govinfo.gov/content/pkg/CFR-2013-title47-vol4/pdf/CFR-2013-title47-vol4-sec73-682.pdf#page=2 FCC-sanctioned] YIQ-to-RGB conversion matrix. This produces a value that can be saved to e.g. framebuffer:<br />
<br />
<nowiki><br />
float gamma = 2.0f; // Assumed display gamma<br />
auto gammafix = [=](float f) { return f <= 0.f ? 0.f : pow(f, 2.2f / gamma); };<br />
auto clamp = [](int v) { return v>255 ? 255 : v; };<br />
unsigned rgb =<br />
0x10000*clamp(255.95 * gammafix(y + 0.946882f*i + 0.623557f*q))<br />
+ 0x00100*clamp(255.95 * gammafix(y + -0.274788f*i + -0.635691f*q))<br />
+ 0x00001*clamp(255.95 * gammafix(y + -1.108545f*i + 1.709007f*q));</nowiki><br />
<br />
The two images below illustrate the NTSC artifacts.<br />
In the left side image, 12 samples of NTSC signal were generated for each NES pixel,<br />
and each display pixel was separately rendered by decoding that 12-sample signal.<br />
In the right side image, 8 samples of NTSC signal were generated for each NES pixel,<br />
and each display pixel was rendered by decoding 12 samples of NTSC signal from the<br />
corresponding location within the scanline.<br clear="all" /><br />
<table cellspacing=0 cellpadding=0><br />
<tr><td colspan=2>[[File:nes_ntsc_perpixel.png|left|frame|Per-pixel rendering: 12 samples of NTSC signal per input pixel; the same 12 samples are decoded for each output pixel]]</td><br />
<td colspan=2>[[File:nes_ntsc_perscanline.gif|left|frame|Per-scanline rendering: 8 samples of NTSC signal per input pixel; 12 samples are decoded for each output pixel]]</td></tr><br />
<tr><td>[[File:nes_ntsc_perpixel_small.png|left|frame|Same as above, but rendered at 256x240 without upscaling]]</td><br />
<td>[[File:nes_ntsc_perpixel_small_bw.png|left|frame|Same in grayscale (zero saturation). This illustrates well how the different color values have exactly the same luminosity; only the chroma phase differs.]]</td><br />
<td>[[File:nes_ntsc_perscanline_small.gif|left|frame|Same as above, but rendered at 256x240 rather than at 2048x240 and then downscaled]]</td><br />
<td>[[File:nes_ntsc_perscanline_small_bw.gif|left|frame|Same in grayscale]]</td></tr></table><br />
<br />
The source code of the program that generated both images can be read here: [https://bisqwit.iki.fi/jutut/kuvat/programming_examples/nesemu1/ntsc-small.cc ntsc-small.cc]. Note that even though the image resembles the well-known Philips PM5544 test card, it is not the same; the exact same<br />
colors could not be reproduced with NES colors. In addition, some parts were changed to better test NES features. For example, the backgrounds for the "station ID" regions (the black rectangles at the top and at the bottom inside the circle) are generated using the various blacks within the NES palette.<br />
<br />
Later, Bisqwit made a generic [http://forums.nesdev.org/viewtopic.php?p=172329#p172329 integer-based decoder in C++]. This takes a signal at 12 times color burst and can be used to emulate other systems that use shortcuts when generating NTSC video, such as Apple II (where ''every'' color in <code>HGR</code> is an artifact color) and Atari 7800 (whose game ''Tower Toppler'' seriously exploits artifact colors).<br />
<br />
==Libraries==<br />
<br />
* [http://slack.net/~ant/libs/ntsc.html blargg's nes_ntsc library]<br />
* [//forums.nesdev.org/viewtopic.php?f=21&t=11947 blargg's NTSC demo windows executable]<br />
* [//forums.nesdev.org/viewtopic.php?f=2&t=14338 Forum thread]: New NTSC decoder with integer-only math (short C++ code) - by Bisqwit<br />
* [https://github.com/LMP88959/NTSC-CRT/ LMP88959 (EMMIR)'s NTSC decoder]<br />
<br />
== See also ==<br />
* [[Cycle reference chart]]<br />
* [[PAL video]]<br />
* [[PPU palettes]]<br />
<br />
== References ==<br />
<references /></div>Rainwarriorhttps://www.nesdev.org/w/index.php?title=PAL_video&diff=21004PAL video2023-04-08T00:33:49Z<p>Rainwarrior: explain phase shift per line</p>
<hr />
<div>The 2C07 PPU in the PAL NES and the 6538 PPU in PAL famiclones generate composite '''PAL video''' in much the same way that the 2C02 generates [[NTSC video]]: as a square wave between "high" and "low" levels, offset by 0 to 5.5 master clock cycles from the phase of color burst.<br />
<br />
PAL NES video has several key differences from NTSC NES video:<br />
<br />
;[[wikipedia:PAL|Phase Alternating Line]]<br />
:The phase of the V subcarrier inverts between each scanline and the next. The color burst is ideally at 135 degrees relative to the [[wikipedia:YUV|UV plane]], not 180. This allows the TV to detect the phase of the V subcarrier by comparing the phase of color burst to that of the previous line. The PAL NES outputs a somewhat nonstandard 120 degree color burst.<br />
;Higher color subcarrier frequency<br />
:Pixels are 5 master clock cycles long (5/6 of a pixel), rather than 4 (4/6), increasing the chroma resolution slightly.<br />
;50 Hz<br />
:Each field contains 312 lines, not 262, producing vertical [[Overscan|underscan]] and a pixel aspect ratio close to 1.386:1, which is wider than 1.143:1 of NTSC.<br />
;No short line<br />
:The dot at the end of pre-render scanline is never skipped. This combined with the fact that 312 is a multiple of 6 causes the chroma dot pattern not to vary from one field to the next, producing dirty stills but OK movement.<br />
;Phase per line<br />
:The PAL NES scanline has 284⅙ chroma cycles, rather than the standard 283¾. This results in a 6-line pattern of color artifacts, as the phase changes by 60° on each line. NTSC by comparison has 227⅓ chroma cycles per line, giving a 3-line pattern.<br />
;Larger border<br />
:The border, including the area outside the picture, is always black rather than using the background color at $3F00, and it covers the top scanline and the left and right 2 pixels of each remaining scanline.<br />
;Hue shift<br />
:The color hue is slightly different relative to NTSC. There is a 15 degree shift due to the color burst effectively using color phase "7.5" instead of 8, but this difference may be mitigated for brighter colors by PAL's cancellation of differential phase distortion effects (see below), which on NTSC appear to cause a similar shift but only for brighter colors.<br />
;Differential phase distortion<br />
:The output is subject to differential phase distortion like the NTSC PPU, and on individual scanlines the effect may be even more severe on PAL<ref>[//forums.nesdev.org/viewtopic.php?p=133640#p133640 Re: PAL chroma merging?] TheFox observes a ~60° hue difference between even and odd scanlines.</ref>, but because the alternating-line mechanism causes the hue distortion to be opposite on consecutive lines, the color error can cancel out vertically when it's not on isolated rows. (See: [[NTSC video#Color phases|NTSC video: Color phases]])<br />
<br />
The 2C07 and 6538 additionally have minor timing differences related to post-render length and OAM refresh; see [[Cycle_reference_chart#Clock_rates|Clock rate]].<br />
<br />
There are two different ways that a TV can ''decode'' PAL video.<br />
The simple way treats PAL as if it were NTSC, modulo the five differences above.<br />
If the television signal is subject to phase distortion, this produces an artifact called [[wikipedia:Hanover bars|Hanover bars]].<br />
The other way is a comb filter: average the received scanline's chroma (U and V channels) with the chroma from the received scanline immediately above it in the same field and use that.<br />
This method, invented by an engineer at Telefunken, eliminates Hanover bars at the expense of a 64 microsecond quartz delay line, a royalty payable to Telefunken, and blurred vertical color detail.<br />
Less expensive PAL TVs used the simple method and relied on the change in color burst phase over time to cancel out the Hanover bars, though this technique may not be effective with the slightly nonstandard scanline length in the PAL signal from an NES.<br />
<br />
Emulator developers planning to simulate PAL video decoding can use a signal captured from a 6538 to test the decoder:<br />
* [[:File:PAL signal 6538 250MHz.png|250 MHz capture]]<br />
* [[:File:PAL signal 6538 53.2MHz.png|Same capture downsampled to twelve times the subcarrier frequency (53.2 MHz)]], with one pixel per rise or fall of the master clock<br />
<br />
== Libraries ==<br />
* [https://github.com/LMP88959/PAL-CRT/ LMP88959 (EMMIR)'s PAL decoder]<br />
<br />
== See Also ==<br />
* [[NTSC video]]</div>Rainwarriorhttps://www.nesdev.org/w/index.php?title=PAL_video&diff=21003PAL video2023-04-07T23:23:38Z<p>Rainwarrior: compare increased color resolution. hue shift description is too simple, letting it fall through into phase distortion description</p>
<hr />
<div>The 2C07 PPU in the PAL NES and the 6538 PPU in PAL famiclones generate composite '''PAL video''' in much the same way that the 2C02 generates [[NTSC video]]: as a square wave between "high" and "low" levels, offset by 0 to 5.5 master clock cycles from the phase of color burst.<br />
<br />
PAL NES video has several key differences from NTSC NES video:<br />
<br />
;[[wikipedia:PAL|Phase Alternating Line]]<br />
:The phase of the V subcarrier inverts between each scanline and the next. The color burst is ideally at 135 degrees relative to the [[wikipedia:YUV|UV plane]], not 180. This allows the TV to detect the phase of the V subcarrier by comparing the phase of color burst to that of the previous line. The PAL NES outputs a somewhat nonstandard 120 degree color burst.<br />
;Higher color subcarrier frequency<br />
:Pixels are 5 master clock cycles long (5/6 of a pixel), rather than 4 (4/6), increasing the chroma resolution slightly.<br />
;50 Hz<br />
:Each field contains 312 lines, not 262, producing vertical [[Overscan|underscan]] and a pixel aspect ratio close to 1.386:1, which is wider than 1.143:1 of NTSC.<br />
;No short line<br />
:The dot at the end of pre-render scanline is never skipped. This combined with the fact that 312 is a multiple of 6 causes the chroma dot pattern not to vary from one field to the next, producing dirty stills but OK movement.<br />
;Larger border<br />
:The border, including the area outside the picture, is always black rather than using the background color at $3F00, and it covers the top scanline and the left and right 2 pixels of each remaining scanline.<br />
;Hue shift<br />
:The color hue is slightly different relative to NTSC. There is a 15 degree shift due to the color burst effectively using color phase "7.5" instead of 8, but this difference may be mitigated for brighter colors by PAL's cancellation of differential phase distortion effects (see below), which on NTSC appear to cause a similar shift but only for brighter colors.<br />
;Differential phase distortion<br />
:The output is subject to differential phase distortion like the NTSC PPU, and on individual scanlines the effect may be even more severe on PAL<ref>[//forums.nesdev.org/viewtopic.php?p=133640#p133640 Re: PAL chroma merging?] TheFox observes a ~60° hue difference between even and odd scanlines.</ref>, but because the alternating-line mechanism causes the hue distortion to be opposite on consecutive lines, the color error can cancel out vertically when it's not on isolated rows. (See: [[NTSC video#Color phases|NTSC video: Color phases]])<br />
<br />
The 2C07 and 6538 additionally have minor timing differences related to post-render length and OAM refresh; see [[Cycle_reference_chart#Clock_rates|Clock rate]].<br />
<br />
There are two different ways that a TV can ''decode'' PAL video.<br />
The simple way treats PAL as if it were NTSC, modulo the five differences above.<br />
If the television signal is subject to phase distortion, this produces an artifact called [[wikipedia:Hanover bars|Hanover bars]].<br />
The other way is a comb filter: average the received scanline's chroma (U and V channels) with the chroma from the received scanline immediately above it in the same field and use that.<br />
This method, invented by an engineer at Telefunken, eliminates Hanover bars at the expense of a 64 microsecond quartz delay line, a royalty payable to Telefunken, and blurred vertical color detail.<br />
Less expensive PAL TVs used the simple method and relied on the change in color burst phase over time to cancel out the Hanover bars, though this technique may not be effective with the slightly nonstandard scanline length in the PAL signal from an NES.<br />
<br />
Emulator developers planning to simulate PAL video decoding can use a signal captured from a 6538 to test the decoder:<br />
* [[:File:PAL signal 6538 250MHz.png|250 MHz capture]]<br />
* [[:File:PAL signal 6538 53.2MHz.png|Same capture downsampled to twelve times the subcarrier frequency (53.2 MHz)]], with one pixel per rise or fall of the master clock<br />
<br />
== Libraries ==<br />
* [https://github.com/LMP88959/PAL-CRT/ LMP88959 (EMMIR)'s PAL decoder]<br />
<br />
== See Also ==<br />
* [[NTSC video]]</div>Rainwarriorhttps://www.nesdev.org/w/index.php?title=Talk:PPU_palettes&diff=21002Talk:PPU palettes2023-04-07T23:09:00Z<p>Rainwarrior: /* RC2C03B possible bad dump? */ new section</p>
<hr />
<div>It says that the background palette hack can be used to display the unused palette data. Can the EXT pins also do this? --[[User:Zzo38|Zzo38]] ([[User talk:Zzo38|talk]]) 22:30, 1 July 2013 (MDT)<br />
: Yes, I think so. While rendering background pixels, the palette index that gets looked up is simply 0<exp_in3><exp_in2><exp_in1><exp_in0>. -[[User:Ulfalizer|Ulfalizer]] ([[User talk:Ulfalizer|talk]]) 03:58, 2 July 2013 (MDT)<br />
: Interestingly, it looks like the background palette hack wouldn't work for ''output'' to the EXT pins though (bit 6 of $2000 set). The logic that causes the VRAM address to be used for the palette index while the background palette hack is active comes after the logic that outputs the index to the EXT pins. -[[User:Ulfalizer|Ulfalizer]] ([[User talk:Ulfalizer|talk]]) 04:15, 2 July 2013 (MDT)<br />
::Thank you for information. I suppose if you are using the master/slave, you can connect the EXT pins in reverse (EXT0 to EXT3, EXT1 to EXT2, EXT2 to EXT1, EXT3 to EXT0) so that this can be used to make extra colors. --[[User:Zzo38|Zzo38]] ([[User talk:Zzo38|talk]]) 23:05, 2 July 2013 (MDT)<br />
<br />
== Source of palette ==<br />
<br />
Where did the palette added by Lidnariq in [http://wiki.nesdev.org/w/index.php?title=PPU_palettes&diff=7888&oldid=7887#RGB_palette_values this edit] come from? --[[User:Tepples|Tepples]] ([[User talk:Tepples|talk]]) 18:56, 25 December 2013 (MST)<br />
: Screenshot from Nestopia running blargg's full_colors and nes_ntsc. Feel free to bikeshed. —[[User:Lidnariq|Lidnariq]] ([[User talk:Lidnariq|talk]]) 20:00, 25 December 2013 (MST)<br />
<br />
== Parsing the palette ==<br />
<br />
The palette values from this table are read from left to right, then up -> down. Is this ok?<br />
<br />
00 01 02 03 ... 0F<br><br />
10 11 12 13 ... 1F<br><br />
20 ...<br><br />
<small>([[wikipedia:wikipedia:Signatures|unsigned]] comment by [[User:Zepper|Zepper]])</small><br />
:Almost. They appear to go from $00 to $0D, then the next line from $10 to $1D, etc. --[[User:Tepples|Tepples]] ([[User talk:Tepples|talk]]) 06:42, 28 December 2013 (MST)<br />
<br />
== Browser compatibility of Drag's palette generator ==<br />
<br />
It appears that Firefox 29 implements built-in validation for <code>&lt;input type="number"&gt;</code> such that said elements are expected by default to contain integers. This affects the default hue and saturation settings, causing the boxes to be given glowing red borders and explanatory tooltips, and preventing the values from being changed to other reasonable non-integers. The default settings still ''work'' (in that they produce the same palette as in older versions of Firefox) as long as they are not changed.<br />
<br />
Relevant documentation can be found on various Mozilla websites (not bothering to link any of it here due to lack of login). --[[Special:Contributions/150.135.211.242|150.135.211.242]] 22:30, 18 May 2014 (MDT)<!-- Eighty5cacao on Pin Eight --><br />
:Maybe send this information to Drag? I don't think it does much good here. - [[User:Rainwarrior|Rainwarrior]] ([[User talk:Rainwarrior|talk]]) 11:00, 20 May 2014 (MDT)<br />
::How does Drag prefer to be contacted? I am not active on the forums (and therefore don't qualify for an account on the wiki either). The homepage of the domain on which the generator is hosted mentions that Drag has a Twitter account, but I'm not a registered Twitter user either (and I don't feel like registering just for this one issue).<br />
::I don't see how posting here is useless given that some other user could make a fixed version. For example, Tepples has some webspace which could theoretically be used for this. --[[Special:Contributions/150.135.211.242|150.135.211.242]] 14:46, 20 May 2014 (MDT)<br />
:::You used to need a reputation on the BBS or [[IRC]] to qualify for a wiki account. You don't anymore; that ended 20 months ago with the transition away from Parodius. Feel free to register and jump right into the talk pages, and so long as your posts there show clue, you'll get [[Nesdev wiki:Users|autoconfirmed]] in no time. --[[User:Tepples|Tepples]] ([[User talk:Tepples|talk]]) 19:35, 20 May 2014 (MDT)<br />
:I'll take this into account if I decide to poke at my palette generator again. :P Thanks for letting me know about it though. --[[User:Drag|Drag]] ([[User talk:Drag|talk]]) 17:27, 26 May 2014 (MDT)<br />
:The number fields should now be fixed, I hope. I just needed to add a "step" property to the input field to specify that I expect decimals to 0.001 precision. --[[User:Drag|Drag]] ([[User talk:Drag|talk]]) 01:09, 28 May 2014 (MDT)<br />
&larr;<br />
<br />
One more problem with the validation: Press the "Get current preset" button with everything else left at defaults. The Wx value of 0.3127 gets flagged as invalid because it has one more decimal place than the current validation allows. It's probably a good idea to allow four decimal places in all the custom colorimetry settings, based on the conventions I've seen. (I suppose I'm fine downloading a copy to run locally if you don't want to bother)<br />
<br />
(Aside: My main reason not for registering at this point is lack of HTTPS support. Even if I were to ignore that, I'm a little confused why some accounts have needed to be confirmed manually recently.) --[[Special:Contributions/150.135.211.242|150.135.211.242]] 14:32, 21 April 2015 (MDT)<br />
<br />
== Palette color format? ==<br />
<br />
What's the color format used in the palette entries? Example: 755,637,700,447... ???<br />
How do I "decode" the 755 value in RGB? --[[User:Zepper|Zepper]] ([[User talk:Zepper|talk]]) 13:24, 29 October 2014 (MDT)<br />
:Those are RGB333 values, so 637 means 6/7 red (0xDB), 3/7 green (0x6D), and 7/7 blue (0xFF). --[[User:Quietust|Quietust]] ([[User talk:Quietust|talk]]) 20:36, 29 October 2014 (MDT)<br />
::The .PAL format should consist of the same color formatting as the [http://www.shikadi.net/moddingwiki/VGA_Palette Classic VGA Palette format] so if you know how to program back then, you already know this. --[[User:Hamtaro126|Hamtaro126]] ([[User talk:Hamtaro126|talk]]) 05:55, 31 October 2014 (MDT)<br />
<br />
Why does this page show strange, nonstandard palettes first ?<br />
<br />
== Platte display ==<br />
One version of the canonical, standard NES palette should appear at the top of the page. Other palettes used by RGB, playchoice or whathever are annecdotical and should only appear below. They should most certainly *not* appear first.<br />
[[User:Bregalad|Bregalad]] ([[User talk:Bregalad|talk]]) 14:29, 6 January 2016 (MST)<br />
<br />
== Move the palette chart to the top ==<br />
<br />
I don't know about you guys, but most of the time I visit this page is because I want to see a chart which maps NES colors to their corresponding numbers. Strangely, the only chart on the page for this is found at the very bottom! The charts that come before it are for the 2C03, 2C04, 2C05 PPUs, not the 2C02 PPU which is what most people would expect.<br />
<br />
Suggested change: Move [http://wiki.nesdev.org/w/index.php/File:Savtool-swatches.png savtool's NES palette] to the top of the page, above any mention of the 2C03. <br />
<br />
[[User:Pubby|Pubby]] ([[User talk:Pubby|talk]]) 11:20, 11 May 2016 (MDT)<br />
:Good point. Done. --[[User:Tepples|Tepples]] ([[User talk:Tepples|talk]]) 13:10, 11 May 2016 (MDT)<br />
<br />
== "classic EGA palette" ==<br />
<br />
"These NES colors approximate colors in the classic Windows or EGA palette, though the NES doesn't really have a good yellow"<br />
Is this sentence supposed to refer to the chromas prior to or those following it? [[User:Myask|Myask]] ([[User talk:Myask|talk]]) 21:01, 10 January 2017 (MST)<br />
<br />
:The values before the statement you quoted aren't specific colors. They're values like $x2 and $x4 which represent entire "columns" of colors. For example, $x2 = $02, $12, $22, and $32. $x4 = $04, $14, $24, and $34. Also, the statement you quoted ends with a colon, indicating it refers to the values that follow it. --[[User:Bavi H|Bavi H]] ([[User talk:Bavi H|talk]]) 19:08, 11 January 2017 (MST)<br />
:It refers to those that follow. I added a section break between the chroma list and the EGA list to clarify. --[[User:Tepples|Tepples]] ([[User talk:Tepples|talk]]) 12:36, 13 January 2017 (MST)<br />
<br />
== Background Palette Hack Intentionality? ==<br />
<br />
I've looked over the palette logic in Visual 2C02, and I don't see any signs that the "background palette hack" was intentional - whenever the VRAM address is within $3F00-$3FFF, the Palette RAM's address input is connected to A0-A4 so that writes to $2007 will go into the appropriate memory cells, but there's no logic to ''disable'' the palette's output signals so they still end up driving the luma/chroma generators during the visible portion of the frame. To me, that looks very much like it's a side effect of how rendering works. --[[User:Quietust|Quietust]] ([[User talk:Quietust|talk]]) 18:14, 2 July 2022 (UTC)<br />
<br />
== RC2C03B possible bad dump? ==<br />
<br />
There seems to be only one known instance of this, and there are suspicions that it is is simply a bad dump. Moved here to talk page waiting for someone to improve the evidence for it. Has another of these ever been found? Is the original still accessible? - [[User:Rainwarrior|Rainwarrior]] ([[User talk:Rainwarrior|talk]]) 23:09, 7 April 2023 (UTC)<br />
<br />
=== RC2C03B ===<br />
For no particularly discernible reason, the palette for this specific PPU varies in six colors:<br />
<br />
333,014,006,326,403,503,510,420,320,100,031,040,022,000,000,000<br />
555,016,027,407,507,704,700,630,430,140,040,053,044,000,000,000<br />
777,357,447,637,707,717,740,750,660,340,070,276,077,000,000,000<br />
777,547,657,757,747,755,764,772,773,552,473,276,467,000,000,000<br />
{|class="wikitable"<br />
|-<br />
|style="border:0px;background-color:#6d6d6d;width:32px;height:32px;color:#fff;text-align:center"|00<br />
|style="border:0px;background-color:#002491;width:32px;height:32px;color:#fff;text-align:center"|01<br />
|style="border:0px;background-color:#0000da;width:32px;height:32px;color:#fff;text-align:center"|02<br />
|style="border:0px;background-color:#6d48da;width:32px;height:32px;color:#fff;text-align:center"|03<br />
|style="border:0px;background-color:#91006d;width:32px;height:32px;color:#fff;text-align:center"|04<br />
|style="border:0px;background-color:#b6006d;width:32px;height:32px;color:#fff;text-align:center"|05<br />
|style="border:0px;background-color:#b62400;width:32px;height:32px;color:#fff;text-align:center"|06<br />
|style="border:0px;background-color:#914800;width:32px;height:32px;color:#fff;text-align:center"|07<br />
|style="border:0px;background-color:#6d4800;width:32px;height:32px;color:#fff;text-align:center"|08<br />
|style="border:0px;background-color:#240000;width:32px;height:32px;color:#fff;border:1px solid #fff;text-align:center"|09<br />
|style="border:0px;background-color:#006d24;width:32px;height:32px;color:#fff;text-align:center"|0A<br />
|style="border:0px;background-color:#009100;width:32px;height:32px;color:#fff;text-align:center"|0B<br />
|style="border:0px;background-color:#004848;width:32px;height:32px;color:#fff;text-align:center"|0C<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|0D<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|0E<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|0F<br />
|-<br />
|style="border:0px;background-color:#b6b6b6;width:32px;height:32px;color:#fff;text-align:center"|10<br />
|style="border:0px;background-color:#0024da;width:32px;height:32px;color:#fff;border:1px solid #fff;text-align:center"|11<br />
|style="border:0px;background-color:#0048ff;width:32px;height:32px;color:#fff;text-align:center"|12<br />
|style="border:0px;background-color:#9100ff;width:32px;height:32px;color:#fff;text-align:center"|13<br />
|style="border:0px;background-color:#b600ff;width:32px;height:32px;color:#fff;text-align:center"|14<br />
|style="border:0px;background-color:#ff0091;width:32px;height:32px;color:#fff;text-align:center"|15<br />
|style="border:0px;background-color:#ff0000;width:32px;height:32px;color:#fff;text-align:center"|16<br />
|style="border:0px;background-color:#da6d00;width:32px;height:32px;color:#fff;text-align:center"|17<br />
|style="border:0px;background-color:#916d00;width:32px;height:32px;color:#fff;text-align:center"|18<br />
|style="border:0px;background-color:#249100;width:32px;height:32px;color:#fff;text-align:center"|19<br />
|style="border:0px;background-color:#009100;width:32px;height:32px;color:#fff;text-align:center"|1A<br />
|style="border:0px;background-color:#00b66d;width:32px;height:32px;color:#fff;text-align:center"|1B<br />
|style="border:0px;background-color:#009191;width:32px;height:32px;color:#fff;text-align:center"|1C<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|1D<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|1E<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|1F<br />
|-<br />
|style="border:0px;background-color:#ffffff;width:32px;height:32px;color:#000;text-align:center"|20<br />
|style="border:0px;background-color:#6db6ff;width:32px;height:32px;color:#000;text-align:center"|21<br />
|style="border:0px;background-color:#9191ff;width:32px;height:32px;color:#000;text-align:center"|22<br />
|style="border:0px;background-color:#da6dff;width:32px;height:32px;color:#000;text-align:center"|23<br />
|style="border:0px;background-color:#ff00ff;width:32px;height:32px;color:#000;text-align:center"|24<br />
|style="border:0px;background-color:#ff24ff;width:32px;height:32px;color:#000;border:1px solid #000;text-align:center"|25<br />
|style="border:0px;background-color:#ff9100;width:32px;height:32px;color:#000;text-align:center"|26<br />
|style="border:0px;background-color:#ffb600;width:32px;height:32px;color:#000;text-align:center"|27<br />
|style="border:0px;background-color:#dada00;width:32px;height:32px;color:#000;text-align:center"|28<br />
|style="border:0px;background-color:#6d9100;width:32px;height:32px;color:#000;border:1px solid #000;text-align:center"|29<br />
|style="border:0px;background-color:#00ff00;width:32px;height:32px;color:#000;text-align:center"|2A<br />
|style="border:0px;background-color:#48ffda;width:32px;height:32px;color:#000;text-align:center"|2B<br />
|style="border:0px;background-color:#00ffff;width:32px;height:32px;color:#000;text-align:center"|2C<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|2D<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|2E<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|2F<br />
|-<br />
|style="border:0px;background-color:#ffffff;width:32px;height:32px;color:#000;text-align:center"|30<br />
|style="border:0px;background-color:#b691ff;width:32px;height:32px;color:#000;border:1px solid #000;text-align:center"|31<br />
|style="border:0px;background-color:#dab6ff;width:32px;height:32px;color:#000;text-align:center"|32<br />
|style="border:0px;background-color:#ffb6ff;width:32px;height:32px;color:#000;text-align:center"|33<br />
|style="border:0px;background-color:#ff91ff;width:32px;height:32px;color:#000;text-align:center"|34<br />
|style="border:0px;background-color:#ffb6b6;width:32px;height:32px;color:#000;text-align:center"|35<br />
|style="border:0px;background-color:#ffda91;width:32px;height:32px;color:#000;text-align:center"|36<br />
|style="border:0px;background-color:#ffff48;width:32px;height:32px;color:#000;text-align:center"|37<br />
|style="border:0px;background-color:#ffff6d;width:32px;height:32px;color:#000;text-align:center"|38<br />
|style="border:0px;background-color:#b6b648;width:32px;height:32px;color:#000;border:1px solid #000;text-align:center"|39<br />
|style="border:0px;background-color:#91ff6d;width:32px;height:32px;color:#000;text-align:center"|3A<br />
|style="border:0px;background-color:#48ffda;width:32px;height:32px;color:#000;text-align:center"|3B<br />
|style="border:0px;background-color:#91daff;width:32px;height:32px;color:#000;text-align:center"|3C<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|3D<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|3E<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|3F<br />
|}<br />
<br />
The pattern compared to the normal 2C03 is that where color bits 0-1 are 01 (i.e. palette entries $01/$11/$21/$31, $05/$15/$25/$35, and $09/$19/$29/$39), green is ANDed with 5 (bit 1 is 0). No games are known to be designed for this palette. Given the pattern, it was probably a mistake in the mask.<br />
<br />
Later anecdotes imply the specific PPU used to generate the above dump might have been damaged. [https://forums.nesdev.org/viewtopic.php?p=283412#p283412]</div>Rainwarriorhttps://www.nesdev.org/w/index.php?title=PPU_palettes&diff=21001PPU palettes2023-04-07T23:07:20Z<p>Rainwarrior: /* RC2C03B */ move this possible bad dump to talk page pending verification</p>
<hr />
<div>The NES has a limited selection of color outputs. A 6-bit value in the palette memory area corresponds to one of 64 outputs. The [[Colour emphasis|emphasis]] bits of the [[PPUMASK]] register ($2001) provide an additional color modifier.<br />
<br />
For more information on how the colors are generated on an NTSC NES, see: [[NTSC video]]<br />
<br />
== Memory Map ==<br />
The palette for the background runs from VRAM $3F00 to $3F0F; the palette for the sprites runs from $3F10 to $3F1F. Each color takes up one byte.<br />
<br />
{| class="wikitable"<br />
! Address || Purpose<br />
|-<br />
| $3F00 || Universal background color<br />
|-<br />
| $3F01-$3F03 || Background palette 0<br />
|-<br />
| $3F05-$3F07 || Background palette 1<br />
|-<br />
| $3F09-$3F0B || Background palette 2<br />
|-<br />
| $3F0D-$3F0F || Background palette 3<br />
|-<br />
| $3F11-$3F13 || Sprite palette 0<br />
|-<br />
| $3F15-$3F17 || Sprite palette 1<br />
|-<br />
| $3F19-$3F1B || Sprite palette 2<br />
|-<br />
| $3F1D-$3F1F || Sprite palette 3<br />
|}<br />
<br />
Each palette has three colors.<br />
Each 16x16 pixel area of the background can use the backdrop color and the three colors from one of the four background palettes.<br />
The choice of palette for each 16x16 pixel area is controlled by bits in the attribute table at the end of each [[PPU nametables|nametable]].<br />
Each sprite can use the three colors from one of the sprite palettes.<br />
The choice of palette is in attribute 2 of each sprite (see [[PPU OAM]]).<br />
<br />
Addresses $3F04/$3F08/$3F0C can contain unique data, though these values are not used by the PPU when normally rendering (since the pattern values that would otherwise select those cells select the backdrop color instead). They can still be shown using the background palette hack, explained below.<br />
<br />
Addresses $3F10/$3F14/$3F18/$3F1C are mirrors of $3F00/$3F04/$3F08/$3F0C. Note that this goes for writing as well as reading.<br />
A symptom of not having implemented this correctly in an emulator is the sky being black in ''Super Mario Bros.'', which writes the backdrop color through $3F10.<br />
<br />
Thus, indices into the palette are formed as follows:<br />
43210<br />
|||||<br />
|||++- Pixel value from tile data<br />
|++--- Palette number from attribute table or OAM<br />
+----- Background/Sprite select<br />
As in some second-generation game consoles, values in the NES palette are based on [[wikipedia:HSL and HSV|hue and brightness]]:<br />
76543210<br />
||||||||<br />
||||++++- Hue (phase, determines NTSC/PAL chroma)<br />
||++----- Value (voltage, determines NTSC/PAL luma)<br />
++------- Unimplemented, reads back as 0<br />
Hue $0 is light gray, $1-$C are blue to red to green to cyan, $D is dark gray, and $E-$F are mirrors of $1D (black).<br />
<br />
It works this way because of the way colors are represented in an NTSC or PAL signal, with the phase of a color subcarrier controlling the hue. For details, see [[NTSC video]], or for a list see [[Color $0D games]].<br />
<br />
The canonical code for "black" is $0F or $1D.<br />
{{mbox<br />
| type = warning<br />
| text = <font size=+1>Do not use color $0D. It results in a "blacker than black" signal that may cause problems for some TVs.</font><br />
<hr><br />
Further details can be found [[Color_$0D_games#Effects|here]]}}<br />
<br />
The 2C03 RGB PPU used in the PlayChoice-10 and Famicom Titler renders hue $D as black, not dark gray.<br />
The 2C04 PPUs used in many [[Vs. System]] arcade games have completely different palettes as a copy protection measure.<br />
<br />
== Palettes ==<br />
<br />
The 2C02 (NTSC) and 2C07 (PAL) PPU is used to generate an analog composite video signal. These were used in most home consoles.<br />
<br />
The 2C03, 2C04, and 2C05, on the other hand, all output analog red, green, blue, and sync (RGBS) signals. The sync signal contains horizontal and vertical sync pulses in the same format as an all-black composite signal.<br />
Each of the three video channels uses a 3-bit DAC driven by a look-up table in a 64x9-bit ROM inside the PPU.<br />
The look-up tables (one digit for each of red, green, and blue, in order) are given below.<br />
<br />
RGB PPUs were used mostly in arcade machines (e.g. [[Vs. System]], Playchoice 10), as well as the Sharp Famicom Titler.<br />
<br />
=== 2C02 and 2C07 ===<br />
[[File:Savtool-swatches.png|frame|right|NES palette generated with Bisqwit's tool]]<br />
The RF Famicom, AV Famicom, NES (both front- and top-loading), and the North American version of the Sharp Nintendo TV use the 2C02 PPU.<br />
Unlike some other consoles' video circuits, the 2C02 does not generate RGB video and then encode that to composite.<br />
Instead it generates [[NTSC video]] directly in the composite domain, decoded by the television receiver into RGB to drive its picture tube.<br />
<br />
Most emulators can use a predefined palette, such as one commonly stored in common [[.pal]] format, in which each triplet represents the sRGB color that results from decoding a large flat area with a given palette value. The following table was generated using [http://forums.nesdev.org/viewtopic.php?f=2&t=6484 blargg's Full Palette demo] on [[Emulators|Nestopia]]:<br />
<pre style="font-size: 70%"><br />
84 84 84 0 30 116 8 16 144 48 0 136 68 0 100 92 0 48 84 4 0 60 24 0 32 42 0 8 58 0 0 64 0 0 60 0 0 50 60 0 0 0<br />
152 150 152 8 76 196 48 50 236 92 30 228 136 20 176 160 20 100 152 34 32 120 60 0 84 90 0 40 114 0 8 124 0 0 118 40 0 102 120 0 0 0<br />
236 238 236 76 154 236 120 124 236 176 98 236 228 84 236 236 88 180 236 106 100 212 136 32 160 170 0 116 196 0 76 208 32 56 204 108 56 180 204 60 60 60<br />
236 238 236 168 204 236 188 188 236 212 178 236 236 174 236 236 174 212 236 180 176 228 196 144 204 210 120 180 222 120 168 226 144 152 226 180 160 214 228 160 162 160<br />
</pre><br />
<br />
Other tools for generating a palette include [http://bisqwit.iki.fi/utils/nespalette.php one by Bisqwit] and [http://drag.wootest.net/misc/palgen.html one by Drag].<br />
These simulate generating a large area of one flat color and then decoding that with the adjustment knobs set to various settings.<br />
<br />
The PAL PPU (2C07) has a 15 degree hue shift relative to NTSC.<br />
<br />
=== 2C03 and 2C05 ===<br />
This palette is intentionally similar to the NES's standard palette, but notably is missing the greys in entries $2D and $3D.<br />
The 2C03 is used in ''Vs. Duck Hunt'', ''Vs. Tennis'', all PlayChoice games, the Famicom Titler, and the Famicom TV.<br />
The 2C05 is used in some later Vs. games as a copy protection measure.<br />
Both have been used in RGB mods for the NES, as a circuit implementing <code>A0' = A0 xor (A1 nor A2)</code> can swap PPUCTRL and PPUMASK to make a 2C05 behave as a 2C03.<br />
<br />
333,014,006,326,403,503,510,420,320,120,031,040,022,000,000,000<br />
555,036,027,407,507,704,700,630,430,140,040,053,044,000,000,000<br />
777,357,447,637,707,737,740,750,660,360,070,276,077,000,000,000<br />
777,567,657,757,747,755,764,772,773,572,473,276,467,000,000,000<br />
{|class="wikitable"<br />
|-<br />
|style="border:0px;background-color:#6D6D6D;width:32px;height:32px;color:#fff;text-align:center"|00<br />
|style="border:0px;background-color:#002491;width:32px;height:32px;color:#fff;text-align:center"|01<br />
|style="border:0px;background-color:#0000DA;width:32px;height:32px;color:#fff;text-align:center"|02<br />
|style="border:0px;background-color:#6D48DA;width:32px;height:32px;color:#fff;text-align:center"|03<br />
|style="border:0px;background-color:#91006D;width:32px;height:32px;color:#fff;text-align:center"|04<br />
|style="border:0px;background-color:#B6006D;width:32px;height:32px;color:#fff;text-align:center"|05<br />
|style="border:0px;background-color:#B62400;width:32px;height:32px;color:#fff;text-align:center"|06<br />
|style="border:0px;background-color:#914800;width:32px;height:32px;color:#fff;text-align:center"|07<br />
|style="border:0px;background-color:#6D4800;width:32px;height:32px;color:#fff;text-align:center"|08<br />
|style="border:0px;background-color:#244800;width:32px;height:32px;color:#fff;text-align:center"|09<br />
|style="border:0px;background-color:#006D24;width:32px;height:32px;color:#fff;text-align:center"|0A<br />
|style="border:0px;background-color:#009100;width:32px;height:32px;color:#fff;text-align:center"|0B<br />
|style="border:0px;background-color:#004848;width:32px;height:32px;color:#fff;text-align:center"|0C<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|0D<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|0E<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|0F<br />
|- <br />
|style="border:0px;background-color:#B6B6B6;width:32px;height:32px;color:#fff;text-align:center"|10<br />
|style="border:0px;background-color:#006DDA;width:32px;height:32px;color:#fff;text-align:center"|11<br />
|style="border:0px;background-color:#0048FF;width:32px;height:32px;color:#fff;text-align:center"|12<br />
|style="border:0px;background-color:#9100FF;width:32px;height:32px;color:#fff;text-align:center"|13<br />
|style="border:0px;background-color:#B600FF;width:32px;height:32px;color:#fff;text-align:center"|14<br />
|style="border:0px;background-color:#FF0091;width:32px;height:32px;color:#fff;text-align:center"|15<br />
|style="border:0px;background-color:#FF0000;width:32px;height:32px;color:#fff;text-align:center"|16<br />
|style="border:0px;background-color:#DA6D00;width:32px;height:32px;color:#fff;text-align:center"|17<br />
|style="border:0px;background-color:#916D00;width:32px;height:32px;color:#fff;text-align:center"|18<br />
|style="border:0px;background-color:#249100;width:32px;height:32px;color:#fff;text-align:center"|19<br />
|style="border:0px;background-color:#009100;width:32px;height:32px;color:#fff;text-align:center"|1A<br />
|style="border:0px;background-color:#00B66D;width:32px;height:32px;color:#fff;text-align:center"|1B<br />
|style="border:0px;background-color:#009191;width:32px;height:32px;color:#fff;text-align:center"|1C<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|1D<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|1E<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|1F<br />
|- <br />
|style="border:0px;background-color:#FFFFFF;width:32px;height:32px;color:#000;text-align:center"|20<br />
|style="border:0px;background-color:#6DB6FF;width:32px;height:32px;color:#000;text-align:center"|21<br />
|style="border:0px;background-color:#9191FF;width:32px;height:32px;color:#000;text-align:center"|22<br />
|style="border:0px;background-color:#DA6DFF;width:32px;height:32px;color:#000;text-align:center"|23<br />
|style="border:0px;background-color:#FF00FF;width:32px;height:32px;color:#000;text-align:center"|24<br />
|style="border:0px;background-color:#FF6DFF;width:32px;height:32px;color:#000;text-align:center"|25<br />
|style="border:0px;background-color:#FF9100;width:32px;height:32px;color:#000;text-align:center"|26<br />
|style="border:0px;background-color:#FFB600;width:32px;height:32px;color:#000;text-align:center"|27<br />
|style="border:0px;background-color:#DADA00;width:32px;height:32px;color:#000;text-align:center"|28<br />
|style="border:0px;background-color:#6DDA00;width:32px;height:32px;color:#000;text-align:center"|29<br />
|style="border:0px;background-color:#00FF00;width:32px;height:32px;color:#000;text-align:center"|2A<br />
|style="border:0px;background-color:#48FFDA;width:32px;height:32px;color:#000;text-align:center"|2B<br />
|style="border:0px;background-color:#00FFFF;width:32px;height:32px;color:#000;text-align:center"|2C<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#f00;text-align:center"|2D<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|2E<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|2F<br />
|- <br />
|style="border:0px;background-color:#FFFFFF;width:32px;height:32px;color:#000;text-align:center"|30<br />
|style="border:0px;background-color:#B6DAFF;width:32px;height:32px;color:#000;text-align:center"|31<br />
|style="border:0px;background-color:#DAB6FF;width:32px;height:32px;color:#000;text-align:center"|32<br />
|style="border:0px;background-color:#FFB6FF;width:32px;height:32px;color:#000;text-align:center"|33<br />
|style="border:0px;background-color:#FF91FF;width:32px;height:32px;color:#000;text-align:center"|34<br />
|style="border:0px;background-color:#FFB6B6;width:32px;height:32px;color:#000;text-align:center"|35<br />
|style="border:0px;background-color:#FFDA91;width:32px;height:32px;color:#000;text-align:center"|36<br />
|style="border:0px;background-color:#FFFF48;width:32px;height:32px;color:#000;text-align:center"|37<br />
|style="border:0px;background-color:#FFFF6D;width:32px;height:32px;color:#000;text-align:center"|38<br />
|style="border:0px;background-color:#B6FF48;width:32px;height:32px;color:#000;text-align:center"|39<br />
|style="border:0px;background-color:#91FF6D;width:32px;height:32px;color:#000;text-align:center"|3A<br />
|style="border:0px;background-color:#48FFDA;width:32px;height:32px;color:#000;text-align:center"|3B<br />
|style="border:0px;background-color:#91DAFF;width:32px;height:32px;color:#000;text-align:center"|3C<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#f00;text-align:center"|3D<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|3E<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|3F<br />
|}<br />
<br />
Note that some of the colors are duplicates: $0B and $1A = 040, $2B and $3B = 276.<br />
<br />
Kevtris's dumped palettes imply that the monochrome bit has unique function on the 2C03 and 2C05: instead of just using the leftmost column of the palette (and forcing the lower four bits to zero), instead the top two bits index into a palette with colors: 000, 333, 777, 777. Given that the 2C04 does '''not''' do this, this exception feels weird, and corroboration would be appreciated.<br />
<br />
=== 2C04 ===<br />
All four 2C04 PPUs contain the same master palette, but in different permutations. It's almost a superset of the 2C03/5 palette, adding four greys, six other colors, and making the bright yellow more pure.<br />
<br />
Note that using the greyscale bit in [[PPUMASK]] will remap the palette by index, not by color. This means that with the scrambled palettes, each row will remap to the colors in the $0X column for that 2C04 version.<br />
<br />
Visualization tool: [https://www.nesdev.org/rgbppu/ RGB PPU Palette Converter]<br />
<br />
'''No version of the 2C04 was ever made with the below ordering''', but it shows the similarity to the 2C03:<br />
{|class="wikitable"<br />
|-<br />
|style="border:0px;background-color:#6D6D6D;width:32px;height:32px;color:#fff;text-align:center"|333<br />
|style="border:0px;background-color:#002491;width:32px;height:32px;color:#fff;text-align:center"|014<br />
|style="border:0px;background-color:#0000DA;width:32px;height:32px;color:#fff;text-align:center"|006<br />
|style="border:0px;background-color:#6D48DA;width:32px;height:32px;color:#fff;text-align:center"|326<br />
|style="border:0px;background-color:#91006D;width:32px;height:32px;color:#fff;text-align:center"|403<br />
|style="border:0px;background-color:#B6006D;width:32px;height:32px;color:#fff;text-align:center"|503<br />
|style="border:0px;background-color:#B62400;width:32px;height:32px;color:#fff;text-align:center"|510<br />
|style="border:0px;background-color:#914800;width:32px;height:32px;color:#fff;text-align:center"|420<br />
|style="border:0px;background-color:#6D4800;width:32px;height:32px;color:#fff;text-align:center"|320<br />
|style="border:0px;background-color:#244800;width:32px;height:32px;color:#fff;text-align:center"|120<br />
|style="border:0px;background-color:#006D24;width:32px;height:32px;color:#fff;text-align:center"|031<br />
|style="border:0px;background-color:#009100;width:32px;height:32px;color:#fff;text-align:center"|040<br />
|style="border:0px;background-color:#004848;width:32px;height:32px;color:#fff;text-align:center"|022<br />
|style="border:0px;background-color:#242424;width:32px;height:32px;color:#fff;text-align:center"|111<br />
|style="border:0px;background-color:#00006d;width:32px;height:32px;color:#fff;text-align:center"|003<br />
|style="border:0px;background-color:#004800;width:32px;height:32px;color:#fff;text-align:center"|020<br />
|-<br />
|style="border:0px;background-color:#B6B6B6;width:32px;height:32px;color:#fff;text-align:center"|555<br />
|style="border:0px;background-color:#006DDA;width:32px;height:32px;color:#fff;text-align:center"|036<br />
|style="border:0px;background-color:#0048FF;width:32px;height:32px;color:#fff;text-align:center"|027<br />
|style="border:0px;background-color:#9100FF;width:32px;height:32px;color:#fff;text-align:center"|407<br />
|style="border:0px;background-color:#B600FF;width:32px;height:32px;color:#fff;text-align:center"|507<br />
|style="border:0px;background-color:#FF0091;width:32px;height:32px;color:#fff;text-align:center"|704<br />
|style="border:0px;background-color:#FF0000;width:32px;height:32px;color:#fff;text-align:center"|700<br />
|style="border:0px;background-color:#DA6D00;width:32px;height:32px;color:#fff;text-align:center"|630<br />
|style="border:0px;background-color:#916D00;width:32px;height:32px;color:#fff;text-align:center"|430<br />
|style="border:0px;background-color:#249100;width:32px;height:32px;color:#fff;text-align:center"|140<br />
|style="border:0px;background-color:#009100;width:32px;height:32px;color:#fff;text-align:center"|040<br />
|style="border:0px;background-color:#00B66D;width:32px;height:32px;color:#fff;text-align:center"|053<br />
|style="border:0px;background-color:#009191;width:32px;height:32px;color:#fff;text-align:center"|044<br />
|style="border:0px;background-color:#484848;width:32px;height:32px;color:#fff;text-align:center"|222<br />
|style="border:0px;background-color:#480000;width:32px;height:32px;color:#fff;text-align:center"|200<br />
|style="border:0px;background-color:#6d2400;width:32px;height:32px;color:#fff;text-align:center"|310<br />
|-<br />
|style="border:0px;background-color:#FFFFFF;width:32px;height:32px;color:#000;text-align:center"|777<br />
|style="border:0px;background-color:#6DB6FF;width:32px;height:32px;color:#000;text-align:center"|357<br />
|style="border:0px;background-color:#9191FF;width:32px;height:32px;color:#000;text-align:center"|447<br />
|style="border:0px;background-color:#DA6DFF;width:32px;height:32px;color:#000;text-align:center"|637<br />
|style="border:0px;background-color:#FF00FF;width:32px;height:32px;color:#000;text-align:center"|707<br />
|style="border:0px;background-color:#FF6DFF;width:32px;height:32px;color:#000;text-align:center"|737<br />
|style="border:0px;background-color:#FF9100;width:32px;height:32px;color:#000;text-align:center"|740<br />
|style="border:0px;background-color:#FFB600;width:32px;height:32px;color:#000;text-align:center"|750<br />
|style="border:0px;background-color:#DADA00;width:32px;height:32px;color:#000;text-align:center"|660<br />
|style="border:0px;background-color:#6DDA00;width:32px;height:32px;color:#000;text-align:center"|360<br />
|style="border:0px;background-color:#00FF00;width:32px;height:32px;color:#000;text-align:center"|070<br />
|style="border:0px;background-color:#48FFDA;width:32px;height:32px;color:#000;text-align:center"|276<br />
|style="border:0px;background-color:#00FFFF;width:32px;height:32px;color:#000;text-align:center"|077<br />
|style="border:0px;background-color:#919191;width:32px;height:32px;color:#000;text-align:center"|444<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|000<br />
|style="border:0px;background-color:#000000;width:32px;height:32px;color:#fff;text-align:center"|000<br />
|-<br />
|style="border:0px;background-color:#FFFFFF;width:32px;height:32px;color:#000;text-align:center"|777<br />
|style="border:0px;background-color:#B6DAFF;width:32px;height:32px;color:#000;text-align:center"|567<br />
|style="border:0px;background-color:#DAB6FF;width:32px;height:32px;color:#000;text-align:center"|657<br />
|style="border:0px;background-color:#FFB6FF;width:32px;height:32px;color:#000;text-align:center"|757<br />
|style="border:0px;background-color:#FF91FF;width:32px;height:32px;color:#000;text-align:center"|747<br />
|style="border:0px;background-color:#FFB6B6;width:32px;height:32px;color:#000;text-align:center"|755<br />
|style="border:0px;background-color:#FFDA91;width:32px;height:32px;color:#000;text-align:center"|764<br />
|style="border:0px;background-color:#FFFF00;width:32px;height:32px;color:#000;text-align:center"|770<br />
|style="border:0px;background-color:#FFFF6D;width:32px;height:32px;color:#000;text-align:center"|773<br />
|style="border:0px;background-color:#B6FF48;width:32px;height:32px;color:#000;text-align:center"|572<br />
|style="border:0px;background-color:#91FF6D;width:32px;height:32px;color:#000;text-align:center"|473<br />
|style="border:0px;background-color:#48FFDA;width:32px;height:32px;color:#000;text-align:center"|276<br />
|style="border:0px;background-color:#91DAFF;width:32px;height:32px;color:#000;text-align:center"|467<br />
|style="border:0px;background-color:#dadada;width:32px;height:32px;color:#000;text-align:center"|666<br />
|style="border:0px;background-color:#dab66d;width:32px;height:32px;color:#000;text-align:center"|653<br />
|style="border:0px;background-color:#ffda00;width:32px;height:32px;color:#000;text-align:center"|760<br />
|}<br />
<!-- <br />
This image shows all the colors except the six shades of grey:<br />
<br />
[[Image:2C04_Palette_(Voronoi).png]] --><br />
The [[PPUMASK]] monochrome bit has the same implementation as on the 2C02, and so it has an unintuitive effect on the 2C04 PPUs; rather than forcing colors to grayscale, it instead forces them to the first column.<br />
==== RP2C04-0001 ====<br />
MAME's source claims that ''Baseball'', ''Freedom Force'', ''Gradius'', ''Hogan's Alley'', ''Mach Rider'', ''Pinball'', and ''Platoon'' require this palette.<br />
755,637,700,447,044,120,222,704,777,333,750,503,403,660,320,777<br />
357,653,310,360,467,657,764,027,760,276,000,200,666,444,707,014<br />
003,567,757,070,077,022,053,507,000,420,747,510,407,006,740,000<br />
000,140,555,031,572,326,770,630,020,036,040,111,773,737,430,473<br />
==== RP2C04-0002 ====<br />
MAME's source claims that ''Castlevania'', ''Mach Rider (Endurance Course)'', ''Raid on Bungeling Bay'', ''Slalom'', ''Soccer'', ''Stroke & Match Golf'' (both versions), and ''Wrecking Crew'' require this palette.<br />
000,750,430,572,473,737,044,567,700,407,773,747,777,637,467,040<br />
020,357,510,666,053,360,200,447,222,707,003,276,657,320,000,326<br />
403,764,740,757,036,310,555,006,507,760,333,120,027,000,660,777<br />
653,111,070,630,022,014,704,140,000,077,420,770,755,503,031,444<br />
==== RP2C04-0003 ====<br />
MAME's source claims that ''Balloon Fight'', ''Dr. Mario'', ''Excitebike'' (US), ''Goonies'', and ''Soccer'' require this palette.<br />
507,737,473,555,040,777,567,120,014,000,764,320,704,666,653,467<br />
447,044,503,027,140,430,630,053,333,326,000,006,700,510,747,755<br />
637,020,003,770,111,750,740,777,360,403,357,707,036,444,000,310<br />
077,200,572,757,420,070,660,222,031,000,657,773,407,276,760,022<br />
==== RP2C04-0004 ====<br />
MAME's source claims that ''Clu Clu Land'', ''Excitebike'' (Japan), ''Ice Climber'' (both versions), and ''Super Mario Bros.'' require this palette.<br />
430,326,044,660,000,755,014,630,555,310,070,003,764,770,040,572<br />
737,200,027,747,000,222,510,740,653,053,447,140,403,000,473,357<br />
503,031,420,006,407,507,333,704,022,666,036,020,111,773,444,707<br />
757,777,320,700,760,276,777,467,000,750,637,567,360,657,077,120<br />
<br />
==== Games compatible with multiple different PPUs ====<br />
Some games don't require that arcade owners have the correct physical PPU.<br />
<br />
At the very least, the following games use some of the DIP switches to support multiple different PPUs:<br />
* Atari RBI Baseball<br />
* Battle City<br />
* Star Luster<br />
* Super Sky Kid<br />
* Super Xevious<br />
* Tetris (Tengen)<br />
* TKO Boxing<br />
<br />
== Backdrop color (palette index 0) uses ==<br />
<br />
During forced blanking, when neither background nor sprites are enabled in [[PPU registers|PPUMASK ($2001)]], the picture will show the backdrop color.<br />
If only the background or sprites are disabled, or if the left 8 pixels are clipped off, the PPU continues its [[PPU rendering|normal video memory access pattern]] but uses the backdrop color for anything disabled.<br />
<br />
== The background palette hack ==<br />
<br />
If the current VRAM address points in the range $3F00-$3FFF during forced blanking, the color indicated by this palette location will be shown on screen instead of the backdrop color.<br />
(Looking at the relevant circuitry in [[Visual 2C02]], this is an intentional feature of the PPU and not merely a side effect of how rendering works.)<br />
This can be used to display colors from the normally unused $3F04/$3F08/$3F0C palette locations.<br />
A loop that fills the palette will cause each color in turn to be shown on the screen, so to avoid horizontal rainbow bar glitches while loading the palette, wait for a real vertical blank first using an [[NMI]] technique.<br />
<br />
== Color names ==<br />
When programmers and artists are communicating, it's often useful to have human-readable names for colors.<br />
Many graphic designers who have done web or game work will be familiar with [[wikipedia:Web colors#HTML color names|HTML color names]].<br />
<br />
=== Luma ===<br />
<br />
* $0F: Black<br />
* $00: Dark gray<br />
* $10: Light gray or silver<br />
* $20: White<br />
* $01-$0C: Dark colors, medium mixed with black<br />
* $11-$1C: Medium colors, similar brightness to dark gray<br />
* $21-$2C: Light colors, similar brightness to light gray<br />
* $31-$3C: Pale colors, light mixed with white<br />
<br />
=== Chroma ===<br />
Names for hues:<br />
* $x0: Gray<br />
* $x1: Azure<br />
* $x2: Blue<br />
* $x3: Violet<br />
* $x4: Magenta<br />
* $x5: Rose<br />
* $x6: Red or maroon<br />
* $x7: Orange<br />
* $x8: Yellow or olive<br />
* $x9: Chartreuse<br />
* $xA: Green<br />
* $xB: Spring<br />
* $xC: Cyan<br />
<br />
=== RGBI ===<br />
These NES colors approximate colors in 16-color RGBI palettes, such as the CGA, EGA, or classic Windows palette, though the NES doesn't really have particularly good approximations:<br />
* $0F: 0/Black<br />
* $02: 1/Navy<br />
* $1A: 2/Green<br />
* $1C: 3/Teal<br />
* $06: 4/Maroon<br />
* $14: 5/Purple<br />
* $18: 6/Olive ($17 for the brown in CGA/EGA in RGB)<br />
* $10: 7/Silver<br />
* $00: 8/Gray<br />
* $12: 9/Blue<br />
* $2A: 10/Lime<br />
* $2C: 11/Aqua/Cyan<br />
* $16: 12/Red<br />
* $24: 13/Fuchsia/Magenta<br />
* $28: 14/Yellow<br />
* $30: 15/White<br />
<br />
== See also ==<br />
* [[NTSC video]] - details of the NTSC signal generation and how it produces the palette<br />
* [[PAL video]]<br />
* [[:Category:Palettes|Palettes (gallery)]] - a few different visualizations of PPU palettes.<br />
* [//forums.nesdev.org/viewtopic.php?t=13264 Another palette test] - Simple test ROM to display the palette.<br />
* [[Full palette demo]] - Demo that displays the entire palette with all emphasis settings at once.<br />
* [//www.nesdev.org/rgbppu/ RGB PPU Palette Converter] - RGB PPU palette conversion and visualization tool, [//forums.nesdev.org/viewtopic.php?p=104217 written by WhoaMan].<br />
<br />
== References ==<br />
* [//forums.nesdev.org/viewtopic.php?p=98955#p98955 Re: Various questions about the color palette and emulators] - 2012 collection of 2C03, 2C04, 2C05 palettes.</div>Rainwarriorhttps://www.nesdev.org/w/index.php?title=NES_2.0&diff=21000NES 2.02023-04-07T18:21:58Z<p>Rainwarrior: /* Hard-Wired Mirroring */ revising explanation, try also to give brief summary of the cases rather than just links to mapper numbers</p>
<hr />
<div>'''NES 2.0''' extends the [[iNES]] single file cart format to better describe NES/Famicom-compatible cartridge hardware. Some of its purpose include:<br />
* Removing the need to use ROM checksums, or other information outside the header, to disambiguate emulation behavior not encoded by iNES.<br />
* Making room for new mapper allocation.<br />
* Allowing for larger ROM sizes.<br />
* Supporting other than standard NES/Famicom console types such as the Nintendo Vs. System and enhanced Famiclones.<br />
* Providing additional information such as the region-specific CPU/PPU type and default expansion port devices.<br />
* Replaces the deprecated [[UNIF]] format.<br />
<br />
The format is [[#Backwards Compatibility to iNES|backwards-compatible]] to iNES, so that ROM images with a NES 2.0 header run in non-NES-2.0-compliant emulators as long as they do not require NES-2.0-exclusive features.<br />
<br />
=Identification=<br />
A file is a NES 2.0 ROM image file if it begins with "NES<EOF>" (same as iNES) and, additionally, the byte at offset 7 has bit 2 clear and bit 3 set:<br />
bool iNESFormat=false;<br />
if (header[0]=='N' && header[1]=='E' && header[2]=='S' && header[3]==0x1A)<br />
iNESFormat=true;<br />
<br />
bool NES20Format=false;<br />
if (iNESFormat==true && (header[7]&0x0C)==0x08)<br />
NES20Format=true;<br />
=File Structure=<br />
A NES 2.0 file contains a sixteen-byte header, followed by Trainer, PRG-ROM, CHR-ROM and Miscellaneous ROM data.<br />
<br />
==Header==<br />
Offset Meaning<br />
--------------<br />
0-3 Identification String. Must be "NES<EOF>".<br />
<br />
4 [[#PRG-ROM Area|PRG-ROM]] size LSB<br />
5 [[#CHR-ROM Area|CHR-ROM]] size LSB<br />
<br />
6 Flags 6<br />
D~7654 3210<br />
---------<br />
NNNN FTBM<br />
|||| |||+-- [[#Hard-Wired Mirroring|Hard-wired nametable mirroring type]]<br />
|||| ||| 0: Horizontal (vertical arrangement) or mapper-controlled<br />
|||| ||| 1: Vertical (horizontal arrangement)<br />
|||| ||+--- "Battery" and other non-volatile memory<br />
|||| || 0: Not present<br />
|||| || 1: Present<br />
|||| |+--- 512-byte [[#Trainer Area|Trainer]]<br />
|||| | 0: Not present<br />
|||| | 1: Present between Header and PRG-ROM data<br />
|||| +---- [[#Hard-Wired Mirroring|Hard-wired four-screen mode]]<br />
|||| 0: No<br />
|||| 1: Yes<br />
++++------ Mapper Number D0..D3<br />
<br />
7 Flags 7<br />
D~7654 3210<br />
---------<br />
NNNN 10TT<br />
|||| ||++- Console type<br />
|||| || 0: Nintendo Entertainment System/Family Computer<br />
|||| || 1: Nintendo [[Vs. System]]<br />
|||| || 2: Nintendo [[PC10 ROM-Images|Playchoice 10]]<br />
|||| || 3: [[#Extended Console Type|Extended Console Type]]<br />
|||| ++--- NES 2.0 identifier<br />
++++------ Mapper Number D4..D7<br />
<br />
8 [[Mapper]] MSB/[[Submapper]]<br />
D~7654 3210<br />
---------<br />
SSSS NNNN<br />
|||| ++++- Mapper number D8..D11<br />
++++------ Submapper number<br />
<br />
9 [[#PRG-ROM Area|PRG-ROM]]/[[#CHR-ROM Area|CHR-ROM]] size MSB<br />
D~7654 3210<br />
---------<br />
CCCC PPPP<br />
|||| ++++- PRG-ROM size MSB<br />
++++------ CHR-ROM size MSB<br />
<br />
10 [[#PRG-(NV)RAM/EEPROM|PRG-RAM/EEPROM]] size<br />
D~7654 3210<br />
---------<br />
pppp PPPP<br />
|||| ++++- PRG-RAM (volatile) shift count<br />
++++------ PRG-NVRAM/EEPROM (non-volatile) shift count<br />
If the shift count is zero, there is no PRG-(NV)RAM.<br />
If the shift count is non-zero, the actual size is<br />
"64 << shift count" bytes, i.e. 8192 bytes for a shift count of 7.<br />
<br />
11 [[#CHR-(NV)RAM|CHR-RAM]] size<br />
D~7654 3210<br />
---------<br />
cccc CCCC<br />
|||| ++++- CHR-RAM size (volatile) shift count<br />
++++------ [[:Category:Mappers with battery-backed CHR-RAM|CHR-NVRAM]] size (non-volatile) shift count<br />
If the shift count is zero, there is no CHR-(NV)RAM.<br />
If the shift count is non-zero, the actual size is<br />
"64 << shift count" bytes, i.e. 8192 bytes for a shift count of 7.<br />
<br />
12 [[#CPU/PPU Timing|CPU/PPU Timing]]<br />
D~7654 3210<br />
---------<br />
.... ..VV<br />
++- CPU/PPU timing mode<br />
0: RP2C02 ("NTSC NES")<br />
1: RP2C07 ("Licensed PAL NES")<br />
2: Multiple-region<br />
3: UA6538 ("Dendy")<br />
<br />
13 When Byte 7 AND 3 =1: [[#Vs. System Type|Vs. System Type]]<br />
D~7654 3210<br />
---------<br />
MMMM PPPP<br />
|||| ++++- Vs. PPU Type<br />
++++------ Vs. Hardware Type<br />
<br />
When Byte 7 AND 3 =3: [[#Extended Console Type|Extended Console Type]]<br />
D~7654 3210<br />
---------<br />
.... CCCC<br />
++++- Extended Console Type<br />
<br />
14 [[#Miscellaneous ROM Area|Miscellaneous ROMs]]<br />
D~7654 3210<br />
---------<br />
.... ..RR<br />
++- Number of miscellaneous ROMs present<br />
<br />
15 [[#Default Expansion Device|Default Expansion Device]]<br />
D~7654 3210<br />
---------<br />
..DD DDDD<br />
++-++++- Default Expansion Device<br />
<br />
==Trainer Area==<br />
The Trainer Area follows the 16-byte Header and precedes the PRG-ROM area if bit 2 of Header byte 6 is set. It is always 512 bytes in size if present,<br />
and contains data to be loaded into CPU memory at $7000. It is only used by some games that were modified to run on different hardware from the original cartridges,<br />
such as early RAM cartridges and emulators, and which put some additional compatibility code into those address ranges.<br />
==PRG-ROM Area==<br />
The PRG-ROM Area follows the 16-byte Header and the Trainer Area and precedes the CHR-ROM Area. Header byte 4 (LSB) and bits 0-3 of Header byte 9 (MSB) together specify its size.<br />
If the MSB nibble is $0-E, LSB and MSB together simply specify the PRG-ROM size in 16 KiB units:<br />
++++----------- Header byte 9 D0..D3<br />
|||| ++++-++++- Header byte 4<br />
D~BA98 7654 3210<br />
--------------<br />
BBBB BBBB BBBB<br />
++++-++++-++++- PRG-ROM size in 16 KiB units,<br />
values $000-$EFF for 0..62,898,176 bytes<br />
If the MSB nibble is $F, an exponent-multiplier notation is used:<br />
++++----------- Header byte 9 D0..D3<br />
|||| ++++-++++- Header byte 4<br />
D~BA98 7654 3210<br />
--------------<br />
1111 EEEE EEMM<br />
|||| ||++- Multiplier, actual value is MM*2+1 (1,3,5,7)<br />
++++-++--- Exponent (2^E), 0-63<br />
<br />
The actual PRG-ROM size is 2^E *(MM*2+1) bytes.<br />
The exponent-multiplier form may only be used if the PRG-ROM size cannot be specified correctly using the simpler notation. If the PRG-ROM data has an odd size that cannot<br />
be represented in either notation, the data must be padded to a size that can be represented.<br />
<br />
In Vs. Dual System ROM images, the first half block of the specified PRG-ROM size belongs to the first unit, and the second half block of PRG-ROM belongs to the the second unit.<br />
24 KiB (half-)blocks are mapped to $A000-$FFFF both in Vs. Unisystem and Vs. Dual System.<br />
An exception is granted for two oddly-sized Vs. System ROM images with a total of 40 KiB PRG-ROM, which are defined to represent 32 KiB +8 KiB instead:<br />
* ''Vs. Gumshoe'', [[#Vs. System Type|Vs. Hardware type]] #0:<br />
** First 32 KiB represent the entire CPU $8000-$FFFF area, including the CPU $8000-$9FFF area with $4016 D2=0;<br />
** Second 8 KiB represent the CPU $8000-$9FFF area with $4016 D2=1.<br />
* ''Vs. Raid on Bungeling Bay'', [[#Vs. System Type|Vs. Hardware type]] #6:<br />
** First 32 KiB represent the first unit's PRG-ROM at CPU $8000-$FFFF;<br />
** Second 8 KiB represent the second unit's PRG-ROM at CPU $E000-$FFFF.<br />
** The second unit only executes a dummy program that does nothing except set a flag in the shared WRAM at $6000-$67FF.<br />
<br />
==CHR-ROM Area==<br />
The CHR-ROM Area, if present, follows the Trainer and PRG-ROM Areas and precedes the Miscellaneous ROM Area. Header byte 5 (LSB) and bits 4-7 of Header byte 9 (MSB)<br />
specify its size. If the MSB nibble is $0-E, LSB and MSB together simply specify the CHR-ROM size in 8 KiB units:<br />
++++----------- Header byte 9 D4..D7<br />
|||| ++++-++++- Header byte 5<br />
D~BA98 7654 3210<br />
--------------<br />
BBBB BBBB BBBB<br />
++++-++++-++++- CHR-ROM size in 8 KiB units,<br />
values $000-$EFF for 0..31,449,088 bytes<br />
If the MSB nibble is $F, an exponent-multiplier notation is used:<br />
++++----------- Header byte 9 D4..D7<br />
|||| ++++-++++- Header byte 5<br />
D~BA98 7654 3210<br />
--------------<br />
1111 EEEE EEMM<br />
|||| ||++- Multiplier, actual value is MM*2+1 (1,3,5,7)<br />
++++-++--- Exponent (2^E), 0-63<br />
<br />
The actual CHR-ROM size therefore becomes 2^E * (MM*2+1).<br />
The exponent-multiplier form may only be used if the CHR-ROM size cannot be specified correctly using the simpler notation. If the CHR-ROM data has an odd size that cannot<br />
be represented by either notation, the data must be padded to a size that can be represented.<br />
<br />
For Vs. Dual System ROM images, if the CHR-ROM size is 32 KiB, the first 16 KiB belong to the first unit, and the second 16 KiB of CHR-ROM belong to the second unit.<br />
If the CHR-ROM size is 16 KiB, the both units use the same bank-switched 16 KiB CHR-ROM data.<br />
<br />
==Miscellaneous ROM Area==<br />
The Miscellaneous ROM Area, if present, follows the CHR-ROM area and occupies the remainder of the file. Its size is not explicitly denoted in the header, and can be deduced<br />
by subtracting the 16-byte Header, Trainer, PRG-ROM and CHR-ROM Area sizes from the total file size. The meaning of this data depends on the console type and mapper type; Header<br />
byte 14 is used to denote the presence of the Miscellaneous ROM Area and the number of ROM chips in case any disambiguation is needed. Currently, miscellaneous ROMs are defined<br />
for the following situations:<br />
* on console type [[PC10 ROM-Images|Playchoice 10]], an 8 KiB INST ROM, 16 bytes of PROM Data, 16 bytes of PROM Counter Out data, for a total of "3" miscellaneous ROMs;<br />
* on console type [[VT369]], 4 KiB of ROM that is embedded into the NES-on-a-chip itself;<br />
* on [[INES Mapper 086]] submapper 1, a single miscellaneous ROM containing speech data;<br />
* on [[NES 2.0 Mapper 355]], the embedded ROM of the PIC16C54 microcontroller that the games use for protection purposes.<br />
* on [[NES 2.0 Mapper 561]] and [[NES 2.0 Mapper 562]] to deliver trainers that do not match the iNES trainer conventions in size (512 byte) or location ($7000).<br />
<br />
=Notes=<br />
==Backwards Compatibility to iNES==<br />
* Bytes 0-7 have the same meaning as in [[iNES]], so that NES-2.0-headered games will still run in emulators that do not support NES 2.0 unless the header specifies features that those older emulators did not support anyway.<br />
* The NES 2.0 identifier (Byte 7 D2..D3) has been chosen so that it does not collide with any valid iNES header nor with any known ROM image that has garbage in bytes 7-15 such as "DiskDude!".<br />
==Hard-Wired Mirroring==<br />
Byte 6 (Flags 6) contains two bits to describe the [[Mirroring#Nametable Mirroring|nametable mirroring]] capabilities of the cartridge.<br />
<br />
D~7654 3210<br />
---------<br />
.... F..M<br />
| +-- Horizontal/vertical hard-wired mirroring.<br />
+----- 4-screen nametables.<br />
<br />
* Bit 0 is normally relevant only if the mapper does not allow the mirroring type to be switched. It should be set to zero otherwise.<br />
* The standard meaning of bit 3 is that 4 KiB of RAM are present at PPU $2000-2FFF, exclusive to that region, and cannot be banked, replaced, or rearranged. This applies to:<br />
** [[INES Mapper 004|Mapper 4]] (MMC3)<br />
** [[INES Mapper 206|Mapper 206]] (DxROM, etc. MMC3-like subset)<br />
** [[INES Mapper 077|Mapper 77]] (Napoleon Senki)<br />
** [[NES 2.0 Mapper 262|Mapper 262]] (Street Heroes)<br />
** [[INES Mapper 002|Mapper 2]] (UxROM)<br />
* Three mappers use these bits in a nonstandard way:<br />
** [[INES Mapper 030#Nametable Configuration|Mapper 30]] (UNROM 512) - This board can be wired for H/V fixed, 1-screen, or 4-screen.<br />
** [[INES Mapper 218|Mapper 218]] (Magic Floor) - This experimental board had 4 configurations that allowed the internal 2k CIRAM to be used for both CHR and nametables at once.<br />
** [[INES Mapper 078|Mapper 78]] (Holy Diver, Cosmo Carrier) - This board had two different mapper-controlled nametable configurations. Bit 3 was used to select between them in the past, but NES 2.0 has assigned [[NES 2.0 submappers#078: Cosmo Carrier / Holy Diver|submappers for this]] instead.<br />
* Some emulators allow bit 3 in its standard meaning to be used with a wide variety of mappers, replacing the fixed or mapper-controlled nametable mirroring with exclusive RAM. Support for this is inconsistent across emulators.<br />
<br />
==PRG-(NV)RAM/EEPROM==<br />
The PRG-(NV)RAM/EEPROM fields specify the sizes of...<br />
* Memory that is mapped into CPU address space, regardless of whether that memory is internal to a mapper chip or in a separate RAM chip;<br />
* EEPROM even if it is not mapped into CPU address space.<br />
They do not specify the sizes of...<br />
* Mapper-chip-internal memory that is not mapped into CPU address space, even if battery-backed, such as the [[Namco 163]]'s wavetable RAM which some games use to store saved game data. The size of such memory is part of the Mapper definition instead. The Battery bit (Header byte 6 bit 1) denotes whether such memory is battery-backed. The [[MMC5]]'s EXRAM is not included in the PRG-RAM size, as it can be mapped by software to CPU, PPU, or no address space at all;<br />
* self-flashable PRG-ROM;<br />
* external storage such as cassette tape or the ASCII Turbo File.<br />
When the upper nibble (PRG-NVRAM/EEPROM) has a non-zero value, the Battery bit (Header byte 6 bit 1) must always be set for compatibility with [[iNES]]. Conversely, if the Battery bit is set, the upper nibble must have a non-zero value, unless the only battery-backed memory is either mapper-chip-internal memory that is not mapped into CPU address space, such as the [[Namco 163]]'s wavetable RAM, or the PRG-ROM is self-flashable.<br />
<br />
==CHR-(NV)RAM==<br />
* In the presence of a NES 2.0 Header, an emulator must not assume that if a ROM image specifies no CHR-ROM, the game will automatically have 8 KiB of CHR-RAM; all CHR-RAM must instead be explicitly specified in Header byte 11.<br />
* Memory that is permanently mapped into the nametable address space (PPU $2000-$2FFF) is not included in the CHR-RAM size. Setting the hard-wired four-screen mode bit in Header byte 6 bit 3 therefore does not entail a 4 KiB increase of the CHR-RAM size.<br />
* The [[MMC5]]'s EXRAM is not included in the CHR-RAM size, as it can be mapped by software to CPU, PPU, or no address space at all.<br />
<br />
==CPU/PPU Timing==<br />
For non-homebrew NES/Famicom games, this field's value is always a function of the region in which a game was released:<br />
Value Meaning Regions<br />
0 RP2C02 North America, Japan, South Korea, Taiwan<br />
1 RP2C07 Western Europe, Australia<br />
2 Multiple Multiple<br />
3 UA6538 Eastern Europe, Russia, Mainland China, India, Africa<br />
Value 2 ("multiple-region") is used either if a game was released with identical ROM content in both NTSC and PAL countries, such as Nintendo's early games, or if the game detects the console's timing and adjusts itself. Emulators should implement this value by either switching to a user-specified "Default Region" or by keeping the previously-set region.<br />
<br />
[[VTxx|V.R. Technology Famiclones]] only come with RP2C02 or UA6538 timing, so games with such a console type can only bear values 0 or 3.<br />
<br />
==Vs. System Type==<br />
When the console type in Header byte 7 D0..D1 is 1 (Vs. System), the lower nibble of Header byte 13 specifies the Vs. PPU type, and the upper nibble the non-PPU-based protection<br />
type and whether the ROM is for the Vs. Unisystem or the Vs. Dual System.<br />
Vs. PPU types (Header byte 13 D0..D3):<br />
$0: RP2C03B<br />
$1: RP2C03G<br />
$2: RP2C04-0001<br />
$3: RP2C04-0002<br />
$4: RP2C04-0003<br />
$5: RP2C04-0004<br />
$6: RC2C03B<br />
$7: RC2C03C<br />
$8: RC2C05-01 ($2002 AND $?? =$1B)<br />
$9: RC2C05-02 ($2002 AND $3F =$3D)<br />
$A: RC2C05-03 ($2002 AND $1F =$1C)<br />
$B: RC2C05-04 ($2002 AND $1F =$1B)<br />
$C: RC2C05-05 ($2002 AND $1F =unknown)<br />
$D-F: reserved<br />
For copy protection purposes, these PPU types have different [[PPU palettes|palettes]]; the RC2C05 PPUs furthermore swap [[PPU registers]] $2000 and $2001 and return a signature in the lower bits of $2002. If a game uses the DIP switches to select different PPU models, this field represents the correct PPU model when those DIP switches are all set to zero.<br />
Vs. Hardware type (Header byte 13 D4..D7):<br />
$0: Vs. Unisystem (normal)<br />
$1: Vs. Unisystem (RBI Baseball protection)<br />
$2: Vs. Unisystem (TKO Boxing protection)<br />
$3: Vs. Unisystem (Super Xevious protection)<br />
$4: Vs. Unisystem (Vs. Ice Climber Japan protection)<br />
$5: Vs. Dual System (normal)<br />
$6: Vs. Dual System (Raid on Bungeling Bay protection)<br />
Refer to the [[Vs. System]] entry for more information.<br />
==Extended Console Type==<br />
When the console type in Header byte 7 D0..D1 is 3 (Extended), the lower nibble of Header byte 13 specifies the type of console on which the ROM image is supposed to be run.<br />
$0 [Regular NES/Famicom/Dendy]<br />
$1 [Nintendo Vs. System]<br />
$2 [Playchoice 10]<br />
$3 Regular Famiclone, but with CPU that supports Decimal Mode<br />
$4 Regular NES/Famicom with [[EPSM]] module or plug-through cartridge<br />
$5 [[VT01 STN_Palette|V.R. Technology VT01 with red/cyan STN palette]]<br />
$6 [[VTxx|V.R. Technology VT02]]<br />
$7 [[VTxx|V.R. Technology VT03]]<br />
$8 [[VTxx|V.R. Technology VT09]]<br />
$9 V.R. Technology VT32<br />
$A V.R. Technology VT369<br />
$B UMC UM6578<br />
$C [[Famicom Network System]]<br />
$D-$F reserved<br />
Values $0-$2 are not used for the extended console type, as they can be expressed by only using Header byte 7 D0..D1. They are reserved here so that emulators<br />
can fold the information in Header Byte 7 D0..D1 and Header byte 13 into one "console type" variable without recoding the values.<br />
<br />
==Default Expansion Device==<br />
Header byte 15 indicates that the ROM expects a specific set of devices accessible at CPU $4016/$4017. For an emulator that wishes to automatically provide selection of needed peripherals, this gives the required information directly within the header.<br />
<br />
Value $00 is reserved for compatibility with older versions of this specification and indicates no information on the default input device.<br />
<br />
In almost all cases, this byte will specify ''the'' device without which the game cannot be played at all, such as the NES Zapper or Power Pad. If a game supports an ''optional'' expansion port device, and having that device connected does not preclude using the normal controllers with that game, this byte will specify that device, such as the ASCII Turbo File or the Arkanoid Vaus Controller. For games that support multiple combinations of expansion devices, this byte will denote the game's default selection.<br />
<br />
This byte does not denote devices that connect to a cartridge; such devices are part of the respective Mapper's definition.<br />
$00 Unspecified<br />
$01 [[Standard controller|Standard NES/Famicom controllers]]<br />
$02 NES [[Four Score]]/Satellite with two additional standard controllers<br />
$03 Famicom Four Players Adapter with two additional standard controllers using the [[Four player adapters#"Simple" Famicom adapters|"simple"]] protocol<br />
$04 [[Vs. System]] (1P via $4016)<br />
$05 Vs. System (1P via $4017)<br />
$06 Reserved<br />
$07 Vs. [[Zapper]]<br />
$08 [[Zapper]] ($4017)<br />
$09 Two Zappers<br />
$0A Bandai Hyper Shot Lightgun<br />
$0B [[Power Pad]] Side A<br />
$0C [[Power Pad]] Side B<br />
$0D [[Power Pad#Family Trainer Mat|Family Trainer]] Side A<br />
$0E [[Power Pad#Family Trainer Mat|Family Trainer]] Side B<br />
$0F [[Arkanoid controller|Arkanoid Vaus Controller (NES)]]<br />
$10 [[Arkanoid controller|Arkanoid Vaus Controller (Famicom)]]<br />
$11 Two Vaus Controllers plus [[Family BASIC Data Recorder|Famicom Data Recorder]]<br />
$12 [[Konami Hyper Shot]] Controller<br />
$13 [[Coconuts Pachinko]] Controller<br />
$14 [[Exciting Boxing Punching Bag]] (Blowup Doll)<br />
$15 [[Jissen Mahjong controller|Jissen Mahjong Controller]]<br />
$16 [[Partytap|Party Tap]] <br />
$17 [[Oeka Kids tablet|Oeka Kids Tablet]]<br />
$18 Sunsoft Barcode Battler<br />
$19 [[Miracle_Piano|Miracle Piano Keyboard]]<br />
$1A Pokkun Moguraa (Whack-a-Mole Mat and Mallet)<br />
$1B Top Rider (Inflatable Bicycle)<br />
$1C Double-Fisted (Requires or allows use of two controllers by one player)<br />
$1D [[Famicom 3D glasses|Famicom 3D System]]<br />
$1E Doremikko Keyboard<br />
$1F R.O.B. Gyro Set<br />
$20 [[Family BASIC Data Recorder|Famicom Data Recorder]] ("silent" keyboard)<br />
$21 ASCII Turbo File<br />
$22 IGS Storage Battle Box<br />
$23 [[Family BASIC Keyboard]] plus Famicom Data Recorder<br />
$24 Dongda PEC-586 Keyboard<br />
$25 Bit Corp. Bit-79 Keyboard<br />
$26 Subor Keyboard<br />
$27 Subor Keyboard plus [[Mouse#Subor Mouse|mouse]] (3x8-bit protocol)<br />
$28 Subor Keyboard plus mouse (24-bit protocol via $4016)<br />
$29 [[Mouse#SNES Mouse|SNES Mouse]] ($4017.d0)<br />
$2A Multicart<br />
$2B Two [[SNES_controller|SNES controllers]] replacing the two standard NES controllers<br />
$2C RacerMate Bicycle<br />
$2D U-Force<br />
$2E R.O.B. Stack-Up<br />
$2F City Patrolman Lightgun<br />
$30 Sharp C1 Cassette Interface<br />
$31 Standard Controller with swapped Left-Right/Up-Down/B-A<br />
$32 Excalibor Sudoku Pad<br />
$33 ABL Pinball<br />
$34 Golden Nugget Casino extra buttons<br />
$35 Unknown famiclone keyboard used by the "Golden Key" educational cartridge<br />
$36 Subor Keyboard plus mouse (24-bit protocol via $4017)<br />
$37 [[Port test controller]]<br />
Notes:<br />
* The Famicom Four Players Adapter ($03) is denoted only if the additional controllers provide ''independent'' 3P/4P input, not if they just alias the built-in 1P/2P controllers.<br />
* So far, there have been no games that provide independent 3P/4P input solely through the [[Four player adapters#Hori 4 Players Adapter|"Hori"]] protocol, which is why there has been no value assigned for it yet.<br />
* For Vs. System games that do not care which stick is used and therefore could be denoted either with value $04 or $05, use value $04.<br />
* Value $06 originally denoted "Pinball (Japan)" and was thought to represent a unique wiring variant, but was since found to represent a peculiar MAME behavior that MAME has since removed.<br />
* "Two Vaus Controllers plus Famicom Data Recorder" ($11) can be trivially emulated as just connecting a Famicom Vaus controller, or sophisticatedly emulated as "Connect two daisy-chained Vaus controllers on startup, disconnect them and connect Family BASIC keyboard with Data Recorder when the user selects Tape Playback or Tape Record from the emulator's user interface; detach these and re-connect the two Vaus controllers when the user selects Tape Stop".<br />
* "Double-Fisted" ($1C) assumes a Four Score is connected, which allows two players to use two controllers at once (Smash T.V.) if the game supports two players.<br />
* The difference between "Famicom Data Recorder" ($20) and "Family BASIC Keyboard" ($23) is that although $20 emulates the Family BASIC keyboard's response to strobe, no actual emulated keyboard input is registered ("silent" keyboard), allowing desktop emulators to keep allowing the use of the host's keyboard for other purposes (such as D-Pad input), and not necessitating the display of an on-screen keyboard on mobile emulators.<br />
* "Multicart" ($2A) is only used if any game on that multicart actually uses expansion port devices. As these will be mostly Zapper games, emulating an expansion port Zapper together with two standard controllers is the simplest way of implementing this value.<br />
* The [[PowerPak]] official loader considers any .NES with a non-zero byte 15 to be invalid, and will fail to load the ROM. A [https://forums.nesdev.org/viewtopic.php?p=283943#p283943 patched N.MAP loader] is available.<br />
<br />
==Version History==<br />
* 2006-09-18 - Original version of specification by kevtris.<br />
** [https://forums.nesdev.org/viewtopic.php?p=17727#p17727 NES 2.0 "Official" Specification]<br />
* 2019-01-02 - Additions by NewRisingSun.<br />
** [https://forums.nesdev.org/viewtopic.php?f=3&t=17213&start=45#p220624 Additions proposal by NewRisingSun]<br />
** Flags 7: adds [[#Extended Console Type|Extended Console Type]] value<br />
** Flags 12: adds [[#CPU/PPU Timing|Dendy]] value<br />
** Flags 13: adds [[#Extended Console Type|Extended Console Type]] field<br />
** Flags 14: adds [[#Miscellaneous ROM Area|miscellaneous ROM]] specifier<br />
** Flags 15: adds [[#Default Expansion Device|Default Expansion Device]]<br />
<br />
==See Also==<br />
* [[NES 2.0 submappers]] - disambiguation for mappers that were under-specified in iNES 1<br />
* [[NES 2.0 header for ca65]] - macro header generator for ca65 assembly<br />
* [[NES 2.0 header for cc65]] - macro header generator for cc65 C code<br />
<br />
==References==<br />
* [https://forums.nesdev.org/viewtopic.php?p=17727#p17727 Original proposal by kevtris]<br />
* [https://forums.nesdev.org/viewtopic.php?f=3&t=17213&start=45#p220624 Additions proposal by NewRisingSun]<br />
* [https://forums.nesdev.org/viewtopic.php?t=19940 NES 2.0 XML Database, with link to Python script for applying it to a ROM files collection]<br />
<references/><br />
[[Category:File formats]]</div>Rainwarriorhttps://www.nesdev.org/w/index.php?title=NES_2.0&diff=20999NES 2.02023-04-07T17:52:56Z<p>Rainwarrior: /* Header */ give alternate mirroring term, as with iNES</p>
<hr />
<div>'''NES 2.0''' extends the [[iNES]] single file cart format to better describe NES/Famicom-compatible cartridge hardware. Some of its purpose include:<br />
* Removing the need to use ROM checksums, or other information outside the header, to disambiguate emulation behavior not encoded by iNES.<br />
* Making room for new mapper allocation.<br />
* Allowing for larger ROM sizes.<br />
* Supporting other than standard NES/Famicom console types such as the Nintendo Vs. System and enhanced Famiclones.<br />
* Providing additional information such as the region-specific CPU/PPU type and default expansion port devices.<br />
* Replaces the deprecated [[UNIF]] format.<br />
<br />
The format is [[#Backwards Compatibility to iNES|backwards-compatible]] to iNES, so that ROM images with a NES 2.0 header run in non-NES-2.0-compliant emulators as long as they do not require NES-2.0-exclusive features.<br />
<br />
=Identification=<br />
A file is a NES 2.0 ROM image file if it begins with "NES<EOF>" (same as iNES) and, additionally, the byte at offset 7 has bit 2 clear and bit 3 set:<br />
bool iNESFormat=false;<br />
if (header[0]=='N' && header[1]=='E' && header[2]=='S' && header[3]==0x1A)<br />
iNESFormat=true;<br />
<br />
bool NES20Format=false;<br />
if (iNESFormat==true && (header[7]&0x0C)==0x08)<br />
NES20Format=true;<br />
=File Structure=<br />
A NES 2.0 file contains a sixteen-byte header, followed by Trainer, PRG-ROM, CHR-ROM and Miscellaneous ROM data.<br />
<br />
==Header==<br />
Offset Meaning<br />
--------------<br />
0-3 Identification String. Must be "NES<EOF>".<br />
<br />
4 [[#PRG-ROM Area|PRG-ROM]] size LSB<br />
5 [[#CHR-ROM Area|CHR-ROM]] size LSB<br />
<br />
6 Flags 6<br />
D~7654 3210<br />
---------<br />
NNNN FTBM<br />
|||| |||+-- [[#Hard-Wired Mirroring|Hard-wired nametable mirroring type]]<br />
|||| ||| 0: Horizontal (vertical arrangement) or mapper-controlled<br />
|||| ||| 1: Vertical (horizontal arrangement)<br />
|||| ||+--- "Battery" and other non-volatile memory<br />
|||| || 0: Not present<br />
|||| || 1: Present<br />
|||| |+--- 512-byte [[#Trainer Area|Trainer]]<br />
|||| | 0: Not present<br />
|||| | 1: Present between Header and PRG-ROM data<br />
|||| +---- [[#Hard-Wired Mirroring|Hard-wired four-screen mode]]<br />
|||| 0: No<br />
|||| 1: Yes<br />
++++------ Mapper Number D0..D3<br />
<br />
7 Flags 7<br />
D~7654 3210<br />
---------<br />
NNNN 10TT<br />
|||| ||++- Console type<br />
|||| || 0: Nintendo Entertainment System/Family Computer<br />
|||| || 1: Nintendo [[Vs. System]]<br />
|||| || 2: Nintendo [[PC10 ROM-Images|Playchoice 10]]<br />
|||| || 3: [[#Extended Console Type|Extended Console Type]]<br />
|||| ++--- NES 2.0 identifier<br />
++++------ Mapper Number D4..D7<br />
<br />
8 [[Mapper]] MSB/[[Submapper]]<br />
D~7654 3210<br />
---------<br />
SSSS NNNN<br />
|||| ++++- Mapper number D8..D11<br />
++++------ Submapper number<br />
<br />
9 [[#PRG-ROM Area|PRG-ROM]]/[[#CHR-ROM Area|CHR-ROM]] size MSB<br />
D~7654 3210<br />
---------<br />
CCCC PPPP<br />
|||| ++++- PRG-ROM size MSB<br />
++++------ CHR-ROM size MSB<br />
<br />
10 [[#PRG-(NV)RAM/EEPROM|PRG-RAM/EEPROM]] size<br />
D~7654 3210<br />
---------<br />
pppp PPPP<br />
|||| ++++- PRG-RAM (volatile) shift count<br />
++++------ PRG-NVRAM/EEPROM (non-volatile) shift count<br />
If the shift count is zero, there is no PRG-(NV)RAM.<br />
If the shift count is non-zero, the actual size is<br />
"64 << shift count" bytes, i.e. 8192 bytes for a shift count of 7.<br />
<br />
11 [[#CHR-(NV)RAM|CHR-RAM]] size<br />
D~7654 3210<br />
---------<br />
cccc CCCC<br />
|||| ++++- CHR-RAM size (volatile) shift count<br />
++++------ [[:Category:Mappers with battery-backed CHR-RAM|CHR-NVRAM]] size (non-volatile) shift count<br />
If the shift count is zero, there is no CHR-(NV)RAM.<br />
If the shift count is non-zero, the actual size is<br />
"64 << shift count" bytes, i.e. 8192 bytes for a shift count of 7.<br />
<br />
12 [[#CPU/PPU Timing|CPU/PPU Timing]]<br />
D~7654 3210<br />
---------<br />
.... ..VV<br />
++- CPU/PPU timing mode<br />
0: RP2C02 ("NTSC NES")<br />
1: RP2C07 ("Licensed PAL NES")<br />
2: Multiple-region<br />
3: UA6538 ("Dendy")<br />
<br />
13 When Byte 7 AND 3 =1: [[#Vs. System Type|Vs. System Type]]<br />
D~7654 3210<br />
---------<br />
MMMM PPPP<br />
|||| ++++- Vs. PPU Type<br />
++++------ Vs. Hardware Type<br />
<br />
When Byte 7 AND 3 =3: [[#Extended Console Type|Extended Console Type]]<br />
D~7654 3210<br />
---------<br />
.... CCCC<br />
++++- Extended Console Type<br />
<br />
14 [[#Miscellaneous ROM Area|Miscellaneous ROMs]]<br />
D~7654 3210<br />
---------<br />
.... ..RR<br />
++- Number of miscellaneous ROMs present<br />
<br />
15 [[#Default Expansion Device|Default Expansion Device]]<br />
D~7654 3210<br />
---------<br />
..DD DDDD<br />
++-++++- Default Expansion Device<br />
<br />
==Trainer Area==<br />
The Trainer Area follows the 16-byte Header and precedes the PRG-ROM area if bit 2 of Header byte 6 is set. It is always 512 bytes in size if present,<br />
and contains data to be loaded into CPU memory at $7000. It is only used by some games that were modified to run on different hardware from the original cartridges,<br />
such as early RAM cartridges and emulators, and which put some additional compatibility code into those address ranges.<br />
==PRG-ROM Area==<br />
The PRG-ROM Area follows the 16-byte Header and the Trainer Area and precedes the CHR-ROM Area. Header byte 4 (LSB) and bits 0-3 of Header byte 9 (MSB) together specify its size.<br />
If the MSB nibble is $0-E, LSB and MSB together simply specify the PRG-ROM size in 16 KiB units:<br />
++++----------- Header byte 9 D0..D3<br />
|||| ++++-++++- Header byte 4<br />
D~BA98 7654 3210<br />
--------------<br />
BBBB BBBB BBBB<br />
++++-++++-++++- PRG-ROM size in 16 KiB units,<br />
values $000-$EFF for 0..62,898,176 bytes<br />
If the MSB nibble is $F, an exponent-multiplier notation is used:<br />
++++----------- Header byte 9 D0..D3<br />
|||| ++++-++++- Header byte 4<br />
D~BA98 7654 3210<br />
--------------<br />
1111 EEEE EEMM<br />
|||| ||++- Multiplier, actual value is MM*2+1 (1,3,5,7)<br />
++++-++--- Exponent (2^E), 0-63<br />
<br />
The actual PRG-ROM size is 2^E *(MM*2+1) bytes.<br />
The exponent-multiplier form may only be used if the PRG-ROM size cannot be specified correctly using the simpler notation. If the PRG-ROM data has an odd size that cannot<br />
be represented in either notation, the data must be padded to a size that can be represented.<br />
<br />
In Vs. Dual System ROM images, the first half block of the specified PRG-ROM size belongs to the first unit, and the second half block of PRG-ROM belongs to the the second unit.<br />
24 KiB (half-)blocks are mapped to $A000-$FFFF both in Vs. Unisystem and Vs. Dual System.<br />
An exception is granted for two oddly-sized Vs. System ROM images with a total of 40 KiB PRG-ROM, which are defined to represent 32 KiB +8 KiB instead:<br />
* ''Vs. Gumshoe'', [[#Vs. System Type|Vs. Hardware type]] #0:<br />
** First 32 KiB represent the entire CPU $8000-$FFFF area, including the CPU $8000-$9FFF area with $4016 D2=0;<br />
** Second 8 KiB represent the CPU $8000-$9FFF area with $4016 D2=1.<br />
* ''Vs. Raid on Bungeling Bay'', [[#Vs. System Type|Vs. Hardware type]] #6:<br />
** First 32 KiB represent the first unit's PRG-ROM at CPU $8000-$FFFF;<br />
** Second 8 KiB represent the second unit's PRG-ROM at CPU $E000-$FFFF.<br />
** The second unit only executes a dummy program that does nothing except set a flag in the shared WRAM at $6000-$67FF.<br />
<br />
==CHR-ROM Area==<br />
The CHR-ROM Area, if present, follows the Trainer and PRG-ROM Areas and precedes the Miscellaneous ROM Area. Header byte 5 (LSB) and bits 4-7 of Header byte 9 (MSB)<br />
specify its size. If the MSB nibble is $0-E, LSB and MSB together simply specify the CHR-ROM size in 8 KiB units:<br />
++++----------- Header byte 9 D4..D7<br />
|||| ++++-++++- Header byte 5<br />
D~BA98 7654 3210<br />
--------------<br />
BBBB BBBB BBBB<br />
++++-++++-++++- CHR-ROM size in 8 KiB units,<br />
values $000-$EFF for 0..31,449,088 bytes<br />
If the MSB nibble is $F, an exponent-multiplier notation is used:<br />
++++----------- Header byte 9 D4..D7<br />
|||| ++++-++++- Header byte 5<br />
D~BA98 7654 3210<br />
--------------<br />
1111 EEEE EEMM<br />
|||| ||++- Multiplier, actual value is MM*2+1 (1,3,5,7)<br />
++++-++--- Exponent (2^E), 0-63<br />
<br />
The actual CHR-ROM size therefore becomes 2^E * (MM*2+1).<br />
The exponent-multiplier form may only be used if the CHR-ROM size cannot be specified correctly using the simpler notation. If the CHR-ROM data has an odd size that cannot<br />
be represented by either notation, the data must be padded to a size that can be represented.<br />
<br />
For Vs. Dual System ROM images, if the CHR-ROM size is 32 KiB, the first 16 KiB belong to the first unit, and the second 16 KiB of CHR-ROM belong to the second unit.<br />
If the CHR-ROM size is 16 KiB, the both units use the same bank-switched 16 KiB CHR-ROM data.<br />
<br />
==Miscellaneous ROM Area==<br />
The Miscellaneous ROM Area, if present, follows the CHR-ROM area and occupies the remainder of the file. Its size is not explicitly denoted in the header, and can be deduced<br />
by subtracting the 16-byte Header, Trainer, PRG-ROM and CHR-ROM Area sizes from the total file size. The meaning of this data depends on the console type and mapper type; Header<br />
byte 14 is used to denote the presence of the Miscellaneous ROM Area and the number of ROM chips in case any disambiguation is needed. Currently, miscellaneous ROMs are defined<br />
for the following situations:<br />
* on console type [[PC10 ROM-Images|Playchoice 10]], an 8 KiB INST ROM, 16 bytes of PROM Data, 16 bytes of PROM Counter Out data, for a total of "3" miscellaneous ROMs;<br />
* on console type [[VT369]], 4 KiB of ROM that is embedded into the NES-on-a-chip itself;<br />
* on [[INES Mapper 086]] submapper 1, a single miscellaneous ROM containing speech data;<br />
* on [[NES 2.0 Mapper 355]], the embedded ROM of the PIC16C54 microcontroller that the games use for protection purposes.<br />
* on [[NES 2.0 Mapper 561]] and [[NES 2.0 Mapper 562]] to deliver trainers that do not match the iNES trainer conventions in size (512 byte) or location ($7000).<br />
<br />
=Notes=<br />
==Backwards Compatibility to iNES==<br />
* Bytes 0-7 have the same meaning as in [[iNES]], so that NES-2.0-headered games will still run in emulators that do not support NES 2.0 unless the header specifies features that those older emulators did not support anyway.<br />
* The NES 2.0 identifier (Byte 7 D2..D3) has been chosen so that it does not collide with any valid iNES header nor with any known ROM image that has garbage in bytes 7-15 such as "DiskDude!".<br />
==Hard-Wired Mirroring==<br />
* Header Byte 6 bit 0 is relevant only if the mapper does not allow the mirroring type to be switched. Otherwise, it must be ignored and should be set to zero.<br />
* Bit 3 is set only if 4 KiB of RAM are present at PPU $2000-2FFF, exclusive to that region, and cannot be banked, replaced, or rearranged. Currently, only the four-screen variants of mappers [[INES Mapper 004|4]] and [[INES Mapper 206|206]] as well as [[INES Mapper 077|77]], [[NES 2.0 Mapper 262|262]] and the Nintendo [[Vs. System]] meet that definition. However, as the original [[iNES]] format (incorrectly) assumed that the availability of four-screen mirroring is independent of the mapper, perfect iNES compatibility would require that bit 3=1 overrides the hard-wired/software-controlled mirroring of ''any'' mapper unless it can remap CHR-RAM/ROM into the nametable address space.<br />
* Mappers [[INES Mapper 030|30]] and [[INES Mapper 218|218]] are exceptions and interpret these two bits in idiosyncratic ways<br />
* [[INES Mapper 078]] historically used bit 3 to select between two incompatible sets of mirroring logic; NES 2.0 instead uses submappers to distinguish them.<br />
<br />
==PRG-(NV)RAM/EEPROM==<br />
The PRG-(NV)RAM/EEPROM fields specify the sizes of...<br />
* Memory that is mapped into CPU address space, regardless of whether that memory is internal to a mapper chip or in a separate RAM chip;<br />
* EEPROM even if it is not mapped into CPU address space.<br />
They do not specify the sizes of...<br />
* Mapper-chip-internal memory that is not mapped into CPU address space, even if battery-backed, such as the [[Namco 163]]'s wavetable RAM which some games use to store saved game data. The size of such memory is part of the Mapper definition instead. The Battery bit (Header byte 6 bit 1) denotes whether such memory is battery-backed. The [[MMC5]]'s EXRAM is not included in the PRG-RAM size, as it can be mapped by software to CPU, PPU, or no address space at all;<br />
* self-flashable PRG-ROM;<br />
* external storage such as cassette tape or the ASCII Turbo File.<br />
When the upper nibble (PRG-NVRAM/EEPROM) has a non-zero value, the Battery bit (Header byte 6 bit 1) must always be set for compatibility with [[iNES]]. Conversely, if the Battery bit is set, the upper nibble must have a non-zero value, unless the only battery-backed memory is either mapper-chip-internal memory that is not mapped into CPU address space, such as the [[Namco 163]]'s wavetable RAM, or the PRG-ROM is self-flashable.<br />
<br />
==CHR-(NV)RAM==<br />
* In the presence of a NES 2.0 Header, an emulator must not assume that if a ROM image specifies no CHR-ROM, the game will automatically have 8 KiB of CHR-RAM; all CHR-RAM must instead be explicitly specified in Header byte 11.<br />
* Memory that is permanently mapped into the nametable address space (PPU $2000-$2FFF) is not included in the CHR-RAM size. Setting the hard-wired four-screen mode bit in Header byte 6 bit 3 therefore does not entail a 4 KiB increase of the CHR-RAM size.<br />
* The [[MMC5]]'s EXRAM is not included in the CHR-RAM size, as it can be mapped by software to CPU, PPU, or no address space at all.<br />
<br />
==CPU/PPU Timing==<br />
For non-homebrew NES/Famicom games, this field's value is always a function of the region in which a game was released:<br />
Value Meaning Regions<br />
0 RP2C02 North America, Japan, South Korea, Taiwan<br />
1 RP2C07 Western Europe, Australia<br />
2 Multiple Multiple<br />
3 UA6538 Eastern Europe, Russia, Mainland China, India, Africa<br />
Value 2 ("multiple-region") is used either if a game was released with identical ROM content in both NTSC and PAL countries, such as Nintendo's early games, or if the game detects the console's timing and adjusts itself. Emulators should implement this value by either switching to a user-specified "Default Region" or by keeping the previously-set region.<br />
<br />
[[VTxx|V.R. Technology Famiclones]] only come with RP2C02 or UA6538 timing, so games with such a console type can only bear values 0 or 3.<br />
<br />
==Vs. System Type==<br />
When the console type in Header byte 7 D0..D1 is 1 (Vs. System), the lower nibble of Header byte 13 specifies the Vs. PPU type, and the upper nibble the non-PPU-based protection<br />
type and whether the ROM is for the Vs. Unisystem or the Vs. Dual System.<br />
Vs. PPU types (Header byte 13 D0..D3):<br />
$0: RP2C03B<br />
$1: RP2C03G<br />
$2: RP2C04-0001<br />
$3: RP2C04-0002<br />
$4: RP2C04-0003<br />
$5: RP2C04-0004<br />
$6: RC2C03B<br />
$7: RC2C03C<br />
$8: RC2C05-01 ($2002 AND $?? =$1B)<br />
$9: RC2C05-02 ($2002 AND $3F =$3D)<br />
$A: RC2C05-03 ($2002 AND $1F =$1C)<br />
$B: RC2C05-04 ($2002 AND $1F =$1B)<br />
$C: RC2C05-05 ($2002 AND $1F =unknown)<br />
$D-F: reserved<br />
For copy protection purposes, these PPU types have different [[PPU palettes|palettes]]; the RC2C05 PPUs furthermore swap [[PPU registers]] $2000 and $2001 and return a signature in the lower bits of $2002. If a game uses the DIP switches to select different PPU models, this field represents the correct PPU model when those DIP switches are all set to zero.<br />
Vs. Hardware type (Header byte 13 D4..D7):<br />
$0: Vs. Unisystem (normal)<br />
$1: Vs. Unisystem (RBI Baseball protection)<br />
$2: Vs. Unisystem (TKO Boxing protection)<br />
$3: Vs. Unisystem (Super Xevious protection)<br />
$4: Vs. Unisystem (Vs. Ice Climber Japan protection)<br />
$5: Vs. Dual System (normal)<br />
$6: Vs. Dual System (Raid on Bungeling Bay protection)<br />
Refer to the [[Vs. System]] entry for more information.<br />
==Extended Console Type==<br />
When the console type in Header byte 7 D0..D1 is 3 (Extended), the lower nibble of Header byte 13 specifies the type of console on which the ROM image is supposed to be run.<br />
$0 [Regular NES/Famicom/Dendy]<br />
$1 [Nintendo Vs. System]<br />
$2 [Playchoice 10]<br />
$3 Regular Famiclone, but with CPU that supports Decimal Mode<br />
$4 Regular NES/Famicom with [[EPSM]] module or plug-through cartridge<br />
$5 [[VT01 STN_Palette|V.R. Technology VT01 with red/cyan STN palette]]<br />
$6 [[VTxx|V.R. Technology VT02]]<br />
$7 [[VTxx|V.R. Technology VT03]]<br />
$8 [[VTxx|V.R. Technology VT09]]<br />
$9 V.R. Technology VT32<br />
$A V.R. Technology VT369<br />
$B UMC UM6578<br />
$C [[Famicom Network System]]<br />
$D-$F reserved<br />
Values $0-$2 are not used for the extended console type, as they can be expressed by only using Header byte 7 D0..D1. They are reserved here so that emulators<br />
can fold the information in Header Byte 7 D0..D1 and Header byte 13 into one "console type" variable without recoding the values.<br />
<br />
==Default Expansion Device==<br />
Header byte 15 indicates that the ROM expects a specific set of devices accessible at CPU $4016/$4017. For an emulator that wishes to automatically provide selection of needed peripherals, this gives the required information directly within the header.<br />
<br />
Value $00 is reserved for compatibility with older versions of this specification and indicates no information on the default input device.<br />
<br />
In almost all cases, this byte will specify ''the'' device without which the game cannot be played at all, such as the NES Zapper or Power Pad. If a game supports an ''optional'' expansion port device, and having that device connected does not preclude using the normal controllers with that game, this byte will specify that device, such as the ASCII Turbo File or the Arkanoid Vaus Controller. For games that support multiple combinations of expansion devices, this byte will denote the game's default selection.<br />
<br />
This byte does not denote devices that connect to a cartridge; such devices are part of the respective Mapper's definition.<br />
$00 Unspecified<br />
$01 [[Standard controller|Standard NES/Famicom controllers]]<br />
$02 NES [[Four Score]]/Satellite with two additional standard controllers<br />
$03 Famicom Four Players Adapter with two additional standard controllers using the [[Four player adapters#"Simple" Famicom adapters|"simple"]] protocol<br />
$04 [[Vs. System]] (1P via $4016)<br />
$05 Vs. System (1P via $4017)<br />
$06 Reserved<br />
$07 Vs. [[Zapper]]<br />
$08 [[Zapper]] ($4017)<br />
$09 Two Zappers<br />
$0A Bandai Hyper Shot Lightgun<br />
$0B [[Power Pad]] Side A<br />
$0C [[Power Pad]] Side B<br />
$0D [[Power Pad#Family Trainer Mat|Family Trainer]] Side A<br />
$0E [[Power Pad#Family Trainer Mat|Family Trainer]] Side B<br />
$0F [[Arkanoid controller|Arkanoid Vaus Controller (NES)]]<br />
$10 [[Arkanoid controller|Arkanoid Vaus Controller (Famicom)]]<br />
$11 Two Vaus Controllers plus [[Family BASIC Data Recorder|Famicom Data Recorder]]<br />
$12 [[Konami Hyper Shot]] Controller<br />
$13 [[Coconuts Pachinko]] Controller<br />
$14 [[Exciting Boxing Punching Bag]] (Blowup Doll)<br />
$15 [[Jissen Mahjong controller|Jissen Mahjong Controller]]<br />
$16 [[Partytap|Party Tap]] <br />
$17 [[Oeka Kids tablet|Oeka Kids Tablet]]<br />
$18 Sunsoft Barcode Battler<br />
$19 [[Miracle_Piano|Miracle Piano Keyboard]]<br />
$1A Pokkun Moguraa (Whack-a-Mole Mat and Mallet)<br />
$1B Top Rider (Inflatable Bicycle)<br />
$1C Double-Fisted (Requires or allows use of two controllers by one player)<br />
$1D [[Famicom 3D glasses|Famicom 3D System]]<br />
$1E Doremikko Keyboard<br />
$1F R.O.B. Gyro Set<br />
$20 [[Family BASIC Data Recorder|Famicom Data Recorder]] ("silent" keyboard)<br />
$21 ASCII Turbo File<br />
$22 IGS Storage Battle Box<br />
$23 [[Family BASIC Keyboard]] plus Famicom Data Recorder<br />
$24 Dongda PEC-586 Keyboard<br />
$25 Bit Corp. Bit-79 Keyboard<br />
$26 Subor Keyboard<br />
$27 Subor Keyboard plus [[Mouse#Subor Mouse|mouse]] (3x8-bit protocol)<br />
$28 Subor Keyboard plus mouse (24-bit protocol via $4016)<br />
$29 [[Mouse#SNES Mouse|SNES Mouse]] ($4017.d0)<br />
$2A Multicart<br />
$2B Two [[SNES_controller|SNES controllers]] replacing the two standard NES controllers<br />
$2C RacerMate Bicycle<br />
$2D U-Force<br />
$2E R.O.B. Stack-Up<br />
$2F City Patrolman Lightgun<br />
$30 Sharp C1 Cassette Interface<br />
$31 Standard Controller with swapped Left-Right/Up-Down/B-A<br />
$32 Excalibor Sudoku Pad<br />
$33 ABL Pinball<br />
$34 Golden Nugget Casino extra buttons<br />
$35 Unknown famiclone keyboard used by the "Golden Key" educational cartridge<br />
$36 Subor Keyboard plus mouse (24-bit protocol via $4017)<br />
$37 [[Port test controller]]<br />
Notes:<br />
* The Famicom Four Players Adapter ($03) is denoted only if the additional controllers provide ''independent'' 3P/4P input, not if they just alias the built-in 1P/2P controllers.<br />
* So far, there have been no games that provide independent 3P/4P input solely through the [[Four player adapters#Hori 4 Players Adapter|"Hori"]] protocol, which is why there has been no value assigned for it yet.<br />
* For Vs. System games that do not care which stick is used and therefore could be denoted either with value $04 or $05, use value $04.<br />
* Value $06 originally denoted "Pinball (Japan)" and was thought to represent a unique wiring variant, but was since found to represent a peculiar MAME behavior that MAME has since removed.<br />
* "Two Vaus Controllers plus Famicom Data Recorder" ($11) can be trivially emulated as just connecting a Famicom Vaus controller, or sophisticatedly emulated as "Connect two daisy-chained Vaus controllers on startup, disconnect them and connect Family BASIC keyboard with Data Recorder when the user selects Tape Playback or Tape Record from the emulator's user interface; detach these and re-connect the two Vaus controllers when the user selects Tape Stop".<br />
* "Double-Fisted" ($1C) assumes a Four Score is connected, which allows two players to use two controllers at once (Smash T.V.) if the game supports two players.<br />
* The difference between "Famicom Data Recorder" ($20) and "Family BASIC Keyboard" ($23) is that although $20 emulates the Family BASIC keyboard's response to strobe, no actual emulated keyboard input is registered ("silent" keyboard), allowing desktop emulators to keep allowing the use of the host's keyboard for other purposes (such as D-Pad input), and not necessitating the display of an on-screen keyboard on mobile emulators.<br />
* "Multicart" ($2A) is only used if any game on that multicart actually uses expansion port devices. As these will be mostly Zapper games, emulating an expansion port Zapper together with two standard controllers is the simplest way of implementing this value.<br />
* The [[PowerPak]] official loader considers any .NES with a non-zero byte 15 to be invalid, and will fail to load the ROM. A [https://forums.nesdev.org/viewtopic.php?p=283943#p283943 patched N.MAP loader] is available.<br />
<br />
==Version History==<br />
* 2006-09-18 - Original version of specification by kevtris.<br />
** [https://forums.nesdev.org/viewtopic.php?p=17727#p17727 NES 2.0 "Official" Specification]<br />
* 2019-01-02 - Additions by NewRisingSun.<br />
** [https://forums.nesdev.org/viewtopic.php?f=3&t=17213&start=45#p220624 Additions proposal by NewRisingSun]<br />
** Flags 7: adds [[#Extended Console Type|Extended Console Type]] value<br />
** Flags 12: adds [[#CPU/PPU Timing|Dendy]] value<br />
** Flags 13: adds [[#Extended Console Type|Extended Console Type]] field<br />
** Flags 14: adds [[#Miscellaneous ROM Area|miscellaneous ROM]] specifier<br />
** Flags 15: adds [[#Default Expansion Device|Default Expansion Device]]<br />
<br />
==See Also==<br />
* [[NES 2.0 submappers]] - disambiguation for mappers that were under-specified in iNES 1<br />
* [[NES 2.0 header for ca65]] - macro header generator for ca65 assembly<br />
* [[NES 2.0 header for cc65]] - macro header generator for cc65 C code<br />
<br />
==References==<br />
* [https://forums.nesdev.org/viewtopic.php?p=17727#p17727 Original proposal by kevtris]<br />
* [https://forums.nesdev.org/viewtopic.php?f=3&t=17213&start=45#p220624 Additions proposal by NewRisingSun]<br />
* [https://forums.nesdev.org/viewtopic.php?t=19940 NES 2.0 XML Database, with link to Python script for applying it to a ROM files collection]<br />
<references/><br />
[[Category:File formats]]</div>Rainwarriorhttps://www.nesdev.org/w/index.php?title=MMC5_audio&diff=20995MMC5 audio2023-04-03T04:50:51Z<p>Rainwarrior: /* References */ volume test ROM</p>
<hr />
<div>[[Category:Expansion audio]]<br />
Nintendo's [[MMC5|MMC5]] mapper provides extra sound output, consisting of two pulse wave channels and a PCM channel. The pulse wave channels behave almost identically to the native pulse channels in the [[APU|NES APU]].<br />
<br />
The sound output of the square channels are equivalent in volume to the corresponding APU channels, but the polarity of all MMC5 channels is reversed compared to the APU.<br />
<br />
The PCM channel is similarly equivalent in volume to the APU with equivalent input, and inverted, but using the extra high bit of input it can become twice as loud.<br />
<br />
== Pulse 1 ($5000-$5003) ==<br />
These registers manipulate the MMC5's first [[APU Pulse|pulse wave]] channel, which functions the same as to those found in the [[APU|NES APU]] except for the following differences:<br />
<br />
* $5001 has no effect. The MMC5 pulse channels will not sweep, as they have no [[APU Sweep|sweep unit]].<br />
* Frequency values less than 8 do not silence the MMC5 pulse channels; they can output ultrasonic frequencies.<br />
* Length counter operates twice as fast as the APU length counter (might be clocked at the envelope rate).<br />
* MMC5 does not have an equivalent [[APU Frame Counter|frame sequencer]] (APU $4017); envelope and length counter are fixed to a 240hz update rate.<br />
<br />
Other features such as the envelope and phase reset are the same as their APU counterparts.<br />
<br />
== Pulse 2 ($5004-$5007) ==<br />
These registers manipulate the MMC5's second pulse channel.<br />
<br />
== PCM Mode/IRQ ($5010) ==<br />
<br />
=== Write ===<br />
7 bit 0<br />
---- ----<br />
Ixxx xxxM<br />
| |<br />
| +- Mode select (0 = write mode. 1 = read mode.)<br />
+--------- PCM IRQ enable (1 = enabled.)<br />
<br />
=== Read ===<br />
7 bit 0<br />
---- ----<br />
Ixxx xxxM MMC5A default power-on read value = $01<br />
| |<br />
| +- In theory but not verified: Read back of mode select (0 = write mode. 1 = read mode.)<br />
+--------- IRQ (0 = No IRQ triggered. 1 = IRQ was triggered.) Reading $5010 acknowledges the IRQ and clears this flag.<br />
<br />
== Raw PCM ($5011) ==<br />
This functions similarly to the [[APU|NES APU]]'s register $4011, except that all 8 bits are used.<br />
<br />
''Shin 4 Nin Uchi Mahjong'' is the only game to uses the extra PCM channel ($5011).<br />
<br />
=== Write ===<br />
Writes are ignored in PCM read-mode.<br />
7 bit 0<br />
---- ----<br />
WWWW WWWW<br />
|||| ||||<br />
++++-++++- 8-bit PCM data<br />
<br />
Writing $00 to this register will have no effect on the output sound, and does not change the PCM counter.<br />
<br />
=== Pin 2 DAC Characteristic ===<br />
Pin 2 no-load voltage very closely follows the equation:<br />
<br />
Voltage = [(DAC value / 255) * (0.4 * AVcc)] + (0.1 * AVcc)<br />
<br />
[[Image:MMC5 DAC Characteristic.png]]<br />
<br />
The DAC output is very low impedance -- it holds its voltage true under load. To protect itself, the output also has a current limit. The current limit level depends on AVcc. MMC5A measured current limit in microAmps = (42.178 * Avcc) - 36.808. It is unknown, but quite doubtful, that prolonged exposure to current limit mode could cause damage to the DAC or other parts of the MMC5. Since current limit mode would cause audible distortion, it should be considered a self-protection feature that should be avoided. In practice, with Avcc = 5V, the DAC output pin should drive 15kohms or higher to avoid current limit mode.<br />
<br />
The same MMC5A chip, tested with repeated power cycles on different days of the week and different moon phases, etc, has been observed to power on with a DAC voltage equivalent to DAC value $EF or $FF. No other power-on values have been observed. This voltage is not affected by a reset detected when M2 stops toggling.<br />
<br />
== PCM description ==<br />
MMC5's DAC is changed either by writing a value to $5011 (in write mode) or reading a value from $8000-BFFF (in read mode). If you try to assign a value of $00, the DAC is not changed; an IRQ is generated instead. This could be used to read stream 8-bit PCM from ROM and terminate at $00.<br />
<br />
=== IRQ operation ===<br />
(pseudocode)<br />
(On DAC write)<br />
if(value=0)<br />
irqTrip=1<br />
else<br />
irqTrip=0<br />
<br />
(On $5010 write)<br />
irqEnable=value.bit7<br />
<br />
(On $5010 read)<br />
value.bit7=(irqTrip AND irqEnable)<br />
irqTrip=0<br />
<br />
Cart IRQ line=(irqTrip AND irqEnable)<br />
<br />
== Status ($5015, read/write) ==<br />
This register is analogous to the [[APU Status]] register found within the NES at $4015, except that only the bottom 2 bits are used; being for the MMC5's two pulse channels. The MMC5A default power-on value read from this register is $00.<br />
<br />
== Hardware ==<br />
Expansion audio hardware configuration from HVC-ETROM-02:<br />
<br />
R3 15k C4 100n<br />
From 2A03 ---/\/\/-----||------+ R4 10k<br />
(Cart.45) | +--------/\/\/---------+<br />
| | _ |<br />
R2 15k C3 100n | | (MMC5.1) | \ +--- To RF<br />
MMC5 DAC ----/\/\/-----||------+---+----------|+ \ | (Cart.46)<br />
(MMC5.2) | | >------+<br />
| GND ---|- / (MMC5.100)<br />
R1 15k C2 100n | |_/<br />
MMC5 Pulse --/\/\/-----||------+<br />
(MMC5.3)<br />
<br />
== References ==<br />
* [//forums.nesdev.org/viewtopic.php?p=90245#p90245 Famicom expansion hardware recordings] - forum thread with MMC5 test ROMs and recordings confirming various MMC5 audio features.<br />
* [//forums.nesdev.org/viewtopic.php?p=124288#p124288 MMC5 volume test] - hotswap test ROM for investigating MMC5 volume.</div>Rainwarriorhttps://www.nesdev.org/w/index.php?title=User_talk:Sivak/Battle_Kid:_Fortress_of_Peril&diff=20991User talk:Sivak/Battle Kid: Fortress of Peril2023-04-01T16:28:37Z<p>Rainwarrior: Rainwarrior moved page Talk:Battle Kid: Fortress of Peril to User talk:Sivak/Battle Kid: Fortress of Peril: moved article page to userspace</p>
<hr />
<div>==comments==<br />
*looks intresting, do you need any beta testers? email me durda_dan@hotmail.com [[User:Durda_dan|Durdadan]] Nov.6th 2009<br />
**Not at this phase. Thanks. --[[User:Sivak|Sivak]] 17:09, 6 November 2009 (UTC)</div>Rainwarriorhttps://www.nesdev.org/w/index.php?title=Talk:NTSC_video&diff=20990Talk:NTSC video2023-04-01T01:10:11Z<p>Rainwarrior: /* Differential phase distortion and black/white stroke widening/narrowing? */ new section</p>
<hr />
<div>The part of the PPU that generates the video signal (immediately to the right of the NMI and CLK pins) appears to consist of a very long resistor between VCC and GND with taps at various points, and one of them (closest to VCC) is a switchable pulldown to GND (no doubt for color emphasis). The logic itself can select 12 different voltage levels (00/10/20/30, 0D/1D/2D/3D, synch, colorburst L/H, and GND), and they appear to correspond to 10 distinct voltage levels - one of the duplicates is at the highest voltage (likely 20/30), and the other one is the 3rd-lowest [non-GND] voltage (not sure which one). --[[User:Quietust|Quietust]] 17:59, 28 September 2011 (UTC)<br />
*With the help of ChipSim, I've traced down exactly what the 12 voltage levels correspond to - Synch (GND), Colorburst L, Color 0D, Color xE/xF and Color 1D, Colorburst H, Color 2D, Color 00, Color 10, color 3D, Color 20 and Color 30 ("and" == two signals which select the same actual voltage). --[[User:Quietust|Quietust]] 11:17, 29 October 2012 (MDT)<br />
<br />
==Absolute Video Signal Timing==<br />
Some tests with Visual2C02 managed to confirm all of the contents of the Scanline Timing table, plus one more interesting bit of information: the ''offset''. Specifically, the "active" region begins at cycle '''4''', which is when the PPU is just finishing the attribute byte fetch for the 3rd tile in the scanline (the first 2 are fetched at the end of the previous scanline). --[[User:Quietust|Quietust]] 08:50, 1 November 2012 (MDT)<br />
:But during which cycles is sync output? We need that too to align the NES picture center relative to the NTSC standard picture center (see [[Overscan]]). --[[User:Tepples|Tepples]] 09:41, 1 November 2012 (MDT)<br />
::It's probably been mentioned elsewhere, but for completeness: cycles 280 through 304, inclusive, which happens to correspond to when the VRAM address gets reloaded during the prerender scanline. --[[User:Quietust|Quietust]] ([[User talk:Quietust|talk]]) 07:24, 14 February 2013 (MST)<br />
<br />
== C++ code? ==<br />
<br />
Is this really C++ code? Can we call it what it is, if it's not?<br />
auto InColorPhase = [=](int color) { return (color + phase) % 12 < 6; }; // Inline function<br />
-- [[User:Rainwarrior|Rainwarrior]] ([[User talk:Rainwarrior|talk]]) 07:26, 13 August 2014 (MDT)<br />
:It appears to be C++11 code. Not all C++ compilers understand C++11 yet. --[[User:Tepples|Tepples]] ([[User talk:Tepples|talk]]) 19:42, 13 August 2014 (MDT)<br />
<br />
::Am I just out of touch? Is C++11 the accepted standard now? I didn't know it was safe to call it "C++" now, but maybe it is? :S - [[User:Rainwarrior|Rainwarrior]] ([[User talk:Rainwarrior|talk]]) 21:08, 13 August 2014 (MDT)<br />
::: Yes, it's the standard. The draft was commonly referred to as "C++0x" because they aimed to get it accepted by the end of 2009. It became [[wikipedia:C++11|C++11]] when the changes were officially added to ISO C++ in 2011. --[[User:Tepples|Tepples]] ([[User talk:Tepples|talk]]) 06:56, 14 August 2014 (MDT)<br />
:::: It was an official standard in 2011, but that's different than it being the primary flavour of C++, which is really what I meant. After looking around, I've noted that as usual Microsoft has done a pick-and-choose with which features to implement, but the C++11 features they did implement have been enabled by default since VS2010. GCC on the other hand much more fully supports it, but requires a compiler switch to enable. Clang is in the same situation as GCC. Intel's compiler looks like partial support, off by default. I imagine other compilers are in similar states. As such, I'd say we're in a period of transition, but C++11 will surely become the default before long. - [[User:Rainwarrior|Rainwarrior]] ([[User talk:Rainwarrior|talk]]) 11:56, 14 August 2014 (MDT)<br />
<br />
== Differential phase distortion and black/white stroke widening/narrowing? ==<br />
<br />
I removed this, because it seemed to be debated in a discord discussion. I think the effect may be real, but it might not be the differential phase distortion effect?<br />
<br />
This can also be seen to slightly widen black strokes on a white background and narrow white strokes on a black background.<br />
<br />
So, it might belong elsewhere in the article. Keeping it here as a reminder to discuss/resolve. - [[User:Rainwarrior|Rainwarrior]] ([[User talk:Rainwarrior|talk]]) 01:10, 1 April 2023 (UTC)</div>Rainwarriorhttps://www.nesdev.org/w/index.php?title=NTSC_video&diff=20989NTSC video2023-04-01T01:07:23Z<p>Rainwarrior: /* Color Phases */ "black strokes on a white background" effect seems to be disputed, moving it to talk temporarily</p>
<hr />
<div>Unlike many other game consoles, the NES does not generate RGB or YUV and then encode that to composite.<br />
Instead, it generates '''NTSC video''' directly in the composite domain, which leads to interesting artifacts.<br />
<br />
NTSC Master clock is 21.47727273 MHz and each PPU pixel lasts four clocks; PAL master clock is 26.6017125 MHz, and each PPU pixel lasts five clocks. $xy refers to a palette color in the range $00 to $3F.<br />
<br />
==Scanline Timing==<br />
Values in PPU pixels (341 total per scanline).<br />
[[File:Ntsc video timing.png|right|frame|A visualization of the tables to the left, starts with Cyan for short sync]]<br />
<br />
Rendering scanlines (n=240):<br />
<br />
{| class="wikitable"<br />
! name || start || duration || row || notes<br />
|-<br />
| short sync || 280 || 25 || 0-239 ||<br />
|-<br />
| black (back porch) || 305 || 4 || 0-239 ||<br />
|-<br />
| colorburst || 309 || 15 || 0-239 ||<br />
|-<br />
| black (the rest of back porch) || 324 || 5 || 0-239 ||<br />
|-<br />
| pulse (background color in grayscale) || 329 || 1 || 0-239 ||<br />
|-<br />
| left border (background color) || 330 || 15 || 0-239 ||<br />
|-<br />
| active || 4 || 256 || 0-239 || if background rendering is disabled, border will be rendered instead<br />
|-<br />
| right border (background color) || 260 || 11 || 0-239 ||<br />
|-<br />
| black (front porch) || 271 || 9 || 0-239 ||<br />
|}<br />
<br />
Post-render scanlines (n=2):<br />
<br />
{| class="wikitable"<br />
! name || start || duration || row<br />
|-<br />
| short sync || 280 || 25 || 240-241<br />
|-<br />
| black (back porch) || 305 || 4 || 240-241<br />
|-<br />
| colorburst || 309 || 15 || 240-241<br />
|-<br />
| black (the rest of back porch) || 324 || 5 || 240-241<br />
|-<br />
| pulse (background color in grayscale) || 329 || 1 || 240-241<br />
|-<br />
| bottom border (background color) || 330 || 282 || 240-241<br />
|-<br />
| black (front porch) || 271 || 9 || 240-241<br />
|}<br />
<br />
Post-render blanking scanlines (n=3):<br />
<br />
{| class="wikitable"<br />
! name || start || duration || row<br />
|-<br />
| short sync || 280 || 25 || 242-244<br />
|-<br />
| black (back porch) || 305 || 4 || 242-244<br />
|-<br />
| colorburst || 309 || 15 || 242-244<br />
|-<br />
| black || 324 || 297 || 242-244<br />
|}<br />
<br />
Vertical sync scanlines (n=3):<br />
<br />
{| class="wikitable"<br />
! name || start || duration || row<br />
|-<br />
| long sync || 280 || 318 || 245-247<br />
|-<br />
| black (sync separator) || 257 || 23 || 245-247<br />
|}<br />
<br />
Pre-render blanking scanlines (n=14):<br />
<br />
{| class="wikitable"<br />
! name || start || duration || row || notes<br />
|-<br />
| short sync || 280 || 25 || 248-261 ||<br />
|-<br />
| black (back porch) || 305 || 4 || 248-261 ||<br />
|-<br />
| colorburst || 309 || 15 || 248-261 || 14 columns on end of row 261 for odd frames, if either background or sprite rendering is enabled<br />
|-<br />
| black || 324 || 297 || 248-261 ||<br />
|}<br />
<br />
This amounts to a total of 262 scanlines.<br />
<br />
In standard NTSC, a scanline is 227.5 subcarrier cycles long (equivalent to 341.25 NES pixels), and each field is 262.5 scanlines lines tall. Vertical sync "serrations" or "equalization pulses" use a brief period of 31kHz horizontal sync to be able to start vertical sync half-way through a scanline, which makes the TV draw the next field one half scanline higher, resulting in ''interlaced'' video.<br />
<br />
The video timing in the NES is non-standard - it both generates 341 pixels, making 227 1/3 subcarrier cycles per scanline, and always generates 262 scanlines. This causes the TV to draw the fields on top of each other, resulting in a non-standard low-definition "progressive" or "double struck" video mode sometimes called [http://junkerhq.net/xrgb/index.php/240p_video 240p].<br />
<br />
Some high-definition displays and upscalers cannot handle 240p video, instead introducing artifacts that make the video appear as if it were interlaced. Artemio Urbina's [http://junkerhq.net/xrgb/index.php/240p_test_suite 240p test suite], which has been [https://forums.nesdev.org/viewtopic.php?p=157634#p157634 ported to NES] by [[User:Tepples|Damian Yerrick]], contains a set of test patterns to diagnose problems with decoding 240p composite video.<br />
<br />
Note that emulators usually crop the top and bottom 8 lines from the picture, as most televisions will hide at least part of the picture in a similar way. See: [[Overscan]]<br />
<br />
==Brightness Levels==<br />
<br />
$xE/$xF output the same voltage as $1D. $x1-$xC output a square wave alternating between levels for $xD and $x0. Colors $20 and $30 are exactly the same.<br />
<br />
When grayscale is active, all colors between $x1-$xD are treated as $x0. Notably this behavior extends to the first pixel of the border color, which acts as a sync pulse on every visible scanline.<br />
<br />
=== Terminated measurement ===<br />
<br />
Standard video (not NES) looks like this:<br />
{| class="wikitable"<br />
! Type || IRE level || Voltage (mV)<br />
|-<br />
| Peak white || 120 ||<br />
|-<br />
| White || 100 || 714<br />
|-<br />
| Colorburst H || 20 || 143<br />
|-<br />
| Black || 7.5 || 53.6<br />
|-<br />
| Blanking || 0 || 0<br />
|-<br />
| Colorburst L || -20 || -143<br />
|-<br />
| Sync || -40 || -286<br />
|}<br />
<br />
The following [http://forums.nesdev.org/viewtopic.php?p=159266#p159266 measurements by lidnariq] into a properly terminated (75 Ω) TV have about 10 mV of noise and 4 mV of quantization error, which implies an error of ±2 IRE:<br />
{| class="wikitable"<br />
! Signal || Potential || IRE<br />
|-<br />
| SYNC || 48 mV || -37 IRE<br />
|-<br />
| CBL || 148 mV || -23 IRE<br />
|-<br />
| 0D || 228 mV || -12 IRE<br />
|-<br />
| 1D || 312 mV || ≡ 0 IRE<br />
|-<br />
| CBH || 524 mV || 30 IRE<br />
|-<br />
| 2D || 552 mV || 34 IRE<br />
|-<br />
| 00 || 616 mV || 43 IRE<br />
|-<br />
| 10 || 840 mV || 74 IRE<br />
|-<br />
| 3D || 880 mV || 80 IRE<br />
|-<br />
| 20 || 1100 mV || 110 IRE<br />
|-<br />
| 0Dem || 192 mV || -17 IRE<br />
|-<br />
| 1Dem || 256 mV || -8 IRE<br />
|-<br />
| 2Dem || 448 mV || 19 IRE<br />
|-<br />
| 00em || 500 mV || 26 IRE<br />
|-<br />
| 10em || 676 mV || 51 IRE<br />
|-<br />
| 3Dem || 712 mV || 56 IRE<br />
|-<br />
| 20em || 896 mV || 82 IRE<br />
|}<br />
Unlike PAL, US NTSC is supposed to have a "setup", a difference between blanking and black level. Japanese NTSC does not make this distinction.<br />
<br />
=== Old measurement ===<br />
<br />
This measurment table was added to the wiki in 2009. Its source is unknown, and its results differ from the terminated measurements above. This was used for Bisqwit's example C++ implementation below.<br />
<br />
Voltage levels used by the PPU are as follows - absolute, relative to synch, and normalized between black level and white:<br />
{| class="wikitable"<br />
! Type || Absolute || Relative || Normalized<br />
|-<br />
| Synch || 0.781 || 0.000 || -0.359<br />
|-<br />
| Colorburst L || 1.000 || 0.218 || -0.208<br />
|-<br />
| Colorburst H || 1.712 || 0.931 || 0.286<br />
|-<br />
|Color 0D || 1.131 || 0.350 || -0.117<br />
|-<br />
|Color 1D (black) || 1.300 || 0.518 || 0.000<br />
|-<br />
|Color 2D || 1.743 || 0.962 || 0.308<br />
|-<br />
|Color 3D || 2.331 || 1.550 || 0.715<br />
|-<br />
|Color 00 || 1.875 || 1.090 || 0.397<br />
|-<br />
|Color 10 || 2.287 || 1.500 || 0.681<br />
|-<br />
|Color 20 || 2.743 || 1.960 || 1.000<br />
|-<br />
|Color 30 || 2.743 || 1.960 || 1.000<br />
|}<br />
<br />
These levels don't quite match the standard levels.<br />
Ideally, the composite signal is 1000 millivolts from peak to peak (1.0 Vp-p) when loaded with a 75 Ω output impedance.<br />
(Unloaded levels may be twice that amount, which may explain the levels seen above.)<br />
Levels are commonly measured in units called IRE.<ref>[https://www.maximintegrated.com/en/app-notes/index.mvp/id/1184 Tutorial 1184: Understanding Analog Video Signals]</ref><ref>[http://www.ni.com/white-paper/4750/en/ Analog Video 101]</ref><br />
<br />
==Color Phases==<br />
111111------<br />
22222------2<br />
3333------33<br />
444------444<br />
55------5555<br />
6------66666<br />
------777777<br />
-----888888-<br />
----999999--<br />
---AAAAAA---<br />
--BBBBBB----<br />
-CCCCCC-----<br />
<br />
The color generator is clocked by the rising ''and'' falling edges of the ~21.48 MHz clock, resulting in an effective ~42.95 MHz clock rate. There are 12 color square waves, spaced at regular phases. Each runs at the ~3.58 MHz colorburst rate. On NTSC, color $xY uses the wave shown in row Y from the table. NTSC color burst (pure shade -U) uses color phase 8 (with voltages listed above); PAL color burst is believed to alternate between 6 (-U+V) and 9 (-U-V), so hue is rotated by 15° from NTSC. [[wikipedia:PAL|PAL]] alternates the broadcast sign of the V component, so on PAL every odd scanline will use the appropriate opposite phase—e.g. phases 5-C are respectively replaced with C-5.<br />
<br />
<br />
The output is subject to a [[wikipedia:Differential phase|differential phase distortion]] effect<ref>[https://forums.nesdev.org/viewtopic.php?p=287241#p287241 Re: In search of a PAL region reference palette] - Explanation of the differential phase distortion of the NES.</ref>. This causes a rotation of the NTSC signal's effective hue, proportional to the voltage, causing more shift for brighter colors. Current estimates approximate about 2.5° (2C02E) or 5° (2C02G) of additional rotation for each row of the palette.<br />
<br />
The reason for this distortion is that the output impedance of the PPU is dependent on the signal level. When combined with the board's capacitance, it slows level transitions, causes the edges at high signal levels to be less steep. The high frequency chroma signal is sensitive to this, and the delay to its phase causes the hue rotation.<br />
<br />
A [[PAL video|PAL NES]] is affected by the same differential phase distortion, but because of the alternating-line mechanism of PAL, the effect is mostly cancelled out on consecutive scanlines.<br />
<br />
==Color Tint Bits==<br />
There are three color modulation channels controlled by the top three bits of $2001. Each channel uses one of the color square waves (see above diagram) and enables attenuation of the video signal when the color square wave is high. A single attenuator is shared by all channels. It is active for 6 out of 12 half-clocks if one bit is set, 10 half-clocks if two bits are set, or all 12 if all three bits are set.<br />
<br />
{| class="wikitable"<br />
! $2001 || Active phase || Active diagram || Complement<br />
|-<br />
|| Bit 7 || Color 8 || <tt>-----888888-</tt> || Color 2 (blue)<br />
|-<br />
|| Bit 6 || Color 4 || <tt>444------444</tt> || Color A (green)<br />
|-<br />
|| Bit 5 || Color C || <tt>-CCCCCC-----</tt> || Color 6 (red)<br />
|}<br />
<br />
When attenuation is active and the current pixel is a color other than $xE/$xF (black), the signal is attenuated.<br />
<br />
For example, when $2001 bit 6 is true, the attenuator will be active during the phases of color 4.<br />
This means the attenuator is not active during its complement (color A), and the screen appears to have a tint of color A, which is green.<br />
<br />
Note that on the Dendy and PAL NES, the green and red bits swap meaning.<br />
<br />
[http://forums.nesdev.org/viewtopic.php?p=160669#p160669 Tests performed on NTSC NES] show that emphasis does not affect the black colours in columns $E or $F, but it does affect all other columns, including the blacks and greys in column $D.<br />
<br />
The terminated measurements above suggest that resulting attenuated absolute voltage is approximately '''0.81 times''' the un-attenuated absolute voltage.<br />
<br />
The old measurement suggested a different approximation, applied to its relative or normalized values. This does not agree with the terminated measurements:<br />
attenuated relative = relative * 0.746<br />
attenuated normalized = normalized * 0.746 - 0.0912<br />
<br />
==Example Waveform==<br />
<br />
This waveform steps through various grays and then stops on a color.<br />
[[File:Composite_waveform_example.gif|center|frame|The composite signal steps through 6 gray colors ($0D, $0F, $2D, $00, $10, $30) then continues through with color $11. ]]<br />
<br />
The PPU's shortcut method of NTSC modulation often produces artifacts in which vertical lines appear slightly ragged, as the chroma spills over into luma.<br />
[[File:NTSC video ragged box animated.gif|right|frame|Generation and demodulation of a red corner]]<br />
<br clear="all"/><br />
<br />
== Composite decoding ==<br />
<br />
Normal composite video encodes chroma and luma information into one composite analog signal. In order to convert composite into an RGB signal, it firsts needs to be decoded into YUV, before converting the resulting YUV into RGB.<br />
<br />
The NES PPU does not encode anything into composite; instead, directly drawing the composite waveform itself. In order to convert the NES's composite signal into an RGB signal, it is decoded under the "assumption" that it was encoded under YUV.<br />
<br />
YUV in this article refers to and will continue to refer to the equiband encoding of composite video as Y, b-y and r-y respectively. YIQ refers to the non-equiband encoding of composite, which has much more additional considerations regarding bandlimiting.<br />
<br />
In practice, YIQ decoding is not used by any modern TV receiver and composite decoder, instead using YUV decoding as it is much simpler and less mathematically intensive to decode.<ref>[https://www.itu.int/rec/R-REC-BT.1700-0-200502-I/en S170m-2004.pdf: Composite Analog Video Signal NTSC for Studio Applications. Page 17.]</ref><ref>SMPTE EG 27-2004: Supplemental Information for SMPTE 170M and Background on the Development of NTSC Color Standards. Page 5.</ref><br />
<br />
=== Decoding composite video into YUV ===<br />
<br />
Although encoding composite is somewhat standardized, the methods of decoding composite may vary from TV to TV. This article shows one way to decode composite.<br />
<br />
==== Decoding chroma information (UV) ====<br />
<br />
Decoding chroma information requires a subcarrier reference sine wave to determine the hue, whose phase is "locked" (or aligned as best as possible) to the colorburst of the composite scanline.<br />
<br />
The subcarrier reference is used to demodulate the U component. A copy (or a phase offset) of the reference is delayed by 90 degrees, which is then used to demodulate the V component.<br />
<br />
The U/V component is demodulated by multiplying the subcarrier reference to the composite waveform. The resulting waveform is then filtered typically by a lowpass filter. A comb filter can also be used if desired.<br />
<br />
==== Decoding luma information (Y) ====<br />
<br />
To get the luma (Y) component, the base signal is filtered by a lowpass or comb filter. Some TVs use more complex methods to decode luma, some TVs do not filter at all.<br />
<br />
=== Converting YUV to linear RGB ===<br />
<br />
To convert YUV to linear RGB, we multiply the components to the following inversed matrix:<br />
<br />
<nowiki><br />
R = Y + V*1.14<br />
G = Y - (R*0.299 - B*0.114) / 0.587<br />
B = Y + U*2.03</nowiki><br />
<br />
Or, in terms of YUV only:<br />
<br />
<nowiki><br />
R = Y + V*1.14<br />
G = Y - U*0.394242... - V*0.580681...<br />
B = Y + U*2.03</nowiki><br />
<br />
The matrices above is derived from the NTSC base matrix<ref>[https://www.itu.int/rec/R-REC-BT.1700-0-200502-I/en S170m-2004.pdf: Composite Analog Video Signal NTSC for Studio Applications. Page 4.]</ref> of luminance and color-difference:<br />
<br />
<nowiki><br />
Y = R*0.299 + G*0.587 + B*0.114<br />
B-Y = -R*0.299 - G*0.587 + B*0.886<br />
R-Y = R*0.701 - G*0.587 - B*0.114</nowiki><br />
<br />
Which, when applied with the approximate color reduction factors 1/2.03 and 1/1.14 for B-Y and R-Y respectively<ref>[https://www.itu.int/rec/R-REC-BT.1700-0-200502-I/en S170m-2004.pdf: Composite Analog Video Signal NTSC for Studio Applications. Page 16.]</ref>, results in the definition of the linear RGB to YUV matrix equation:<br />
<br />
<nowiki><br />
Y = R*0.299 + G*0.587 + B*0.114<br />
U = (-R*0.299 - G*0.587 + B*0.886) / 2.03<br />
V = ( R*0.701 - G*0.587 - B*0.114) / 1.14</nowiki><br />
<br />
In YIQ, the IQ component's chroma hue is just the UV component's chroma hue rotated by 33 degrees. Note that this is not precisely the same as properly decoding YIQ with different bandwidths for the I and Q component.<br />
<br />
The following conversion is optional, and might match the look of other composite decoders:<br />
<br />
<nowiki><br />
U = -(I * sin(-33 deg)) + (Q * cos(-33 deg))<br />
V = (I * cos(-33 deg)) + (Q * sin(-33 deg))</nowiki><br />
<br />
=== Converting linear RGB to output colorspace ===<br />
<br />
The final step is to convert linear RGB into the output colorspace, typically sRGB for most monitors.<br />
<br />
==== Linear RGB into sRGB ====<br />
<br />
According to IEC 61966-2-1:1999, a gamma curve correction must be applied to the R, G and B signals before they are displayed.<ref>[https://www.color.org/chardata/rgb/srgb.xalter ICC page on sRGB]</ref> The transfer function for sRGB is:<br />
<br />
<nowiki><br />
C = linear R, G, or B signal<br />
C' = gamma corrected R, G or B signal<br />
<br />
C' = 12.92 * C if C <= 0.0031308<br />
C' = 1.055 * C^(1/2.4) - 0.055 if C > 0.0031308</nowiki><br />
<br />
The resulting R, G and B values can then be quantized into 8 bits per channel:<br />
<br />
<nowiki><br />
C8bpc = quantized R, G, or B channel<br />
C' = gamma corrected R, G or B signal<br />
<br />
C8bpc = (int)(C` * 255)</nowiki><br />
<br />
==Emulating in C++ code==<br />
<br />
For efficient, ready to use implementations, see [[#Libraries|Libraries]] below. The following is an illustrative example. The values used are based on the "old" measurements given above.<br />
<br />
Calculating the momentary NTSC signal level can be done as follows in C++:<br />
<br />
<nowiki><br />
// pixel = Pixel color (9-bit) given as input. Bitmask format: "eeellcccc".<br />
// phase = Signal phase (0..11). It is a variable that increases by 8 each pixel.<br />
float NTSCsignal(int pixel, int phase)<br />
{<br />
// Voltage levels, relative to synch voltage<br />
static const float black=.518f, white=1.962f, attenuation=.746f,<br />
levels[8] = {.350f, .518f, .962f,1.550f, // Signal low<br />
1.094f,1.506f,1.962f,1.962f}; // Signal high<br />
<br />
// Decode the NES color.<br />
int color = (pixel & 0x0F); // 0..15 "cccc"<br />
int level = (pixel >> 4) & 3; // 0..3 "ll"<br />
int emphasis = (pixel >> 6); // 0..7 "eee"<br />
if(color > 13) { level = 1; } // For colors 14..15, level 1 is forced.<br />
<br />
// The square wave for this color alternates between these two voltages:<br />
float low = levels[0 + level];<br />
float high = levels[4 + level];<br />
if(color == 0) { low = high; } // For color 0, only high level is emitted<br />
if(color > 12) { high = low; } // For colors 13..15, only low level is emitted<br />
<br />
// Generate the square wave<br />
auto InColorPhase = [=](int color) { return (color + phase) % 12 < 6; }; // Inline function<br />
float signal = InColorPhase(color) ? high : low;<br />
<br />
// When de-emphasis bits are set, some parts of the signal are attenuated:<br />
if( ((emphasis & 1) && InColorPhase(0))<br />
|| ((emphasis & 2) && InColorPhase(4))<br />
|| ((emphasis & 4) && InColorPhase(8)) ) signal = signal * attenuation;<br />
<br />
return signal;<br />
}</nowiki><br />
<br />
The process of generating NTSC signal for a single pixel can be simulated with the following C++ code:<br />
<br />
<nowiki><br />
void RenderNTSCpixel(unsigned x, int pixel, int PPU_cycle_counter)<br />
{<br />
int phase = PPU_cycle_counter * 8;<br />
for(int p=0; p<8; ++p) // Each pixel produces distinct 8 samples of NTSC signal.<br />
{<br />
float signal = NTSCsignal(pixel, phase + p); // Calculated as above<br />
// Optionally apply some lowpass-filtering to the signal here.<br />
// Optionally normalize the signal to 0..1 range:<br />
static const float black=.518f, white=1.962f;<br />
signal = (signal-black) / (white-black);<br />
// Save the signal for this pixel.<br />
signal_levels[ x*8 + p ] = signal;<br />
}<br />
}</nowiki><br />
<br />
It is important to note that while the NES only generates eight (8) samples of NTSC signal per pixel, the wavelength for chroma is 12 samples long. This means that the colors of adjacent pixels get mandatorily mixed up to some degree. For the same reason, narrow black&white details can be interpreted as colors.<br />
<br />
Because the scanline length is uneven (341*8 is not an even multiple of 12), the color mixing shifts a little each scanline. This appears visually as a sawtooth effect at the edges of colors at high resolution. The sawtooth cycles every 3 scanlines.<br />
<br />
Because also the frame length is uneven (neither 262*341*8 nor (262*341-1)*8 is an even multiple of 12), the color mixing also changes a little every frame. When rendering is normally enabled, the screen is alternatingly 89342 and 89341 cycles long. The combination of these (89342+89341)*8 <i>is</i> an even multiple of 12, which means that the artifact pattern cycles every 2 frames. The pattern of cycling can be changed by disabling rendering during the end of the pre-render scanline; it forces the screen length to 89342 cycles, even if would be 89341 otherwise.<br />
<br />
The process of decoding NTSC signal (convert it into RGB) is subject to a lot of study, and there are many patents and different techniques for it. A simple method suitable for emulation is covered below. It is not accurate, because in reality the chroma is blurred much more than is done here (the region of signal sampled for I and Q is wider than 12 samples), and the filter used here is a simple box FIR filter rather than an IIR filter, but it already produces a quite authentic looking picture. In addition, the border region (total of 26 pixels of background color around the 256-pixel scanline) is not sampled.<br />
<br />
<nowiki><br />
float signal_levels[256*8] = {...}; // Eight signal levels for each pixel, normalized to 0..1 range. <br />
Calculated as above.<br />
<br />
unsigned Width; // Input: Screen width. Can be not only 256, but anything up to 2048.<br />
float phase; // Input: This should the value that was PPU_cycle_counter * 8 + 3.9<br />
// at the BEGINNING of this scanline. It should be modulo 12.<br />
// It can additionally include a floating-point hue offset.<br />
for(unsigned x = 0; x < Width; ++x)<br />
{<br />
// Determine the region of scanline signal to sample. Take 12 samples.<br />
int center = x * (256*8) / Width + 0;<br />
int begin = center - 6; if(begin < 0) begin = 0;<br />
int end = center + 6; if(end > 256*8) end = 256*8;<br />
float y = 0.f, i = 0.f, q = 0.f; // Calculate the color in YIQ.<br />
for(int p = begin; p < end; ++p) // Collect and accumulate samples<br />
{<br />
float level = signal_levels[p] / 12.f;<br />
y = y + level;<br />
i = i + level * cos( M_PI * (phase+p) / 6 );<br />
q = q + level * sin( M_PI * (phase+p) / 6 );<br />
}<br />
render_pixel(y,i,q); // Send the YIQ color for rendering.<br />
}</nowiki><br />
<br />
The NTSC decoder here produces pixels in YIQ color space.<br />
<br />
If you want more saturated colors, just multiply <code>i</code> and <code>q</code> with a factor of your choosing, such as 1.7. If you want brighter colors, just multiply <code>y</code>, <code>i</code> and <code>q</code> with a factor of your choosing, such as 1.1. If you want to adjust the hue, just add or subtract a value from/to <code>phase</code>. If you want to see so called chroma dots, change the begin and end in such manner that you collect a number of samples that is not divisible with 12. If you want to blur the video horizontally, change the begin and end in such manner that the samples are collected from a wider region.<br />
<br />
The YIQ colors can be converted into sRGB colors with the following formula, using the [https://www.govinfo.gov/content/pkg/CFR-2013-title47-vol4/pdf/CFR-2013-title47-vol4-sec73-682.pdf#page=2 FCC-sanctioned] YIQ-to-RGB conversion matrix. This produces a value that can be saved to e.g. framebuffer:<br />
<br />
<nowiki><br />
float gamma = 2.0f; // Assumed display gamma<br />
auto gammafix = [=](float f) { return f <= 0.f ? 0.f : pow(f, 2.2f / gamma); };<br />
auto clamp = [](int v) { return v>255 ? 255 : v; };<br />
unsigned rgb =<br />
0x10000*clamp(255.95 * gammafix(y + 0.946882f*i + 0.623557f*q))<br />
+ 0x00100*clamp(255.95 * gammafix(y + -0.274788f*i + -0.635691f*q))<br />
+ 0x00001*clamp(255.95 * gammafix(y + -1.108545f*i + 1.709007f*q));</nowiki><br />
<br />
The two images below illustrate the NTSC artifacts.<br />
In the left side image, 12 samples of NTSC signal were generated for each NES pixel,<br />
and each display pixel was separately rendered by decoding that 12-sample signal.<br />
In the right side image, 8 samples of NTSC signal were generated for each NES pixel,<br />
and each display pixel was rendered by decoding 12 samples of NTSC signal from the<br />
corresponding location within the scanline.<br clear="all" /><br />
<table cellspacing=0 cellpadding=0><br />
<tr><td colspan=2>[[File:nes_ntsc_perpixel.png|left|frame|Per-pixel rendering: 12 samples of NTSC signal per input pixel; the same 12 samples are decoded for each output pixel]]</td><br />
<td colspan=2>[[File:nes_ntsc_perscanline.gif|left|frame|Per-scanline rendering: 8 samples of NTSC signal per input pixel; 12 samples are decoded for each output pixel]]</td></tr><br />
<tr><td>[[File:nes_ntsc_perpixel_small.png|left|frame|Same as above, but rendered at 256x240 without upscaling]]</td><br />
<td>[[File:nes_ntsc_perpixel_small_bw.png|left|frame|Same in grayscale (zero saturation). This illustrates well how the different color values have exactly the same luminosity; only the chroma phase differs.]]</td><br />
<td>[[File:nes_ntsc_perscanline_small.gif|left|frame|Same as above, but rendered at 256x240 rather than at 2048x240 and then downscaled]]</td><br />
<td>[[File:nes_ntsc_perscanline_small_bw.gif|left|frame|Same in grayscale]]</td></tr></table><br />
<br />
The source code of the program that generated both images can be read here: [https://bisqwit.iki.fi/jutut/kuvat/programming_examples/nesemu1/ntsc-small.cc ntsc-small.cc]. Note that even though the image resembles the well-known Philips PM5544 test card, it is not the same; the exact same<br />
colors could not be reproduced with NES colors. In addition, some parts were changed to better test NES features. For example, the backgrounds for the "station ID" regions (the black rectangles at the top and at the bottom inside the circle) are generated using the various blacks within the NES palette.<br />
<br />
Later, Bisqwit made a generic [http://forums.nesdev.org/viewtopic.php?p=172329#p172329 integer-based decoder in C++]. This takes a signal at 12 times color burst and can be used to emulate other systems that use shortcuts when generating NTSC video, such as Apple II (where ''every'' color in <code>HGR</code> is an artifact color) and Atari 7800 (whose game ''Tower Toppler'' seriously exploits artifact colors).<br />
<br />
==Libraries==<br />
<br />
* [http://slack.net/~ant/libs/ntsc.html blargg's nes_ntsc library]<br />
* [//forums.nesdev.org/viewtopic.php?f=21&t=11947 blargg's NTSC demo windows executable]<br />
* [//forums.nesdev.org/viewtopic.php?f=2&t=14338 Forum thread]: New NTSC decoder with integer-only math (short C++ code) - by Bisqwit<br />
* [https://github.com/LMP88959/NTSC-CRT/ LMP88959 (EMMIR)'s NTSC decoder]<br />
<br />
== See also ==<br />
* [[Cycle reference chart]]<br />
* [[PAL video]]<br />
* [[PPU palettes]]<br />
<br />
== References ==<br />
<references /></div>Rainwarrior