Jump to content





Take 4

Posted by SpiceWare, in Medieval Mayhem 29 November 2007 · 1,460 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.

Attached Files






Ah, David is reviewing more homebrews. :)
  • Report

Ah, David is reviewing more homebrews. ;)

:)
  • Report
David has confirmed that the new build is working properly on his system.
  • Report

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).
  • Report

Ah, David is reviewing more homebrews. :)

he has ;)
  • Report
Heya! Congratulations!

I just saw that Star Fire got a "B" as well today! :)
  • Report

Search My Blog

Recent Entries

Recent Comments

Latest Visitors

0 user(s) viewing

0 members, 0 guests, 0 anonymous users