This page is a mirror of Tepples' nesdev forum mirror (URL TBD).
Last updated on Oct-18-2019 Download

Help with a bug..

Help with a bug..
by on (#159408)
Mostly I want someone just to see if I have an obvious ASM error in this loop.. :(
When I add one to bullet(x) it comes out with some other value not being 80 or 81 which is the expected..


UpdateBullets:

LDA #$00
STA bullet_index

.next_bullet

LDX bullet_index

LDA bullet_y, x
CMP #INACTIVE
BEQ .skip_update

LDA bullet_x, x
CLC
ADC bullet_speed
STA bullet_x, x

.skip_update

INC bullet_index

LDA bullet_index
CMP #ALL_MAX_BULLETS
BNE .next_bullet

RTS
Re: Help with a bug..
by on (#159409)
I don't see anything wrong with this piece of code. How exactly are the bullets misbehaving? How are you creating and destroying the bullets? Are you initializing bullet_speed properly before firing any bullets?
Re: Help with a bug..
by on (#159410)
I'm assuming bullet_speed is variable stored in memory that is used the routine and not a constant since its not in all CAPS

Perhaps something else is modifying the bullet speed variable before it gets used in the routine?

But the loop itself looks fine to me otherwise. Unless you meant to check the bullet x location to see if it's inactive rather than the y location.
Re: Help with a bug..
by on (#159421)
By values 80 or 81, did you mean hex values $80 and $81?
I think it has something to do with negative numbers, as values $80 thru $FF are negative in signed operations.
I couldn't help to fix it ATM as I haven't touched 6502 assembly for a while(will pick it up again later).
Re: Help with a bug..
by on (#159422)
Gilbert wrote:
I think it has something to do with negative numbers

I'm assuming that bullet_speed could be positive or negative, so that bullets can be fired to the left and to the right. This would have to be set for each bullet though, so maybe this is like a space shooter where bullets can only be fired in one direction?

Anyway, even if the speed is signed, that shouldn't affect the final positions of the bullets, since positions will always be considered unsigned when used as sprite coordinates.
Re: Help with a bug..
by on (#159425)
I would have expected adc #BULLET_SPEED or adc bullet_speed, X, but I obviously know nothing about the context.

As a side note, you can do increments and comparisons directly on the X register. You don't really need to store and retrieve bullet_index in this example.
Code:
INX                  ; INC bullet_index
                     ; LDA bullet_index
CPX #ALL_MAX_BULLETS ; CMP #ALL_MAX_BULLETS
BNE .next_bullet
Re: Help with a bug..
by on (#159431)
rainwarrior wrote:
I would have expected adc #BULLET_SPEED or adc bullet_speed, X, but I obviously know nothing about the context.

As a side note, you can do increments and comparisons directly on the X register. You don't really need to store and retrieve bullet_index in this example.
Code:
INX                  ; INC bullet_index
                     ; LDA bullet_index
CPX #ALL_MAX_BULLETS ; CMP #ALL_MAX_BULLETS
BNE .next_bullet


You are right about missing bullet_speed, X, as it is a variable not a constant, yet so far I am working my code for the 1st bullet to work so it should have worked anyways, trouble would have been for the next bullets.

I will give more context in the next post.
Re: Help with a bug..
by on (#159432)
tokumaru wrote:
I don't see anything wrong with this piece of code. How exactly are the bullets misbehaving? How are you creating and destroying the bullets? Are you initializing bullet_speed properly before firing any bullets?


Thank for your help guys on making sure the loop is proper ASM, I am still not confident when writing ASM, but I guess I am getting better now. So more context on the issue.

Main issue is the bullet is not showing on screen. I would expect 1 bullet to be drawn and move to the right. Its all I am looking for now.

Image
(This is what I am working on, a Zelda-Mad God inspired game)

;
; Init all bullets as off at the start of a level
;
LDA #$00
STA bullet_index

.next_bullet

LDA bullet_index
TAX

LDA #$02
STA bullet_speed, x

LDA #$80
STA bullet_y, x

LDA #$80
STA bullet_x, x

LDA bullet_update_constants, x
TAX

LDA #INACTIVE
STA SPRITE_RAM_BULLETS, x

INC bullet_index

LDA bullet_index
CMP #ALL_MAX_BULLETS
BNE .next_bullet

------------------------------------------

;------------------------
; FireBullet()
; NOTE: this is triggering correctly on button press...
;------------------------
FireBullet:

LDA entity_x
STA bullet_x

LDA entity_y
STA bullet_y

RTS

;-------------------------------------------------------------------------------
; UpdateBulletsPosition()
; PPU position update for bullets
;-------------------------------------------------------------------------------
UpdateBulletsPosition: ; This seems to be not working

LDA #$00
STA bullet_index

.next_bullet

LDY bullet_index

LDA bullet_y, y
CMP #INACTIVE
BNE .skip_bullet

LDA bullet_update_constants, y
TAX

LDA bullet_x, y
STA SPRITE_RAM_BULLETS + 3, x

LDA bullet_y, y
STA SPRITE_RAM_BULLETS, x

.skip_bullet

INC bullet_index

LDA bullet_index
CMP #ALL_MAX_BULLETS
BNE .next_bullet

RTS

;----------------------------------------------------------------------
;-----------------------START MAIN PROGRAM-----------------------------
;----------------------------------------------------------------------
Forever:
INC sleeping ;wait for NMI

.loop
LDA sleeping
BNE .loop ;wait for NMI to clear out the sleeping flag

LDA #$01
STA updating_background ;this is for when you are changing rooms or something, not really needed here
;it will skip the NMI updates so as not to mess with your room loading routines


LDA level_loaded
CMP #$00
BNE .no_level_load_request
JSR LoadRoom
INC level_loaded

.no_level_load_request

; Update random number ticker vars
INC random_dir
LDA random_dir
CMP #$04
BNE .no_update_needed

LDA #$00
STA random_dir

.no_update_needed

JSR ReadController1 ; get the current button data for player 1

JSR ProcessUserInput

JSR UpdateEnemies

JSR UpdateBullets

JSR CheckItemCollisions

JSR CheckEnemyCollisions

JSR CheckEntityBackgroundCollision

; PPU sprite update (position and possible tile attributes?)
JSR UpdateMetaSpritesPosition
JSR UpdateBulletsPosition

LDA #$00
STA updating_background

.end_loop

JMP Forever ;jump back to Forever, and go back to sleep
Re: Help with a bug..
by on (#159451)
; Relevant constants:

SPRITE_RAM_BULLETS = $0258
ALL_MAX_BULLETS = $08
Re: Help with a bug..
by on (#159458)
You will have to run it through a debugger. Set a breakpoint for writes to $258 or possibly whatever "bullet_index" is and step through it to see if it loads the values the way you expect.

Are you sure you are assigning a non-empty tile to the bullet?
Re: Help with a bug..
by on (#159651)
dougeff wrote:
You will have to run it through a debugger. Set a breakpoint for writes to $258 or possibly whatever "bullet_index" is and step through it to see if it loads the values the way you expect.

Are you sure you are assigning a non-empty tile to the bullet?


I pinpoint the error to the bullet_index var, but is non nonsensical:

;-------------------------------------------------------
UpdateBulletsPosition: ; This seems to be not working

LDA #$00
STA bullet_index

.next_bullet


LDA bullet_index
CMP #$00
BEQ .skip_debug
JSR DebugAlert
.skip_debug

;---------------------------

I am loading 0 into bullet_index, are right after I compare it to 0 (for debug purpose) and its not 0! without any other lines of code in the middle. What could cause such a thing?
Re: Help with a bug..
by on (#159661)
This is why you need to go step by step in a debugger (like FCEUX) to see why it's not doing what you expect.

By the way, you don't need to CMP #0. If bullet_index is zero, LDA bullet_index will set the zero flag...beq will branch if zero flag is set, therefore it will branch correctly without the CMP #0.
Re: Help with a bug..
by on (#159662)
dougeff wrote:
This is why you need to go step by step in a debugger (like FCEUX) to see why it's not doing what you expect.

By the way, you don't need to CMP #0. If bullet_index is zero, LDA bullet_index will set the zero flag...beq will branch if zero flag is set, therefore it will branch correctly without the CMP #0.


Thanks for the tip!

Btw, I am using a debbuger for now as for some reason my game won't run on FCEUX 2.2. It is crashing the emulator, weird thing is it runs on the NES!! I will try on an older version.
Re: Help with a bug..
by on (#159664)
Failing on an emulator but working in a NES probably means that the mapper registers and such aren't initialized correctly, or FCEUX is extremely anal about Bus Conflicts.
Re: Help with a bug..
by on (#159671)
Not sure if sempressimo meant crashing in the emulator, or actually crashing the emulator program itself. If the latter happened, this is a bug in the emulator and should be reported (would you mind sending me the ROM if this is the case?).
Re: Help with a bug..
by on (#159682)
rainwarrior wrote:
Not sure if sempressimo meant crashing in the emulator, or actually crashing the emulator program itself. If the latter happened, this is a bug in the emulator and should be reported (would you mind sending me the ROM if this is the case?).


Yes, I meant crashing the emulator itself, it is crashing FCEUX 2.2.2

Here is my source:

https://www.dropbox.com/s/xwxz37zezj9spx4/Dungeon%20Demo.rar?dl=0
Re: Help with a bug..
by on (#159683)
Works alright on my PC, with the same(?) version of FCEUX. What's your build date?
Re: Help with a bug..
by on (#159684)
Dwedit wrote:
Works alright on my PC, with the same(?) version of FCEUX. What's your build date?


Image

Image
Re: Help with a bug..
by on (#159688)
OK, so it works on previous version 2.2.1

I saw the debugger window, but I have no idea how to go from here;

Can someone walk-me through just do watch the value of 1 variable?
Re: Help with a bug..
by on (#159704)
sempressimo wrote:
Yes, I meant crashing the emulator itself, it is crashing FCEUX 2.2.2
Dwedit wrote:
Works alright on my PC, with the same(?) version of FCEUX. What's your build date?
sempressimo's screenshot wrote:
FCEUX 2.2.2
01:48:45 Sep 24 2013
mscv 1600 x86 release

I'm also using the same version of FCEUX. I think there's something unusual about sempressimo.nes.deb that is causing FCEUX to crash. If I remove or rename that file then FCEUX will run the ROM without crashing.
Re: Help with a bug..
by on (#159718)
Found the problem

Here is your build code that i downloaded
Code:
UpdateBulletsPosition: ; This seems to be not working

  LDA #$00
  TAX

.next_bullet
 
  LDA bullet_y, x
  CMP #INACTIVE
  BNE .skip_bullet
 
  LDA bullet_update_constants, x
  TAY
 
  LDA bullet_x, x
  ;STA SPRITE_RAM_BULLETS + 3, y

  LDA bullet_y, x
  ;STA SPRITE_RAM_BULLETS, y

.skip_bullet

  INX
 
  CPX #ALL_MAX_BULLETS
  BNE .next_bullet

  RTS


Two problems.

1. You load the bullet Y position which will be at #$FF if it is inactive. You do a compare and skip the update if it is NOT equal to the inactive value. But you want to skip the sprite bullet location update if it IS inactive. So it should be

BEQ .skip_bullet

2. The lines that actually updated the bullet x and y location were commented out. They need to be un-commented.

;STA SPRITE_RAM_BULLETS + 3, y
;STA SPRITE_RAM_BULLETS, y



The update code looks like this

Code:
UpdateBulletsPosition: ; This seems to be not working

  LDA #$00
  TAX

.next_bullet
 
  LDA bullet_y, x
  CMP #INACTIVE
  BEQ .skip_bullet
 
  LDA bullet_update_constants, x
  TAY
 
  LDA bullet_x, x
  STA SPRITE_RAM_BULLETS + 3, y

  LDA bullet_y, x
  STA SPRITE_RAM_BULLETS, y

.skip_bullet

  INX
 
  CPX #ALL_MAX_BULLETS
  BNE .next_bullet

  RTS


I rebuit it and could fire a bullet and it traveled across the screen endlessly.

Image
Re: Help with a bug..
by on (#159754)
Thanks a lot! I was struggling with this for a while.