Jump to content


Recommended Posts

  • 1 month later...



Got some questions of course..


These things:

        lda INPT0         ; 3   - always 9
        bpl .save         ; 2 3
        .byte $2c         ; 4 0
.save   sty Paddle1       ; 0 3

I assume these are macros? Does DASM use these to insert the code whenever it finds READ_PADDLE...?


Also, this one and others don't appear to even be used- are they?


It looks like you are only using READ_TWO_PADDLES which is alternating between frames.


So do INPUTs have a positive value until their associated capacitor is completely discharged? If they are not discharged, the current y value will be stored in RAM for the appropriate player. When the value is zero (cap discharged), byte $2C will prevent subsequent y's from being stored for the player and the last y stored is the player position?.


And paddles are read between turning off VBLANK and the start of the kernal? Is VBLANK turned off a little earlier to account for this?


When are the paddle capacitors charged?


Is this a carefully timed routine? If so, what's the time?

Link to comment
Share on other sites

Yes, that's a macro. Macros start with MAC name and end with ENDM. DASM inserts the code between those statements anyplace it sees name. You can see that in the listing. The macro definition for READ_TWO_PADDLES:

     73 U0086					      MAC	read_two_paddles
     74 U0086					      ldx	Paddles2Read	; 21-23  3
     75 U0086					      lda	INPT0,x	; |	  4
     76 U0086					      bpl	.save1	; |	  2 3
     77 U0086					      .byte	$2c	; |	  4 0
     78 U0086				   .save1     sty	Paddle1,x	; |	  0 4
     79 U0086					      lda	INPT2,x	; |	  4
     80 U0086					      bpl	.save2	; |	  2 3
     81 U0086					      .byte	$2c	; |	  4 0
     82 U0086				   .save2     sty	Paddle3,x	; |	  0 4
     83 U0086							; +-23 worse case scenerio
     84 U0086					      ENDM

vs where it's used later in the program:

      0  f077					      READ_TWO_PADDLES		; reads the paddles
      1  f077		       a6 85		      ldx	Paddles2Read
      2  f079		       b5 38		      lda	INPT0,x
      3  f07b		       10 01		      bpl	.save1
      4  f07d		       2c		      .byte.b	$2c
      5  f07e		       94 81	   .save1     sty	Paddle1,x
      6  f080		       b5 3a		      lda	INPT2,x
      7  f082		       10 01		      bpl	.save2
      8  f084		       2c		      .byte.b	$2c
      9  f085		       94 83	   .save2     sty	Paddle3,x

In the definition snippet the U in U0086 means it's uninitialized (not in the ROM). In the program snippet the f077-f085 is the location the code was inserted, the a6 86, b5 38, etc the values the code compiles to.


I'd previously written a bunch of paddle macros, so included them when I copy/pasted the routines, but for that demo I only used the one as I was reading all 4 paddles (2 per frame).


From Stella Programmer's Guide:


12.1 Dumped Input Ports (INPT0 thru INPT3)

These four ports are used to read up to four paddle controllers. Each paddle controller contains an adjustable pot controlled by the knob on the controller. The output of the pot is used to charge a capacitor in the console, and when the capacitor is charged the input port goes HI. The microprocessor discharges this capacitor by writing a "1" to D7 of VBLANK then measures the time it takes to detect a logic one at that port. This information can be used to position objects on the screen based on the position of the knob on the paddle controller.

From the Paddles source:


        lda #$82   <-------- D7 = 1
        sta WSYNC
        sta VSYNC         ; 3    start vertical sync, D1=1
        sta VBLANK        ; 3  6 start vertical blank and dump paddles to ground

vs a joystick game:


        ldx #2    <------- D7 = 0
        stx WSYNC    
        stx VSYNC           ; 3  3
        stx VBLANK          ; 3  6


8. Input ports

A. General Description

There are 6 input ports on this chip whose logic state may be read on data line 7 with read addresses INPT0 through INPT5. These 6 ports are divided into two types, "dumped" and "latched". See Figure 8.

B. Dumped Input Ports (I0 through I3)

These 4 input ports are normally used to read paddle position from an external potentiometer-capacitor circuit. In order to discharge these capacitors each of these input ports has a large transistor, which may be turned on (grounding the input ports) by writing into bit 7 of the register VBLANK. When this control bit is cleared the potentiometers begin to recharge the capacitors and the microprocessor measures the time required to detect a logic 1 at each input port.

As long as bit 7 of register VBLANK is zero, these four ports are general purpose high impedance input ports. When this bit is a 1 these ports are grounded.

data line 7(or bit 7) is the "plus/minus" bit within a byte. If bit7 = 0 the value is positive, bit7 = 1 denotes negative.


Paddles are read during the kernel, not before it. For the demo the ReadLoop is a kernel - it's drawing the rainbow section of the screen. In a real game, instead of changing the background color, you'd be drawing the bricks in a breakout style game, drawing players in an Astroblast type game, etc.


The paddle capacitors start to charge as soon as you remove the ground. In Paddles that's at this point:


    ldx #0
    lda INTIM
    bpl VblankWait
    sta WSYNC
    sta HMCLR         ; clear hmoves for next time around
    stx VBLANK        ; turn on video output & remove paddle dump to ground  <-----------

I don't know what you mean by "carefully timed". What you're doing is taking a measure of how many scanlines worth of time it takes to recharge the capacitor, the time of which is controlled by how much the user has turned the paddle.

Link to comment
Share on other sites

  • 3 weeks later...
  • 7 months later...

I tried many examples trying to get paddles working in my sample code. I posted a new thread but I was hoping someone here could take a quick look..I know I am doing something wrong but I just can't see it, I need another pair of eyes. B-)





Link to comment
Share on other sites

  • 4 weeks later...

I have a question. Is it possible to read the paddles during overscan?


At the start of the kernel, you would write #$80 to VBLANK. This would enable the display as well as ground the capacitor. At the end of the kernel, you would write #$02 to VBLANK, disabling the display and allowing the capacitor to start charging up again. Then you could count some scanlines to check the position of the paddle in overscan, without having to do it in the kernel itself. This would obviously be used to prepare for the following frame.


Is that the way it would work?

Link to comment
Share on other sites

  • 1 year later...

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.

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.

  • Recently Browsing   0 members

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