💾 Archived View for mirrors.apple2.org.za › archive › ftp.gno.org › gs.specific › orca › libraries ›… captured on 2024-12-17 at 23:44:20.
-=-=-=-=-=-=-
; ; Arc3D line-drawing code ; By Andy McFadden ; Adapted from code by the FTA. ; ; Draws from (clpx0,clpy0) to (clpx1,clpy1) (output of a clipping routine). ; penColor equ $70 ;0 - 15 clpx0 equ $72 clpy0 equ $74 clpx1 equ $76 clpy1 equ $78 x0 equ $80 y0 equ $82 x1 equ $84 y1 equ $86 offset equ $88 deltax equ $8a deltay equ $8c diff equ $8e even_c equ $90 odd_c equ $92 _DrawLine ENTRY DoDrawLine ANOP lda <clpy1 ;4 is y1 < y0? cmp <clpy0 ;4 blt in_order ;2/3 yes, so leave alone ; lda <clpy1 ;we want y0 to be the largest, sta y0 ; so switch lda <clpx1 sta x0 lda <clpy0 sta y1 lda <clpx0 sta x1 bra copy_done in_order ANOP ; lda <clpy1 sta y1 lda <clpx1 sta x1 lda <clpy0 sta y0 lda <clpx0 sta x0 ; 39/41 cycles to here ; setup offset and deltas copy_done ANOP lda y1 asl A asl A adc y1 asl A asl A asl A asl A asl A asl A adc x1 sta offset ;16+16=32 ; penColor must be between 0 and 15 lda <penColor ;setup pixel images sta even_c ;0x000f xba asl A asl A asl A asl A and #$f000 sta odd_c ;0xf000 lda y0 sec sbc y1 sta deltay ;we know y0 is larger... beq Horizontal ;+2 do as special case lda x1 cmp x0 beq Vertical ;+2 do as special case ; bcc Rev ;x1 is smaller; go other way bcs Forw brl Rev Forw ANOP sbc x0 sta deltax cmp deltay bcc Forw_bigy_j brl Forw_bigx Forw_bigy_j brl Forw_bigy ; ; Handle special cases (horizontal/vertical/point) ; ; handle vertical (deltax=0) lines Vertical ANOP lda deltay tay ;count down lda offset lsr A tax bcc vf_odd2 clc ; bra vf_even2 ; loop below vf_even2 lda $2000,x and #$fff0 ora even_c sta $2000,x txa adc #160 tax dey bpl vf_even2 bra vf_done vf_odd2 lda $1fff,x and #$0fff ora odd_c sta $1fff,x txa adc #160 tax dey bpl vf_odd2 ; bra vf_done vf_done brl Exit ; handle horizontal (deltay=0) lines Horizontal ANOP lda x1 cmp x0 bcc h_rev ;x1 is smaller; go other way sbc x0 sta deltax ; horizontal, moving forward h_forw ANOP lda deltax tay ;count down lda offset lsr A tax bcc hf_odd2 clc ; bra hf_even2 ; loop below hf_even2 lda $2000,x and #$fff0 ora even_c sta $2000,x dey bmi hf_done hf_odd2 lda $1fff,x and #$0fff ora odd_c sta $1fff,x dex dey bpl hf_even2 hf_done brl Exit ; horizontal, reverse direction h_rev ANOP sec lda x0 sbc x1 sta deltax lda deltax tay ;count down lda offset lsr A tax bcc hr_odd2 clc ; bra hr_even2 ; loop below hr_even2 lda $2000,x and #$fff0 ora even_c sta $2000,x dey bmi hr_done inx hr_odd2 lda $1fff,x and #$0fff ora odd_c sta $1fff,x dey bpl hr_even2 ; bra hr_done hr_done brl Exit ; ; Standard cases ; ; forward direction, deltay is bigger than deltax Forw_bigy ANOP lda deltay tay ;count down lsr A eor #$ffff inc A sta diff lda offset lsr A tax bcc fy_odd2 clc bra fy_even2 ; loop below fy_even1 sta diff fy_even2 lda $2000,x and #$fff0 ora even_c sta $2000,x dey bmi fy_done txa adc #160 tax lda deltax adc diff bmi fy_even1 sbc deltay fy_odd1 sta diff fy_odd2 lda $1fff,x and #$0fff ora odd_c sta $1fff,x dey bmi fy_done txa adc #160 tax lda deltax adc diff bmi fy_odd1 sbc deltay dex bra fy_even1 fy_done brl Exit ; reverse direction Rev ANOP sec lda x0 sbc x1 sta deltax cmp deltay bcs Rev_bigx ; reverse direction, deltay is bigger than deltax Rev_bigy ANOP lda deltay tay ;count down inc A lsr A eor #$ffff inc A sta diff lda offset lsr A tax bcc ry_odd2 clc bra ry_even2 ; loop below ry_even1 sta diff ry_even2 lda $2000,x and #$fff0 ora even_c sta $2000,x dey bmi ry_done txa adc #160 tax lda deltax adc diff bmi ry_even1 sbc deltay inx ry_odd1 sta diff ry_odd2 lda $1fff,x and #$0fff ora odd_c sta $1fff,x dey bmi ry_done txa adc #160 tax lda deltax adc diff bmi ry_odd1 sbc deltay bra ry_even1 ry_done brl Exit ; reverse direction, deltax is bigger than deltay Rev_bigx ANOP lda deltax tay ;count down lsr A eor #$ffff inc A sta diff lda offset lsr A tax bcc rx_odd2 clc bra rx_even2 ; loop below rx_even1 sta diff rx_even2 lda $2000,x and #$fff0 ora even_c sta $2000,x dey bmi rx_done inx lda deltay adc diff bmi rx_odd1 sbc deltax sta diff txa adc #160 tax bra rx_odd2 rx_odd1 sta diff rx_odd2 lda $1fff,x and #$0fff ora odd_c sta $1fff,x dey bmi rx_done lda deltay adc diff bmi rx_even1 sbc deltax sta diff txa adc #160 tax bra rx_even2 rx_done brl Exit ; forward direction, deltax is bigger than deltay Forw_bigx ANOP lda deltax tay ;count down lsr A eor #$ffff inc A sta diff lda offset lsr A tax bcc fx_odd2 clc bra fx_even2 ; loop below fx_even1 sta diff fx_even2 lda $2000,x and #$fff0 ora even_c sta $2000,x dey bmi fx_done lda deltay adc diff bmi fx_odd1 sbc deltax sta diff txa adc #160 tax bra fx_odd2 fx_odd1 sta diff fx_odd2 lda $1fff,x and #$0fff ora odd_c sta $1fff,x dey bmi fx_done dex lda deltay adc diff bmi fx_even1 sbc deltax sta diff txa adc #160 tax bra fx_even2 fx_done brl Exit ; ; common exit point ; Exit ANOP rtl