This article is from the Apple II Programming FAQ, by Jeff Hurlburt with numerous contributions by others.
Only the high bit of these locations is valid. When the high bit of either location becomes 0 then the corresponding analog input has timed out. You will actually get more accurate results by reading them one after the other with the accumulator set to 8 bits wide and the index registers used to hold the counts (16 bits wide). This allows for a much faster loop, giving better resolution. Assuming that this routine is called from full native mode, the following code will do the trick: strobe equ $C070 ; analog input timing reset pdl0 equ $C064 ; analog input 0 pdl1 equ $C065 ; analog input 1 start php ; save processor status register phb ; and data bank register sep #%100000 ; make accumulator 8 bits wide lda #0 ; make data bank = 0 pha plb ldx #0 ; initialize the counters txy lda strobe ; strobe the timing reset loop1 inx ; increment pdl0 count lda pdl0 ; is high bit = 0? bmi loop1 ; no, keep checking lda strobe ; yes, strobe the timing reset again loop2 iny ; increment pdl1 counter lda pdl1 ; is high bit = 0? bmi loop2 ; no, keep checking plb ; yes, restore data bank plp ; and processor status register rts ; return to caller (could be RTL) Notice that the actual counting loops are only 9 cycles long. This gives the best possible resolution. You will need your counters to be 16 bits wide as the results will easily overflow the capacity of an 8 bit counter. Using memory locations as counters will only serve to slow the counting loop down. If X and Y contain valid data before entry, you will need to save them off to the stack and pull them back in after interpreting the joystick results. I have used this exact method to read the analog inputs on my Science Toolkit box which connects to the joystick port. The results have been extremely accurate (much more than would be needed for a game which reads the joystick). --email@example.com (System Administrator)