I am working on a physics system for my game which uses 3 bytes of precision. First byte showing your x or y pixel position on the screen. The physics constants are also defined like this:
GRAVITY0 = $0
GRAVITY1 = $20
GRAVITY2 = $1
MAX_FALL0 = $1
MAX_FALL1 = $10
MAX_FALL2 = $10
WALK_ACCEL0 = $0
WALK_ACCEL1 = $16
WALK_ACCEL2 = $80
And I'm also using 2's compliment for my negatives. This is how I calculate the negative of a 3 byte number:
clc
lda ax2
eor #$ff
adc #1
sta ax2
lda ax1
eor #$ff
adc #0
sta ax1
lda ax0
eor #$ff
adc #0
sta ax0
ax0 being the most significant and ax2 the least significant byte. But for values that are constant, calculating the negatives in real time doesn't make much sense since the value is always going to be the same and the addressing mode is always immediate. But this wouldn't work:
lda #-WALK_ACCEL0
sta ax0
lda #-WALK_ACCEL1
sta ax1
lda #-WALK_ACCEL2
sta ax2
since it's only calculating the negative of each byte by itself. The only other way that I can think is to also define the negatives as constants and use those when the negative of a constant is needed. But that would be very tedious to do as every time I want to change a number I also have to change its negative value. This feels like something that the assembler should be able to do automatically but I can't figure out how to do it in ca65. Thanks in advance.
Calculating negative of 3 byte constants
Moderator: Moderators
Re: Calculating negative of 3 byte constants
Wow, 3 bytes is a lot for velocity and acceleration! In most games games, objects are restricted to moving 16 pixels at a time, because that's how big metatiles usually are and any movement bigger than that would cause them to go through solid blocks... So 1 byte for the whole part and another one for the fractional part is more than enough!
I can understand having a 3rd byte if you don't want to manually extend the top byte when doing calculations, but then the 3rd byte will always be either $00 (positive values) or $FF (negative values).
Normally you'd define the constant as the full 16-bit (or 24-bit) value, instead of splitting it in bytes, and then extract the individual bytes from that. This way you can negate the values before extracting the individual bytes if you need the negative version of the value:
Most assemblers have fast ways of accessing the low and high bytes of a value, but I'm not sure how you'd go about accessing a third byte... you may need to use bitmasks and bitshifting.
I can understand having a 3rd byte if you don't want to manually extend the top byte when doing calculations, but then the 3rd byte will always be either $00 (positive values) or $FF (negative values).
Normally you'd define the constant as the full 16-bit (or 24-bit) value, instead of splitting it in bytes, and then extract the individual bytes from that. This way you can negate the values before extracting the individual bytes if you need the negative version of the value:
Code: Select all
ACCELERATION = $0180
;use positive acceleration
lda #<ACCELERATION
sta ax+0
lda #>ACCELERATION
sta ax+1
;use negative acceleration
lda #<(-ACCELERATION)
sta ax+0
lda #>(-ACCELERATION)
sta ax+1
Re: Calculating negative of 3 byte constants
ca65's third byte operator is ^.
Re: Calculating negative of 3 byte constants
Turns out I was actually using dasm.
For future reference this is how I'm doing it now:
and as said in ca65 you can use ^ for accessing the third byte (aka bank byte). Thank you both.
For future reference this is how I'm doing it now:
Code: Select all
GRAVITY = $012000
lda #<(GRAVITY)
sta ay2
lda #>(GRAVITY)
sta ay1
lda #>(GRAVITY>>8)
sta ay0