[Oberon] FPGA - Bitmap Paint Horizontal Line
Tomas Kral
thomas.kral at email.cz
Mon May 22 09:20:12 CEST 2017
Hi,
This is almost final version.
I found it easier to align bitmap lines on word
boundaries, as it simplifies the code, but may waste 3 bytes per line at
worst case.
(w+31+w MOD 32) DIV 32 (* number of words on bitmap line, padded
to word boundary *)
(x DIV 32)*4 (* x aligned on word boundary *)
----
PROCEDURE PaintHLine(x, src, dst, w: INTEGER);
VAR bt: BYTE; w0, wd: INTEGER; pix: SET;
BEGIN
(* (pix * {maskleft*8..31} * {0..maskright*8-1}) *)
w0 := w MOD 32;
WHILE w > 0 DO
SYSTEM.GET(src, wd); INC(src, 4); DEC(w, 32);
IF w < 0 THEN wd := SYSTEM.VAL(INTEGER, SYSTEM.VAL(SET,
wd)*{0..w0}) END;
SYSTEM.GET(dst, pix);
SYSTEM.PUT(dst, SYSTEM.VAL(SET, LSL(wd, x MOD 32)) + pix);
INC(dst, 4);
IF x MOD 32 > 0 THEN
SYSTEM.GET(dst, pix); wd := ASR(wd, -(x MOD 32));
SYSTEM.PUT(dst, SYSTEM.VAL(SET, wd)*{0..x MOD 32-1} + pix)
END
END
END PaintHLine;
On Wed, 10 May 2017 21:01:29 +0200
Tomas Kral <thomas.kral at email.cz> wrote:
> Hi,
>
> Just realised `remaining bits' on the line can be coded as
> w0 := w - (w DIV 32) * 32;
>
> The mask is then wd*{0..w0}
>
> Not sure I can get it any simpler.
>
> Tomas
>
> On Wed, 10 May 2017 11:33:19 +0200
> Tomas Kral <thomas.kral at email.cz> wrote:
>
> > Hi,
> >
> > I have coded this improved version. It generally works and seems to
> > handle both x, and w on bitwise level.
> >
> > The main loop goes initially fast over words, and the rest by bytes.
> >
> > This line `w0 := (w MOD 32) DIV 8 + 1' computes remaining bytes on
> > line over MOD 32, and this clips the outstretching bits
> > wd*{0..w0*8+w}.
> >
> > But the above calculation seems complicated, is there an easier
> > invariant I could code instead?
> >
> > `w0' can then be passed as a parameter as its value is known before
> > calling to `PaintHLine'.
> >
> >
> > PROCEDURE PaintHLine(x, src, dst, w: INTEGER);
> > VAR bt: BYTE; w0, w1, wd: INTEGER; pix: SET;
> > BEGIN
> >
> > (* (pix * {maskleft*8..31} * {0..maskright*8-1}) *)
> >
> > w0 := (w MOD 32) DIV 8 + 1;
> >
> > WHILE w > 0 DO
> >
> > IF w > 31 THEN SYSTEM.GET(src, wd); INC(src, 4); DEC(w, 32);
> > ELSE
> > wd := 0; WHILE w > 0 DO SYSTEM.GET(src, bt); wd := LSL(wd,
> > 8)+bt; INC(src); DEC(w, 8) END END;
> >
> > IF w < 0 THEN wd := SYSTEM.VAL(INTEGER, SYSTEM.VAL(SET,
> > wd)*{0..w0*8+w}) END;
> >
> > SYSTEM.GET(dst, pix);
> > SYSTEM.PUT(dst, SYSTEM.VAL(SET, LSL(wd, x MOD 32)) + pix);
> >
> > INC(dst, 4);
> > IF x MOD 32 > 0 THEN
> > SYSTEM.GET(dst, pix); wd := ASR(wd, -(x MOD 32));
> > SYSTEM.PUT(dst, SYSTEM.VAL(SET, wd)*{0..x MOD 32-1}+ pix)
> > END
> >
> > END
> > END PaintHLine;
> >
> >
>
>
>
--
Tomas Kral <thomas.kral at email.cz>
More information about the Oberon
mailing list