1541ultimate icon indicating copy to clipboard operation
1541ultimate copied to clipboard

U64E-II Paddle registers can only be read from one port.

Open grue74 opened this issue 8 months ago • 3 comments

I'm currently developing support for 2nd fire button for a game. 2nd button is connected to the $d419 register.

I understand that paddle override setting at Sid Addressing is changing how the pot x/y is read.

my test code is:

10 print peek (54297):goto 10

Paddle Override enabled:

I have joystick in port 2, when I press the 2nd button connected to Pot X the output is just rolling 255

Paddle Override disabled:

I get 0 values when I have pressed the 2nd button down, just like it should be.

When I move the controller into port 1 the results are reversed.

Paddle Override seems to change the port which is currently read.

I checked from the original c64 schematics that paddle lines are shared between ports 1 and 2 and it shouldn't matter on which port you have the paddles connected.

Am I doing something wrong, or is this a firmware bug or even a feature that it should work like this?

grue74 avatar Aug 25 '25 11:08 grue74

Everything seems to be OK. To read the paddle from both control ports, you need to specify which port should currently use the paddle input, as it's common to both. Maybe this code will explain it a bit.

;*** Driver for 3-button Joysticks ***
*                       = $0801
                        byte            $0D, $08, $00, $00, $9E, $32, $30, $36, $34, $3A, $89, $00, $00, $00
;
*                       = $0810
;1- for Control Port 2 and 1 (two joysticks)
;0- for Control Port 2 only (one joystick)
number_joysticks        = 1
;for Control Port 2 and 1, save Control Ports 2 and 1 values to temp_cp and temp_cp+1
;for Control Port 2 only, save Control Port 2 value to temp_cp
temp_cp                 = $0400
;bit-0 up
;bit-1 down
;bit-2 left
;bit-3 right
;bit-4 fire
;bit-5 fire 2 (Pot-X)
;bit-6 fire 3 (Pot-Y)
;bit-7 is unused and set to HI
;
                        sei
;
                        ldx             #number_joysticks
;
                        lda             $dc02                   ;get current value of DDR A
                        sta             temp_ddr_a              ;save it away
;
                        lda             #%11000000              ;
                        sta             $dc02                   ;set Port A for input
;
                        lda             #%01000000              ;set Paddle A / Control Port 1
                        cpx             #$01                    ;how many ports will be read?
                        beq             main_loop               ;read both Control Ports, 2 and 1
;
set_paddle_b            lda             #%10000000              ;set Paddle B / Control Port 2
;
main_loop               sta             $dc00                   ;%01xxxxxx = Paddles A in Control Port 1, %10xxxxxx = Paddles B in Control Port 2
;
                        ldy             #$80                    ;wait
wait                    nop                                     ;
                        dey                                     ;
                        bne             wait                    ;
;
                        lda             #%00000000              ;set bit-5/6 to LO, for button 2/3 as released
                        sta             button_2+1              ;
                        sta             button_3+1              ;
;
pot_x                   lda             $d419                   ;read Pot-X register (range $ff-00 / button 2 released or pressed)
;
                        cmp             #$80                    ;
                        bcs             pot_y                   ;if Pot-X is >= #$80 that means button 2 is released
;
                        lda             #%00100000              ;set bit-5 to HI, because button 2 is pressed (Pot-X is <$80)
                        sta             button_2+1              ;
;
pot_y                   lda             $d41a                   ;read Pot-Y register (range $ff-00 / button 3 released or pressed)
;
                        cmp             #$80                    ;
                        bcs             end                     ;if Pot-Y is >= #$80 that means button 3 is released
;
                        lda             #%01000000              ;set bit-6 to HI, because button 3 is pressed (Pot-Y is <$80)
                        sta             button_3+1              ;
;
end                     lda             $dc00,x                 ;read Control Port
                        ora             #%11100000              ;set bit-5/6 to HI, button 2/3 as released; bit-7 is unused and set to HI
button_2                eor             #%00100000              ;add current Pot-X state to bit-5 (if button 2 is pressed then value 1 reversed HI to LO)
button_3                eor             #%01000000              ;add current Pot-Y state to bit-6 (if button 3 is pressed then value 1 reversed HI to LO)
                        sta             temp_cp,x               ;save Control Port 2 values to temp_cp, or CP2 to temp_cp and CP1 to temp_cp+1
;
                        dex                                     ;all Control Ports done?
                        bpl             set_paddle_b            ;no
;
                        lda             temp_ddr_a              ;
                        sta             $dc02                   ;restore previous value of DDR A
;
                        cli
;
                        rts
;
temp_ddr_a              byte            $00
;

radius75 avatar Aug 25 '25 12:08 radius75

Ok. thank you for this!

grue74 avatar Aug 25 '25 13:08 grue74

This example of additional joystick buttons is based on: https://www.devili.iki.fi/Computers/Commodore/C64/Programmers_Reference/Chapter_6/page_346.html

radius75 avatar Aug 26 '25 12:08 radius75