1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-11-18 04:08:58 +00:00
kickc/src/test/ref/cordic-atan2-16-ref.asm

454 lines
7.0 KiB
NASM
Raw Normal View History

// Find atan2(x, y) using the CORDIC method
// See http://bsvi.ru/uploads/CORDIC--_10EBA/cordic.pdf
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
// The number of iterations performed during 16-bit CORDIC atan2 calculation
.const CORDIC_ITERATIONS_16 = $f
.label D018 = $d018
// Color Ram
.label COLS = $d800
.label CHARSET = $2000
.label SCREEN = $2800
2019-07-04 17:56:11 +00:00
.label print_char_cursor = $a
main: {
.const toD0181_return = (>(SCREEN&$3fff)*4)|(>CHARSET)/4&$f
2019-06-29 08:08:46 +00:00
.label _12 = $10
2019-07-04 17:56:11 +00:00
.label xw = $1f
.label yw = $21
2019-06-29 08:08:46 +00:00
.label angle_w = $10
2019-07-04 17:56:11 +00:00
.label diff_sum = 6
.label screen = 8
.label screen_ref = 4
.label x = 3
.label y = 2
jsr init_font_hex
lda #toD0181_return
sta D018
lda #<SCREEN
sta screen
lda #>SCREEN
sta screen+1
2019-06-29 08:08:46 +00:00
lda #0
sta diff_sum
sta diff_sum+1
lda #<SCREEN_REF
sta screen_ref
lda #>SCREEN_REF
sta screen_ref+1
lda #-$c
sta y
b1:
2019-07-04 17:56:11 +00:00
lda #-$13
sta x
b2:
2019-07-04 17:56:11 +00:00
lda x
ldy #0
sta xw+1
sty xw
lda y
sta yw+1
sty yw
jsr atan2_16
lda #$80
clc
2019-06-29 08:08:46 +00:00
adc _12
sta _12
bcc !+
inc _12+1
!:
lda _12+1
2019-07-04 17:56:11 +00:00
tax
2019-06-29 08:08:46 +00:00
ldy #0
lda (screen_ref),y
jsr diff
//*screen = (>angle_w)-angle_b;
//*screen = >angle_w;
clc
adc diff_sum
sta diff_sum
bcc !+
2019-06-29 08:08:46 +00:00
inc diff_sum+1
!:
2019-07-04 17:56:11 +00:00
txa
sec
ldy #0
sbc (screen_ref),y
sta (screen),y
inc screen
bne !+
inc screen+1
!:
inc screen_ref
bne !+
inc screen_ref+1
!:
2019-07-04 17:56:11 +00:00
inc x
lda #$15
cmp x
bne b2
inc y
lda #$d
cmp y
bne b1
2019-06-29 08:08:46 +00:00
jsr print_word
b5:
lda COLS+$c*$28+$13
clc
adc #1
sta COLS+$c*$28+$13
2019-06-29 08:08:46 +00:00
jmp b5
}
// Print a word as HEX
2019-07-04 17:56:11 +00:00
// print_word(word zeropage(6) w)
2019-06-29 08:08:46 +00:00
print_word: {
2019-07-04 17:56:11 +00:00
.label w = 6
2019-06-29 08:08:46 +00:00
lda w+1
tax
lda #<$400
sta print_char_cursor
lda #>$400
sta print_char_cursor+1
jsr print_byte
lda w
tax
jsr print_byte
rts
}
// Print a byte as HEX
// print_byte(byte register(X) b)
print_byte: {
txa
lsr
lsr
lsr
lsr
tay
lda print_hextab,y
jsr print_char
lda #$f
axs #0
lda print_hextab,x
jsr print_char
rts
}
// Print a single char
// print_char(byte register(A) ch)
print_char: {
ldy #0
sta (print_char_cursor),y
inc print_char_cursor
bne !+
inc print_char_cursor+1
!:
rts
}
2019-07-04 17:56:11 +00:00
// diff(byte register(X) bb1, byte register(A) bb2)
2019-06-29 08:08:46 +00:00
diff: {
2019-07-04 17:56:11 +00:00
sta $ff
cpx $ff
bcc b1
sta $ff
txa
2019-06-29 08:08:46 +00:00
sec
2019-07-04 17:56:11 +00:00
sbc $ff
2019-06-29 08:08:46 +00:00
rts
b1:
2019-07-04 17:56:11 +00:00
stx $ff
2019-06-29 08:08:46 +00:00
sec
2019-07-04 17:56:11 +00:00
sbc $ff
2019-06-29 08:08:46 +00:00
rts
}
// Find the atan2(x, y) - which is the angle of the line from (0,0) to (x,y)
// Finding the angle requires a binary search using CORDIC_ITERATIONS_16
// Returns the angle in hex-degrees (0=0, 0x8000=PI, 0x10000=2*PI)
2019-07-04 17:56:11 +00:00
// atan2_16(signed word zeropage($1f) x, signed word zeropage($21) y)
atan2_16: {
2019-07-04 17:56:11 +00:00
.label _2 = $c
.label _7 = $e
.label yi = $c
.label xi = $e
2019-06-29 08:08:46 +00:00
.label angle = $10
2019-07-04 17:56:11 +00:00
.label xd = $14
.label yd = $12
2019-06-29 08:08:46 +00:00
.label return = $10
2019-07-04 17:56:11 +00:00
.label x = $1f
.label y = $21
lda y+1
bmi !b1+
jmp b1
!b1:
sec
lda #0
sbc y
sta _2
lda #0
sbc y+1
sta _2+1
b3:
lda x+1
bmi !b4+
jmp b4
!b4:
sec
lda #0
sbc x
sta _7
lda #0
sbc x+1
sta _7+1
b6:
lda #0
sta angle
sta angle+1
2019-07-04 17:56:11 +00:00
tax
b10:
lda yi+1
bne b11
lda yi
bne b11
b12:
lsr angle+1
ror angle
lda x+1
bpl b7
sec
lda #<$8000
sbc angle
sta angle
lda #>$8000
sbc angle+1
sta angle+1
b7:
lda y+1
bpl b8
sec
lda #0
sbc angle
sta angle
lda #0
sbc angle+1
sta angle+1
b8:
rts
b11:
2019-07-04 17:56:11 +00:00
txa
tay
lda xi
sta xd
lda xi+1
sta xd+1
lda yi
sta yd
lda yi+1
sta yd+1
2019-07-04 17:56:11 +00:00
b13:
2019-07-05 04:56:24 +00:00
cpy #2
2019-07-04 17:56:11 +00:00
bcs b14
cpy #0
2019-07-04 17:56:11 +00:00
beq b17
lda xd+1
cmp #$80
ror xd+1
ror xd
lda yd+1
cmp #$80
ror yd+1
ror yd
2019-07-04 17:56:11 +00:00
b17:
lda yi+1
2019-07-04 17:56:11 +00:00
bpl b18
lda xi
sec
sbc yd
sta xi
lda xi+1
sbc yd+1
sta xi+1
lda yi
clc
adc xd
sta yi
lda yi+1
adc xd+1
sta yi+1
2019-07-04 17:56:11 +00:00
txa
asl
tay
sec
lda angle
sbc CORDIC_ATAN2_ANGLES_16,y
sta angle
lda angle+1
sbc CORDIC_ATAN2_ANGLES_16+1,y
sta angle+1
2019-07-04 17:56:11 +00:00
b19:
inx
cpx #CORDIC_ITERATIONS_16-1+1
bne !b12+
jmp b12
!b12:
jmp b10
2019-07-04 17:56:11 +00:00
b18:
lda xi
clc
adc yd
sta xi
lda xi+1
adc yd+1
sta xi+1
lda yi
sec
sbc xd
sta yi
lda yi+1
sbc xd+1
sta yi+1
2019-07-04 17:56:11 +00:00
txa
asl
tay
clc
lda angle
adc CORDIC_ATAN2_ANGLES_16,y
sta angle
lda angle+1
adc CORDIC_ATAN2_ANGLES_16+1,y
sta angle+1
2019-07-04 17:56:11 +00:00
jmp b19
b14:
lda xd+1
cmp #$80
ror xd+1
ror xd
lda xd+1
cmp #$80
ror xd+1
ror xd
lda yd+1
cmp #$80
ror yd+1
ror yd
lda yd+1
cmp #$80
ror yd+1
ror yd
dey
dey
jmp b13
b4:
lda x
sta xi
lda x+1
sta xi+1
jmp b6
b1:
lda y
sta yi
lda y+1
sta yi+1
jmp b3
}
// Make charset from proto chars
2019-07-04 17:56:11 +00:00
// init_font_hex(byte* zeropage($19) charset)
init_font_hex: {
2019-07-04 17:56:11 +00:00
.label _0 = $23
.label idx = $1e
.label proto_lo = $1b
.label charset = $19
.label c1 = $1d
.label proto_hi = $16
.label c = $18
lda #0
sta c
lda #<FONT_HEX_PROTO
sta proto_hi
lda #>FONT_HEX_PROTO
sta proto_hi+1
lda #<CHARSET
sta charset
lda #>CHARSET
sta charset+1
b1:
lda #0
sta c1
lda #<FONT_HEX_PROTO
sta proto_lo
lda #>FONT_HEX_PROTO
sta proto_lo+1
b2:
lda #0
tay
sta (charset),y
lda #1
sta idx
ldx #0
b3:
txa
tay
lda (proto_hi),y
asl
asl
asl
asl
sta _0
txa
tay
lda (proto_lo),y
asl
ora _0
ldy idx
sta (charset),y
inc idx
inx
cpx #5
bne b3
lda #0
ldy idx
sta (charset),y
iny
sta (charset),y
lda #5
clc
adc proto_lo
sta proto_lo
bcc !+
inc proto_lo+1
!:
lda #8
clc
adc charset
sta charset
bcc !+
inc charset+1
!:
inc c1
lda #$10
cmp c1
bne b2
lda #5
clc
adc proto_hi
sta proto_hi
bcc !+
inc proto_hi+1
!:
inc c
lda #$10
cmp c
bne b1
rts
}
// Bit patterns for symbols 0-f (3x5 pixels) used in font hex
FONT_HEX_PROTO: .byte 2, 5, 5, 5, 2, 6, 2, 2, 2, 7, 6, 1, 2, 4, 7, 6, 1, 2, 1, 6, 5, 5, 7, 1, 1, 7, 4, 6, 1, 6, 3, 4, 6, 5, 2, 7, 1, 1, 1, 1, 2, 5, 2, 5, 2, 2, 5, 3, 1, 1, 2, 5, 7, 5, 5, 6, 5, 6, 5, 6, 2, 5, 4, 5, 2, 6, 5, 5, 5, 6, 7, 4, 6, 4, 7, 7, 4, 6, 4, 4
// Angles representing ATAN(0.5), ATAN(0.25), ATAN(0.125), ...
CORDIC_ATAN2_ANGLES_16:
.for (var i=0; i<CORDIC_ITERATIONS_16; i++)
2019-06-30 13:30:08 +00:00
.word 256*2*256*atan(1/pow(2,i))/PI/2
print_hextab: .text "0123456789abcdef"
SCREEN_REF:
.for(var y=-12;y<=12;y++)
.for(var x=-19;x<=20;x++)
.byte round(256*atan2(y, x)/PI/2)