diff --git a/graphics/gr/lines/Makefile b/graphics/gr/lines/Makefile index 794d1157..65150634 100644 --- a/graphics/gr/lines/Makefile +++ b/graphics/gr/lines/Makefile @@ -7,13 +7,14 @@ EMPTYDISK = ../../../empty_disk/empty.dsk all: lines.dsk -lines.dsk: HELLO LINES LINES_SMALL LINES_ROM LINES_WIKI +lines.dsk: HELLO LINES LINES_SMALL LINES_ROM LINES_WIKI LINES_BOT cp $(EMPTYDISK) lines.dsk $(DOS33) -y lines.dsk SAVE A HELLO $(DOS33) -y lines.dsk BSAVE -a 0xC00 LINES $(DOS33) -y lines.dsk BSAVE -a 0xC00 LINES_SMALL $(DOS33) -y lines.dsk BSAVE -a 0xC00 LINES_ROM $(DOS33) -y lines.dsk BSAVE -a 0xC00 LINES_WIKI + $(DOS33) -y lines.dsk BSAVE -a 0xC00 LINES_BOT ### @@ -52,8 +53,15 @@ LINES_WIKI: lines_wiki.o lines_wiki.o: lines_wiki.s ca65 -o lines_wiki.o lines_wiki.s -l lines_wiki.lst +### + +LINES_BOT: lines_bot.o + ld65 -o LINES_BOT lines_bot.o -C $(LINKERSCRIPTS)/apple2_c00.inc + +lines_bot.o: lines_bot.s + ca65 -o lines_bot.o lines_bot.s -l lines_bot.lst ### clean: - rm -f *~ *.o *.lst HELLO LINES LINES_SMALL LINES_ROM LINES_WIKI + rm -f *~ *.o *.lst HELLO LINES LINES_SMALL LINES_ROM LINES_WIKI LINES_BOT diff --git a/graphics/gr/lines/hardware.inc b/graphics/gr/lines/hardware.inc index 7eb03c89..8e0d0a83 100644 --- a/graphics/gr/lines/hardware.inc +++ b/graphics/gr/lines/hardware.inc @@ -39,7 +39,7 @@ NORMAL = $F273 ;; MONITOR ROUTINES -PLOT = $F800 ;; PLOT AT Y,A +PLOT = $F800 ;; PLOT AT Y,A (A colors output, Y preserved) PLOT1 = $F80E ;; PLOT at (GBASL),Y (need MASK to be $0f or $f0) SCRN2 = $F879 ;; set A to top or bottom nibble based on C HLINE = $F819 ;; HLINE Y,$2C at A diff --git a/graphics/gr/lines/lines_bot.s b/graphics/gr/lines/lines_bot.s new file mode 100644 index 00000000..f531aca0 --- /dev/null +++ b/graphics/gr/lines/lines_bot.s @@ -0,0 +1,242 @@ +; Bresenham Lines + +; by Vince `deater` Weaver + +; based on pseudo-code from +; https://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm + + + +.include "zp.inc" +.include "hardware.inc" + +; 174 -- initial +; 170 -- inline init +; 166 -- inline step +; 161 -- merge absolute_value/negative code +; 159 -- merging init X/Y paths +; 156 -- more merging X/Y init +; 154 -- note PLOT doesn't touch Y +; 152 -- merge into common_inc +; 151 -- share an RTS +; 150 -- use X when plotting +; 147 -- count down instead of up +; 144 -- mess around with how count set +; 142 -- who needs COUNT anyway +; 139 -- inline draw_line + +B_X1 = $F0 +B_Y1 = $F1 +B_X2 = $F2 +B_Y2 = $F3 +B_DX = $F4 +B_DY = $F5 +B_SX = $F6 +B_SY = $F7 +B_ERR = $F8 + +lines_bot: + + jsr SETGR ; set lo-res 40x40 mode + ; A=$D0 afterward + +restart: + lda #36 + sta B_Y2 +lines_loop: + pha + sta B_X2 + sta B_Y1 + + jsr NEXTCOL + + lda #0 + sta B_X1 + +;==================================== +; inline draw_line +;==================================== + + + + ;============================ + ; draw line + ; from x1,y1 to x2,y2 + ;============================ +draw_line: + + ; from wikipedia + + ; dx = abs(x2 - x1) + ; sx = x1 < x2 ? 1 : -1 + ; dy = -abs(y2 - y1) + ; sy = y1 < y2 ? 1 : -1 + ; err = dx+dy + +init_bresenham: + + ; dx = abs(x2-x1) + ; sx = x1= dy: + ; err = err + dy + ; x1 = x1 + sx + + + ; B_ERR already in A + cmp B_DY ; check equal first + beq do_x + + clc ; signed compare + sbc B_DY + bvc blah2 + eor #$80 +blah2: + bmi skip_x ; ble + +do_x: + lda B_DY + jsr common_inc +skip_x: + + + + inx ; setup common inc + + ; if err2 <= dx: + ; err = err + dx + ; y1 = y1 + sy + pla ; restore err2 + + clc ; signed compare + sbc B_DX + bvc blah + eor #$80 +blah: + bpl skip_y + +do_y: + lda B_DX + jsr common_inc + +skip_y: + + jmp line_loop + +;============================= +;end inline draw_line +;============================= + +; jsr draw_line + +end_inline_draw_line: + + pla + sec + sbc #4 ; update count + + bpl lines_loop + bmi restart + + + + + + + + ;===================================== + ; common increment + ;===================================== +common_inc: + + clc + adc B_ERR + sta B_ERR + + lda B_X1,X + clc + adc B_SX,X + sta B_X1,X +done_line: + rts + + + ;===================================== + ; init, do the abs and sx calculations + ; x=0, for X + ; x=1, for Y + ;===================================== +do_abs: + sec + lda B_X1,X + sbc B_X2,X ; A = x1 - x2 + + bmi is_neg + + ldy #$ff + bmi neg_done + +is_neg: + ldy #$1 +neg: + eor #$ff + clc + adc #1 + +neg_done: + sty B_SX,X + sta B_DX,X + rts + + jmp lines_bot diff --git a/graphics/gr/lines/lines_small.s b/graphics/gr/lines/lines_small.s index 803cf80c..a1c46f52 100644 --- a/graphics/gr/lines/lines_small.s +++ b/graphics/gr/lines/lines_small.s @@ -19,6 +19,7 @@ ; 154 -- note PLOT doesn't touch Y ; 152 -- merge into common_inc ; 151 -- share an RTS +; 150 -- use X when plotting B_X1 = $F0 B_Y1 = $F1 @@ -36,7 +37,7 @@ lines: jsr SETGR ; set lo-res 40x40 mode ; A=$D0 afterward - +restart: lda #0 sta COUNT lines_loop: @@ -50,8 +51,8 @@ lines_loop: lda COUNT cmp #10 -end: - beq end +;end: + beq restart asl asl @@ -109,7 +110,8 @@ line_loop: ; plot X1,Y1 ldy B_X1 - lda B_Y1 + ldx B_Y1 + txa jsr PLOT ; PLOT AT Y,A (A colors output, Y preserved) ; check if hit end @@ -118,52 +120,51 @@ line_loop: cpy B_X2 bne line_no_end - lda B_Y1 - cmp B_Y2 +; lda B_Y1 + cpx B_Y2 beq done_line line_no_end: ;======================== - ; step + ; step bresenham ;======================== -step_bresenham: - ; err2 = 2*err lda B_ERR asl - pha ; push err2 + pha ; save err2 for later + + ldx #0 ; setup for common_inc ; if err2 >= dy: ; err = err + dy ; x1 = x1 + sx - ; signed compare - ldx #0 - clc - cmp B_DY + ; B_ERR already in A + cmp B_DY ; check equal first beq do_x + + clc ; signed compare sbc B_DY bvc blah2 eor #$80 blah2: bmi skip_x ; ble - do_x: lda B_DY - jsr common_inc skip_x: + inx ; setup common inc + ; if err2 <= dx: ; err = err + dx ; y1 = y1 + sy - pla ; pop err2 - inx + pla ; restore err2 clc ; signed compare sbc B_DX @@ -226,17 +227,3 @@ neg_done: rts - -;B_X1 = $F0 00 -;B_Y1 = $F1 00 -;B_X2 = $F2 00 -;B_Y2 = $F3 $23 = 35 -;B_DX = $F4 $00 -;B_DY = $F5 $DD = -35 -;B_SX = $F6 $FF = -1 -;B_SY = $F7 $01 = 1 -;B_ERR = $F8 $DD = -35 - -; E2=2*ERR = 1101 1101 1011 1010 = 0100 0110 = $46 = -70 -; if -70 >= -35 .... no -; if -70 <= 0 ... yes, err=err+dx, -35+0=-35