I'm currently working in a demo of a platformer in 6502 assembly for a college project, and I'm not understanding how I could implement smooth horizontal/vertical movement and acceleration in this project. Basically, every movement consists in a slight different version of the following code:
READ_RIGHT:
  LDA JOYPAD1
  AND #%00000001
  BNE DO_RIGHT
  JMP READ_RIGHT_DONE
DO_RIGHT:
  JSR HandleAcceleration
  JSR UpdatePlayerPosition
READ_RIGHT_DONE:
  RTI
HandleAcceleration:
  LDA ACCEL + 1
  CLC
  ADC #$01
  STA ACCEL + 1
  BCC @ON_CARRY
  LDA ACCEL + 0
  CMP MAX_ACCEL
  BCC @NOT_MAX_ACCEL
  LDA MAX_ACCEL
  STA ACCEL
@ON_CARRY:
  INC ACCEL
  INC MOV_FLAG
@NOT_MAX_ACCEL:
  RTS
UpdatePlayerPosition:
  LDA PLAYER_X
  STA $0203
  STA $020B
  TAX
  CLC
  ADC #$08
  STA $0207
  STA $020F
  ADC SPEED
  STA PLAYER_X
  RTS
I think I should use fixed-point arithmetics for this, but every single time I've tried, the program didn't work like it was intended. If someone knows what I should do or what I'm doing wrong, please help.
I've tried applying the following logic to the code:
READ_RIGHT:
  LDA JOYPAD1
  AND #%00000001
  BNE DO_RIGHT
  JMP READ_RIGHT_DONE
DO_RIGHT:
  JSR HandleAcceleration
  JSR UpdatePlayerPosition
READ_RIGHT_DONE:
  RTI
HandleAcceleration:
  LDA ACCEL + 1
  CLC
  ADC #$01
  STA ACCEL + 1
  BCC @ON_CARRY
  LDA ACCEL + 0
  CMP MAX_ACCEL
  BCC @NOT_MAX_ACCEL
  LDA MAX_ACCEL
  STA ACCEL
@ON_CARRY:
  INC ACCEL
  INC MOV_FLAG
@NOT_MAX_ACCEL:
  RTS
UpdatePlayerPosition:
  LDA PLAYER_X
  STA $0203
  STA $020B
  TAX
  CLC
  ADC #$08
  STA $0207
  STA $020F
  ADC SPEED
  STA PLAYER_X
  RTS
Instead of smoothly applying acceleration to the sprite, it only made it go a lot faster instantly and nothing else.
 
                        
This is a slight guess because I've never done any NES programming, but 6502 is a little endian machine. Traditionally 16 bit values are stored with the least significant byte at the low address and the most significant byte at the high address.
In your code you are adding 1 to the high byte first and then doing some weird stuff I don't fully understand and may well be wrong, as follows:
If
ACCELis a 16 bit value, to add 1 to it I would expect something like:Another problem is your code after
bcc @on_carry. The code immediately following that will only get executed when the carry is set. And if you are adding 1, the only time carry will be set is if the result of the addition is zero (wrapping round from$ff).So most of the time you end up incrementing both
accelandaccel+1.If
accel+1is zero after the add, you then compareacceltomax_accel.cmpclears the carry flag if the accumulator is less than the operand. Socmpfollowed bybccwill jump ifA < max_accelIf
accelless thanmax_accel, you do nothing (by going straight torts), but if it is more, you setacceltomax_acceland then you fall through to incrementaccel. That doesn't seem right at all.