1
0
mirror of https://github.com/cc65/cc65.git synced 2024-12-26 08:32:00 +00:00

Factored out generic LINE implementation based on SETPIXEL from the three drivers previously containing the identical code.

Note: Originally I planned to create a module to be linked to the driver. However this turned out to cause quite some issues with the Makefiles - especially on the Apple2 where one driver uses to generic LINE implementation and the other doesn't. The final Makefile was so ugly that I rather opted for including the code in question on source level. In order to avoid to unwanted cross dependencies the whole .inc file content is wrapped in its own scope.

git-svn-id: svn://svn.cc65.org/cc65/trunk@4553 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
ol.sc 2010-01-24 11:21:44 +00:00
parent 16129b2724
commit e9f69ad123
4 changed files with 327 additions and 819 deletions

View File

@ -30,28 +30,13 @@ SCRN := $F871
SETGR := $FB40
HOME := $FC58
; ------------------------------------------------------------------------
; Variables mapped to the zero page segment variables. Some of these are
; used for passing parameters to the driver.
; Used for passing parameters to the driver
X1 := ptr1
Y1 := ptr2
X2 := ptr3
Y2 := ptr4
TEMP := tmp3
TEMP2 := tmp4
TEMP3 := sreg
TEMP4 := sreg+1
; Line routine stuff (must be on zpage)
PB := ptr3 ; (2) LINE
UB := ptr4 ; (2) LINE
ERR := regsave ; (2) LINE
NX := regsave+2 ; (2) LINE
; ------------------------------------------------------------------------
.segment "JUMPTABLE"
@ -99,26 +84,13 @@ NX := regsave+2 ; (2) LINE
.bss
; Absolute variables used in the code
ERROR: .res 1 ; Error code
MIX: .res 1 ; 4 lines of text
; Line routine stuff
COUNT: .res 2
NY: .res 2
DX: .res 1
DY: .res 1
AX: .res 1
AY: .res 1
; ------------------------------------------------------------------------
.rodata
; Constants and tables
DEFPALETTE: .byte $00, $01, $02, $03, $04, $05, $06, $07
.byte $08, $09, $0A, $0B, $0C, $0D, $0E, $0F
@ -333,226 +305,6 @@ GETPIXEL:
bit $C080 ; Switch in LC bank 2 for R/O
rts
; LINE: Draw a line from X1/Y1 to X2/Y2, where X1/Y1 = ptr1/ptr2 and
; X2/Y2 = ptr3/ptr4 using the current drawing color.
; Must set an error code: NO
LINE:
; nx = abs (x2 - x1)
sec
lda X2
sbc X1
sta NX
lda X2+1
sbc X1+1
tay
lda NX
jsr abs
sta NX
sty NX+1
; ny = abs (y2 - y1)
sec
lda Y2
sbc Y1
sta NY
lda Y2+1
sbc Y1+1
tay
lda NY
jsr abs
sta NY
sty NY+1
; if (x2 >= x1)
ldx #X2
lda X1
ldy X1+1
jsr icmp
bcc :+
; dx = 1
lda #$01
bne :++
; else
; dx = -1
: lda #$FF
: sta DX
; if (y2 >= y1)
ldx #Y2
lda Y1
ldy Y1+1
jsr icmp
bcc :+
; dy = 1
lda #$01
bne :++
; else
; dy = -1
: lda #$FF
: sta DY
; err = ax = ay = 0
lda #$00
sta ERR
sta ERR+1
sta AX
sta AY
; if (nx < ny) {
ldx #NX
lda NY
ldy NY+1
jsr icmp
bcs :+
; nx <-> ny
lda NX
ldx NY
sta NY
stx NX
lda NX+1
ldx NY+1
sta NY+1
stx NX+1
; ax = dx
lda DX
sta AX
; ay = dy
lda DY
sta AY
; dx = dy = 0 }
lda #$00
sta DX
sta DY
; ny = - ny
: lda NY
ldy NY+1
jsr neg
sta NY
sty NY+1
; for (count = nx; count > 0; --count) {
lda NX
ldx NX+1
sta COUNT
stx COUNT+1
for: lda COUNT ; count > 0
ora COUNT+1
bne :+
rts
; setpixel (X1, Y1)
: jsr SETPIXEL
; pb = err + ny
clc
lda ERR
adc NY
sta PB
lda ERR+1
adc NY+1
sta PB+1
tax
; ub = pb + nx
clc
lda PB
adc NX
sta UB
txa
adc NX+1
sta UB+1
; x1 = x1 + dx
ldx #$00
lda DX
bpl :+
dex
: clc
adc X1
sta X1
txa
adc X1+1
sta X1+1
; y1 = y1 + ay
ldx #$00
lda AY
bpl :+
dex
: clc
adc Y1
sta Y1
txa
adc Y1+1
sta Y1+1
; if (abs (pb) < abs (ub)) {
lda PB
ldy PB+1
jsr abs
sta TEMP3
sty TEMP4
lda UB
ldy UB+1
jsr abs
ldx #TEMP3
jsr icmp
bpl :+
; err = pb }
lda PB
ldx PB+1
jmp next
; else { x1 = x1 + ax
: ldx #$00
lda AX
bpl :+
dex
: clc
adc X1
sta X1
txa
adc X1+1
sta X1+1
; y1 = y1 + dy
ldx #$00
lda DY
bpl :+
dex
: clc
adc Y1
sta Y1
txa
adc Y1+1
sta Y1+1
; err = ub }
lda UB
ldx UB+1
next: sta ERR
stx ERR+1
; } (--count)
lda COUNT
sec
sbc #$01
sta COUNT
bcc :+
jmp for
: dec COUNT+1
jmp for
; BAR: Draw a filled rectangle with the corners X1/Y1, X2/Y2, where
; X1/Y1 = ptr1/ptr2 and X2/Y2 = ptr3/ptr4 using the current drawing color.
; Contrary to most other functions, the graphics kernel will sort and clip
@ -580,46 +332,6 @@ BAR:
bit $C080 ; Switch in LC bank 2 for R/O
rts
; Copies of some runtime routines
; ------------------------------------------------------------------------
abs:
; A/Y := abs (A/Y)
cpy #$00
bpl :+
; A/Y := neg (A/Y)
neg: clc
eor #$FF
adc #$01
pha
tya
eor #$FF
adc #$00
tay
pla
: rts
icmp:
; Compare A/Y to zp,X
sta TEMP ; TEMP/TEMP2 - arg2
sty TEMP2
lda $00,x
pha
lda $01,x
tay
pla
tax
tya ; X/A - arg1 (a = high)
sec
sbc TEMP2
bne :++
cpx TEMP
beq :+
adc #$FF
ora #$01
: rts
: bvc :+
eor #$FF
ora #$01
: rts
.include "../tgi/tgidrv_line.inc"

View File

@ -99,17 +99,10 @@ Y1 = ptr2
X2 = ptr3
Y2 = ptr4
ADDR = tmp1 ; (2) CALC
TEMP = tmp3 ; CALC icmp
TEMP2 = tmp4 ; icmp
TEMP3 = sreg ; LINE
TEMP4 = sreg+1 ; LINE
; Line routine stuff (must be on zpage)
PB = ptr3 ; (2) LINE
UB = ptr4 ; (2) LINE
ERR = regsave ; (2) LINE
NX = regsave+2 ; (2) LINE
ADDR = tmp1
TEMP = tmp3
TEMP2 = tmp4 ; HORLINE
TEMP3 = sreg ; HORLINE
; Absolute variables used in the code
@ -124,15 +117,6 @@ BITMASK: .res 1 ; $00 = clear, $FF = set pixels
OLDCOLOR: .res 1 ; colors before entering gfx mode
; Line routine stuff
COUNT: .res 2
NY: .res 2
DX: .res 1
DY: .res 1
AX: .res 1
AY: .res 1
; Text output stuff
TEXTMAGX: .res 1
TEXTMAGY: .res 1
@ -541,207 +525,6 @@ GETPIXEL:
ldx #$00 ; Clear high byte
rts
; ------------------------------------------------------------------------
; LINE: Draw a line from X1/Y1 to X2/Y2, where X1/Y1 = ptr1/ptr2 and
; X2/Y2 = ptr3/ptr4 using the current drawing color.
;
; Must set an error code: NO
;
LINE:
; nx = abs(x2 - x1)
lda X2
sec
sbc X1
sta NX
lda X2+1
sbc X1+1
tay
lda NX
jsr abs
sta NX
sty NX+1
; ny = abs(y2 - y1)
lda Y2
sec
sbc Y1
sta NY
lda Y2+1
sbc Y1+1
tay
lda NY
jsr abs
sta NY
sty NY+1
; if (x2>=x1)
ldx #X2
lda X1
ldy X1+1
jsr icmp
bcc @L0243
; dx = 1;
lda #1
bne @L0244
; else
; dx = -1;
@L0243: lda #$ff
@L0244: sta DX
; if (y2>=y1)
ldx #Y2
lda Y1
ldy Y1+1
jsr icmp
bcc @L024A
; dy = 1;
lda #1
bne @L024B
; else
; dy = -1;
@L024A: lda #$ff
@L024B: sta DY
; err = ax = ay = 0;
lda #0
sta ERR
sta ERR+1
sta AX
sta AY
; if (nx<ny) {
ldx #NX
lda NY
ldy NY+1
jsr icmp
bcs @L0255
; nx <-> ny
lda NX
ldx NY
sta NY
stx NX
lda NX+1
ldx NY+1
sta NY+1
stx NX+1
; ax = dx
lda DX
sta AX
; ay = dy
lda DY
sta AY
; dx = dy = 0;
lda #0
sta DX
sta DY
; ny = - ny;
@L0255: lda NY
ldy NY+1
jsr neg
sta NY
sty NY+1
; for (count=nx;count>0;--count) {
lda NX
ldx NX+1
sta COUNT
stx COUNT+1
@L0166: lda COUNT ; count>0
ora COUNT+1
bne @L0167
rts
; setpixel(X1,Y1)
@L0167: jsr SETPIXEL
; pb = err + ny
lda ERR
clc
adc NY
sta PB
lda ERR+1
adc NY+1
sta PB+1
tax
; ub = pb + nx
lda PB
clc
adc NX
sta UB
txa
adc NX+1
sta UB+1
; x1 = x1 + dx
ldx #0
lda DX
bpl @L027B
dex
@L027B: clc
adc X1
sta X1
txa
adc X1+1
sta X1+1
; y1 = y1 + ay
ldx #0
lda AY
bpl @L027E
dex
@L027E: clc
adc Y1
sta Y1
txa
adc Y1+1
sta Y1+1
; if (abs(pb)<abs(ub)) {
lda PB
ldy PB+1
jsr abs
sta TEMP3
sty TEMP4
lda UB
ldy UB+1
jsr abs
ldx #TEMP3
jsr icmp
bpl @L027F
; err = pb
lda PB
ldx PB+1
jmp @L0312
; } else { x1 = x1 + ax
@L027F:
ldx #0
lda AX
bpl @L0288
dex
@L0288: clc
adc X1
sta X1
txa
adc X1+1
sta X1+1
; y1 = y1 + dy
ldx #0
lda DY
bpl @L028B
dex
@L028B: clc
adc Y1
sta Y1
txa
adc Y1+1
sta Y1+1
; err = ub }
lda UB
ldx UB+1
@L0312:
sta ERR
stx ERR+1
; } (--count)
sec
lda COUNT
sbc #1
sta COUNT
bcc @L0260
jmp @L0166
@L0260: dec COUNT+1
jmp @L0166
; ------------------------------------------------------------------------
; BAR: Draw a filled rectangle with the corners X1/Y1, X2/Y2, where
; X1/Y1 = ptr1/ptr2 and X2/Y2 = ptr3/ptr4 using the current drawing color.
@ -960,49 +743,6 @@ CALC:
tax
rts
;-------------
; copies of some runtime routines
abs:
; a/y := abs(a/y)
cpy #$00
bpl absend
; negay
neg: eor #$ff
add #1
pha
tya
eor #$ff
adc #0
tay
pla
absend: rts
icmp:
; compare a/y to zp,x
sta TEMP ; TEMP/TEMP2 - arg2
sty TEMP2
lda $0,x
pha
lda $1,x
tay
pla
tax
tya ; x/a - arg1 (a=high)
sec
sbc TEMP2
bne @L4
cpx TEMP
beq @L3
adc #$ff
ora #$01
@L3: rts
@L4: bvc @L3
eor #$ff
ora #$01
rts
;-------------
; VDC helpers
@ -1033,3 +773,6 @@ VDCWriteReg:
sta VDC_DATA_REG
rts
; ------------------------------------------------------------------------
.include "../tgi/tgidrv_line.inc"

View File

@ -100,17 +100,10 @@ Y1 = ptr2
X2 = ptr3
Y2 = ptr4
ADDR = tmp1 ; (2) CALC
TEMP = tmp3 ; CALC icmp
TEMP2 = tmp4 ; icmp
TEMP3 = sreg ; LINE
TEMP4 = sreg+1 ; LINE
; Line routine stuff (must be on zpage)
PB = ptr3 ; (2) LINE
UB = ptr4 ; (2) LINE
ERR = regsave ; (2) LINE
NX = regsave+2 ; (2) LINE
ADDR = tmp1
TEMP = tmp3
TEMP2 = tmp4 ; HORLINE
TEMP3 = sreg ; HORLINE
; Absolute variables used in the code
@ -123,15 +116,6 @@ BITMASK: .res 1 ; $00 = clear, $FF = set pixels
OLDCOLOR: .res 1 ; colors before entering gfx mode
; Line routine stuff
COUNT: .res 2
NY: .res 2
DX: .res 1
DY: .res 1
AX: .res 1
AY: .res 1
; Text output stuff
TEXTMAGX: .res 1
TEXTMAGY: .res 1
@ -539,207 +523,6 @@ GETPIXEL:
ldx #$00 ; Clear high byte
rts
; ------------------------------------------------------------------------
; LINE: Draw a line from X1/Y1 to X2/Y2, where X1/Y1 = ptr1/ptr2 and
; X2/Y2 = ptr3/ptr4 using the current drawing color.
;
; Must set an error code: NO
;
LINE:
; nx = abs(x2 - x1)
lda X2
sec
sbc X1
sta NX
lda X2+1
sbc X1+1
tay
lda NX
jsr abs
sta NX
sty NX+1
; ny = abs(y2 - y1)
lda Y2
sec
sbc Y1
sta NY
lda Y2+1
sbc Y1+1
tay
lda NY
jsr abs
sta NY
sty NY+1
; if (x2>=x1)
ldx #X2
lda X1
ldy X1+1
jsr icmp
bcc @L0243
; dx = 1;
lda #1
bne @L0244
; else
; dx = -1;
@L0243: lda #$ff
@L0244: sta DX
; if (y2>=y1)
ldx #Y2
lda Y1
ldy Y1+1
jsr icmp
bcc @L024A
; dy = 1;
lda #1
bne @L024B
; else
; dy = -1;
@L024A: lda #$ff
@L024B: sta DY
; err = ax = ay = 0;
lda #0
sta ERR
sta ERR+1
sta AX
sta AY
; if (nx<ny) {
ldx #NX
lda NY
ldy NY+1
jsr icmp
bcs @L0255
; nx <-> ny
lda NX
ldx NY
sta NY
stx NX
lda NX+1
ldx NY+1
sta NY+1
stx NX+1
; ax = dx
lda DX
sta AX
; ay = dy
lda DY
sta AY
; dx = dy = 0;
lda #0
sta DX
sta DY
; ny = - ny;
@L0255: lda NY
ldy NY+1
jsr neg
sta NY
sty NY+1
; for (count=nx;count>0;--count) {
lda NX
ldx NX+1
sta COUNT
stx COUNT+1
@L0166: lda COUNT ; count>0
ora COUNT+1
bne @L0167
rts
; setpixel(X1,Y1)
@L0167: jsr SETPIXEL
; pb = err + ny
lda ERR
clc
adc NY
sta PB
lda ERR+1
adc NY+1
sta PB+1
tax
; ub = pb + nx
lda PB
clc
adc NX
sta UB
txa
adc NX+1
sta UB+1
; x1 = x1 + dx
ldx #0
lda DX
bpl @L027B
dex
@L027B: clc
adc X1
sta X1
txa
adc X1+1
sta X1+1
; y1 = y1 + ay
ldx #0
lda AY
bpl @L027E
dex
@L027E: clc
adc Y1
sta Y1
txa
adc Y1+1
sta Y1+1
; if (abs(pb)<abs(ub)) {
lda PB
ldy PB+1
jsr abs
sta TEMP3
sty TEMP4
lda UB
ldy UB+1
jsr abs
ldx #TEMP3
jsr icmp
bpl @L027F
; err = pb
lda PB
ldx PB+1
jmp @L0312
; } else { x1 = x1 + ax
@L027F:
ldx #0
lda AX
bpl @L0288
dex
@L0288: clc
adc X1
sta X1
txa
adc X1+1
sta X1+1
; y1 = y1 + dy
ldx #0
lda DY
bpl @L028B
dex
@L028B: clc
adc Y1
sta Y1
txa
adc Y1+1
sta Y1+1
; err = ub }
lda UB
ldx UB+1
@L0312:
sta ERR
stx ERR+1
; } (--count)
sec
lda COUNT
sbc #1
sta COUNT
bcc @L0260
jmp @L0166
@L0260: dec COUNT+1
jmp @L0166
; ------------------------------------------------------------------------
; BAR: Draw a filled rectangle with the corners X1/Y1, X2/Y2, where
; X1/Y1 = ptr1/ptr2 and X2/Y2 = ptr3/ptr4 using the current drawing color.
@ -974,49 +757,6 @@ CALC:
tax
rts
;-------------
; copies of some runtime routines
abs:
; a/y := abs(a/y)
cpy #$00
bpl absend
; negay
neg: eor #$ff
add #1
pha
tya
eor #$ff
adc #0
tay
pla
absend: rts
icmp:
; compare a/y to zp,x
sta TEMP ; TEMP/TEMP2 - arg2
sty TEMP2
lda $0,x
pha
lda $1,x
tay
pla
tax
tya ; x/a - arg1 (a=high)
sec
sbc TEMP2
bne @L4
cpx TEMP
beq @L3
adc #$ff
ora #$01
@L3: rts
@L4: bvc @L3
eor #$ff
ora #$01
rts
;-------------
; VDC helpers
@ -1047,3 +787,6 @@ VDCWriteReg:
sta VDC_DATA_REG
rts
; ------------------------------------------------------------------------
.include "../tgi/tgidrv_line.inc"

310
libsrc/tgi/tgidrv_line.inc Normal file
View File

@ -0,0 +1,310 @@
;
; Oliver Schmidt <ol.sc@web.de>
;
; Generic LINE implementation based on SETPIXEL for TGI driver inclusion
; Code previously present in a2.lo.tgi, c128-vdc.tgi and c128-vdc2.tgi
;
; ------------------------------------------------------------------------
; LINE: Draw a line from X1/Y1 to X2/Y2, where X1/Y1 = ptr1/ptr2 and
; X2/Y2 = ptr3/ptr4 using the current drawing color.
; Must set an error code: NO
.proc LINE
; Used for passing parameters to the driver.
X1 := ptr1
Y1 := ptr2
X2 := ptr3
Y2 := ptr4
; These ones must be on zpage.
TEMP1 := tmp3
TEMP2 := tmp4
TEMP3 := sreg
TEMP4 := sreg+1
PB := ptr3
UB := ptr4
ERR := regsave
NX := regsave+2
; ------------------------------------------------------------------------
.bss
COUNT: .res 2
NY: .res 2
DX: .res 1
DY: .res 1
AX: .res 1
AY: .res 1
; ------------------------------------------------------------------------
.code
; nx = abs (x2 - x1)
sec
lda X2
sbc X1
sta NX
lda X2+1
sbc X1+1
tay
lda NX
jsr abs
sta NX
sty NX+1
; ny = abs (y2 - y1)
sec
lda Y2
sbc Y1
sta NY
lda Y2+1
sbc Y1+1
tay
lda NY
jsr abs
sta NY
sty NY+1
; if (x2 >= x1)
ldx #X2
lda X1
ldy X1+1
jsr icmp
bcc :+
; dx = 1
lda #$01
bne :++
; else
; dx = -1
: lda #$FF
: sta DX
; if (y2 >= y1)
ldx #Y2
lda Y1
ldy Y1+1
jsr icmp
bcc :+
; dy = 1
lda #$01
bne :++
; else
; dy = -1
: lda #$FF
: sta DY
; err = ax = ay = 0
lda #$00
sta ERR
sta ERR+1
sta AX
sta AY
; if (nx < ny) {
ldx #NX
lda NY
ldy NY+1
jsr icmp
bcs :+
; nx <-> ny
lda NX
ldx NY
sta NY
stx NX
lda NX+1
ldx NY+1
sta NY+1
stx NX+1
; ax = dx
lda DX
sta AX
; ay = dy
lda DY
sta AY
; dx = dy = 0 }
lda #$00
sta DX
sta DY
; ny = - ny
: lda NY
ldy NY+1
jsr neg
sta NY
sty NY+1
; for (count = nx; count > 0; --count) {
lda NX
ldx NX+1
sta COUNT
stx COUNT+1
for: lda COUNT ; count > 0
ora COUNT+1
bne :+
rts
; setpixel (X1, Y1)
: jsr SETPIXEL
; pb = err + ny
clc
lda ERR
adc NY
sta PB
lda ERR+1
adc NY+1
sta PB+1
tax
; ub = pb + nx
clc
lda PB
adc NX
sta UB
txa
adc NX+1
sta UB+1
; x1 = x1 + dx
ldx #$00
lda DX
bpl :+
dex
: clc
adc X1
sta X1
txa
adc X1+1
sta X1+1
; y1 = y1 + ay
ldx #$00
lda AY
bpl :+
dex
: clc
adc Y1
sta Y1
txa
adc Y1+1
sta Y1+1
; if (abs (pb) < abs (ub)) {
lda PB
ldy PB+1
jsr abs
sta TEMP3
sty TEMP4
lda UB
ldy UB+1
jsr abs
ldx #TEMP3
jsr icmp
bpl :+
; err = pb }
lda PB
ldx PB+1
jmp next
; else { x1 = x1 + ax
: ldx #$00
lda AX
bpl :+
dex
: clc
adc X1
sta X1
txa
adc X1+1
sta X1+1
; y1 = y1 + dy
ldx #$00
lda DY
bpl :+
dex
: clc
adc Y1
sta Y1
txa
adc Y1+1
sta Y1+1
; err = ub }
lda UB
ldx UB+1
next: sta ERR
stx ERR+1
; } (--count)
lda COUNT
sec
sbc #$01
sta COUNT
bcc :+
jmp for
: dec COUNT+1
jmp for
; Copies of some runtime routines
abs:
; A/Y := abs (A/Y)
cpy #$00
bpl :+
; A/Y := neg (A/Y)
neg: clc
eor #$FF
adc #$01
pha
tya
eor #$FF
adc #$00
tay
pla
: rts
icmp:
; Compare A/Y to zp,X
sta TEMP1 ; TEMP1/TEMP2 - arg2
sty TEMP2
lda $00,x
pha
lda $01,x
tay
pla
tax
tya ; X/A - arg1 (a = high)
sec
sbc TEMP2
bne :++
cpx TEMP1
beq :+
adc #$FF
ora #$01
: rts
: bvc :+
eor #$FF
ora #$01
: rts
.endproc