c64-livecoding/wip-hugo/routines/circle/circle.s

125 lines
3.3 KiB
ArmAsm

;;; -*- Mode: asm; indent-tabs-mode: t; tab-width: 8 -*-
.proc circle
.include "circle.inc"
;; We use the algorithm jerkos method
;; git
;; X_rel = radius (share the same address)
;;Y_rel =0
LDA #$00
STA Y_rel
;; t1 = radius >> 4
LDA radius
LSR
LSR
LSR
LSR
STA t1
draw_center_px_in_circle:
JSR pixel_draw
LDA btp_mem_pos
STA btp_mem_pos_center
LDA btp_mem_pos + 1
STA btp_mem_pos_center + 1
;; btp_mem_pos_center_two = 2*btp_mem_pos_center | used later for calculating btp_mem_pos_inv
Mult_16 btp_mem_pos_center, btp_mem_pos_center + 1
;; fix offset of 8 bytes, idk why this is needed
Sub_16 btp_mem_pos_center, btp_mem_pos_center + 1, #$40, #$01 ;-320
draw_lower_px_in_circle:
CLC
LDA Y_pos
STA temp
ADC radius
STA Y_pos
JSR pixel_draw
LDA btp_mem_pos
STA btp_mem_pos_qcb
STA btp_mem_pos_qdb
LDA btp_mem_pos + 1
STA btp_mem_pos_qdb + 1
STA btp_mem_pos_qcb + 1
;; fix offset of 8 bytes, idk why this is needed
Sub_16 btp_mem_pos_qcb, btp_mem_pos_qcb + 1, #$40, #$01 ;-320
Sub_16 btp_mem_pos_qdb, btp_mem_pos_qdb + 1, #$40, #$01 ;-320
LDA temp
STA Y_pos
draw_right_px_in_circle:
CLC
LDA X_pos
ADC radius
STA X_pos
;; We only draw the first pixel using absolute position.
;; After that we use relative position.
JSR pixel_draw
;; This sets byte_to_paint, btp_mem_pos and Y
LDA btp_mem_pos
STA btp_mem_pos_qda
LDA btp_mem_pos + 1
STA btp_mem_pos_qda + 1
;; fix offset of 8 bytes, idk why this is needed
Sub_16 btp_mem_pos_qda, btp_mem_pos_qda + 1, #$40, #$01 ;-320
while_x_bigger_then_y:
;;Draw pixels and does the ypos incrementation logic
;; WARNING expects C=1 before and C =0 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
JSR circle_help
;;t1 += y
; C==0 from circle_help
LDA t1
ADC Y_rel
STA t1
;; t2 = t1 - x
SEC
SBC X_rel
STA t2
;; if t2 < 0 then skip to endif
;; we can skipp CMP #$00 because SBC above do the same
BMI endif
if:
decrement_x_pos:
DEC X_rel
ASL byte_to_paint
BCC decrement_x_pos_end
move_8px_left:
;; Next chunk is 8 addresses away. Look in pixel_draw for more detail.
;; -8.
;; C = 1 because branching
Sub_16 btp_mem_pos, btp_mem_pos + 1, #$08, #$00, ! ;+8
;; Y is inverted
Sub_16 btp_mem_pos_qda, btp_mem_pos_qda + 1, #$08, #$00, ! ;+8
;; X and Y has swoped
Sub_16 btp_mem_pos_qcb, btp_mem_pos_qcb + 1, #$40, #$01, ! ;-320
;; X and Y has swoped and Y has inverted
Sub_16 btp_mem_pos_qdb, btp_mem_pos_qdb +1, #$40, #$01, ! ;+320
;; Restores byte to paint
LDX #%00000001
STX byte_to_paint
LDA t2
decrement_x_pos_end:
STA t1 ; t1 = t2
endif:
;; repeat if X > Y
LDA X_rel
CMP Y_rel
BCS while_x_bigger_then_y
RTS
.include "routines/circle/circle_help.s"
.endproc