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

141 lines
3.4 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:
LDA Y_pos
STA temp
CLC
ADC radius
STA Y_pos
JSR pixel_draw
LDA btp_mem_pos
STA btp_mem_pos_swop
LDA btp_mem_pos + 1
STA btp_mem_pos_swop + 1
;; fix offset of 8 bytes, idk why this is needed
Sub_16 btp_mem_pos_swop, btp_mem_pos_swop + 1, #$40, #$01 ;-320
LDA temp
STA Y_pos
draw_right_px_in_circle:
;; C = 0, because Mult_16
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_inv_y
LDA btp_mem_pos + 1
STA btp_mem_pos_inv_y + 1
;; fix offset of 8 bytes, idk why this is needed
Sub_16 btp_mem_pos_inv_y, btp_mem_pos_inv_y + 1, #$40, #$01 ;-320
SEC ;; See draw_pixel_inv
while_x_bigger_then_y:
;;Draw pixels
JSR circle_help
increment_y_pos:
INC Y_rel ; y++
DEY
BPL increment_y_pos_end
move_8px_down:
LDY #$07
;; Switch to chunk bellow
; So we subtract #$0140
; C = 1 because branching!
Sub_16 btp_mem_pos, btp_mem_pos + 1, #$40, #$01, ! ;-320
;; Y is inverted
Add_16 btp_mem_pos_inv_y, btp_mem_pos_inv_y + 1, #$40, #$01 ;+320
;; X and Y has swopped
Sub_16 btp_mem_pos_swop, btp_mem_pos_swop + 1, #$08, #$00
increment_y_pos_end:
;;t1 += y
CLC
LDA t1
ADC Y_rel
STA t1
;; t2 = t1 - x
SEC
LDA t1
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, !
;; Y is inverted
Sub_16 btp_mem_pos_inv_y, btp_mem_pos_inv_y + 1, #$08, #$00, !
;; X and Y has swoped
Sub_16 btp_mem_pos_swop, btp_mem_pos_swop + 1, #$40, #$01 ;-320
;; Restores byte to paint
LDA #%00000001
STA byte_to_paint
decrement_x_pos_end:
LDA t2
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