[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