DrawPointNop ret ; D=X, E=Y; Preserve: BC, HL, IX EllipseGetPixelInfo push bc ld a,d ; For future reference. ; hl = (e*12)+Lcd.Buffer ld h,0 ld l,e add hl,hl add hl,hl ld d,h ld e,l add hl,hl add hl,de ld de,(Lcd.Buffer) add hl,de ; de = a\8 ld d,0 ld e,a srl e srl e srl e ; hl = (l*12)+Lcd.Buffer+(a\8) add hl,de and 7 push hl ld l,a ld h,PointOffsets>>8 ld a,(hl) pop hl pop bc ret DrawPointW push hl call EllipseGetPixelInfo cpl and (hl) ld (hl),a pop hl ret DrawPointB push hl call EllipseGetPixelInfo or (hl) ld (hl),a pop hl ret DrawPointE push hl call EllipseGetPixelInfo xor (hl) ld (hl),a pop hl ret ;------------------------------------------------------------------------------- ; ; === HLineFill === ; ; Fills a horizontal line segment with the specified pattern. ; ; INPUTS: ; ; REGISTERS ; * A - Y co-ordinate ; * B - Line x1 (pixel offset from DE) ; * C - Line x2 (pixel offset from DE) ; ; MEMORY ; * ellipseCanvas - screen buffer address ; * ellipseFillPattern - address of 8x8 pixel (8 byte) pattern ; ;------------------------------------------------------------------------------- .for FillMode = 0 to 4 .if FillMode == PlotMode.Plot HLineFill.Plot .elseif FillMode == PlotMode.Or HLineFill.Or .elseif FillMode == PlotMode.And HLineFill.And .elseif FillMode == PlotMode.Eor HLineFill.Eor .elseif FillMode == PlotMode.Invert HLineFill.Invert .endif eval(".module HLineFill_" + FillMode) ;------------------------------------------------------------------- ; Calculate A * 12 and offset into canvas ;------------------------------------------------------------------- push bc ; [11] push af ; [11] ld l, a ; [4] add a, a ; [4] * 2 add a, l ; [4] * 3 ld l, a ; [4] ld h, 0 ; [7] add hl, hl ; [11] * 6 add hl, hl ; [11] * 12 ld de, (Lcd.Buffer) ; [10/20] add hl, de ; [11] ex de, hl ; [4] pop af ; [10] ;------------------------------------------------------------------- ; Load pattern byte ;------------------------------------------------------------------- and $07 ld hl, ellipseFillPattern ; [10] add a, l ; [4] ld l, a ; [4] ld a, 0 ; [7] adc a, h ; [4] ld h, a ; [4] ld h, (hl) ; [7] ;------------------------------------------------------------------- ; Calculate the starting byte offset and add to DE. ;------------------------------------------------------------------- ld a, b ; [4] and $f8 ; [7] mask out low 3 bits to rra ; [4] prevent and chance of a rra ; [4] carry during RRA. rra ; [4] add a, e ; [4] add computed offset to DE. ld e, a ; [4] ld a, d ; [4] adc a, 0 ; [7] ld d, a ; [4] ;------------------------------------------------------------------- ; Calculate the width of the line and store the result in C. ;------------------------------------------------------------------- ld a, c ; [4] calculate width of line and sub b ; [4] store result in C. ld c, a ; [4] ld a, b ; [4] mask out the high 5 bits of and $07 ; [7] B to get the bit offset. ld b, a ; [4] ld l, hFillPlotMask & $ff ; [10] add a, l ; [4] ld l, a ; [4] ld a, 7 ; [7] if this result doesn't set sub b ; [4] the carry flag then the sub c ; [4] line fits into one screen ld b, h ; [4] byte. ld h, hFillPlotMask >> 8 ; [7] jp nc, _byteLine ; [10] special case - 1 byte line ;------------------------------------------------------------------- ; Draw left edge of line [57] ;------------------------------------------------------------------- neg ; [8] negate A to get bits ld c, a ; [4] remaining after this draw. ld h, (hl) ; [7] ld a, h cpl ld l, a ; h = mask of area to retain. ; l = mask of area to write. ; b = pattern. ; (de) = byte to modify. .if FillMode == PlotMode.Plot ld a,(de) and h ld l,a ld a,h cpl and b or l ld (de),a .elseif FillMode == PlotMode.Or ld a,b and l ld l,a ld a,(de) or l ld (de),a .elseif FillMode == PlotMode.And ld a,b or h ld h,a ld a,(de) and h ld (de),a .elseif FillMode == PlotMode.Eor ld a,b and l ld l,a ld a,(de) xor l ld (de),a .elseif FillMode == PlotMode.Invert ld a,(de) xor l ld (de),a .endif ;------------------------------------------------------------------- ; Draw middle segment of line [45 + 26 per byte] ;------------------------------------------------------------------- ld a, c ; [4] and $f8 ; [7] jump if there no middle bytes. jp z, _lineEnd ; [10] rra ; [4] othwerwise rotate number of rra ; [4] bits remaining right 3 rra ; [4] places (divide by 8). ld h, b ; [4] ld b, a ; [4] copy the middle bytes ld a, h ; [4] ; Mid-section: h->(de) .if FillMode == PlotMode.Plot - inc de ld (de),a djnz - .elseif FillMode == PlotMode.Or - inc de ld a,(de) or h ld (de),a djnz - .elseif FillMode == PlotMode.And - inc de ld a,(de) and h ld (de),a djnz - .elseif FillMode == PlotMode.Eor - inc de ld a,(de) xor h ld (de),a djnz - .elseif FillMode == PlotMode.Invert - inc de ld a,(de) cpl ld (de),a djnz - .endif ld b, h ; [4] ;------------------------------------------------------------------- ; Draw right edge of line [107] ;------------------------------------------------------------------- _lineEnd: ld a, c ; [4] mask low 3 bits of C to check and $07 ; [7] how many bits to write. jp z, _hFillRet ; [11/5] return if nothing to do. ld hl, hFillPlotMask ; [10] load the bitmask for the right add a, l ; [4] ld l, a ; [4] ld a, (hl) ; [7] ld l, a ; [4] cpl ; [4] inc de ; [6] ld h, a ; [4] plot mask -> H. ; h = mask of area to retain. ; l = mask of area to write. ; b = pattern. ; (de) = byte to modify. .if FillMode == PlotMode.Plot ld a,(de) and h ld l,a ld a,h cpl and b or l ld (de),a .elseif FillMode == PlotMode.Or ld a,b and l ld l,a ld a,(de) or l ld (de),a .elseif FillMode == PlotMode.And ld a,b or h ld h,a ld a,(de) and h ld (de),a .elseif FillMode == PlotMode.Eor ld a,b and l ld l,a ld a,(de) xor l ld (de),a .elseif FillMode == PlotMode.Invert ld a,(de) xor l ld (de),a .endif _hFillRet: pop bc ; [10] ret ; [10] ;------------------------------------------------------------------- ; This code is to handle the special case of x1 and x2 both ; residing in the same byte of screen RAM. ;------------------------------------------------------------------- _byteLine: ld a,c inc a add a,l ld c,(hl) ld l,a ld a,(hl) xor c .if FillMode == PlotMode.Plot ld h,a and b ld l,a ld a,h cpl ex de,hl and (hl) or e ld (hl),a .elseif FillMode == PlotMode.Or and b ex de,hl or (hl) ld (hl),a .elseif FillMode == PlotMode.And cpl or b ex de,hl and (hl) ld (hl),a .elseif FillMode == PlotMode.Eor and b ex de,hl xor (hl) ld (hl),a .elseif FillMode == PlotMode.Invert ex de,hl xor (hl) ld (hl),a .endif pop bc ; [10] ret ; [10] .endmodule .loop ;------------------------------------------------------------------------------- ; End of HLineFill ;-------------------------------------------------------------------------------