joypad management in PVSnesLib - state sometimes reset

Discussion of hardware and software development for Super NES and Super Famicom.

Moderator: Moderators

Forum rules
  • For making cartridges of your Super NES games, see Reproduction.
Post Reply
hoit
Posts: 21
Joined: Sun Dec 24, 2017 10:16 am

joypad management in PVSnesLib - state sometimes reset

Post by hoit » Mon Mar 25, 2019 1:32 pm

Hello,

Still with PVSneslib, i would like to run with main sprite when right key is pressed twice.

I saw that when you keep button pressed, its state is sometimes reset.

This minimal code reproduce issue :

Code: Select all

//#include <snes.h>
#include "snes/console.h"
#include "snes/interrupt.h"
#include "snes/pad.h"

int main(void)
{
	consoleInit();	
	unsigned short pad0;
	
	//setMode(BG_MODE1,0);
	//bgSetDisable(1);
	//bgSetDisable(2);
	//setScreenOn();
	
	while(true)
	{
		pad0 = padsCurrent(0);
		if (pad0 & KEY_DOWN) 
		{
			consoleNocashMessage("PRESSED\r\n");
		}
		else
			consoleNocashMessage("RELEASED\r\n");
		
		WaitForVBlank();
	}
	return 0;
}
If you check console in no$sns, you will find "released" lines between "pressed"
I checked in pvsneslib how is managed pads and scanPads function which give state for pad0 = padsCurrent(0); is called during VBlank,

Function is wrote in asm and i am not familiar with it :

Code: Select all

;---------------------------------------------------------------------------------
; void scanPads(void)
scanPads:
	php
	phb
	phy
	
	sep	#$20                                   ; change bank address to 0
	lda.b	#$0
	pha
	plb
	
	rep	#$20                                   ; copy joy states
	ldy	pad_keys
	sty	pad_keysold
	ldy	pad_keys+2
	sty	pad_keysold+2
	
;-:	lda	REG_SLHV                                   ; wait until past lines 224,225
;	lda	REG_OPHCT
;	cmp	#224
;	beq	-
;	cmp	#225
;	beq	-

-:	lda	REG_HVBJOY                             ; wait until joypads are ready
	lsr
	bcs -

	lda	REG_JOY1L                              ; read joypad register #1
	bit	#$0F                                   ; catch non-joypad input
	beq	+                                      ; (bits 0-3 should be zero)
	lda.b	#$0
+	sta	pad_keys                               ; store 'current' state
	eor	pad_keysold                            ; compute 'down' state from bits that
	and	pad_keys                               ; have changed from 0 to 1
	sta	pad_keysrepeat                         ;

	lda	REG_JOY2L                              ; read joypad register #2
	bit	#$0F                                   ; catch non-joypad input
	beq	+                                      ; (bits 0-3 should be zero)
	lda.b	#$0
+	sta	pad_keys+2                             ; store 'current' state
	eor	pad_keysold+2                          ; compute 'down' state from bits that
	and	pad_keys+2                             ; have changed from 0 to 1
	sta	pad_keysrepeat+2                       ;

	ply
	plb
	plp
	rtl
i tried to compare it with other implementation sample but my level doesn't permit to say if it is correct or not.

Can you say me if you think something is wrong or if it doesn't come from this function ?

If you have any other idea that could explain this issue, i will be happy to hear clues :)

Thanks for your help

hoit
Posts: 21
Joined: Sun Dec 24, 2017 10:16 am

Re: joypad management in PVSnesLib - state sometimes reset

Post by hoit » Tue Mar 26, 2019 11:54 am

I add few informations. This is the main.c file generated to asm file, juste before using wla:

Code: Select all

.include "hdr.asm"
.accu 16
.index 16
.16bit
.define __main_locals 2
.section ".text_0x0" superfree
main:
.ifgr __main_locals 0
tsa
sec
sbc #__main_locals
tas
.endif
jsr.l consoleInit
__local_2:
lda.l pad_keys + 0
sta -2 + __main_locals + 1,s
and.w #1024
sta.b tcc__r0
lda.b tcc__r0 ; DON'T OPTIMIZE
bne +
brl __local_0
+
pea.w :__tccs_L.5
pea.w __tccs_L.5 + 0
jsr.l consoleNocashMessage
tsa
clc
adc #4
tas
bra __local_1
__local_0:
pea.w :__tccs_L.6
pea.w __tccs_L.6 + 0
jsr.l consoleNocashMessage
tsa
clc
adc #4
tas
__local_1:
jsr.l WaitForVBlank
bra __local_2
lda.w #0
sta.b tcc__r0
__local_3:
.ifgr __main_locals 0
tsa
clc
adc #__main_locals
tas
.endif
rtl
.ends
.ramsection "ram.data" bank $7f slot 3
__local_dummy.data dsb 1
.ends
.section ".data" superfree
__local_dummy.data: .db 0
.ends
.section ".rodata" superfree
__tccs_L.5: .db $50,$52,$45,$53,$53,$45,$44,$d,$a,$0
__tccs_L.6: .db $52,$45,$4c,$45,$41,$53,$45,$44,$d,$a,$0
.ends



.ramsection ".bss" bank $7e slot 2
__local_dummybss dsb 1
.ends
Is it possible that it is a bug while generating this one ?
I try to locate where the bug comes from, if it is in PVSnesLib or in tool used after to build the rom.

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

Re: joypad management in PVSnesLib - state sometimes reset

Post by lidnariq » Tue Mar 26, 2019 12:13 pm

hoit wrote:-: lda REG_HVBJOY ; wait until joypads are ready
lsr
bcs -
Checking that [$004212] & $01 is clear at the start of your function does not mean that it will remain clear when you actually read the registers, especially if you execute this code immediately after waiting for vblank.

That's what gave me problems here.

Nicole
Posts: 218
Joined: Sun Mar 27, 2016 7:56 pm

Re: joypad management in PVSnesLib - state sometimes reset

Post by Nicole » Tue Mar 26, 2019 12:54 pm

In other words, have two loops instead of one: wait until it's set, then wait until it's clear.

hoit
Posts: 21
Joined: Sun Dec 24, 2017 10:16 am

Re: joypad management in PVSnesLib - state sometimes reset

Post by hoit » Thu Mar 28, 2019 3:15 am

I hoped it was only a line to change!
I need to learn 65816 asm to do this because i don't know how to implement it.

Thanks for you help

Nicole
Posts: 218
Joined: Sun Mar 27, 2016 7:56 pm

Re: joypad management in PVSnesLib - state sometimes reset

Post by Nicole » Thu Mar 28, 2019 8:22 am

Here's the change you need to make. This:

Code: Select all

-:   lda   REG_HVBJOY                             ; wait until joypads are ready
   lsr
   bcs -
needs to be:

Code: Select all

-:   lda   REG_HVBJOY                             ; wait until joypads are being read
   lsr
   bcc -

-:   lda   REG_HVBJOY                             ; wait until joypads are ready
   lsr
   bcs -

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

Re: joypad management in PVSnesLib - state sometimes reset

Post by lidnariq » Thu Mar 28, 2019 9:59 am

I think I'd actually recommend ignoring the VBlank bit altogether and just synchronizing to the AutoRead bit instead...

hoit
Posts: 21
Joined: Sun Dec 24, 2017 10:16 am

Re: joypad management in PVSnesLib - state sometimes reset

Post by hoit » Fri Mar 29, 2019 3:50 am

Thanks for these informations.
I juste tried this code but my issue is still existing : i get few release states when button is pressed.

So i investigated on the second solution to understand (with autoread bit in NMI) and it seems to be already implemented in the lib :

I saw this in ConsoleInit() function (the first function to call in program) :

// enable NMI, enable autojoy
REG_NMITIMEN = INT_VBLENABLE | INT_JOYPAD_ENABLE;


and INT_JOYPAD_ENABLE is declared like that :
#define INT_JOYPAD_ENABLE (1)
Joypad Enable (0=Disable, 1=Enable Automatic Reading of Joypad)


Do you have any other idea ? :)

Post Reply