Display.Mod.txt 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. MODULE Display; (*NW 5.11.2013 / 17.1.2019*)
  2. IMPORT SYSTEM;
  3. CONST black* = 0; white* = 1; (*black = background*)
  4. replace* = 0; paint* = 1; invert* = 2; (*modes*)
  5. base = 0E7F00H; (*adr of 1024 x 768 pixel, monocolor display frame*)
  6. TYPE Frame* = POINTER TO FrameDesc;
  7. FrameMsg* = RECORD END ;
  8. Handler* = PROCEDURE (F: Frame; VAR M: FrameMsg);
  9. FrameDesc* = RECORD next*, dsc*: Frame;
  10. X*, Y*, W*, H*: INTEGER;
  11. handle*: Handler
  12. END ;
  13. VAR Base*, Width*, Height*: INTEGER;
  14. arrow*, star*, hook*, updown*, block*, cross*, grey*: INTEGER;
  15. (*a pattern is an array of bytes; the first is its width (< 32), the second its height, the rest the raster*)
  16. PROCEDURE Handle*(F: Frame; VAR M: FrameMsg);
  17. BEGIN
  18. IF (F # NIL) & (F.handle # NIL) THEN F.handle(F, M) END
  19. END Handle;
  20. (* raster ops *)
  21. PROCEDURE Dot*(col, x, y, mode: INTEGER);
  22. VAR a: INTEGER; u, s: SET;
  23. BEGIN a := base + (x DIV 32)*4 + y*128;
  24. s := {x MOD 32}; SYSTEM.GET(a, u);
  25. IF mode = paint THEN SYSTEM.PUT(a, u + s)
  26. ELSIF mode = invert THEN SYSTEM.PUT(a, u / s)
  27. ELSE (*mode = replace*)
  28. IF col # black THEN SYSTEM.PUT(a, u + s) ELSE SYSTEM.PUT(a, u - s) END
  29. END
  30. END Dot;
  31. PROCEDURE ReplConst*(col, x, y, w, h, mode: INTEGER);
  32. VAR al, ar, a0, a1: INTEGER; left, right, mid, pix, pixl, pixr: SET;
  33. BEGIN al := base + y*128;
  34. ar := ((x+w-1) DIV 32)*4 + al; al := (x DIV 32)*4 + al;
  35. IF ar = al THEN
  36. mid := {(x MOD 32) .. ((x+w-1) MOD 32)};
  37. FOR a1 := al TO al + (h-1)*128 BY 128 DO
  38. SYSTEM.GET(a1, pix);
  39. IF mode = invert THEN SYSTEM.PUT(a1, pix / mid)
  40. ELSIF (mode = replace) & (col = black) THEN (*erase*) SYSTEM.PUT(a1, pix - mid)
  41. ELSE (* (mode = paint) OR (mode = replace) & (col # black) *) SYSTEM.PUT(a1, pix + mid)
  42. END
  43. END
  44. ELSIF ar > al THEN
  45. left := {(x MOD 32) .. 31}; right := {0 .. ((x+w-1) MOD 32)};
  46. FOR a0 := al TO al + (h-1)*128 BY 128 DO
  47. SYSTEM.GET(a0, pixl); SYSTEM.GET(ar, pixr);
  48. IF mode = invert THEN
  49. SYSTEM.PUT(a0, pixl / left);
  50. FOR a1 := a0+4 TO ar-4 BY 4 DO SYSTEM.GET(a1, pix); SYSTEM.PUT(a1, -pix) END ;
  51. SYSTEM.PUT(ar, pixr / right)
  52. ELSIF (mode = replace) & (col = black) THEN (*erase*)
  53. SYSTEM.PUT(a0, pixl - left);
  54. FOR a1 := a0+4 TO ar-4 BY 4 DO SYSTEM.PUT(a1, {}) END ;
  55. SYSTEM.PUT(ar, pixr - right)
  56. ELSE (* (mode = paint) OR (mode = replace) & (col # black) *)
  57. SYSTEM.PUT(a0, pixl + left);
  58. FOR a1 := a0+4 TO ar-4 BY 4 DO SYSTEM.PUT(a1, {0 .. 31}) END ;
  59. SYSTEM.PUT(ar, pixr + right)
  60. END ;
  61. INC(ar, 128)
  62. END
  63. END
  64. END ReplConst;
  65. PROCEDURE CopyPattern*(col, patadr, x, y, mode: INTEGER); (*only for modes = paint, invert*)
  66. VAR a, a0, pwd: INTEGER;
  67. w, h, pbt: BYTE; pix, mask: SET;
  68. BEGIN SYSTEM.GET(patadr, w); SYSTEM.GET(patadr+1, h); INC(patadr, 2);
  69. a := base + (x DIV 32)*4 + y*128; x := x MOD 32; mask := SYSTEM.VAL(SET, ASR(7FFFFFFFH, 31-x));
  70. FOR a0 := a TO a + (h-1)*128 BY 128 DO
  71. (*build pattern line; w <= 32*)
  72. SYSTEM.GET(patadr, pbt); INC(patadr); pwd := pbt;
  73. IF w > 8 THEN SYSTEM.GET(patadr, pbt); INC(patadr); pwd := pbt*100H + pwd;
  74. IF w > 16 THEN SYSTEM.GET(patadr, pbt); INC(patadr); pwd := pbt*10000H + pwd;
  75. IF w > 24 THEN SYSTEM.GET(patadr, pbt); INC(patadr); pwd := pbt*1000000H + pwd END
  76. END
  77. END ;
  78. SYSTEM.GET(a0, pix);
  79. IF mode = invert THEN SYSTEM.PUT(a0, SYSTEM.VAL(SET, LSL(pwd, x)) / pix)
  80. ELSE SYSTEM.PUT(a0, SYSTEM.VAL(SET, LSL(pwd, x)) + pix)
  81. END ;
  82. IF x + w > 32 THEN (*spill over*)
  83. SYSTEM.GET(a0+4, pix);
  84. IF mode = invert THEN SYSTEM.PUT(a0+4, SYSTEM.VAL(SET, ASR(pwd, -x)) * mask/ pix)
  85. ELSE SYSTEM.PUT(a0+4, SYSTEM.VAL(SET, ASR(pwd, -x)) * mask+ pix)
  86. END
  87. END
  88. END
  89. END CopyPattern;
  90. PROCEDURE CopyBlock*(sx, sy, w, h, dx, dy, mode: INTEGER); (*only for mode = replace*)
  91. VAR sa, da, sa0, sa1, d, len: INTEGER;
  92. u0, u1, u2, u3, v0, v1, v2, v3, n: INTEGER;
  93. end, step: INTEGER;
  94. src, dst, spill: SET;
  95. m0, m1, m2, m3: SET;
  96. BEGIN
  97. u0 := sx DIV 32; u1 := sx MOD 32; u2 := (sx+w) DIV 32; u3 := (sx+w) MOD 32;
  98. v0 := dx DIV 32; v1 := dx MOD 32; v2 := (dx+w) DIV 32; v3 := (dx+w) MOD 32;
  99. sa := base + u0*4 + sy*128; da := base + v0*4 + dy*128;
  100. d := da - sa; n := u1 - v1; (*displacement in words and bits*)
  101. len := (u2 - u0) * 4;
  102. m0 := {v1 .. 31}; m2 := {v3 .. 31}; m3 := m0 / m2;
  103. IF d >= 0 THEN (*copy up, scan down*) sa0 := sa + (h-1)*128; end := sa-128; step := -128
  104. ELSE (*copy down, scan up*) sa0 := sa; end := sa + h*128; step := 128
  105. END ;
  106. WHILE sa0 # end DO
  107. IF n >= 0 THEN (*shift right*) m1 := {n .. 31};
  108. IF v1 + w >= 32 THEN
  109. SYSTEM.GET(sa0+len, src); src := ROR(src, n);
  110. SYSTEM.GET(sa0+len+d, dst);
  111. SYSTEM.PUT(sa0+len+d, (dst * m2) + (src - m2));
  112. spill := src - m1;
  113. FOR sa1 := sa0 + len-4 TO sa0+4 BY -4 DO
  114. SYSTEM.GET(sa1, src); src := ROR(src, n);
  115. SYSTEM.PUT(sa1+d, spill + (src * m1));
  116. spill := src - m1
  117. END ;
  118. SYSTEM.GET(sa0, src); src := ROR(src, n);
  119. SYSTEM.GET(sa0+d, dst);
  120. SYSTEM.PUT(sa0+d, (src * m0) + (dst - m0))
  121. ELSE SYSTEM.GET(sa0, src); src := ROR(src, n);
  122. SYSTEM.GET(sa0+d, dst);
  123. SYSTEM.PUT(sa0+d, (src * m3) + (dst - m3))
  124. END
  125. ELSE (*shift left*) m1 := {-n .. 31};
  126. SYSTEM.GET(sa0, src); src := ROR(src, n);
  127. SYSTEM.GET(sa0+d, dst);
  128. IF v1 + w < 32 THEN
  129. SYSTEM.PUT(sa0+d, (dst - m3) + (src * m3))
  130. ELSE SYSTEM.PUT(sa0+d, (dst - m0) + (src * m0));
  131. spill := src - m1;
  132. FOR sa1 := sa0+4 TO sa0 + len-4 BY 4 DO
  133. SYSTEM.GET(sa1, src); src := ROR(src, n);
  134. SYSTEM.PUT(sa1+d, spill + (src * m1));
  135. spill := src - m1
  136. END ;
  137. SYSTEM.GET(sa0+len, src); src := ROR(src, n);
  138. SYSTEM.GET(sa0+len+d, dst);
  139. SYSTEM.PUT(sa0+len+d, (src - m2) + (dst * m2))
  140. END
  141. END ;
  142. INC(sa0, step)
  143. END
  144. END CopyBlock;
  145. PROCEDURE ReplPattern*(col, patadr, x, y, w, h, mode: INTEGER);
  146. (* pattern width = 32, fixed; pattern starts at patadr+4, for mode = invert only *)
  147. VAR al, ar, a0, a1: INTEGER;
  148. pta0, pta1: INTEGER; (*pattern addresses*)
  149. ph: BYTE;
  150. left, right, mid, pix, pixl, pixr, ptw: SET;
  151. BEGIN al := base + y*128; SYSTEM.GET(patadr+1, ph);
  152. pta0 := patadr+4; pta1 := ph*4 + pta0;
  153. ar := ((x+w-1) DIV 32)*4 + al; al := (x DIV 32)*4 + al;
  154. IF ar = al THEN
  155. mid := {(x MOD 32) .. ((x+w-1) MOD 32)};
  156. FOR a1 := al TO al + (h-1)*128 BY 128 DO
  157. SYSTEM.GET(a1, pix); SYSTEM.GET(pta0, ptw); SYSTEM.PUT(a1, (pix - mid) + (pix/ptw * mid)); INC(pta0, 4);
  158. IF pta0 = pta1 THEN pta0 := patadr+4 END
  159. END
  160. ELSIF ar > al THEN
  161. left := {(x MOD 32) .. 31}; right := {0 .. ((x+w-1) MOD 32)};
  162. FOR a0 := al TO al + (h-1)*128 BY 128 DO
  163. SYSTEM.GET(a0, pixl); SYSTEM.GET(pta0, ptw); SYSTEM.PUT(a0, (pixl - left) + (pixl/ptw * left));
  164. FOR a1 := a0+4 TO ar-4 BY 4 DO SYSTEM.GET(a1, pix); SYSTEM.PUT(a1, pix/ptw) END ;
  165. SYSTEM.GET(ar, pixr); SYSTEM.PUT(ar, (pixr - right) + (pixr/ptw * right));
  166. INC(pta0, 4); INC(ar, 128);
  167. IF pta0 = pta1 THEN pta0 := patadr+4 END
  168. END
  169. END
  170. END ReplPattern;
  171. BEGIN Base := base; Width := 1024; Height := 768;
  172. arrow := SYSTEM.ADR($0F0F 0060 0070 0038 001C 000E 0007 8003 C101 E300 7700 3F00 1F00 3F00 7F00 FF00$);
  173. star := SYSTEM.ADR($0F0F 8000 8220 8410 8808 9004 A002 C001 7F7F C001 A002 9004 8808 8410 8220 8000$);
  174. hook := SYSTEM.ADR($0C0C 070F 8707 C703 E701 F700 7F00 3F00 1F00 0F00 0700 0300 01$);
  175. updown := SYSTEM.ADR($080E 183C 7EFF 1818 1818 1818 FF7E3C18$);
  176. block := SYSTEM.ADR($0808 FFFF C3C3 C3C3 FFFF$);
  177. cross := SYSTEM.ADR($0F0F 0140 0220 0410 0808 1004 2002 4001 0000 4001 2002 1004 0808 0410 0220 0140$);
  178. grey := SYSTEM.ADR($2002 0000 5555 5555 AAAA AAAA$)
  179. END Display.