Jump to content
IGNORED

Vertical bars appearing at the screen sides


Danjovic

Recommended Posts

I am working on the SNES function for my homebrew joystick tester and two bars are appearing on the sides of the screen (see attached picture)

 

I have tracked down the problem to the instruction  rol INPT5  and can I think of a workaround, but I could not understand why do this would affect the  TIA (at least in Stella emulator).

Any thoughts?

 

 

 

     asm
     lda #$0          ; 2 clock down, latch down
     sta SWCHA       ; 4 make both latch and clock down
     ldx #$01         ; 2 clock up, latch down
     ldy #16          ; 2 16 bits
     lda #$ff         ; 2 Initialize with no button pressed
     sta snesButtonsL ; 5 if necessary to gain a few microseconds
     sta snesButtonsH ; 5 from latch/clk down till first bit sample
     lda #$0          ; 2
SMPSN0:          
     rol INPT5        ; 5 sample data
     stx SWCHA        ; 5 clock up
     ror snesButtonsL ; 5 take some time assume 
     ror snesButtonsH ; 5 
     sta SWCHA        ; 4 clock down 
     dey              ; 2 next bit
     bne  SMPSN0     ; 2 repeat 
     
     stx SWCHA        ; 5 clock up, next edge  to read 17th bit
     rol INPT5        ; 5 sample data, 17th bit on Carry
     rol bit17        ; 5 temp1 bit 0 contains 17th bit  value. should be zero for SNES
     lda #$03         ; 2 both clock and latch up
     sta SWCHA        ; 5 finish sampling
end

 

image.thumb.png.90792de985d443f6d63cdead4922ce33.png

 

Link to comment
Share on other sites

Thanks ! that should explain the vertical bars, but I went down on another rabbit hole, lol!!

 

My workaround was to read the INPT5 to register A, then rotate register A, but it did not worked the way I expected because I came across a really strange behavior, probably in the  emulation.

 

Let me explain better ( reducing the code to a minimum) :

 

First the code without the workaround. At the end of execution the state of the snesButton variables will follow the state of the fire button input, as expected because I am shifting in the logic state of the fire button.
       
     for the button released  
     snesButtonsL ; = %11111111
     snesButtonsH ; = %11111111         
    
     for the button pressed  
     snesButtonsL ; = %00000000
     snesButtonsH ; = %00000000

 

     lda #$c3         ; initialize
     sta snesButtonsL ; = %11000011
     sta snesButtonsH ; = %11000011
SMPSN0:    
     rol INPT5        ;
     ror snesButtonsL ;
     ror snesButtonsH ;  
     dey              ;
     bne  SMPSN0      ;


  On the other hand, with my workaround,   no matter the state of the fire button input I always have the outputs like only one shift was performed, just once   


     snesButtonsL ; = %10000111

     snesButtonsH ; = %11000010    

     lda #$c3         ; initialize
     sta snesButtonsL ; = %11000011
     sta snesButtonsH ; = %11000011
SMPSN0:     
     lda INPT5        ;      WORKAROUND
     rol a
     ;rol INPT5        ; commented
     ror snesButtonsL ;
     ror snesButtonsH ;  
     dey              ;
     bne  SMPSN0      ;

The most bizarre is that the state of these variables won't be different even if I do something like this
 

     lda #$c3         ; initialize
     sta snesButtonsL ; = %11000011
     sta snesButtonsH ; = %11000011
SMPSN0:    
     lda, #$ff
     rol a
     ror snesButtonsL ;
     ror snesButtonsH ;  
     dey              ;
     bne  SMPSN0      ;

 

This behaviour is teh same on either Stella and Z26..  :(

 

Link to comment
Share on other sites

Well at the end I wrote the sampling routine in Basic.

 

__sampleSNES
     rem initialize ports
     
     SWCHB{2} = 0 : rem disable transistors Q6 (for 7800)
     SWCHB{4} = 0 : rem disable transistors Q5 (for 7800)

     SWACNT = 3   : rem enable pins UP/DOWN to work as outputs
     SWCHA  = 3   : rem make pins clock (UP) and latch (DOWN) to go high

     rem sample first 8 bits 
     temp1 = 8
__sampleH
     SWCHA = 0    : rem latch down, clock down
     snesButtonsH = snesButtonsH * 2
     if !joy1fire then snesButtonsH{0} = 1
     SWCHA = 1    : rem latch down, clock up (next bit)
     temp1 = temp1 - 1
     if temp1 > 0 then goto __sampleH

     rem sample next 8 bits  
     temp1 = 8
__sampleL
     SWCHA = 0    : rem latch down, clock down
     snesButtonsL = snesButtonsL * 2
     if !joy1fire then snesButtonsL{0} = 1
     SWCHA = 1    : rem latch down, clock up (next bit)
     temp1 = temp1 - 1
     if temp1 > 0 then goto __sampleL

     rem sample 17th bit 
__bit17
     if !joy1fire then bit17{7} = 1 else bit17{7} = 0

     SWCHA  = 3   : rem latch up, clock up


  return

 

Link to comment
Share on other sites

18 hours ago, Danjovic said:

[...]
  On the other hand, with my workaround,   no matter the state of the fire button input I always have the outputs like only one shift was performed, just once   

[...]

If you were running this code within bB, "a" is actually a defined symbol that references some ZP memory. If that's the case, using just "rol" (implicitly referencing the accumulator) instead of "rol a" would do what you want.

 

  • Thanks 1
Link to comment
Share on other sites

  • 2 weeks later...
2 hours ago, Danjovic said:

Hi @RevEng, I have tested the code with rol and it worked fine on emulator, thanks!

On the other hand, it did not worked on the real console either with the assembly code or with the Basic code. I should investigate it further with the aid of an oscilloscope.

Binaries that work in emulators but not on hardware are valuable for emulator authors to improve emulator accuracy.

Have you checked it on the Gopher emulator?  If not, possibly worth doing so. I would be happy to check, if you wish - I'd need a binary.

 

  • Like 1
Link to comment
Share on other sites

In fact I was dumb enough to plug the cable in the left port instead of the right port!

 

On the go, I have captured some insteresting waveforms:

 

The SNES reading pulses, followed by two of the row selection pulses to read the keyboard

Yellow is CLOCK (UP) and blue is LATCH (DOWN)

image.png.33d93317f4c67322cab323681035dbac.png

 

The whole SNES sampling time, marked by LATCH signal low, takes 426us. There are 17 rising edges on the clock signal, 12 for the buttons and the last 5 for reading the ID of the controller (to allow its detection)

image.png.1479d61ed74571aeefe7ff0797cce1a3.png

 

The keyboard is read every frame (16.7ms, rounded to 17 by the resolution of the scope cursor)

image.png.12c36ed42f46d4cc5f9c6be9a861ba42.png

 

One thing that makes me wonder. As the duration of the LATCH signal coincides with the waiting required to read the POT lines (~400us) it should be possible to use some optimization to gain some machine cycles by using the following algorithm:

 

ROW123 LOW

Wait400us

read FIRE, POT1, POT2

ROW123 HIGH

 

ROW456 ->LOW

SAMPLE SNES CONTROLLER

read FIRE, POT1, POT2

ROW456 ->HIGH

 

ROW789 LOW

Wait400us

read FIRE, POT1, POT2

ROW789 HIGH

 

ROW*0# LOW

Wait400us

read FIRE, POT1, POT2

ROW*0# HIGH

 

@Andrew Davie, here follows the source code and the binary. I am still working on the detection logic.

 

JK2tester.basJK2tester.bas.binkeyread.asm

 

 

Edited by Danjovic
added a missing file
Link to comment
Share on other sites

1 hour ago, Danjovic said:

 

@Andrew Davie, here follows the source code and the binary. I am still working on the detection logic.

 

Had a quick look in Gopher.

267 scanlines is rather unusual.  This will be unsuitable for a PAL TV.

It "ran" on all my emulators and hardware (harmony cart, NTSC console) - I see a screen as shown...

 

1206174233_ScreenShot2022-03-19at11_56_21pm.thumb.png.9182332dd598ff3e4f5480f4915933e3.png

 

So I'm not sure what you meant by "not working"; I thought you meant you got nothing at all...

 

 

 

Edited by Andrew Davie
Link to comment
Share on other sites

1 hour ago, Andrew Davie said:

So I'm not sure what you meant by "not working"; I thought you meant you got nothing at all..

Ok... a bit of context....

"not working" was a reference to a previous post where I used the "rol a" instruction on the inline assembly code  to shift in the data sent by the SNES controller, but Mike pointed me out that Batari Basic will take the "a" as the predefined variable and therefore I should use the implicit form of the rotation instruction "rol".

After doing that I was able to visualize on the emulator that the bits have been properly shifted in, by press "F" to emulate the 2nd trigger line on Stella.

I have then burned a EPROM and started to test the code on the real hardware, but plugged the cable by mistake on the left port instead of the right port and it looked like the code was not reading the button line.

 

2 hours ago, Andrew Davie said:

It "ran" on all my emulators and hardware (harmony cart, NTSC console) - I see a screen as shown...

To use the program press START and the program will read the difficulty keys as well as the Black/White switch to decide which combination of keyboard and controller should be tested.

With the color mode switch on position COLOR: Difficulty A means Joystick, B means Keyboard controller.

While the color mode switch set to B/W you enter the SNES test mode on right port, regardless of the state of Difficulty switches.

Some screenshots and more info here: https://hackaday.io/project/183582-wolf/log/204102-custom-atari-2600-test-cart

 

 

2 hours ago, Andrew Davie said:

267 scanlines is rather unusual.  This will be unsuitable for a PAL TV.

I am using a standard kernel plus an inline routine on the vblank to scan the keyboard controllers. I can't tell if the extra scanlines are being caused by such routine. I suppose we should have 263 scanlines, right ?  Can you point me a clue to fix that ?

 

Thanks!

 

 

 

 

Link to comment
Share on other sites

On 3/6/2022 at 12:36 PM, Danjovic said:

Thanks ! that should explain the vertical bars, but I went down on another rabbit hole, lol!!

 

My workaround was to read the INPT5 to register A, then rotate register A, but it did not worked the way I expected because I came across a really strange behavior, probably in the  emulation.

 

Let me explain better ( reducing the code to a minimum) :

 

First the code without the workaround. At the end of execution the state of the snesButton variables will follow the state of the fire button input, as expected because I am shifting in the logic state of the fire button.
       
     for the button released  
     snesButtonsL ; = %11111111
     snesButtonsH ; = %11111111         
    
     for the button pressed  
     snesButtonsL ; = %00000000
     snesButtonsH ; = %00000000

 


     lda #$c3         ; initialize
     sta snesButtonsL ; = %11000011
     sta snesButtonsH ; = %11000011
SMPSN0:    
     rol INPT5        ;
     ror snesButtonsL ;
     ror snesButtonsH ;  
     dey              ;
     bne  SMPSN0      ;


  On the other hand, with my workaround,   no matter the state of the fire button input I always have the outputs like only one shift was performed, just once   


     snesButtonsL ; = %10000111

     snesButtonsH ; = %11000010    


     lda #$c3         ; initialize
     sta snesButtonsL ; = %11000011
     sta snesButtonsH ; = %11000011
SMPSN0:     
     lda INPT5        ;      WORKAROUND
     rol a
     ;rol INPT5        ; commented
     ror snesButtonsL ;
     ror snesButtonsH ;  
     dey              ;
     bne  SMPSN0      ;

The most bizarre is that the state of these variables won't be different even if I do something like this
 


     lda #$c3         ; initialize
     sta snesButtonsL ; = %11000011
     sta snesButtonsH ; = %11000011
SMPSN0:    
     lda, #$ff
     rol a
     ror snesButtonsL ;
     ror snesButtonsH ;  
     dey              ;
     bne  SMPSN0      ;

 

This behaviour is teh same on either Stella and Z26..  :(

 

 

no idea what you're doing..

 

shouldn't the SMPSN0: be after the lda?

 

also do you know what the carry is at that point? (may not matter)

 

edit oh hell I just realized what you're doing. never mind (I'll go back to sleep now)

Edited by bogax
  • Haha 1
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...