123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190 |
- MODULE Display; (*NW 5.11.2013 / 17.1.2019*)
- IMPORT SYSTEM;
- CONST black* = 0; white* = 1; (*black = background*)
- replace* = 0; paint* = 1; invert* = 2; (*modes*)
- base = 0E7F00H; (*adr of 1024 x 768 pixel, monocolor display frame*)
- TYPE Frame* = POINTER TO FrameDesc;
- FrameMsg* = RECORD END ;
- Handler* = PROCEDURE (F: Frame; VAR M: FrameMsg);
- FrameDesc* = RECORD next*, dsc*: Frame;
- X*, Y*, W*, H*: INTEGER;
- handle*: Handler
- END ;
- VAR Base*, Width*, Height*: INTEGER;
- arrow*, star*, hook*, updown*, block*, cross*, grey*: INTEGER;
- (*a pattern is an array of bytes; the first is its width (< 32), the second its height, the rest the raster*)
- PROCEDURE Handle*(F: Frame; VAR M: FrameMsg);
- BEGIN
- IF (F # NIL) & (F.handle # NIL) THEN F.handle(F, M) END
- END Handle;
- (* raster ops *)
-
- PROCEDURE Dot*(col, x, y, mode: INTEGER);
- VAR a: INTEGER; u, s: SET;
- BEGIN a := base + (x DIV 32)*4 + y*128;
- s := {x MOD 32}; SYSTEM.GET(a, u);
- IF mode = paint THEN SYSTEM.PUT(a, u + s)
- ELSIF mode = invert THEN SYSTEM.PUT(a, u / s)
- ELSE (*mode = replace*)
- IF col # black THEN SYSTEM.PUT(a, u + s) ELSE SYSTEM.PUT(a, u - s) END
- END
- END Dot;
- PROCEDURE ReplConst*(col, x, y, w, h, mode: INTEGER);
- VAR al, ar, a0, a1: INTEGER; left, right, mid, pix, pixl, pixr: SET;
- BEGIN al := base + y*128;
- ar := ((x+w-1) DIV 32)*4 + al; al := (x DIV 32)*4 + al;
- IF ar = al THEN
- mid := {(x MOD 32) .. ((x+w-1) MOD 32)};
- FOR a1 := al TO al + (h-1)*128 BY 128 DO
- SYSTEM.GET(a1, pix);
- IF mode = invert THEN SYSTEM.PUT(a1, pix / mid)
- ELSIF (mode = replace) & (col = black) THEN (*erase*) SYSTEM.PUT(a1, pix - mid)
- ELSE (* (mode = paint) OR (mode = replace) & (col # black) *) SYSTEM.PUT(a1, pix + mid)
- END
- END
- ELSIF ar > al THEN
- left := {(x MOD 32) .. 31}; right := {0 .. ((x+w-1) MOD 32)};
- FOR a0 := al TO al + (h-1)*128 BY 128 DO
- SYSTEM.GET(a0, pixl); SYSTEM.GET(ar, pixr);
- IF mode = invert THEN
- SYSTEM.PUT(a0, pixl / left);
- FOR a1 := a0+4 TO ar-4 BY 4 DO SYSTEM.GET(a1, pix); SYSTEM.PUT(a1, -pix) END ;
- SYSTEM.PUT(ar, pixr / right)
- ELSIF (mode = replace) & (col = black) THEN (*erase*)
- SYSTEM.PUT(a0, pixl - left);
- FOR a1 := a0+4 TO ar-4 BY 4 DO SYSTEM.PUT(a1, {}) END ;
- SYSTEM.PUT(ar, pixr - right)
- ELSE (* (mode = paint) OR (mode = replace) & (col # black) *)
- SYSTEM.PUT(a0, pixl + left);
- FOR a1 := a0+4 TO ar-4 BY 4 DO SYSTEM.PUT(a1, {0 .. 31}) END ;
- SYSTEM.PUT(ar, pixr + right)
- END ;
- INC(ar, 128)
- END
- END
- END ReplConst;
- PROCEDURE CopyPattern*(col, patadr, x, y, mode: INTEGER); (*only for modes = paint, invert*)
- VAR a, a0, pwd: INTEGER;
- w, h, pbt: BYTE; pix, mask: SET;
- BEGIN SYSTEM.GET(patadr, w); SYSTEM.GET(patadr+1, h); INC(patadr, 2);
- a := base + (x DIV 32)*4 + y*128; x := x MOD 32; mask := SYSTEM.VAL(SET, ASR(7FFFFFFFH, 31-x));
- FOR a0 := a TO a + (h-1)*128 BY 128 DO
- (*build pattern line; w <= 32*)
- SYSTEM.GET(patadr, pbt); INC(patadr); pwd := pbt;
- IF w > 8 THEN SYSTEM.GET(patadr, pbt); INC(patadr); pwd := pbt*100H + pwd;
- IF w > 16 THEN SYSTEM.GET(patadr, pbt); INC(patadr); pwd := pbt*10000H + pwd;
- IF w > 24 THEN SYSTEM.GET(patadr, pbt); INC(patadr); pwd := pbt*1000000H + pwd END
- END
- END ;
- SYSTEM.GET(a0, pix);
- IF mode = invert THEN SYSTEM.PUT(a0, SYSTEM.VAL(SET, LSL(pwd, x)) / pix)
- ELSE SYSTEM.PUT(a0, SYSTEM.VAL(SET, LSL(pwd, x)) + pix)
- END ;
- IF x + w > 32 THEN (*spill over*)
- SYSTEM.GET(a0+4, pix);
- IF mode = invert THEN SYSTEM.PUT(a0+4, SYSTEM.VAL(SET, ASR(pwd, -x)) * mask/ pix)
- ELSE SYSTEM.PUT(a0+4, SYSTEM.VAL(SET, ASR(pwd, -x)) * mask+ pix)
- END
- END
- END
- END CopyPattern;
- PROCEDURE CopyBlock*(sx, sy, w, h, dx, dy, mode: INTEGER); (*only for mode = replace*)
- VAR sa, da, sa0, sa1, d, len: INTEGER;
- u0, u1, u2, u3, v0, v1, v2, v3, n: INTEGER;
- end, step: INTEGER;
- src, dst, spill: SET;
- m0, m1, m2, m3: SET;
- BEGIN
- u0 := sx DIV 32; u1 := sx MOD 32; u2 := (sx+w) DIV 32; u3 := (sx+w) MOD 32;
- v0 := dx DIV 32; v1 := dx MOD 32; v2 := (dx+w) DIV 32; v3 := (dx+w) MOD 32;
- sa := base + u0*4 + sy*128; da := base + v0*4 + dy*128;
- d := da - sa; n := u1 - v1; (*displacement in words and bits*)
- len := (u2 - u0) * 4;
- m0 := {v1 .. 31}; m2 := {v3 .. 31}; m3 := m0 / m2;
- IF d >= 0 THEN (*copy up, scan down*) sa0 := sa + (h-1)*128; end := sa-128; step := -128
- ELSE (*copy down, scan up*) sa0 := sa; end := sa + h*128; step := 128
- END ;
- WHILE sa0 # end DO
- IF n >= 0 THEN (*shift right*) m1 := {n .. 31};
- IF v1 + w >= 32 THEN
- SYSTEM.GET(sa0+len, src); src := ROR(src, n);
- SYSTEM.GET(sa0+len+d, dst);
- SYSTEM.PUT(sa0+len+d, (dst * m2) + (src - m2));
- spill := src - m1;
- FOR sa1 := sa0 + len-4 TO sa0+4 BY -4 DO
- SYSTEM.GET(sa1, src); src := ROR(src, n);
- SYSTEM.PUT(sa1+d, spill + (src * m1));
- spill := src - m1
- END ;
- SYSTEM.GET(sa0, src); src := ROR(src, n);
- SYSTEM.GET(sa0+d, dst);
- SYSTEM.PUT(sa0+d, (src * m0) + (dst - m0))
- ELSE SYSTEM.GET(sa0, src); src := ROR(src, n);
- SYSTEM.GET(sa0+d, dst);
- SYSTEM.PUT(sa0+d, (src * m3) + (dst - m3))
- END
- ELSE (*shift left*) m1 := {-n .. 31};
- SYSTEM.GET(sa0, src); src := ROR(src, n);
- SYSTEM.GET(sa0+d, dst);
- IF v1 + w < 32 THEN
- SYSTEM.PUT(sa0+d, (dst - m3) + (src * m3))
- ELSE SYSTEM.PUT(sa0+d, (dst - m0) + (src * m0));
- spill := src - m1;
- FOR sa1 := sa0+4 TO sa0 + len-4 BY 4 DO
- SYSTEM.GET(sa1, src); src := ROR(src, n);
- SYSTEM.PUT(sa1+d, spill + (src * m1));
- spill := src - m1
- END ;
- SYSTEM.GET(sa0+len, src); src := ROR(src, n);
- SYSTEM.GET(sa0+len+d, dst);
- SYSTEM.PUT(sa0+len+d, (src - m2) + (dst * m2))
- END
- END ;
- INC(sa0, step)
- END
- END CopyBlock;
- PROCEDURE ReplPattern*(col, patadr, x, y, w, h, mode: INTEGER);
- (* pattern width = 32, fixed; pattern starts at patadr+4, for mode = invert only *)
- VAR al, ar, a0, a1: INTEGER;
- pta0, pta1: INTEGER; (*pattern addresses*)
- ph: BYTE;
- left, right, mid, pix, pixl, pixr, ptw: SET;
- BEGIN al := base + y*128; SYSTEM.GET(patadr+1, ph);
- pta0 := patadr+4; pta1 := ph*4 + pta0;
- ar := ((x+w-1) DIV 32)*4 + al; al := (x DIV 32)*4 + al;
- IF ar = al THEN
- mid := {(x MOD 32) .. ((x+w-1) MOD 32)};
- FOR a1 := al TO al + (h-1)*128 BY 128 DO
- SYSTEM.GET(a1, pix); SYSTEM.GET(pta0, ptw); SYSTEM.PUT(a1, (pix - mid) + (pix/ptw * mid)); INC(pta0, 4);
- IF pta0 = pta1 THEN pta0 := patadr+4 END
- END
- ELSIF ar > al THEN
- left := {(x MOD 32) .. 31}; right := {0 .. ((x+w-1) MOD 32)};
- FOR a0 := al TO al + (h-1)*128 BY 128 DO
- SYSTEM.GET(a0, pixl); SYSTEM.GET(pta0, ptw); SYSTEM.PUT(a0, (pixl - left) + (pixl/ptw * left));
- FOR a1 := a0+4 TO ar-4 BY 4 DO SYSTEM.GET(a1, pix); SYSTEM.PUT(a1, pix/ptw) END ;
- SYSTEM.GET(ar, pixr); SYSTEM.PUT(ar, (pixr - right) + (pixr/ptw * right));
- INC(pta0, 4); INC(ar, 128);
- IF pta0 = pta1 THEN pta0 := patadr+4 END
- END
- END
- END ReplPattern;
- BEGIN Base := base; Width := 1024; Height := 768;
- arrow := SYSTEM.ADR($0F0F 0060 0070 0038 001C 000E 0007 8003 C101 E300 7700 3F00 1F00 3F00 7F00 FF00$);
- star := SYSTEM.ADR($0F0F 8000 8220 8410 8808 9004 A002 C001 7F7F C001 A002 9004 8808 8410 8220 8000$);
- hook := SYSTEM.ADR($0C0C 070F 8707 C703 E701 F700 7F00 3F00 1F00 0F00 0700 0300 01$);
- updown := SYSTEM.ADR($080E 183C 7EFF 1818 1818 1818 FF7E3C18$);
- block := SYSTEM.ADR($0808 FFFF C3C3 C3C3 FFFF$);
- cross := SYSTEM.ADR($0F0F 0140 0220 0410 0808 1004 2002 4001 0000 4001 2002 1004 0808 0410 0220 0140$);
- grey := SYSTEM.ADR($2002 0000 5555 5555 AAAA AAAA$)
- END Display.
|