From b39f886741666512d65f544d2ef10a4eb3996ec9 Mon Sep 17 00:00:00 2001 From: Bobbi Webber-Manners Date: Tue, 3 Jan 2023 18:10:03 -0500 Subject: [PATCH] First hack at Bresenham. Only x-dominant lines so far. --- applecorn.po | Bin 819200 -> 819200 bytes mainmem.shr.s | 206 +++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 197 insertions(+), 9 deletions(-) diff --git a/applecorn.po b/applecorn.po index c5cc183c40f4adce53c2a05bba4e80f192ed06f6..07746d95220c2210aae01232b5b39f33a4a0a267 100644 GIT binary patch delta 5363 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

Y-BOYDuuHtitBEGz*Y7tBf;B@~;L zJ0x2S@_Q+X9{?#SbPw{!AU?~UX3z|N_+Izx0z46vMmHWaM5UKB1`uG%$vy$1NWfO^ zAVbJ+AcH@u9m%oktxr-NjtBKAhgnpg=~4B{p)TCh2_~PT+(K;OGE16RO3nzS|2Jz# zw$}d3=7svC<-#s3l?l5^m9+g9i%L1=ss3m216fPL+ni{gVeRS z`&X=35io+}KDM8yD6%@K(&CP9s+kIu6;b{GQxk;=)8}&Hi8PyLnrS!z_OvE;nE$GK mr3}Xg%5uGiX7M9{JY%#{U9}`?&1@ diff --git a/mainmem.shr.s b/mainmem.shr.s index 2f6a157..030b15d 100644 --- a/mainmem.shr.s +++ b/mainmem.shr.s @@ -19,6 +19,10 @@ SHRPIXELS DB $00 ; Main memory copy of VDUPIXELS SHRVDUQ DS 16 ; Main memory copy of VDUQ SHRGFXMASK DB $00 ; Colour mask for point plotting SHRGFXACTION DB $00 ; GCOL action for point plotting +SHRXPIXEL DW $0000 ; Previous point in screen coords +SHRYPIXEL DW $0000 ; Previous point in screen coords +SHRTMPWRD DW $0000 ; Temp scratch space + * Explode font to generate SHRFONTXPLD table @@ -218,7 +222,39 @@ SHRCHAR640 PHY ; Preserve Y * TODO: Only does point plotting ATM SHRPLOT >>> ENTMAIN JSR SHRCOORD ; Convert coordinates -SHRPLOT2 LDX A2L ; Screen row (Y-coord) + LDA A1L ; Preserve converted x + PHA + LDA A1H + PHA + LDA A2L ; Preserve converted y + PHA + LDA SHRVDUQ+4 ; k + AND #$F0 ; Keep MS nybble + CMP #$00 ; Move or draw line + BNE :S1 + JSR SHRLINE + BRA :S2 +:S1 CMP #$40 ; Plot point + BNE :BAIL ; Other? Bail out + JSR SHRPOINT + BRA :S2 +:S2 PLA ; Store prev pt in screen coords + STA SHRYPIXEL+0 + STZ SHRYPIXEL+1 + PLA + STA SHRXPIXEL+1 + PLA + STA SHRXPIXEL+0 +:DONE >>> XF2AUX,GFXPLOTRET +:BAIL PLA + PLA + PLA + BRA :DONE + +* Plot a point +* Called in emulation mode or 8 bit native mode +SHRPOINT + LDX A2L ; Screen row (Y-coord) LDA SHRROWSL,X ; Look up addr (LS byte) STA A3L ; Stash in A3L LDA SHRROWSH,X ; Look up addr (MS byte) @@ -285,7 +321,6 @@ SHRPLOTSET TAX ; Keep copy of bit pattern AND SHRGFXMASK ; Mask to set colour ORA A1L ; OR into existing byte STA [A3L],Y ; Write to screen - >>> XF2AUX,GFXPLOTRET RTS @@ -294,7 +329,6 @@ SHRPLOTSET TAX ; Keep copy of bit pattern SHRPLOTOR AND SHRGFXMASK ; Mask to set colour ORA [A3L],Y ; OR into existing byte STA [A3L],Y ; Write to screen - >>> XF2AUX,GFXPLOTRET RTS @@ -312,7 +346,6 @@ SHRPLOTAND TAX ; Keep copy of bit pattern AND [A3L],Y ; Mask remaining bits ORA A1L ; Combine STA [A3L],Y ; Write to screen - >>> XF2AUX,GFXPLOTRET RTS @@ -321,7 +354,6 @@ SHRPLOTAND TAX ; Keep copy of bit pattern SHRPLOTXOR AND SHRGFXMASK ; Mask to set colour EOR [A3L],Y ; EOR into existing byte STA [A3L],Y ; Write to screen - >>> XF2AUX,GFXPLOTRET RTS @@ -338,14 +370,12 @@ SHRPLOTNOT TAX ; Keep copy of bit pattern AND [A3L],Y ; Mask remaining bits ORA A1L ; Combine STA [A3L],Y ; Write to screen - >>> XF2AUX,GFXPLOTRET RTS * NO-OP (GCOL action 5) * Pixel bit pattern in A -SHRPLOTNOP >>> XF2AUX,GFXPLOTRET - RTS +SHRPLOTNOP RTS * Clear (GCOL action 6) @@ -353,7 +383,165 @@ SHRPLOTNOP >>> XF2AUX,GFXPLOTRET SHRPLOTCLR EOR #$FF ; Invert bits AND [A3L],Y ; Load existing byte, clearing pixel STA [A3L],Y ; Write to screen - >>> XF2AUX,GFXPLOTRET + RTS + + +* Bresenham line drawing algorithm, entry point +* x0 is in SHRXPIXEL+0,SHRPIXEL+1 +* y0 is in SHRYPIXEL +* x1 in A1L,A1H +* y1 in A2L +* Called in emulation mode. +SHRLINE LDA A2L ; y1 + SEC + SBC SHRYPIXEL ; Subtract y0 + BPL :S1 ; Skip if +ve + EOR #$FF ; Negate if -ve + INC A +:S1 STA SHRTMPWRD+0 ; abs(y1 - y0) + STZ SHRTMPWRD+1 ; Pad to 16 bit + PHP ; Disable interrupts + SEI + CLC ; 65816 native mode + XCE + REP #$30 ; 16 bit M & X + MX %00 ; Tell Merlin + LDA A1L ; Load x1 (A1L,A1H) + SEC + SBC SHRXPIXEL ; Subtract x0 + BPL :S2 ; Skip if +ve + EOR #$FFFF ; Negate if -ve + INC A +:S2 CMP SHRTMPWRD ; Cmp abs(x1 - x0) w/ abs(y1 - y0) + BCC :YDOM ; abs(x1 - x0) < abs(y1 - y0) + +:XDOM LDA SHRXPIXEL ; x0 + CMP A1L ; x1 + BCS :X1 ; x0 >= x1 + JMP SHRLINELO ; x0 < x1 +:X1 JSR SHRLINESWAP ; Swap parms + JMP SHRLINELO + +:YDOM SEP #$30 ; 8 bit M & X + MX %11 ; Tell Merlin + LDA SHRYPIXEL ; y0 + CMP A2L ; y1 + BCS :Y1 ; y0 >= y1 + REP #$30 ; 16 bit M & X + MX %00 ; Tell Merlin + + JMP SHRLINEHI ; y0 < y1 +:Y1 JSR SHRLINESWAP ; Swap parms + JMP SHRLINEHI + + +* Swap (x0, y0) and (x1, y1) +* Called in 16 bit 65816 native mode +SHRLINESWAP LDA SHRXPIXEL ; x0 + STA SHRTMPWRD + LDA A1L ; x1 + STA SHRXPIXEL + LDA SHRTMPWRD + STA SHRXPIXEL + SEP #$30 ; 8 bit M & X + MX %11 ; Tell Merlin + LDA SHRYPIXEL ; y0 + STA SHRTMPWRD + LDA A2L ; y1 + STA SHRYPIXEL + LDA SHRTMPWRD + STA SHRYPIXEL + REP #$30 ; 16 bit M & X + MX %00 ; Tell Merlin + RTS + + +* Plot x-dominant line (shallow gradient) +* Called in 16 bit 65816 native mode. Returns in emulation mode. +SHRLINELO LDA A1L ; x1 + STA :LIM ; We re-use A1L/H later + SEC + SBC SHRXPIXEL ; Subtract x0 + STA :DX + SEP #$30 ; 8 bit M & X + MX %11 ; Tell Merlin + LDA A2L ; y1 + SEC + SBC SHRYPIXEL ; Subtract y0 + STA :DY+0 + STZ :DY+1 + REP #$30 ; 16 bit M & X + MX %00 ; Tell Merlin + LDA #$0001 + STA :YI ; yi = 1 + LDA :DY + BPL :S1 ; Skip if dy = 0 + EOR #$FFFF ; Negate dy + INC A + STA :DY ; dy = -dy + LDA #$FFFF + STA :YI ; yi = -1 +:S1 LDA :DY ; dy + ASL ; 2 * dy + SEC + SBC :DX ; (2 * dy) - dx + STA :D ; D = (2 * dy) - dx + LDA SHRYPIXEL ; y0 + STA A2L ; y = y0 (re-using A2L/H) + LDA :DY + SEC + SBC :DX + ASL + STA :DX ; DX now (2 * (dy - dx) + LDA :DY + ASL + STA :DY ; DY now (2 * dy) + LDX SHRXPIXEL ; x = x0 +:L1 STX A1L ; Store x-coord for SHRPOINT + PHX + SEP #$30 ; 8 bit M & X + MX %11 ; Tell Merlin + JSR SHRPOINT ; x in A1L/H, y in A2L + REP #$30 ; 16 bit M & X + MX %00 ; Tell Merlin + PLX + LDA :D + BMI :S2 ; D < 0 + CLC + ADC :DX + STA :D ; D = D + (2 * (dy - dx)) + LDA A2L ; y + CLC + ADC :YI + STA A2L ; y = y + yi + BRA :S3 +:S2 CLC + ADC :DY + STA :D ; D = D + 2 * dy +:S3 INX + CPX :LIM ; Compare with x1 + BNE :L1 + + SEC ; 65816 emulation mode + XCE + MX %11 ; Tell Merlin + PLP ; Resume normal service + RTS +:DX DW $0000 ; dx initially, then (2 * (dy - dx)) +:DY DW $0000 ; dy initially, then (2 * dy) +:YI DW $0000 ; +1 or -1 +:D DW $0000 ; D +:LIM DW $0000 ; x1 gets stashed here + + +* Plot y-dominant line (steep gradient) +* Called in 16 bit 65816 native mode. Returns in emulation mode. +SHRLINEHI +* TODO: Write me! + SEC ; 65816 emulation mode + XCE + MX %11 ; Tell Merlin + PLP ; Resume normal service RTS