Jump to content
  • entries
    17
  • comments
    28
  • views
    32,183

Reading Paddles


Omegamatrix

1,254 views

Normally paddles are read with a routine like this:

    bit    INPT0                 ;3  @3
    bmi    .paddleDone-1         ;2³ @5/6
    sty    padZero               ;3  @8
.paddleDone:
 

If the branch is taken it jumps between the opcode and operand of the 'sty padZero' instruction. The trick is to make the ram location of 'padZero' the same as an opcode that takes 2 cycles. That way the routine takes 8 cycles no matter what. There are several ram locations which could be chosen for 'padZero'. Some of the better ones include $EA (NOP opcode), $D8 (CLD opcode), $B8 (CLV opcode).

 

You need to have X or Y as a line counter to make that optimized routine work. For CAA (Circus AtariAge) I didn't have either X or Y available. I'm using Y to skipdraw two objects (each with a different scanline counter that gets loaded into Y). I'm also using X with LAX (indirect),Y to pre-load for an upcoming line when it gets busy in the kernel.

 

I looked for a way to make a paddle routine without using X or Y. I also required it to have constant cycles since a lot of places in the CAA kernel are already fully packed without a WSYNC... for several lines. An unique constraint of CAA allowed me to construct a routine without using X or Y. The constraint was I simply needed less than 128 samples to get the full range of movement for the seesaw:

 

blogentry-7074-0-87951200-1399754474_thumb.png

 

The routine essentially looks like this (for one paddle), with padZero pre-loaded to $7F:

    lda    #$7F                  ;2  @2
    cmp    INPT0                 ;3  @5
    adc    padZero               ;3  @8
    sta    padZero               ;3  @11
 

 

I don't care about bit 7. Only values 128-255 use bit 7, and I need only 118 samples. It can be set or cleared by the routine on different scanlines and that's okay. Ultimately I deal with the result like this:

    lda    #$7F
    eor    padZero
    asl
    lsr    ; clears carry too
    adc    #OFFSET_FOR_SEESAW
    sta    hposSeeSaw
 

Turning the paddle right moves the seesaw right, as it should be. :) I added a similar routine for reading 'padOne' as I'm reading both paddles every frame.

 

 

I've thought about reading paddles every other scanline or so, and alternating frames (read only one paddle per frame). In the end I decided to write a kernel for maximum resolution. In future blog entries I might comment on some the trials and tribulations I had with early HMOVE's and paddle reads, and how it affected design decisions.

  • Like 2

2 Comments


Recommended Comments

Impressive! Medieval Mayhem uses a shorter range as well, 0-74

That's a nice range to deal with. You have more options of when to read the paddles in the kernel. I can't even begin sampling the paddles until a few lines after the last balloon row.

 

 

I was happy I found a solution that didn't use X and Y... partly because I needed it, but also because it was something different to what had been done before. I always like to do new stuff. :)

Link to comment
Guest
Add a comment...

×   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...