2
0

fontdemo.pas 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365
  1. Program FontDemo;
  2. { FontDemo.pas, by Marco van de Voort (C) 2000-2001
  3. Compiler: 1.0.5 or 1.1 after 20-01-2001
  4. Target : FreeBSD 4.x+ with 16x8 font. 3.x untested (syscons driver)
  5. Demonstrate font modification with the console driver "syscons".
  6. This program doesn't work under X or over telnet.
  7. The purpose of the program is to demonstrate the procedures that change the
  8. font. The demonstration assume a 80x25 console. Framebuffer devices or 80x50
  9. displays (80x50 use 8x8 fonts) require a trivial modification.
  10. The example of mirroring is absurd, but is very visible, so good for
  11. demonstration. The real use is to load the font, change a few characters
  12. (linedrawing, (C) characters, force existance of umlaute or tremas for the
  13. duration of the application.
  14. Note that if you switch to a different vty while the font is mirrored, that
  15. vty is also mirrored.
  16. Root can restore the font via a network device with:
  17. vidcontrol -f 8x16 "fontname in /usr/share/syscons/fonts" < /dev/ttyv1
  18. The program saves the font, and will terminate and restore the font when
  19. SIGUSR2 is received, unless -n is specified.
  20. killall -USR2 fontdemo
  21. }
  22. Uses Console,{$ifdef ver1_0}Linux{$else}Baseunix{$endif},GetOpts;
  23. {$ifdef ver1_0}
  24. function fpnanosleep;
  25. begin
  26. nanosleep;
  27. end;
  28. {$endif}
  29. procedure MirrorFont8(var Data;Count:longint); assembler;
  30. {Mirrors on a bit level "Count" bytes in typeless variable "Data"}
  31. asm
  32. mov data,%esi
  33. movl Count,%edx
  34. .LLoop1: movb (%esi),%bl
  35. movl $8,%ecx
  36. .LLoop2: shr $1,%bl
  37. rcl $1,%al
  38. loop .LLoop2
  39. movb %al,(%esi)
  40. incl %esi
  41. decl %edx
  42. jne .LLoop1
  43. end['EAX','EBX','ECX','EDX','ESI'];
  44. procedure GoLeft(var Data;Count:longint;shcnt:longint); assembler;
  45. {Mirrors on a bit level "Count" bytes in typeless variable "Data"}
  46. asm
  47. mov data,%esi
  48. mov data,%edi
  49. mov shcnt,%ecx
  50. movl Count,%edx
  51. xorl %eax,%eax
  52. .LLoop1: lodsb
  53. shl %cl,%eax
  54. stosb
  55. incl %esi
  56. incl %edi
  57. decl %edx
  58. jne .LLoop1
  59. end['EAX','EBX','ECX','EDX','ESI'];
  60. procedure GoRight(var Data;Count:longint;shcnt:longint); assembler;
  61. {Mirrors on a bit level "Count" bytes in typeless variable "Data"}
  62. asm
  63. mov data,%esi
  64. mov data,%edi
  65. mov shcnt,%ecx
  66. movl Count,%edx
  67. xor %eax,%eax
  68. .LLoop1: lodsb
  69. shr %cl,%eax
  70. stosb
  71. incl %esi
  72. incl %edi
  73. decl %edx
  74. jne .LLoop1
  75. end['EAX','EBX','ECX','EDX','ESI'];
  76. procedure DoAlt(var Data;Count:longint;shcnt:longint;alt:integer); assembler;
  77. {Mirrors on a bit level "Count" bytes in typeless variable "Data"}
  78. asm
  79. mov alt,%ecx
  80. mov data,%esi
  81. mov data,%edi
  82. add %ecx,%esi
  83. add %ecx,%edi
  84. mov shcnt,%ecx
  85. movl Count,%edx
  86. xorl %eax,%eax
  87. .LLoop1: lodsb
  88. mov %edx,%ebx
  89. and $1,%ebx
  90. test %ebx,%ebx
  91. je .Lgoleftalt1
  92. shl %cl,%eax
  93. jmp .Lgoleftalt2
  94. .Lgoleftalt1:
  95. shr %cl,%eax
  96. .Lgoleftalt2:
  97. stosb
  98. incl %esi
  99. incl %edi
  100. decl %edx
  101. jne .LLoop1
  102. end['EAX','EBX','ECX','EDX','ESI'];
  103. procedure stripbits (var Data;Count:longint); assembler;
  104. { "Compresses" a byte. 76543210 -> x764310x where x=0 (but 0 was already
  105. used to indicate bit number :-)
  106. Needed for a rotating effect. (Character rotating round vertical axis)
  107. Does this for "Count" bytes in "Data".
  108. }
  109. asm
  110. mov data,%esi
  111. movl Count,%edx
  112. .LLoop1: movb (%esi),%cl
  113. and $219,%ecx
  114. mov %ecx,%eax
  115. mov %ecx,%ebx
  116. and $24,%eax
  117. and $3,%bl
  118. shr $1,%al
  119. or %bl,%al
  120. shl $1,%al
  121. mov %ecx,%ebx
  122. and $192,%bl
  123. shl $1,%al
  124. or %bl,%al
  125. shr $1,%al
  126. movb %al,(%esi)
  127. incl %esi
  128. decl %edx
  129. jne .LLoop1
  130. end['EAX','EBX','ECX','EDX','ESI'];
  131. procedure silloute (var Data;Count:longint); assembler;
  132. {Iterates through "Count" bytes of "Data" and sets a byte to $48 if it is
  133. not zero. If you would rotate a character round vertical axis through 90
  134. degrees, this is about how it looks like}
  135. asm
  136. mov data,%esi
  137. movl Count,%edx
  138. .LLoop1: movb (%esi),%al
  139. mov $48,%ecx
  140. test %al,%al
  141. je .Lfurther
  142. mov %cl,%al
  143. .Lfurther:
  144. movb %al,(%esi)
  145. incl %esi
  146. decl %edx
  147. jne .LLoop1
  148. end['EAX','EBX','ECX','EDX','ESI'];
  149. var Originalfont : Fnt16; {Font on startup, to be saved for restore}
  150. StopIt : BOOLEAN; {Becomes TRUE when SIGUSR2 is received}
  151. RestoreOnExit : Boolean; {Should font be restored on exit?}
  152. procedure OkThatsEnough(sig:longint);cdecl;
  153. begin
  154. StopIt:=TRUE;
  155. end;
  156. procedure dorotate;
  157. { The animation order of the 5 distinctive states, -> 8 changes is one
  158. rotation}
  159. Type RotStatesType = array[0..7] of longint;
  160. const RotStates : RotStatesType=(0,1,4,3,2,3,4,1);
  161. {5 states:
  162. - 0 is mirrored,
  163. - 1 mirrored "compressed"
  164. - 2 is normal,
  165. - 3 normal "compressed",
  166. - 4 "silloutte"}
  167. var fnts : array[0..4] of fnt16;
  168. I : Longint;
  169. iin,oout: timespec;
  170. begin
  171. iin.tv_nsec:=250000000;
  172. iin.tv_sec:=0;
  173. fnts[2]:=OriginalFont;
  174. fnts[0]:=fnts[2]; // Keep a copy.
  175. MirrorFont8(fnts[0],sizeof(fnt16)); // Mirror every byte at bitlevel
  176. fnts[1]:=fnts[0];
  177. stripbits(fnts[1],sizeof(fnt16));
  178. fnts[3]:=fnts[2];
  179. stripbits(fnts[3],sizeof(fnt16));
  180. fnts[4]:=fnts[2];
  181. silloute(fnts[4],sizeof(fnt16));
  182. i:=4;
  183. Repeat
  184. PIO_FONT8x16(0,fnts[RotStates[I and 7]]); // Activate the mirrored set
  185. fpnanosleep(@iin,@oout);
  186. inc(i);
  187. until StopIt;
  188. end;
  189. procedure upanddown(Mini:BOOLEAN);
  190. var
  191. fnts : array[1..4] OF fnt16;
  192. inn,outn : Timespec;
  193. i : longint;
  194. Mask : Longint;
  195. begin
  196. fnts[2]:=OriginalFont;
  197. inn.tv_nsec:=50000000;
  198. inn.tv_sec:=0;
  199. fnts[4]:=fnts[2]; {Make three copies}
  200. fnts[1]:=fnts[2];
  201. fnts[3]:=fnts[2];
  202. {Move one of them one byte up in memory. Font is one bit lower}
  203. move (fnts[1],fnts[1].fnt8x16[1],SIZEOF(Fnt16)-1);
  204. {Move another of them one byte down in memory. Font is one bit higher}
  205. IF Mini THEN
  206. Begin
  207. Mask:=1;
  208. move (fnts[2].fnt8x16[1],fnts[2],SIZEOF(Fnt16)-1);
  209. end
  210. else
  211. begin
  212. move (fnts[3].fnt8x16[1],fnts[3],SIZEOF(Fnt16)-1);
  213. Mask:=3;
  214. end;
  215. Repeat
  216. fpnanosleep(@inn,@outn);
  217. pIO_FONT8x16(0,fnts[1 + (I and Mask)]);
  218. inc(I);
  219. until StopIt;
  220. end;
  221. procedure LeftAndRight;
  222. var
  223. fnts : array[1..4] OF fnt16;
  224. inn,outn : Timespec;
  225. i : longint;
  226. Mask : Longint;
  227. begin
  228. fnts[2]:=OriginalFont;
  229. inn.tv_nsec:=50000000;
  230. inn.tv_sec:=0;
  231. fnts[4]:=fnts[2]; {Make three copies}
  232. fnts[1]:=fnts[2];
  233. fnts[3]:=fnts[2];
  234. {Move one of them one byte up in memory. Font is one bit lower}
  235. Goright(Fnts[1],SIZEOF(FNT16),2);
  236. GoLeft( Fnts[3],SIZEOF(FNT16),2);
  237. Repeat
  238. fpnanosleep(@inn,@outn);
  239. pIO_FONT8x16(0,fnts[1 + (I and 3)]);
  240. inc(I);
  241. until StopIt;
  242. end;
  243. procedure doalternate;
  244. var
  245. fnts : array[0..5] OF fnt16;
  246. inn,outn : Timespec;
  247. i : longint;
  248. Mask : Longint;
  249. begin
  250. fnts[2]:=OriginalFont;
  251. inn.tv_nsec:=500000000;
  252. inn.tv_sec:=0;
  253. fnts[4]:=fnts[2]; {Make three copies}
  254. fnts[1]:=fnts[2];
  255. fnts[3]:=fnts[2];
  256. {Move one of them one byte up in memory. Font is one bit lower}
  257. doalt(fnts[1],SIZEOF(FNT16) div 2,2,1);
  258. doalt(fnts[3],SIZEOF(FNT16) div 2,2,0);
  259. Repeat
  260. fpnanosleep(@inn,@outn);
  261. writeln(1 + (I and 3));
  262. pIO_FONT8x16(0,fnts[1 + (I and 3)]);
  263. inc(I);
  264. until StopIt;
  265. end;
  266. procedure JustMirror;
  267. var fnt : Fnt16;
  268. begin
  269. fnt:=OriginalFont;
  270. MirrorFont8(fnt,sizeof(fnt16));
  271. pIO_FONT8x16(0,fnt);
  272. IF RestoreOnExit THEN
  273. Repeat
  274. until StopIt;
  275. end;
  276. var DoThis : Longint;
  277. c : Char;
  278. begin
  279. DoThis:=0;
  280. RestoreOnExit := TRUE;
  281. if PhysicalConsole(0) then // a vty?
  282. begin
  283. REPEAT
  284. c:=GetOpt('n012345'); // Commandline processing
  285. IF c IN ['0'..'5'] Then
  286. DoThis:= ORD(c)-48;
  287. IF c='n' THEN
  288. RestoreOnExit:=FALSE;
  289. UNTIL C=EndOfOptions;
  290. StopIt:=false; // Turns true on signal USR2
  291. GIO_FONT8x16(0,OriginalFont); // Get font from videocard.
  292. fpSignal(SIGUSR2,@OkThatsEnough); // Install handler for sigusr2.
  293. CASE DoThis OF // Call the font routines
  294. 0 : DoRotate;
  295. 1 : UpAndDown(TRUE);
  296. 2 : JustMirror;
  297. 3 : UpAndDown(FALSE);
  298. 4 : LeftAndRight;
  299. 5 : doAlternate;
  300. END;
  301. IF RestoreOnExit THEN // clean up if required.
  302. PIO_FONT8x16(0,OriginalFont);
  303. end;
  304. end.