Jump to content
  • entries
    657
  • comments
    2,692
  • views
    897,854

Take 4


SpiceWare

2,650 views

Just discovered an obscure bug today! David Mrozek was having a problem with the lower-right shield being flipped.

In this section of the code:

KernelGameBottomCode SUBROUTINE
	sta WSYNC
	cpy BLyOddRow; 3  4
	php			 ; 3  7
	cpy M1yOddRow; 3 10
	php			 ; 3 13
	cpy M0yOddRow; 3 16
	php			 ; 3 19
	ldx #ENABL	  ; 2 21
	txs			 ; 2 22
	READ_TWO_PADDLES;23 45
	ldx #8		  ; 2 47
	sta REFP1	; 3 50   <---- should have been stx REFP1
	ldx #0		  ; 2 52
	stx REFP0	; 3 55
	dey			 ; 2 57
	lda Player4X	; 3 60
	sec			 ; 2 62
	sta WSYNC	; 3 65
 

Just below the macro READ_TWO_PADDLES, the ldx #8, sta REFP1 should have been ldx #8, stx REFP1.

 

The macro READ_TWO_PADDLES is

		MAC READ_TWO_PADDLES
	ldx Paddles2Read ; 21-23  3
	lda INPT0,x	  ; |	  4
	bpl .save1	; |	  2 3
	.byte $2c		; |	  4 0
.save1  sty Paddle1,x	; |	  0 4
	lda INPT2,x	  ; |	  4
	bpl .save2	; |	  2 3
	.byte $2c		; |	  4 0
.save2  sty Paddle3,x	; |	  0 4
					 ; +-23 worse case scenerio
	ENDM
 

 

so the last data value read into A would have been either INPT2 or INPT3 depending which 2 paddles were being read for the current frame (one frame reads paddles 0 & 2, the next frame reads paddles 1 & 3).

 

INPT2 and INPT3 only return a value in bit 7, the other bits are undefined, and as I understand it normally return the same bits as the address.

 

INPT2 = address $A, INPT3 = address $B $A=%00001010, $B = %00001011. The 8 used to flip the sprite = %00001000, so the "normally returns same bits as address" explains why it works for most people as the bit for 8 is turned on for both $A and $B.

 

ROMs:

mm20071129NTSC.bin

mm20071129PAL.bin

 

Source:

Medieval_Mayhem.zip

  • Thanks 1

6 Comments


Recommended Comments

INPT2 = address $A, INPT3 = address $B $A=%00001010, $B = %00001011. The 8 used to flip the sprite = %00001000, so the "normally returns same bits as address" explains why it works for most people as the bit for 8 is turned on for both $A and $B.

 

Bit 6 of INPTx will always be zero. Bits 0-5 of any TIA register will, with most cartridges, read as the last thing on the data bus. When using the ZP addressing mode, the last thing on the data bus will be the address. When using absolute addressing mode to read a TIA register, the last thing on the data bus will be the high byte of the address (can be useful for setting TIA registers without disturbing any 6502 registers).

 

When doing a read via ZP,x or ZP,y addressing, the 6502 will actually perform two reads. The first read will be at the specified address (before indexing); the second will be the indexed address. If X=1, "LDA $0A,X" will do a read of INPT2 (yielding $0A or $8A), ignore that value, and then a read of address $0B (again yielding $0A or $8A, since that's what was last on the data bus). If X=$80, then "LDA $80,X" will perform a read of address $8A (which is RAM), and then a read of $0A (yielding INPT2 on the MSB, zero on the next bit, and 6 bits from whatever was in $8A).

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