Page 1 of 1

Please help me figure out this WEIRD bug

Posted: Wed Sep 20, 2006 5:28 pm
by VanOccupanther
im trying to debug my states code.


Code: Select all

;y portion, y portion decimal, x portion, x portion decimal, delay, , , next state
.byte $01, $00, $01, $00, $78, $00, $00, $01  ;00 ;$78 == 120 == ~ 2 second delay
.byte $01, $00, $00, $00, $3c, $02, $00, $00  ;01 ;$3c == 60  == ~ 1 second delay

.byte $ff, %00010100, $ff, %00101011, $3c, $00, $00, $03  ;02
.byte $00, %11111011, $00, %00000000, $3c, $00, $00, $04  ;03
.byte $00, %00110010, $00, %10110101, $3c, $00, $00, $05  ;04
.byte $00, %00000000, $00, %11101100, $3c, $00, $00, $02  ;05

.byte $ff, %00000000, $01, %00000000, $3c, $00, $00, $07  ;06
.byte $00, %00000000, $01, %00000000, $3c, $00, $00, $08  ;07
.byte $01, %00000000, $01, %00000000, $3c, $00, $00, $09  ;08
.byte $ff, %00000000, $ff, %00000000, $3c, $00, $00, $0a  ;09
.byte $00, %00000000, $ff, %00000000, $3c, $00, $00, $0b  ;0a
.byte $01, %00000000, $ff, %00000000, $3c, $00, $00, $06  ;0b
state number $00 is the first line and so on..

What's happening is that at one point in the code, if i uncomment a 2 byte command (ldy #5), the one enemy on the screen, that is susposed to be a type 02 (starts at state 2 and continues to 3.. ) is some how turned into type 00. I checked, and the state values change from the 02 loop to the 00 loop when two more bytes are added to a part of the code.

What is happening? I'm so lost .

Posted: Wed Sep 20, 2006 5:30 pm
by Quietust
It's hard to debug code without actually seeing it...

Posted: Thu Sep 21, 2006 1:08 pm
by VanOccupanther
hi, im not sure what code you need. This is the part where uncommenting ldy #5 changes the ship from being state 2 to state 0.

Code: Select all

ship_responce:	;************
		;must give shipobject0 an address
		;must give shipnumber0 a value
		;************

				

		lda #<delays
		sta delays_low
		lda #>delays
		sta delays_high

		ldy shipnumber0

		lda (delays_low), y			;find what delay time is left in this state

		bne delay_not_zero
		
	;move into new state if delay = 0
		
		ldy #8
		lda (shipobject0_low), y		;load current type
		

		asl
		asl
		asl					;multiply by 8 because each state is 8 bits long

		

	;indexing into the next state value in states		

		
		adc #<states
		sta states_low
		lda #>states
		sta states_high	

		ldy #0

		lda (states_low), y			; a = y_portion
		sta (shipobject0_low), y

		iny

		lda (states_low), y			; a = y_portion_decimal
		sta (shipobject0_low), y

		iny

		lda (states_low), y			; a = X_portion
		sta (shipobject0_low), y
			
		iny
		lda (states_low), y			; a = x_portion_decimal
		sta (shipobject0_low), y		

		
		iny	;i = 4
		lda (states_low), y			; a = new delay time

		ldy shipnumber0
		sta (delays_low), y		;setting new delay time

		ldy #4

		iny	;i = 5			;setting life
		
;		ldy #5				;NOTE: when uncommented, this instruction makes state 02 work like state 00.
		iny	;i = 6
		iny 	;i = 7

		lda (states_low), y			; a = next_state
		sta look
		ldy #8
		sta (shipobject0_low), y		;change type to new state

		
		jmp ship_responce_end 
		

delay_not_zero:	tax
		dex					;decrease delay time by 1

		txa
		sta (delays_low), y					
		


				

ship_responce_end:
		rts
here is the levels data part, i fits in right above the state data in the first post.

Code: Select all

levels:
;ship y, type, ship x, wave #
.byte $28, $02, $90, $00
.byte $28, $00, $40, $01
.byte $28, $00, $28, $01
.byte $28, $00, $58, $02
.byte $28, $00, $88, $02
.byte $00, $00, $00, $ff

states:
;y portion, y portion decimal, x portion, x portion decimal, delay, , , next state
.byte $01, $00, $01, $00, $78, $00, $00, $01  ;00 ;$78 == 120 == ~ 2 second delay
.byte $01, $00, $00, $00, $3c, $02, $00, $00  ;01 ;$3c == 60  == ~ 1 second delay

.byte $ff, %00010100, $ff, %00101011, $3c, $00, $00, $03  ;02
.byte $00, %11111011, $00, %00000000, $3c, $00, $00, $04  ;03
.byte $00, %00110010, $00, %10110101, $3c, $00, $00, $05  ;04
.byte $00, %00000000, $00, %11101100, $3c, $00, $00, $02  ;05

.byte $ff, %00000000, $01, %00000000, $3c, $00, $00, $07  ;06
.byte $00, %00000000, $01, %00000000, $3c, $00, $00, $08  ;07
.byte $01, %00000000, $01, %00000000, $3c, $00, $00, $09  ;08
.byte $ff, %00000000, $ff, %00000000, $3c, $00, $00, $0a  ;09
.byte $00, %00000000, $ff, %00000000, $3c, $00, $00, $0b  ;0a
.byte $01, %00000000, $ff, %00000000, $3c, $00, $00, $06  ;0b
Look at the first line of the level data. See the first ship is susposed to be type 02, that means it should change states starting at 02. But when i uncomment that ldy #5 the ship somehow changes to starting at state 00. This is the only ship on wave #0 so it's the only one on the screen until it dies.

hope this helps

Posted: Thu Sep 21, 2006 1:28 pm
by Quietust
That's rather odd - "ldy #4 | iny | ldy #5" should behave exactly the same as "ldy #4 | iny" or "ldy #5" alone. What are you using to test the code? Devcart? Emulator (if so, which one)?

Posted: Thu Sep 21, 2006 2:30 pm
by Cybergoth
If this is to be complied with DASM, put

Code: Select all

         ALIGN 256
before the data block.

Posted: Thu Sep 21, 2006 4:03 pm
by dvdmth

Code: Select all

      adc #<states
      sta states_low
      lda #>states
      sta states_high   
I noticed an omission here. I don't know if this explains your problem, but it is something you should be aware of. If the ADC instruction produces a carry (goes beyond 255), then the address will not be properly calculated. To get the right address, you need to propagate the carry into the upper byte of the address with an "ADC #0" command:

Code: Select all

      adc #<states
      sta states_low
      lda #>states
      ADC #0
      sta states_high   

Posted: Thu Sep 21, 2006 4:19 pm
by VanOccupanther
(using: Nintendulator 0.9.6.0 for debugging)
dvdmth wrote:

Code: Select all

      adc #<states
      sta states_low
      lda #>states
      sta states_high   
I noticed an omission here. I don't know if this explains your problem, but it is something you should be aware of. If the ADC instruction produces a carry (goes beyond 255), then the address will not be properly calculated. To get the right address, you need to propagate the carry into the upper byte of the address with an "ADC #0" command:

Code: Select all

      adc #<states
      sta states_low
      lda #>states
      ADC #0
      sta states_high   
THANK YOU SO MUCH! :) that was the problem.

Posted: Fri Sep 22, 2006 12:24 am
by blargg
In the future if you ever encounter something like this, where removing a seeming redundant instruction changes the behavior of the program, try putting an equivalent number of NOPs as the bytes the instruction used. In this case you'd replace the LDY #5 with two NOPs. If the same happens, you know it's due to the shifting of code that this caused. Even inserting NOPs into code can change its behavior.