summaryrefslogtreecommitdiff
path: root/demo/freebsd/fontdemo.pas
blob: 44b880914b82238e8791e012b804a1cf800e15ff (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
Program FontDemo;
{ FontDemo.pas, by Marco van de Voort (C) 2000-2001

Compiler: 1.0.5 or 1.1 after 20-01-2001
Target  : FreeBSD 4.x+ with 16x8 font. 3.x untested  (syscons driver)

Demonstrate font modification with the console driver "syscons".
This program doesn't work under X or over telnet.

The purpose of the program is to demonstrate the procedures that change the
font. The demonstration assume a 80x25 console. Framebuffer devices or 80x50
displays (80x50 use 8x8 fonts) require a trivial modification.

The example of mirroring is absurd, but is very visible, so good for
demonstration. The real use is to load the font, change a few characters
(linedrawing, (C) characters, force existance of umlaute or tremas for the
duration of the application.

Note that if you switch to a different vty while the font is mirrored, that
vty is also mirrored.

Root can restore the font via a network device with:

vidcontrol -f 8x16 "fontname in /usr/share/syscons/fonts"   < /dev/ttyv1

The program saves the font, and will terminate and restore the font when
SIGUSR2 is received, unless -n is specified.

killall -USR2 fontdemo

}


Uses Console,{$ifdef ver1_0}Linux{$else}Baseunix{$endif},GetOpts;

{$ifdef ver1_0}
 function fpnanosleep;
 begin
   nanosleep;
 end;
{$endif}

procedure MirrorFont8(var Data;Count:longint); assembler;
{Mirrors on a bit level "Count" bytes in typeless variable "Data"}

asm
         mov data,%esi
         movl Count,%edx
.LLoop1: movb (%esi),%bl
         movl $8,%ecx
.LLoop2: shr  $1,%bl
         rcl  $1,%al
         loop .LLoop2
         movb %al,(%esi)
         incl %esi
         decl %edx
         jne .LLoop1
end['EAX','EBX','ECX','EDX','ESI'];


procedure GoLeft(var Data;Count:longint;shcnt:longint); assembler;
{Mirrors on a bit level "Count" bytes in typeless variable "Data"}

asm
         mov data,%esi
         mov data,%edi
         mov shcnt,%ecx
         movl Count,%edx
         xorl %eax,%eax
.LLoop1: lodsb
         shl  %cl,%eax
         stosb
         incl %esi
         incl %edi
         decl %edx
         jne .LLoop1
end['EAX','EBX','ECX','EDX','ESI'];

procedure GoRight(var Data;Count:longint;shcnt:longint); assembler;
{Mirrors on a bit level "Count" bytes in typeless variable "Data"}

asm
         mov data,%esi
         mov data,%edi
         mov shcnt,%ecx
         movl Count,%edx
         xor %eax,%eax
.LLoop1: lodsb
         shr  %cl,%eax
         stosb
         incl %esi
         incl %edi
         decl %edx
         jne .LLoop1
end['EAX','EBX','ECX','EDX','ESI'];

procedure DoAlt(var Data;Count:longint;shcnt:longint;alt:integer); assembler;
{Mirrors on a bit level "Count" bytes in typeless variable "Data"}

asm
         mov alt,%ecx
         mov data,%esi
         mov data,%edi
         add %ecx,%esi
         add %ecx,%edi

         mov shcnt,%ecx
         movl Count,%edx
         xorl %eax,%eax
.LLoop1: lodsb
         mov %edx,%ebx
         and  $1,%ebx
         test %ebx,%ebx
         je   .Lgoleftalt1
         shl  %cl,%eax
         jmp  .Lgoleftalt2
.Lgoleftalt1:
         shr  %cl,%eax
.Lgoleftalt2:
         stosb
         incl %esi
         incl %edi
         decl %edx
         jne .LLoop1
end['EAX','EBX','ECX','EDX','ESI'];

procedure stripbits (var Data;Count:longint); assembler;
{ "Compresses" a byte. 76543210 -> x764310x where x=0 (but 0 was already
used to indicate bit number :-)

Needed for a rotating effect. (Character rotating round vertical axis)
Does this for "Count" bytes in "Data".
}

asm
         mov data,%esi
         movl Count,%edx
.LLoop1: movb (%esi),%cl
         and  $219,%ecx
         mov  %ecx,%eax
         mov  %ecx,%ebx
         and  $24,%eax
         and  $3,%bl
         shr  $1,%al
         or   %bl,%al
         shl  $1,%al
         mov  %ecx,%ebx
         and  $192,%bl
         shl  $1,%al
         or   %bl,%al
         shr  $1,%al
         movb %al,(%esi)
         incl %esi
         decl %edx
         jne .LLoop1
end['EAX','EBX','ECX','EDX','ESI'];

procedure silloute (var Data;Count:longint); assembler;
{Iterates through "Count" bytes of "Data" and sets a byte to $48 if it is
not zero. If you would rotate a character round vertical axis through 90
degrees, this is about how it looks like}

asm
         mov data,%esi
         movl Count,%edx
.LLoop1: movb (%esi),%al
         mov  $48,%ecx
         test %al,%al
         je   .Lfurther
         mov  %cl,%al
.Lfurther:
         movb %al,(%esi)
         incl %esi
         decl %edx
         jne .LLoop1
end['EAX','EBX','ECX','EDX','ESI'];

var Originalfont : Fnt16;         {Font on startup, to be saved for restore}
    StopIt       : BOOLEAN;       {Becomes TRUE when SIGUSR2 is received}
    RestoreOnExit : Boolean;      {Should font be restored on exit?}

procedure OkThatsEnough(sig:longint);cdecl;

begin
 StopIt:=TRUE;
end;

procedure dorotate;

{ The animation order of the 5 distinctive states, -> 8 changes is one
rotation}
Type RotStatesType   = array[0..7] of longint;

const RotStates : RotStatesType=(0,1,4,3,2,3,4,1);

{5 states:
- 0 is mirrored,
- 1  mirrored "compressed"
- 2 is normal,
- 3 normal "compressed",
- 4 "silloutte"}

var fnts    : array[0..4] of fnt16;
    I       : Longint;
    iin,oout: timespec;

begin
   iin.tv_nsec:=250000000;
   iin.tv_sec:=0;
   fnts[2]:=OriginalFont;
   fnts[0]:=fnts[2];                    // Keep a copy.
   MirrorFont8(fnts[0],sizeof(fnt16));  // Mirror every byte at bitlevel
   fnts[1]:=fnts[0];
   stripbits(fnts[1],sizeof(fnt16));
   fnts[3]:=fnts[2];
   stripbits(fnts[3],sizeof(fnt16));
   fnts[4]:=fnts[2];
   silloute(fnts[4],sizeof(fnt16));
   i:=4;
   Repeat
     PIO_FONT8x16(0,fnts[RotStates[I and 7]]);          // Activate the mirrored set
     fpnanosleep(@iin,@oout);
     inc(i);
   until StopIt;
 end;

procedure upanddown(Mini:BOOLEAN);

var
    fnts      : array[1..4] OF fnt16;
    inn,outn  : Timespec;
    i         : longint;
    Mask      : Longint;

begin
   fnts[2]:=OriginalFont;
   inn.tv_nsec:=50000000;
   inn.tv_sec:=0;
   fnts[4]:=fnts[2];   {Make three copies}
   fnts[1]:=fnts[2];
   fnts[3]:=fnts[2];

   {Move one of them one byte up in memory. Font is one bit lower}

   move (fnts[1],fnts[1].fnt8x16[1],SIZEOF(Fnt16)-1);

   {Move another of them one byte down in memory. Font is one bit higher}
   IF Mini THEN
    Begin
     Mask:=1;
     move (fnts[2].fnt8x16[1],fnts[2],SIZEOF(Fnt16)-1);
    end
   else
    begin
     move (fnts[3].fnt8x16[1],fnts[3],SIZEOF(Fnt16)-1);
     Mask:=3;
    end;

   Repeat
     fpnanosleep(@inn,@outn);
     pIO_FONT8x16(0,fnts[1 + (I and Mask)]);
     inc(I);
   until StopIt;
end;

procedure LeftAndRight;

var
    fnts      : array[1..4] OF fnt16;
    inn,outn  : Timespec;
    i         : longint;
    Mask      : Longint;

begin
   fnts[2]:=OriginalFont;
   inn.tv_nsec:=50000000;
   inn.tv_sec:=0;
   fnts[4]:=fnts[2];   {Make three copies}
   fnts[1]:=fnts[2];
   fnts[3]:=fnts[2];

   {Move one of them one byte up in memory. Font is one bit lower}

   Goright(Fnts[1],SIZEOF(FNT16),2);
   GoLeft( Fnts[3],SIZEOF(FNT16),2);
   Repeat
     fpnanosleep(@inn,@outn);
     pIO_FONT8x16(0,fnts[1 + (I and 3)]);
     inc(I);
   until StopIt;
end;

procedure doalternate;

var
    fnts      : array[0..5] OF fnt16;
    inn,outn  : Timespec;
    i         : longint;
    Mask      : Longint;

begin
   fnts[2]:=OriginalFont;
   inn.tv_nsec:=500000000;
   inn.tv_sec:=0;
   fnts[4]:=fnts[2];   {Make three copies}
   fnts[1]:=fnts[2];
   fnts[3]:=fnts[2];

   {Move one of them one byte up in memory. Font is one bit lower}
   doalt(fnts[1],SIZEOF(FNT16) div 2,2,1);
   doalt(fnts[3],SIZEOF(FNT16) div 2,2,0);
   Repeat
     fpnanosleep(@inn,@outn);
     writeln(1 + (I and 3));
     pIO_FONT8x16(0,fnts[1 + (I and 3)]);
     inc(I);
   until StopIt;
end;

procedure JustMirror;

var fnt : Fnt16;

begin
  fnt:=OriginalFont;
  MirrorFont8(fnt,sizeof(fnt16));
  pIO_FONT8x16(0,fnt);
  IF RestoreOnExit THEN
  Repeat
  until StopIt;
end;

var DoThis        : Longint;

    c             : Char;
begin
 DoThis:=0;
 RestoreOnExit := TRUE;
 if PhysicalConsole(0) then             // a vty?
  begin
   REPEAT
    c:=GetOpt('n012345');                       // Commandline processing
    IF c IN ['0'..'5'] Then
     DoThis:= ORD(c)-48;
    IF c='n' THEN
     RestoreOnExit:=FALSE;
   UNTIL C=EndOfOptions;

   StopIt:=false;                       // Turns true on signal USR2
   GIO_FONT8x16(0,OriginalFont);        // Get font from videocard.
   fpSignal(SIGUSR2,@OkThatsEnough);    // Install handler for sigusr2.

   CASE DoThis OF                       // Call the font routines
    0 : DoRotate;
    1 : UpAndDown(TRUE);
    2 : JustMirror;
    3 : UpAndDown(FALSE);
    4 : LeftAndRight;
    5 : doAlternate;
    END;

   IF RestoreOnExit THEN                // clean up if required.
    PIO_FONT8x16(0,OriginalFont);
  end;
end.