[Oberon] FPGA - Bitmap Paint Horizontal Line
Jörg
joerg.straube at iaeth.ch
Thu May 4 16:42:57 CEST 2017
If you write "x * 100H", the compiler will detect that "100H" is a power of two and will convert the multiplication into a shift operation.
Jörg
-----Original Message-----
From: Oberon [mailto:oberon-bounces at lists.inf.ethz.ch] On Behalf Of Tomas Kral
Sent: Donnerstag, 4. Mai 2017 11:25
To: oberon at lists.inf.ethz.ch
Subject: Re: [Oberon] FPGA - Bitmap Paint Horizontal Line
Hi,
I arrived at coding this, it may not be correct, but does things on
$AAAAA$ patterns.
PROCEDURE PaintHLine(x, src, dst, w: INTEGER);
VAR bt: BYTE; wd: INTEGER; pix: SET;
BEGIN
(* (pix * {maskleft*8..31} * {0..maskright*8-1}) *)
WHILE w > 0 DO
(* this part modified from Display.Mod:CopyPattern *)
SYSTEM.GET(src, bt); wd := bt; INC(src); DEC(w, 8);
IF w > 0 THEN SYSTEM.GET(src, bt); wd := wd + bt*100H; INC(src);
DEC(w, 8); IF w > 0 THEN SYSTEM.GET(src, bt); wd := wd + bt*10000H;
INC(src); DEC(w, 8); IF w > 0 THEN SYSTEM.GET(src, bt); wd := wd +
bt*1000000H; INC(src); DEC(w, 8) END END
END;
SYSTEM.GET(dst, pix);
SYSTEM.PUT(dst, SYSTEM.VAL(SET, LSL(wd, x MOD 32)) + pix);
SYSTEM.GET(dst+4, pix); wd := ROR(wd, x MOD 32);
SYSTEM.PUT(dst+4, SYSTEM.VAL(SET, wd)*{0..x MOD 32} + pix);
INC(dst, 4)
END
END PaintHLine;
Comments:
[a] it now reflects x coordinate, but works only with w*8, need to deal
with a remaining bits w MOD 8, as the last step
[b] bits shifted left in memory, appears shifted right on display,
interestingly also vice versa, as if on reflection in the mirror
[c] need to somehow unroll the loop into three parts for speed
improvement as suggested, as is, it needs four byte reads from source,
two word read/writes per iteration INC(dst,4), but how?
[d] bt*100H is defacto shift 8 operation, why normal ASR/LSL
were not used instead, how many RISC cycles they got?
Tomas
On Sun, 30 Apr 2017 17:45:08 +0200
Jörg <joerg.straube at iaeth.ch> wrote:
> Hi Tomas
>
> One possibilty is to split your algorithm in three parts
> 1) handle the left border (max 31 bit) until you reach a multiple of
> 32 bit 2) then copy n words (32 bit)
> 3) handle the right border = remaining bits up to the width "w"
>
> Jörg
>
> > Am 30.04.2017 um 16:33 schrieb Tomas Kral <thomas.kral at email.cz>:
> >
> > Chris, Joerg,
> >
> > Learning, not doing much useful bitmap examples.
> >
> > I was surprised to realise, Bitmaps are easy to be copied/displayed,
> > by lines, after each line destination address is incremented by 128
> > bytes per display line, source address by bitmap width DIV 8, lines
> > h decremented by 1.
> >
> > This works nicely on any bitmap of widths multiple of
> > 32 bits accross. 32xN, 64xN, etc, and must be aligned horizontally
> > also on 32 bit as well, for x=0,32,64,.. coordinate (x,y = top
> > left). Bitmaps are drawn upwards.
> >
> > (* paints horizontal bitmap line, for x,w=32,64,... *)
> > PROCEDURE PaintHLine(src, dst, w: INTEGER);
> > VAR s,t: SET;
> > BEGIN
> > w := (w+7) DIV 8; (* bytes per bitmap line *)
> > WHILE w > 0 DO
> > SYSTEM.GET(src, t); SYSTEM.GET(dst, s);
> > SYSTEM.PUT(dst, s + t);
> > INC(dst, 4); INC(src, 4); DEC(w, 4)
> > END
> > END PaintHLine;
> >
> > I am looking into a solution where x can spill over byte boundary,
> > also width of finer bitwise granularity.
> >
> > I did a similar exercise in assembly many, many years ago on 8-bit
> > computers.
> >
> > Tomas
> >
> >
> > On Sun, 30 Apr 2017 21:26:09 +0930
> > Chris Burrows <chris at cfbsoftware.com> wrote:
> >
> >>> -----Original Message-----
> >>> From: Oberon [mailto:oberon-bounces at lists.inf.ethz.ch] On Behalf
> >>> Of Tomas Kral
> >>> Sent: Sunday, 30 April 2017 8:05 PM
> >>> To: oberon at lists.inf.ethz.ch
> >>> Subject: Re: [Oberon] FPGA - SET initialisation
> >>>
> >>> Ah yes, sily me.
> >>>
> >>> But how to best initialise a SET variable with an arbitrary byte /
> >>> integer?
> >>>
> >>> TYPE ii = POINTER TO iidsc;
> >>> iidsc = STRUCT i: INTEGER END;
> >>>
> >>> i := b; SYSTEM.PUT(ii,i); SYSTEM.GET(ii,s); (* initialise a set
> >>> with a byte *) SYSTEM.PUT(ii,i); SYSTEM.GET(ii,s); (* initialise
> >>> a set with an integer
> >>> *)
> >>>
> >>
> >> Do you mean how do you typecast an INTEGER / BYTE variable to a SET
> >> variable?
> >>
> >> If so then:
> >>
> >> VAR
> >> s: SET;
> >> i: INTEGER;
> >> b: BYTE;
> >>
> >> BEGIN
> >> s := SYSTEM.VAL(SET, i);
> >> s := SYSTEM.VAL(SET, ORD(b))
> >>
> >> I'm curious. What is it that you are trying to do that makes you
> >> ask this question?
> >>
> >> Regards,
> >> Chris Burrows
> >> CFB Software
> >> http://www.astrobe.com/RISC5
> >>
> >> --
> >> Oberon at lists.inf.ethz.ch mailing list for ETH Oberon and related
> >> systems https://lists.inf.ethz.ch/mailman/listinfo/oberon
> >
> > --
> > Oberon at lists.inf.ethz.ch mailing list for ETH Oberon and related
> > systems https://lists.inf.ethz.ch/mailman/listinfo/oberon
> --
> Oberon at lists.inf.ethz.ch mailing list for ETH Oberon and related
> systems https://lists.inf.ethz.ch/mailman/listinfo/oberon
--
Tomas Kral <thomas.kral at email.cz>
--
Oberon at lists.inf.ethz.ch mailing list for ETH Oberon and related systems
https://lists.inf.ethz.ch/mailman/listinfo/oberon
More information about the Oberon
mailing list