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.
|