This source file includes following definitions.
- gotoxy
- set_origin
- scrup
- scrdown
- lf
- ri
- cr
- del
- csi_J
- csi_K
- csi_m
- set_cursor
- respond
- insert_char
- insert_line
- delete_char
- delete_line
- csi_at
- csi_L
- csi_P
- csi_M
- save_cur
- restore_cur
- con_write
- con_init
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 #include <linux/sched.h>
25 #include <linux/tty.h>
26 #include <asm/io.h>
27 #include <asm/system.h>
28
29
30
31
32 #define ORIG_X (*(unsigned char *)0x90000)
33 #define ORIG_Y (*(unsigned char *)0x90001)
34
35 #define SCREEN_START 0xb8000
36 #define SCREEN_END 0xc0000
37 #define LINES 25
38 #define COLUMNS 80
39 #define NPAR 16
40
41 extern void keyboard_interrupt(void);
42
43 static unsigned long origin=SCREEN_START;
44 static unsigned long scr_end=SCREEN_START+LINES*COLUMNS*2;
45 static unsigned long pos;
46 static unsigned long x,y;
47 static unsigned long top=0,bottom=LINES;
48 static unsigned long lines=LINES,columns=COLUMNS;
49 static unsigned long state=0;
50 static unsigned long npar,par[NPAR];
51 static unsigned long ques=0;
52 static unsigned char attr=0x07;
53
54
55
56
57
58 #define RESPONSE "\033[?1;2c"
59
60
61 static inline void gotoxy(unsigned int new_x,unsigned int new_y)
62 {
63 if (new_x > columns || new_y >= lines)
64 return;
65 x=new_x;
66 y=new_y;
67 pos=origin+((y*columns+x)<<1);
68 }
69
70 static inline void set_origin(void)
71 {
72 cli();
73 outb_p(12,0x3d4);
74 outb_p(0xff&((origin-SCREEN_START)>>9),0x3d5);
75 outb_p(13,0x3d4);
76 outb_p(0xff&((origin-SCREEN_START)>>1),0x3d5);
77 sti();
78 }
79
80 static void scrup(void)
81 {
82 if (!top && bottom==lines) {
83 origin += columns<<1;
84 pos += columns<<1;
85 scr_end += columns<<1;
86 if (scr_end>SCREEN_END) {
87 __asm__("cld\n\t"
88 "rep\n\t"
89 "movsl\n\t"
90 "movl _columns,%1\n\t"
91 "rep\n\t"
92 "stosw"
93 ::"a" (0x0720),
94 "c" ((lines-1)*columns>>1),
95 "D" (SCREEN_START),
96 "S" (origin)
97 :"cx","di","si");
98 scr_end -= origin-SCREEN_START;
99 pos -= origin-SCREEN_START;
100 origin = SCREEN_START;
101 } else {
102 __asm__("cld\n\t"
103 "rep\n\t"
104 "stosl"
105 ::"a" (0x07200720),
106 "c" (columns>>1),
107 "D" (scr_end-(columns<<1))
108 :"cx","di");
109 }
110 set_origin();
111 } else {
112 __asm__("cld\n\t"
113 "rep\n\t"
114 "movsl\n\t"
115 "movl _columns,%%ecx\n\t"
116 "rep\n\t"
117 "stosw"
118 ::"a" (0x0720),
119 "c" ((bottom-top-1)*columns>>1),
120 "D" (origin+(columns<<1)*top),
121 "S" (origin+(columns<<1)*(top+1))
122 :"cx","di","si");
123 }
124 }
125
126 static void scrdown(void)
127 {
128 __asm__("std\n\t"
129 "rep\n\t"
130 "movsl\n\t"
131 "addl $2,%%edi\n\t"
132 "movl _columns,%%ecx\n\t"
133 "rep\n\t"
134 "stosw"
135 ::"a" (0x0720),
136 "c" ((bottom-top-1)*columns>>1),
137 "D" (origin+(columns<<1)*bottom-4),
138 "S" (origin+(columns<<1)*(bottom-1)-4)
139 :"ax","cx","di","si");
140 }
141
142 static void lf(void)
143 {
144 if (y+1<bottom) {
145 y++;
146 pos += columns<<1;
147 return;
148 }
149 scrup();
150 }
151
152 static void ri(void)
153 {
154 if (y>top) {
155 y--;
156 pos -= columns<<1;
157 return;
158 }
159 scrdown();
160 }
161
162 static void cr(void)
163 {
164 pos -= x<<1;
165 x=0;
166 }
167
168 static void del(void)
169 {
170 if (x) {
171 pos -= 2;
172 x--;
173 *(unsigned short *)pos = 0x0720;
174 }
175 }
176
177 static void csi_J(int par)
178 {
179 long count __asm__("cx");
180 long start __asm__("di");
181
182 switch (par) {
183 case 0:
184 count = (scr_end-pos)>>1;
185 start = pos;
186 break;
187 case 1:
188 count = (pos-origin)>>1;
189 start = origin;
190 break;
191 case 2:
192 count = columns*lines;
193 start = origin;
194 break;
195 default:
196 return;
197 }
198 __asm__("cld\n\t"
199 "rep\n\t"
200 "stosw\n\t"
201 ::"c" (count),
202 "D" (start),"a" (0x0720)
203 :"cx","di");
204 }
205
206 static void csi_K(int par)
207 {
208 long count __asm__("cx");
209 long start __asm__("di");
210
211 switch (par) {
212 case 0:
213 if (x>=columns)
214 return;
215 count = columns-x;
216 start = pos;
217 break;
218 case 1:
219 start = pos - (x<<1);
220 count = (x<columns)?x:columns;
221 break;
222 case 2:
223 start = pos - (x<<1);
224 count = columns;
225 break;
226 default:
227 return;
228 }
229 __asm__("cld\n\t"
230 "rep\n\t"
231 "stosw\n\t"
232 ::"c" (count),
233 "D" (start),"a" (0x0720)
234 :"cx","di");
235 }
236
237 void csi_m(void)
238 {
239 int i;
240
241 for (i=0;i<=npar;i++)
242 switch (par[i]) {
243 case 0:attr=0x07;break;
244 case 1:attr=0x0f;break;
245 case 4:attr=0x0f;break;
246 case 7:attr=0x70;break;
247 case 27:attr=0x07;break;
248 }
249 }
250
251 static inline void set_cursor(void)
252 {
253 cli();
254 outb_p(14,0x3d4);
255 outb_p(0xff&((pos-SCREEN_START)>>9),0x3d5);
256 outb_p(15,0x3d4);
257 outb_p(0xff&((pos-SCREEN_START)>>1),0x3d5);
258 sti();
259 }
260
261 static void respond(struct tty_struct * tty)
262 {
263 char * p = RESPONSE;
264
265 cli();
266 while (*p) {
267 PUTCH(*p,tty->read_q);
268 p++;
269 }
270 sti();
271 copy_to_cooked(tty);
272 }
273
274 static void insert_char(void)
275 {
276 int i=x;
277 unsigned short tmp,old=0x0720;
278 unsigned short * p = (unsigned short *) pos;
279
280 while (i++<columns) {
281 tmp=*p;
282 *p=old;
283 old=tmp;
284 p++;
285 }
286 }
287
288 static void insert_line(void)
289 {
290 int oldtop,oldbottom;
291
292 oldtop=top;
293 oldbottom=bottom;
294 top=y;
295 bottom=lines;
296 scrdown();
297 top=oldtop;
298 bottom=oldbottom;
299 }
300
301 static void delete_char(void)
302 {
303 int i;
304 unsigned short * p = (unsigned short *) pos;
305
306 if (x>=columns)
307 return;
308 i = x;
309 while (++i < columns) {
310 *p = *(p+1);
311 p++;
312 }
313 *p=0x0720;
314 }
315
316 static void delete_line(void)
317 {
318 int oldtop,oldbottom;
319
320 oldtop=top;
321 oldbottom=bottom;
322 top=y;
323 bottom=lines;
324 scrup();
325 top=oldtop;
326 bottom=oldbottom;
327 }
328
329 static void csi_at(unsigned int nr)
330 {
331 if (nr>columns)
332 nr=columns;
333 else if (!nr)
334 nr=1;
335 while (nr--)
336 insert_char();
337 }
338
339 static void csi_L(unsigned int nr)
340 {
341 if (nr>lines)
342 nr=lines;
343 else if (!nr)
344 nr=1;
345 while (nr--)
346 insert_line();
347 }
348
349 static void csi_P(unsigned int nr)
350 {
351 if (nr>columns)
352 nr=columns;
353 else if (!nr)
354 nr=1;
355 while (nr--)
356 delete_char();
357 }
358
359 static void csi_M(unsigned int nr)
360 {
361 if (nr>lines)
362 nr=lines;
363 else if (!nr)
364 nr=1;
365 while (nr--)
366 delete_line();
367 }
368
369 static int saved_x=0;
370 static int saved_y=0;
371
372 static void save_cur(void)
373 {
374 saved_x=x;
375 saved_y=y;
376 }
377
378 static void restore_cur(void)
379 {
380 gotoxy(saved_x, saved_y);
381 }
382
383 void con_write(struct tty_struct * tty)
384 {
385 int nr;
386 char c;
387
388 nr = CHARS(tty->write_q);
389 while (nr--) {
390 GETCH(tty->write_q,c);
391 switch(state) {
392 case 0:
393 if (c>31 && c<127) {
394 if (x>=columns) {
395 x -= columns;
396 pos -= columns<<1;
397 lf();
398 }
399 __asm__("movb _attr,%%ah\n\t"
400 "movw %%ax,%1\n\t"
401 ::"a" (c),"m" (*(short *)pos)
402 :"ax");
403 pos += 2;
404 x++;
405 } else if (c==27)
406 state=1;
407 else if (c==10 || c==11 || c==12)
408 lf();
409 else if (c==13)
410 cr();
411 else if (c==ERASE_CHAR(tty))
412 del();
413 else if (c==8) {
414 if (x) {
415 x--;
416 pos -= 2;
417 }
418 } else if (c==9) {
419 c=8-(x&7);
420 x += c;
421 pos += c<<1;
422 if (x>columns) {
423 x -= columns;
424 pos -= columns<<1;
425 lf();
426 }
427 c=9;
428 }
429 break;
430 case 1:
431 state=0;
432 if (c=='[')
433 state=2;
434 else if (c=='E')
435 gotoxy(0,y+1);
436 else if (c=='M')
437 ri();
438 else if (c=='D')
439 lf();
440 else if (c=='Z')
441 respond(tty);
442 else if (x=='7')
443 save_cur();
444 else if (x=='8')
445 restore_cur();
446 break;
447 case 2:
448 for(npar=0;npar<NPAR;npar++)
449 par[npar]=0;
450 npar=0;
451 state=3;
452 if (ques=(c=='?'))
453 break;
454 case 3:
455 if (c==';' && npar<NPAR-1) {
456 npar++;
457 break;
458 } else if (c>='0' && c<='9') {
459 par[npar]=10*par[npar]+c-'0';
460 break;
461 } else state=4;
462 case 4:
463 state=0;
464 switch(c) {
465 case 'G': case '`':
466 if (par[0]) par[0]--;
467 gotoxy(par[0],y);
468 break;
469 case 'A':
470 if (!par[0]) par[0]++;
471 gotoxy(x,y-par[0]);
472 break;
473 case 'B': case 'e':
474 if (!par[0]) par[0]++;
475 gotoxy(x,y+par[0]);
476 break;
477 case 'C': case 'a':
478 if (!par[0]) par[0]++;
479 gotoxy(x+par[0],y);
480 break;
481 case 'D':
482 if (!par[0]) par[0]++;
483 gotoxy(x-par[0],y);
484 break;
485 case 'E':
486 if (!par[0]) par[0]++;
487 gotoxy(0,y+par[0]);
488 break;
489 case 'F':
490 if (!par[0]) par[0]++;
491 gotoxy(0,y-par[0]);
492 break;
493 case 'd':
494 if (par[0]) par[0]--;
495 gotoxy(x,par[0]);
496 break;
497 case 'H': case 'f':
498 if (par[0]) par[0]--;
499 if (par[1]) par[1]--;
500 gotoxy(par[1],par[0]);
501 break;
502 case 'J':
503 csi_J(par[0]);
504 break;
505 case 'K':
506 csi_K(par[0]);
507 break;
508 case 'L':
509 csi_L(par[0]);
510 break;
511 case 'M':
512 csi_M(par[0]);
513 break;
514 case 'P':
515 csi_P(par[0]);
516 break;
517 case '@':
518 csi_at(par[0]);
519 break;
520 case 'm':
521 csi_m();
522 break;
523 case 'r':
524 if (par[0]) par[0]--;
525 if (!par[1]) par[1]=lines;
526 if (par[0] < par[1] &&
527 par[1] <= lines) {
528 top=par[0];
529 bottom=par[1];
530 }
531 break;
532 case 's':
533 save_cur();
534 break;
535 case 'u':
536 restore_cur();
537 break;
538 }
539 }
540 }
541 set_cursor();
542 }
543
544
545
546
547
548
549
550
551 void con_init(void)
552 {
553 register unsigned char a;
554
555 gotoxy(ORIG_X,ORIG_Y);
556 set_trap_gate(0x21,&keyboard_interrupt);
557 outb_p(inb_p(0x21)&0xfd,0x21);
558 a=inb_p(0x61);
559 outb_p(a|0x80,0x61);
560 outb(a,0x61);
561 }