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

135 lines
2.9 KiB
ArmAsm

;;; -*- Mode: asm; indent-tabs-mode: t; tab-width: 8 -*-
.proc circle
.include "circle.inc"
;; We use the algorithm jerkos method
;; https://schwarzers.com/algorithms/
;; 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
btp_mem_pos_center_two = btp_mem_pos_center
Mult_16 btp_mem_pos_center, btp_mem_pos_center + 1
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
while_x_bigger_then_y:
;STY temp
;LDY #$00
draw_pixel:
LDA byte_to_paint ;A byte containing a single 1. Coresponds to X position in the chunk.
ORA (btp_mem_pos), Y
STA (btp_mem_pos), Y
draw_pixel_inv:
SEC
LDA btp_mem_pos_center_two
SBC btp_mem_pos
STA btp_mem_pos_inv
LDA btp_mem_pos_center_two + 1
SBC btp_mem_pos + 1
STA btp_mem_pos_inv + 1
;; calculate the inverted y value Y = 7-Y
STY temp
LDA #$07
SEC
SBC temp
TAY
;; calculate byte_to_paint_inv (could be faster with lookup table)
LDA byte_to_paint
STA temp_
LDA #%10000000
jmp start_calc
calc:
LSR A
start_calc:
LSR temp_
BCC calc
; A = byte_to_paint_inv
ORA (btp_mem_pos_inv), Y
STA (btp_mem_pos_inv), Y
;;Recover the Y value (we changed it because evrything is inverted)
ldy temp
increment_y_pos:
INC Y_rel ; y++
INY
CPY #$08
BNE increment_y_pos_end
move_8px_down:
LDY #$00
;; Switch to chunk bellow
; So we subtract #$4000
Add_16 btp_mem_pos, btp_mem_pos + 1, #$40, #$01 ;+320
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
CMP #$00
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.
Sub_16 btp_mem_pos, btp_mem_pos + 1, #$08, #$00
;; 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
.endproc