Skip to content

Instantly share code, notes, and snippets.

@digarok
Created July 9, 2019 02:39
Show Gist options
  • Save digarok/f44e8c0e91410f76010707033865a633 to your computer and use it in GitHub Desktop.
Save digarok/f44e8c0e91410f76010707033865a633 to your computer and use it in GitHub Desktop.
An example of wrapping Andy McFadden's 65816 IIgs line drawing code to support arbitrary draw buffer addresses.
MyBuffer = $051800
* Just need to do this once after malloc
InitDrawlines
lda #<MyBuffer ; should be 1800
sta __p0
sta __p1
sta __p2
sta __p3
sta __p4
sta __p5
sta __p6
sta __p7
sta __p8
sta __p9
sta __p10
sta __p11
sta __p12
sta __p13
rtl
MyDoDrawline
phb ; store original bank
lda #>MyBuffer ; should be 0518
pha
plb ; B is 18 (trash)
plb ; B is 05 (good!)
jsl DoDrawLine
plb ; restore original bank
rtl
;
; 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
__p0 = *-2
and #$fff0
ora even_c
sta $2000,x
__p1 = *-2
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
__p2 = *-2
and #$fff0
ora even_c
sta $2000,x
__p3 = *-2
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
__p4 = *-2
and #$fff0
ora even_c
sta $2000,x
__p5 = *-2
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
__p6 = *-2
and #$fff0
ora even_c
sta $2000,x
__p7 = *-2
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
__p8 = *-2
and #$fff0
ora even_c
sta $2000,x
__p9 = *-2
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
__p10 = *-2
and #$fff0
ora even_c
sta $2000,x
__p11 = *-2
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
__p12 = *-2
and #$fff0
ora even_c
sta $2000,x
__p13 = *-2
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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment