OK, here's what I've come up with. Actually runs on a Commodore 64 though
Works pretty well! There's no bounds checking yet so it keeps falling...and falling... You'll see it follows the C code pretty closely.
One thing I need to fix up is the "power" input to give more range. I can just scale down the resulting speed vectors to do that though. Tweaking to the animation speed is needed too.
Code: Select all
sprite8x EQU $D00E
sprite8y EQU $D00F
;Some test code
processor 6502
org $1000
jsr multiplysetup
;Show sprite #8
lda #$80
sta $D015
; Note decimal inputs
lda #100
sta startx
lda #200
sta starty
lda #45
sta angle
lda #1 ;#55
sta power
jsr trajectory
rts
;------------------------------------------------------------------------------
; Input Parameters
startx
.byte $00
starty
.byte $00
angle ;degrees
.byte $00
power
.byte $00
;------------------------------------------------------------------------------
; Lookup tables for SIN/COS, from lookup.xls
sinbyte
.byte 0,4,8,13,17,22,26,31,35,39,44,48,53,57,61,65,70,74,
78,83,87,91,95,99,103,107,111,115,119,123,127,131,135,138,142
,146,149,153,156,160,163,167,170,173,177,180,183,186,189,192,
195,198,200,203,206,208,211,213,216,218,220,223,225,227,229,
231,232,234,236,238,239,241,242,243,245,246,247,248,249,250,
251,251,252,253,253,254,254,254,254,254,255
cosbyte
.byte 255,254,254,254,254,254,253,253,252,251,251,250,249,248,
247,246,245,243,242,241,239,238,236,234,232,231,229,227,
225,223,220,218,216,213,211,208,206,203,200,198,195,192,189
,186,183,180,177,173,170,167,163,160,156,153,149,146,142,138
,135,131,127,123,119,115,111,107,103,99,95,91,87,83,78,74,70
,65,61,57,53,48,44,39,35,31,26,22,17,13,8,4,0
;------------------------------------------------------------------------------
; "Variables"
curx ;X-position
.byte $00,$00 ; First byte is "fraction", second byte is "integer"
cury ;Y-position
.byte $00,$00 ; First byte is "fraction", second byte is "integer"
fspeed ;Scaled initial speed
.byte $00
dy ; Y component of current speed
.byte $00,$00 ; low/high, as above
dx ; X component of current speed
.byte $00,$00 ; low/high
;------------------------------------------------------------------------------
; "Function"
trajectory
; (TODO, check valid input)
; Current object position - 16 bits
lda startx
sta curx+1
lda #$00
sta curx
lda starty
sta cury+1
lda #$00
sta cury
; Object speed
lda power
sta fspeed
; Break speed into component vectors - Y
ldx angle
lda cosbyte,x ; Get cos(angle) from lookup table
ldy fspeed
jsr multiply8x8
stx dy ; Low byte
sta dy+1 ; High byte
; Break speed into component vectors - X
ldx angle
lda sinbyte,x ; Get sin(angle) from lookup table
ldy fspeed
jsr multiply8x8
stx dx ; Low byte
sta dx+1 ; High byte
; Negate dy because "up" is negative on the screen
; 16 bit Binary Negation
SEC ;Ensure carry is set
LDA #0 ;Load constant zero
SBC dy+0 ;... subtract the least significant byte
STA dy+0 ;... and store the result
LDA #0 ;Load constant zero again
SBC dy+1 ;... subtract the most significant byte
STA dy+1 ;... and store the result
trajloop
; Display on screen
ldx curx+1 ; high byte
ldy cury+1 ; high byte
stx sprite8x
sty sprite8y
; Slow the action down so we can actually see it
ldy #$00
slowdown
nop
nop
nop
nop
nop
nop
dey
bne slowdown
; Move the object - 16-bit addition
; X component
clc
lda curx
adc dx
sta curx
lda curx+1
adc dx+1
sta curx+1
; Y component
clc
lda cury
adc dy
sta cury
lda cury+1
adc dy+1
sta cury+1
; TODO Check for collision
; TODO check for out of bounds
; Simulate gravity
inc dy ; Smallest possible, may need to tweak
bne endloop ; dy (low byte) did not wrap around to zero
inc dy+1 ; increment the high byte
endloop
jmp trajloop
This is DASM format.