[NO] Is it safe to assume the values #$40 and #$41 for NTSC button presses?

Discuss technical or other issues relating to programming the Nintendo Entertainment System, Famicom, or compatible systems.

Moderator: Moderators

User avatar
Controllerhead
Posts: 103
Joined: Tue Nov 13, 2018 4:58 am
Location: $4016
Contact:

[NO] Is it safe to assume the values #$40 and #$41 for NTSC button presses?

Post by Controllerhead » Wed Apr 15, 2020 11:42 pm

I am relying on the values #$40 for released and #$41 for pressed specifically for buttons, i have tested it successfully on my NTSC toaster and toploader models with a standard NES pad and Dogbone. I am loading code from an Everdrive N8.

Is this safe to assume this for all systems, regions, and controller makes? Would these values ever be different across NTSC regions (such as Famicom or Dendy), newer clone systems, off brand controllers, or anything else?

Thanks!

EDIT: TL;DR- No. It is not safe. You should handle bit 0, bit 1, and both bits for button presses.
Last edited by Controllerhead on Tue Aug 11, 2020 5:25 pm, edited 5 times in total.
Image

lidnariq
Posts: 9510
Joined: Sun Apr 13, 2008 11:12 am
Location: Seattle

Re: Is it safe to assume the values #$40 and #$41 for NTSC button presses?

Post by lidnariq » Thu Apr 16, 2020 12:05 am

It will not work for anyone using a PowerPak. It will probably not work for anyone with an original Famicom with a microphone that they haven't disabled.

More details in this thread.

User avatar
rainwarrior
Posts: 7824
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: Is it safe to assume the values #$40 and #$41 for NTSC button presses?

Post by rainwarrior » Thu Apr 16, 2020 12:09 am

Controllerhead wrote:
Wed Apr 15, 2020 11:42 pm
Is this safe to assume this for all systems, regions, and controller makes? Would these values ever be different across NTSC regions (such as Famicom or Dendy), newer clone systems, off brand controllers, or anything else?
Definitely not.

There are one or two games that made this assumption (Paperboy?) but this behaviour is highly variable when you get away from very specific original hardware. reference thread

User avatar
Controllerhead
Posts: 103
Joined: Tue Nov 13, 2018 4:58 am
Location: $4016
Contact:

Re: Is it safe to assume the values #$40 and #$41 for NTSC button presses?

Post by Controllerhead » Thu Apr 16, 2020 12:22 am

You know, I kinda figured there would be situations where this would fail. Glad i asked! Thanks for the info =)

So, i suppose i can poll it and use AND #%00000001 and assume bit 0 being 0/1 will give the correct response?
(aside from the DPCM phantom right input stuff, i am not concerned with that, for now...)
Image

lidnariq
Posts: 9510
Joined: Sun Apr 13, 2008 11:12 am
Location: Seattle

Re: Is it safe to assume the values #$40 and #$41 for NTSC button presses?

Post by lidnariq » Thu Apr 16, 2020 12:26 am

We have an article on the wiki you may find helpful: nesdevwiki:Controller reading code

User avatar
Controllerhead
Posts: 103
Joined: Tue Nov 13, 2018 4:58 am
Location: $4016
Contact:

Re: Is it safe to assume the values #$40 and #$41 for NTSC button presses?

Post by Controllerhead » Thu Apr 16, 2020 1:16 am

I've seen the page, but i wrote this baby instead, just have to edit it to not use #$40 and #$41. I think it's quite useful:

Code: Select all

; $47 - $40	Memory		A B Sel St Up Down Left Right
; FE -		onRelease	INX and BEQ / BNE to check onRelease
; FF - 		released 	BMI if released
; 00 - 		onPress		BEQ / BNE determines onPress
; 00 - 7F	pressed		BPL if pressed, with frameCount of 0-127

INY
STY P1_PORT ; 1 				;	Controller button latch set
DEY								
STY P1_PORT ; 0
	
LDX #$08
btnNext:
	LDA P1_PORT				; 	40 released, 41 pressed
	AND #%00000011				;	Fix for non-standard / famicom expansion controllers
	CMP #%00000001				;	* Improved thanks to Tokumaru
	BCC btnReleased				; 	if carry clear skip ahead
		CLC				;	carry always set for pressed, clear it
		INC $3F, x			;	handle frameCount, 00 for onPress, 00-7F for pressed
		BPL btnDone			;	if 00-7F, skip ahead
			DEC $3F, x		;	if 80, DEC to 7F forever
			BNE btnDone		;	branch always btnDone
	btnReleased:
	LDY #$FF
	LDA $3F, x				;	load previous state
	BMI btnWasReleased
		DEY; FE				;	decrement to FE if it was pressed last frame
	btnWasReleased:
	TYA		
	STA $3F, x			        ;	store FF if released, FE if onRelease
	btnDone:
	DEX
BNE btnNext
So, it uses 8 bytes of zero page memory, one for each button. Uh, Why?

Well, it has button states like onRelease, released, onPress, and pressed with an incrememted frameCount of 0-127. FE is on release, FF is released, 00 is onPress, and it counts 00-7F as a pressed frameCount. You can determine all of these states by loading the button byte into the X or Y register and the branch commands. Consider the following...

Code: Select all

LDX p1B 

BEQ / BNE	Test and branch onPress, as it is 0
BPL		Triggers on button pressed, including 00 as it is positive and will not kick the negative flag
BMI		Triggers on button released, and if you INX and check for equality with BEQ or BNE, you can get onRelease
Note that no accumulators were harmed in the loading of this button state! All of this can be done with X or Y.

The general idea is to sacrifice 7 bytes and some cycles to ease and simplify button state testing and save cycles later in the code, as well as preserve the accumulator when doing so. The button pressed frameCount can be super helpful as well with CPX or CPY.

So my goal is to just fix this loop to not specifically use #$40 and #$41. I guess i'll just AND #%00000001 after i poll the button and move on from there, i think that's the best way to go?

EDIT- Applied fix to use bit 0 and/or bit 1 and updated this code. If anyone knows why this wouldn't work, please let me know!
Last edited by Controllerhead on Thu Apr 16, 2020 7:21 am, edited 12 times in total.
Image

User avatar
aa-dav
Posts: 92
Joined: Tue Apr 14, 2020 9:45 pm
Location: Russia

Re: Is it safe to assume the values #$40 and #$41 for NTSC button presses?

Post by aa-dav » Thu Apr 16, 2020 1:29 am

Like in example code you can just shift zero bit of accumulator into carry flag via "LSR A" and do branch on carry.

User avatar
Controllerhead
Posts: 103
Joined: Tue Nov 13, 2018 4:58 am
Location: $4016
Contact:

Re: Is it safe to assume the values #$40 and #$41 for NTSC button presses?

Post by Controllerhead » Thu Apr 16, 2020 1:54 am

aa-dav wrote:
Thu Apr 16, 2020 1:29 am
Like in example code you can just shift zero bit of accumulator into carry flag via "LSR A" and do branch on carry.
I am reading all of the info provided to determine if using bit 0 after polling the controller is safe... it seems to be?
Image

User avatar
aa-dav
Posts: 92
Joined: Tue Apr 14, 2020 9:45 pm
Location: Russia

Re: Is it safe to assume the values #$40 and #$41 for NTSC button presses?

Post by aa-dav » Thu Apr 16, 2020 2:12 am

Controllerhead wrote:
Thu Apr 16, 2020 1:54 am
aa-dav wrote:
Thu Apr 16, 2020 1:29 am
Like in example code you can just shift zero bit of accumulator into carry flag via "LSR A" and do branch on carry.
I am reading all of the info provided to determine if using bit 0 after polling the controller is safe... it seems to be...
Yes, it's ok.
Bit 1 may be concern if you want to get status of extension controller on Famicom (in they do it in wiki article), but I think it is not important.

User avatar
rainwarrior
Posts: 7824
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: Is it safe to assume the values #$40 and #$41 for NTSC button presses?

Post by rainwarrior » Thu Apr 16, 2020 2:20 am

Bit 1 is more or less universally supported/expected for Famicom software, as expansion controllers are very commonly preferred to the built in ones.

The NES on the other hand will never put anything on that bit, and some games made for North America or Europe will ignore it.

User avatar
Controllerhead
Posts: 103
Joined: Tue Nov 13, 2018 4:58 am
Location: $4016
Contact:

Re: Is it safe to assume the values #$40 and #$41 for NTSC button presses?

Post by Controllerhead » Thu Apr 16, 2020 2:50 am

rainwarrior wrote:
Thu Apr 16, 2020 2:20 am
Bit 1 is more or less universally supported/expected for Famicom software, as expansion controllers are very commonly preferred to the built in ones.
Ok, this will work if Either bit 0 or bit 1 are activated, but not both. It will break if they are both set. Will the Famicom or anything else ever trigger both bit 0 and bit 1?

If so i can add more correction code, but i don't want to if i don't have to....

Code: Select all

LDA P1_PORT		;	40 released, 41 pressed
AND #%00000011		;	Fix for non-standard controllers
LSR 			;	Fix for famicom expansion controllers
ADC #$FF 		;	FF released, 00 pressed
EDIT: Here is a fix if both are set

Code: Select all

LDA P1_PORT		;	40 released, 41 pressed
AND #%00000011		;	Fix for non-standard controllers
LSR 			;	Fix for famicom expansion controllers
ADC #$00		;	Add the carry bit, becomes #%00000010 if both are set, #%00000001 if either are set			
LSR			;	Fix if BOTH bit 0 and bit 1 are set
ADC #$FF 		;	FF released, 00 pressed
Last edited by Controllerhead on Thu Apr 16, 2020 3:07 am, edited 1 time in total.
Image

User avatar
aa-dav
Posts: 92
Joined: Tue Apr 14, 2020 9:45 pm
Location: Russia

Re: Is it safe to assume the values #$40 and #$41 for NTSC button presses?

Post by aa-dav » Thu Apr 16, 2020 3:03 am

Controllerhead wrote:
Thu Apr 16, 2020 2:50 am
rainwarrior wrote:
Thu Apr 16, 2020 2:20 am
Bit 1 is more or less universally supported/expected for Famicom software, as expansion controllers are very commonly preferred to the built in ones.
Ok, this will work if Either bit 0 or bit 1 are activated, but not both. It will break if they are both set. Will the Famicom or anything else ever trigger both bit 0 and bit 1?

If so i can add more correction code, but i don't want to if i don't have to....

Code: Select all

LDA P1_PORT		;	40 released, 41 pressed
AND #%00000011		;	Fix for non-standard controllers
LSR 			;	Fix for famicom expansion controllers
ADC #$FF 		;	FF released, 00 pressed
Seems wrong for me.
Try this:

Code: Select all

AND #%011
BNE ... ; path with button on
; path with button off
Instead of adding just load const to A in paths.

Pokun
Posts: 1492
Joined: Tue May 28, 2013 5:49 am
Location: Hokkaido, Japan

Re: Is it safe to assume the values #$40 and #$41 for NTSC button presses?

Post by Pokun » Thu Apr 16, 2020 3:07 am

Controllerhead wrote:
Thu Apr 16, 2020 2:50 am
Will the Famicom or anything else ever trigger both bit 0 and bit 1?
If you press buttons on both internal and external controllers at the same time. See this.
If you are doing controller reading in an unorthodox way, you might want to have it tested properly on various system setups.


Bit 1 is important to the player. If the game doesn't use the expansion port for anything else, I'd rather want to be able to use an arcade stick or other external controller with the game.

User avatar
Controllerhead
Posts: 103
Joined: Tue Nov 13, 2018 4:58 am
Location: $4016
Contact:

Re: Is it safe to assume the values #$40 and #$41 for NTSC button presses?

Post by Controllerhead » Thu Apr 16, 2020 3:15 am

Pokun wrote:
Thu Apr 16, 2020 3:07 am
If you are doing controller reading in an unorthodox way, you might want to have it tested properly on various system setups.
I absolutely agree. I own an NTSC american toaster and toploader with an original 2013 famicom everdrive N8 w the Gyromite pin adapter, a standard pad and a dogbone. that is all i have. It works on them. When the time comes, i'd love some help!
Pokun wrote:
Thu Apr 16, 2020 3:07 am
Bit 1 is important to the player. If the game doesn't use the expansion port for anything else, I'd rather want to be able to use an arcade stick or other external controller with the game.
I have added support for it thanks to this thread! You guys are awesome =)
Pokun wrote:
Thu Apr 16, 2020 3:07 am
If you press buttons on both internal and external controllers at the same time.
Very well. I have added code to deal with it in case the situation arises. Thanks for the heads up!
Last edited by Controllerhead on Thu Apr 16, 2020 3:53 am, edited 1 time in total.
Image

User avatar
Controllerhead
Posts: 103
Joined: Tue Nov 13, 2018 4:58 am
Location: $4016
Contact:

Re: Is it safe to assume the values #$40 and #$41 for NTSC button presses?

Post by Controllerhead » Thu Apr 16, 2020 3:30 am

aa-dav wrote:
Thu Apr 16, 2020 3:03 am
Seems wrong for me.
It isn't. 0 stays 0. Whether the controller read value is 1, 2, or 3; it becomes 1 with an empty carry, or 0 with a carry in every situation =)

Code: Select all

LDA P1_PORT		;	40 released, 41 pressed
AND #%00000011		;	Fix for non-standard controllers
LSR 			;	Fix for famicom expansion controllers
ADC #$00		;	Add the carry bit, becomes #%00000010 if both are set, #%00000001 if either are set			
LSR			;	Fix if BOTH bit 0 and bit 1 are set
ADC #$FF 		;	FF released, 00 pressed
Image

Post Reply