diff options
Diffstat (limited to 'src/kernel/chr_drv/console.c')
-rw-r--r-- | src/kernel/chr_drv/console.c | 710 |
1 files changed, 710 insertions, 0 deletions
diff --git a/src/kernel/chr_drv/console.c b/src/kernel/chr_drv/console.c new file mode 100644 index 0000000..2529569 --- /dev/null +++ b/src/kernel/chr_drv/console.c | |||
@@ -0,0 +1,710 @@ | |||
1 | /* | ||
2 | * linux/kernel/console.c | ||
3 | * | ||
4 | * (C) 1991 Linus Torvalds | ||
5 | */ | ||
6 | |||
7 | /* | ||
8 | * console.c | ||
9 | * | ||
10 | * This module implements the console io functions | ||
11 | * 'void con_init(void)' | ||
12 | * 'void con_write(struct tty_queue * queue)' | ||
13 | * Hopefully this will be a rather complete VT102 implementation. | ||
14 | * | ||
15 | * Beeping thanks to John T Kohl. | ||
16 | */ | ||
17 | |||
18 | /* | ||
19 | * NOTE!!! We sometimes disable and enable interrupts for a short while | ||
20 | * (to put a word in video IO), but this will work even for keyboard | ||
21 | * interrupts. We know interrupts aren't enabled when getting a keyboard | ||
22 | * interrupt, as we use trap-gates. Hopefully all is well. | ||
23 | */ | ||
24 | |||
25 | /* | ||
26 | * Code to check for different video-cards mostly by Galen Hunt, | ||
27 | * <g-hunt@ee.utah.edu> | ||
28 | */ | ||
29 | |||
30 | #include <linux/sched.h> | ||
31 | #include <linux/tty.h> | ||
32 | #include <asm/io.h> | ||
33 | #include <asm/system.h> | ||
34 | |||
35 | /* | ||
36 | * These are set up by the setup-routine at boot-time: | ||
37 | */ | ||
38 | |||
39 | #define ORIG_X (*(unsigned char *)0x90000) | ||
40 | #define ORIG_Y (*(unsigned char *)0x90001) | ||
41 | #define ORIG_VIDEO_PAGE (*(unsigned short *)0x90004) | ||
42 | #define ORIG_VIDEO_MODE ((*(unsigned short *)0x90006) & 0xff) | ||
43 | #define ORIG_VIDEO_COLS (((*(unsigned short *)0x90006) & 0xff00) >> 8) | ||
44 | #define ORIG_VIDEO_LINES (25) | ||
45 | #define ORIG_VIDEO_EGA_AX (*(unsigned short *)0x90008) | ||
46 | #define ORIG_VIDEO_EGA_BX (*(unsigned short *)0x9000a) | ||
47 | #define ORIG_VIDEO_EGA_CX (*(unsigned short *)0x9000c) | ||
48 | |||
49 | #define VIDEO_TYPE_MDA 0x10 /* Monochrome Text Display */ | ||
50 | #define VIDEO_TYPE_CGA 0x11 /* CGA Display */ | ||
51 | #define VIDEO_TYPE_EGAM 0x20 /* EGA/VGA in Monochrome Mode */ | ||
52 | #define VIDEO_TYPE_EGAC 0x21 /* EGA/VGA in Color Mode */ | ||
53 | |||
54 | #define NPAR 16 | ||
55 | |||
56 | extern void keyboard_interrupt(void); | ||
57 | |||
58 | static unsigned char video_type; /* Type of display being used */ | ||
59 | static unsigned long video_num_columns; /* Number of text columns */ | ||
60 | static unsigned long video_size_row; /* Bytes per row */ | ||
61 | static unsigned long video_num_lines; /* Number of test lines */ | ||
62 | static unsigned char video_page; /* Initial video page */ | ||
63 | static unsigned long video_mem_start; /* Start of video RAM */ | ||
64 | static unsigned long video_mem_end; /* End of video RAM (sort of) */ | ||
65 | static unsigned short video_port_reg; /* Video register select port */ | ||
66 | static unsigned short video_port_val; /* Video register value port */ | ||
67 | static unsigned short video_erase_char; /* Char+Attrib to erase with */ | ||
68 | |||
69 | static unsigned long origin; /* Used for EGA/VGA fast scroll */ | ||
70 | static unsigned long scr_end; /* Used for EGA/VGA fast scroll */ | ||
71 | static unsigned long pos; | ||
72 | static unsigned long x,y; | ||
73 | static unsigned long top,bottom; | ||
74 | static unsigned long state=0; | ||
75 | static unsigned long npar,par[NPAR]; | ||
76 | static unsigned long ques=0; | ||
77 | static unsigned char attr=0x07; | ||
78 | |||
79 | static void sysbeep(void); | ||
80 | |||
81 | /* | ||
82 | * this is what the terminal answers to a ESC-Z or csi0c | ||
83 | * query (= vt100 response). | ||
84 | */ | ||
85 | #define RESPONSE "\033[?1;2c" | ||
86 | |||
87 | /* NOTE! gotoxy thinks x==video_num_columns is ok */ | ||
88 | static inline void gotoxy(unsigned int new_x,unsigned int new_y) | ||
89 | { | ||
90 | if (new_x > video_num_columns || new_y >= video_num_lines) | ||
91 | return; | ||
92 | x=new_x; | ||
93 | y=new_y; | ||
94 | pos=origin + y*video_size_row + (x<<1); | ||
95 | } | ||
96 | |||
97 | static inline void set_origin(void) | ||
98 | { | ||
99 | cli(); | ||
100 | outb_p(12, video_port_reg); | ||
101 | outb_p(0xff&((origin-video_mem_start)>>9), video_port_val); | ||
102 | outb_p(13, video_port_reg); | ||
103 | outb_p(0xff&((origin-video_mem_start)>>1), video_port_val); | ||
104 | sti(); | ||
105 | } | ||
106 | |||
107 | static void scrup(void) | ||
108 | { | ||
109 | if (video_type == VIDEO_TYPE_EGAC || video_type == VIDEO_TYPE_EGAM) | ||
110 | { | ||
111 | if (!top && bottom == video_num_lines) { | ||
112 | origin += video_size_row; | ||
113 | pos += video_size_row; | ||
114 | scr_end += video_size_row; | ||
115 | if (scr_end > video_mem_end) { | ||
116 | __asm__("cld\n\t" | ||
117 | "rep\n\t" | ||
118 | "movsl\n\t" | ||
119 | "movl video_num_columns,%1\n\t" | ||
120 | "rep\n\t" | ||
121 | "stosw" | ||
122 | ::"a" (video_erase_char), | ||
123 | "c" ((video_num_lines-1)*video_num_columns>>1), | ||
124 | "D" (video_mem_start), | ||
125 | "S" (origin) | ||
126 | ); | ||
127 | scr_end -= origin-video_mem_start; | ||
128 | pos -= origin-video_mem_start; | ||
129 | origin = video_mem_start; | ||
130 | } else { | ||
131 | __asm__("cld\n\t" | ||
132 | "rep\n\t" | ||
133 | "stosw" | ||
134 | ::"a" (video_erase_char), | ||
135 | "c" (video_num_columns), | ||
136 | "D" (scr_end-video_size_row) | ||
137 | ); | ||
138 | } | ||
139 | set_origin(); | ||
140 | } else { | ||
141 | __asm__("cld\n\t" | ||
142 | "rep\n\t" | ||
143 | "movsl\n\t" | ||
144 | "movl video_num_columns,%%ecx\n\t" | ||
145 | "rep\n\t" | ||
146 | "stosw" | ||
147 | ::"a" (video_erase_char), | ||
148 | "c" ((bottom-top-1)*video_num_columns>>1), | ||
149 | "D" (origin+video_size_row*top), | ||
150 | "S" (origin+video_size_row*(top+1)) | ||
151 | ); | ||
152 | } | ||
153 | } | ||
154 | else /* Not EGA/VGA */ | ||
155 | { | ||
156 | __asm__("cld\n\t" | ||
157 | "rep\n\t" | ||
158 | "movsl\n\t" | ||
159 | "movl video_num_columns,%%ecx\n\t" | ||
160 | "rep\n\t" | ||
161 | "stosw" | ||
162 | ::"a" (video_erase_char), | ||
163 | "c" ((bottom-top-1)*video_num_columns>>1), | ||
164 | "D" (origin+video_size_row*top), | ||
165 | "S" (origin+video_size_row*(top+1)) | ||
166 | ); | ||
167 | } | ||
168 | } | ||
169 | |||
170 | static void scrdown(void) | ||
171 | { | ||
172 | if (video_type == VIDEO_TYPE_EGAC || video_type == VIDEO_TYPE_EGAM) | ||
173 | { | ||
174 | __asm__("std\n\t" | ||
175 | "rep\n\t" | ||
176 | "movsl\n\t" | ||
177 | "addl $2,%%edi\n\t" /* %edi has been decremented by 4 */ | ||
178 | "movl video_num_columns,%%ecx\n\t" | ||
179 | "rep\n\t" | ||
180 | "stosw" | ||
181 | ::"a" (video_erase_char), | ||
182 | "c" ((bottom-top-1)*video_num_columns>>1), | ||
183 | "D" (origin+video_size_row*bottom-4), | ||
184 | "S" (origin+video_size_row*(bottom-1)-4) | ||
185 | ); | ||
186 | } | ||
187 | else /* Not EGA/VGA */ | ||
188 | { | ||
189 | __asm__("std\n\t" | ||
190 | "rep\n\t" | ||
191 | "movsl\n\t" | ||
192 | "addl $2,%%edi\n\t" /* %edi has been decremented by 4 */ | ||
193 | "movl video_num_columns,%%ecx\n\t" | ||
194 | "rep\n\t" | ||
195 | "stosw" | ||
196 | ::"a" (video_erase_char), | ||
197 | "c" ((bottom-top-1)*video_num_columns>>1), | ||
198 | "D" (origin+video_size_row*bottom-4), | ||
199 | "S" (origin+video_size_row*(bottom-1)-4) | ||
200 | ); | ||
201 | } | ||
202 | } | ||
203 | |||
204 | static void lf(void) | ||
205 | { | ||
206 | if (y+1<bottom) { | ||
207 | y++; | ||
208 | pos += video_size_row; | ||
209 | return; | ||
210 | } | ||
211 | scrup(); | ||
212 | } | ||
213 | |||
214 | static void ri(void) | ||
215 | { | ||
216 | if (y>top) { | ||
217 | y--; | ||
218 | pos -= video_size_row; | ||
219 | return; | ||
220 | } | ||
221 | scrdown(); | ||
222 | } | ||
223 | |||
224 | static void cr(void) | ||
225 | { | ||
226 | pos -= x<<1; | ||
227 | x=0; | ||
228 | } | ||
229 | |||
230 | static void del(void) | ||
231 | { | ||
232 | if (x) { | ||
233 | pos -= 2; | ||
234 | x--; | ||
235 | *(unsigned short *)pos = video_erase_char; | ||
236 | } | ||
237 | } | ||
238 | |||
239 | static void csi_J(int par) | ||
240 | { | ||
241 | long count; | ||
242 | long start; | ||
243 | |||
244 | switch (par) { | ||
245 | case 0: /* erase from cursor to end of display */ | ||
246 | count = (scr_end-pos)>>1; | ||
247 | start = pos; | ||
248 | break; | ||
249 | case 1: /* erase from start to cursor */ | ||
250 | count = (pos-origin)>>1; | ||
251 | start = origin; | ||
252 | break; | ||
253 | case 2: /* erase whole display */ | ||
254 | count = video_num_columns * video_num_lines; | ||
255 | start = origin; | ||
256 | break; | ||
257 | default: | ||
258 | return; | ||
259 | } | ||
260 | __asm__("cld\n\t" | ||
261 | "rep\n\t" | ||
262 | "stosw\n\t" | ||
263 | ::"c" (count), | ||
264 | "D" (start),"a" (video_erase_char) | ||
265 | ); | ||
266 | } | ||
267 | |||
268 | static void csi_K(int par) | ||
269 | { | ||
270 | long count; | ||
271 | long start; | ||
272 | |||
273 | switch (par) { | ||
274 | case 0: /* erase from cursor to end of line */ | ||
275 | if (x>=video_num_columns) | ||
276 | return; | ||
277 | count = video_num_columns-x; | ||
278 | start = pos; | ||
279 | break; | ||
280 | case 1: /* erase from start of line to cursor */ | ||
281 | start = pos - (x<<1); | ||
282 | count = (x<video_num_columns)?x:video_num_columns; | ||
283 | break; | ||
284 | case 2: /* erase whole line */ | ||
285 | start = pos - (x<<1); | ||
286 | count = video_num_columns; | ||
287 | break; | ||
288 | default: | ||
289 | return; | ||
290 | } | ||
291 | __asm__("cld\n\t" | ||
292 | "rep\n\t" | ||
293 | "stosw\n\t" | ||
294 | ::"c" (count), | ||
295 | "D" (start),"a" (video_erase_char) | ||
296 | ); | ||
297 | } | ||
298 | |||
299 | void csi_m(void) | ||
300 | { | ||
301 | int i; | ||
302 | |||
303 | for (i=0;i<=npar;i++) | ||
304 | switch (par[i]) { | ||
305 | case 0:attr=0x07;break; | ||
306 | case 1:attr=0x0f;break; | ||
307 | case 4:attr=0x0f;break; | ||
308 | case 7:attr=0x70;break; | ||
309 | case 27:attr=0x07;break; | ||
310 | } | ||
311 | } | ||
312 | |||
313 | static inline void set_cursor(void) | ||
314 | { | ||
315 | cli(); | ||
316 | outb_p(14, video_port_reg); | ||
317 | outb_p(0xff&((pos-video_mem_start)>>9), video_port_val); | ||
318 | outb_p(15, video_port_reg); | ||
319 | outb_p(0xff&((pos-video_mem_start)>>1), video_port_val); | ||
320 | sti(); | ||
321 | } | ||
322 | |||
323 | static void respond(struct tty_struct * tty) | ||
324 | { | ||
325 | char * p = RESPONSE; | ||
326 | |||
327 | cli(); | ||
328 | while (*p) { | ||
329 | PUTCH(*p,tty->read_q); | ||
330 | p++; | ||
331 | } | ||
332 | sti(); | ||
333 | copy_to_cooked(tty); | ||
334 | } | ||
335 | |||
336 | static void insert_char(void) | ||
337 | { | ||
338 | int i=x; | ||
339 | unsigned short tmp, old = video_erase_char; | ||
340 | unsigned short * p = (unsigned short *) pos; | ||
341 | |||
342 | while (i++<video_num_columns) { | ||
343 | tmp=*p; | ||
344 | *p=old; | ||
345 | old=tmp; | ||
346 | p++; | ||
347 | } | ||
348 | } | ||
349 | |||
350 | static void insert_line(void) | ||
351 | { | ||
352 | int oldtop,oldbottom; | ||
353 | |||
354 | oldtop=top; | ||
355 | oldbottom=bottom; | ||
356 | top=y; | ||
357 | bottom = video_num_lines; | ||
358 | scrdown(); | ||
359 | top=oldtop; | ||
360 | bottom=oldbottom; | ||
361 | } | ||
362 | |||
363 | static void delete_char(void) | ||
364 | { | ||
365 | int i; | ||
366 | unsigned short * p = (unsigned short *) pos; | ||
367 | |||
368 | if (x>=video_num_columns) | ||
369 | return; | ||
370 | i = x; | ||
371 | while (++i < video_num_columns) { | ||
372 | *p = *(p+1); | ||
373 | p++; | ||
374 | } | ||
375 | *p = video_erase_char; | ||
376 | } | ||
377 | |||
378 | static void delete_line(void) | ||
379 | { | ||
380 | int oldtop,oldbottom; | ||
381 | |||
382 | oldtop=top; | ||
383 | oldbottom=bottom; | ||
384 | top=y; | ||
385 | bottom = video_num_lines; | ||
386 | scrup(); | ||
387 | top=oldtop; | ||
388 | bottom=oldbottom; | ||
389 | } | ||
390 | |||
391 | static void csi_at(unsigned int nr) | ||
392 | { | ||
393 | if (nr > video_num_columns) | ||
394 | nr = video_num_columns; | ||
395 | else if (!nr) | ||
396 | nr = 1; | ||
397 | while (nr--) | ||
398 | insert_char(); | ||
399 | } | ||
400 | |||
401 | static void csi_L(unsigned int nr) | ||
402 | { | ||
403 | if (nr > video_num_lines) | ||
404 | nr = video_num_lines; | ||
405 | else if (!nr) | ||
406 | nr = 1; | ||
407 | while (nr--) | ||
408 | insert_line(); | ||
409 | } | ||
410 | |||
411 | static void csi_P(unsigned int nr) | ||
412 | { | ||
413 | if (nr > video_num_columns) | ||
414 | nr = video_num_columns; | ||
415 | else if (!nr) | ||
416 | nr = 1; | ||
417 | while (nr--) | ||
418 | delete_char(); | ||
419 | } | ||
420 | |||
421 | static void csi_M(unsigned int nr) | ||
422 | { | ||
423 | if (nr > video_num_lines) | ||
424 | nr = video_num_lines; | ||
425 | else if (!nr) | ||
426 | nr=1; | ||
427 | while (nr--) | ||
428 | delete_line(); | ||
429 | } | ||
430 | |||
431 | static int saved_x=0; | ||
432 | static int saved_y=0; | ||
433 | |||
434 | static void save_cur(void) | ||
435 | { | ||
436 | saved_x=x; | ||
437 | saved_y=y; | ||
438 | } | ||
439 | |||
440 | static void restore_cur(void) | ||
441 | { | ||
442 | gotoxy(saved_x, saved_y); | ||
443 | } | ||
444 | |||
445 | void con_write(struct tty_struct * tty) | ||
446 | { | ||
447 | int nr; | ||
448 | char c; | ||
449 | |||
450 | nr = CHARS(tty->write_q); | ||
451 | while (nr--) { | ||
452 | GETCH(tty->write_q,c); | ||
453 | switch(state) { | ||
454 | case 0: | ||
455 | if (c>31 && c<127) { | ||
456 | if (x>=video_num_columns) { | ||
457 | x -= video_num_columns; | ||
458 | pos -= video_size_row; | ||
459 | lf(); | ||
460 | } | ||
461 | __asm__("movb attr,%%ah\n\t" | ||
462 | "movw %%ax,%1\n\t" | ||
463 | ::"a" (c),"m" (*(short *)pos) | ||
464 | ); | ||
465 | pos += 2; | ||
466 | x++; | ||
467 | } else if (c==27) | ||
468 | state=1; | ||
469 | else if (c==10 || c==11 || c==12) | ||
470 | lf(); | ||
471 | else if (c==13) | ||
472 | cr(); | ||
473 | else if (c==ERASE_CHAR(tty)) | ||
474 | del(); | ||
475 | else if (c==8) { | ||
476 | if (x) { | ||
477 | x--; | ||
478 | pos -= 2; | ||
479 | } | ||
480 | } else if (c==9) { | ||
481 | c=8-(x&7); | ||
482 | x += c; | ||
483 | pos += c<<1; | ||
484 | if (x>video_num_columns) { | ||
485 | x -= video_num_columns; | ||
486 | pos -= video_size_row; | ||
487 | lf(); | ||
488 | } | ||
489 | c=9; | ||
490 | } else if (c==7) | ||
491 | sysbeep(); | ||
492 | break; | ||
493 | case 1: | ||
494 | state=0; | ||
495 | if (c=='[') | ||
496 | state=2; | ||
497 | else if (c=='E') | ||
498 | gotoxy(0,y+1); | ||
499 | else if (c=='M') | ||
500 | ri(); | ||
501 | else if (c=='D') | ||
502 | lf(); | ||
503 | else if (c=='Z') | ||
504 | respond(tty); | ||
505 | else if (x=='7') | ||
506 | save_cur(); | ||
507 | else if (x=='8') | ||
508 | restore_cur(); | ||
509 | break; | ||
510 | case 2: | ||
511 | for(npar=0;npar<NPAR;npar++) | ||
512 | par[npar]=0; | ||
513 | npar=0; | ||
514 | state=3; | ||
515 | if ((ques=(c=='?'))) | ||
516 | break; | ||
517 | case 3: | ||
518 | if (c==';' && npar<NPAR-1) { | ||
519 | npar++; | ||
520 | break; | ||
521 | } else if (c>='0' && c<='9') { | ||
522 | par[npar]=10*par[npar]+c-'0'; | ||
523 | break; | ||
524 | } else state=4; | ||
525 | case 4: | ||
526 | state=0; | ||
527 | switch(c) { | ||
528 | case 'G': case '`': | ||
529 | if (par[0]) par[0]--; | ||
530 | gotoxy(par[0],y); | ||
531 | break; | ||
532 | case 'A': | ||
533 | if (!par[0]) par[0]++; | ||
534 | gotoxy(x,y-par[0]); | ||
535 | break; | ||
536 | case 'B': case 'e': | ||
537 | if (!par[0]) par[0]++; | ||
538 | gotoxy(x,y+par[0]); | ||
539 | break; | ||
540 | case 'C': case 'a': | ||
541 | if (!par[0]) par[0]++; | ||
542 | gotoxy(x+par[0],y); | ||
543 | break; | ||
544 | case 'D': | ||
545 | if (!par[0]) par[0]++; | ||
546 | gotoxy(x-par[0],y); | ||
547 | break; | ||
548 | case 'E': | ||
549 | if (!par[0]) par[0]++; | ||
550 | gotoxy(0,y+par[0]); | ||
551 | break; | ||
552 | case 'F': | ||
553 | if (!par[0]) par[0]++; | ||
554 | gotoxy(0,y-par[0]); | ||
555 | break; | ||
556 | case 'd': | ||
557 | if (par[0]) par[0]--; | ||
558 | gotoxy(x,par[0]); | ||
559 | break; | ||
560 | case 'H': case 'f': | ||
561 | if (par[0]) par[0]--; | ||
562 | if (par[1]) par[1]--; | ||
563 | gotoxy(par[1],par[0]); | ||
564 | break; | ||
565 | case 'J': | ||
566 | csi_J(par[0]); | ||
567 | break; | ||
568 | case 'K': | ||
569 | csi_K(par[0]); | ||
570 | break; | ||
571 | case 'L': | ||
572 | csi_L(par[0]); | ||
573 | break; | ||
574 | case 'M': | ||
575 | csi_M(par[0]); | ||
576 | break; | ||
577 | case 'P': | ||
578 | csi_P(par[0]); | ||
579 | break; | ||
580 | case '@': | ||
581 | csi_at(par[0]); | ||
582 | break; | ||
583 | case 'm': | ||
584 | csi_m(); | ||
585 | break; | ||
586 | case 'r': | ||
587 | if (par[0]) par[0]--; | ||
588 | if (!par[1]) par[1] = video_num_lines; | ||
589 | if (par[0] < par[1] && | ||
590 | par[1] <= video_num_lines) { | ||
591 | top=par[0]; | ||
592 | bottom=par[1]; | ||
593 | } | ||
594 | break; | ||
595 | case 's': | ||
596 | save_cur(); | ||
597 | break; | ||
598 | case 'u': | ||
599 | restore_cur(); | ||
600 | break; | ||
601 | } | ||
602 | } | ||
603 | } | ||
604 | set_cursor(); | ||
605 | } | ||
606 | |||
607 | /* | ||
608 | * void con_init(void); | ||
609 | * | ||
610 | * This routine initalizes console interrupts, and does nothing | ||
611 | * else. If you want the screen to clear, call tty_write with | ||
612 | * the appropriate escape-sequece. | ||
613 | * | ||
614 | * Reads the information preserved by setup.s to determine the current display | ||
615 | * type and sets everything accordingly. | ||
616 | */ | ||
617 | void con_init(void) | ||
618 | { | ||
619 | register unsigned char a; | ||
620 | char *display_desc = "????"; | ||
621 | char *display_ptr; | ||
622 | |||
623 | video_num_columns = ORIG_VIDEO_COLS; | ||
624 | video_size_row = video_num_columns * 2; | ||
625 | video_num_lines = ORIG_VIDEO_LINES; | ||
626 | video_page = ORIG_VIDEO_PAGE; | ||
627 | video_erase_char = 0x0720; | ||
628 | |||
629 | if (ORIG_VIDEO_MODE == 7) /* Is this a monochrome display? */ | ||
630 | { | ||
631 | video_mem_start = 0xb0000; | ||
632 | video_port_reg = 0x3b4; | ||
633 | video_port_val = 0x3b5; | ||
634 | if ((ORIG_VIDEO_EGA_BX & 0xff) != 0x10) | ||
635 | { | ||
636 | video_type = VIDEO_TYPE_EGAM; | ||
637 | video_mem_end = 0xb8000; | ||
638 | display_desc = "EGAm"; | ||
639 | } | ||
640 | else | ||
641 | { | ||
642 | video_type = VIDEO_TYPE_MDA; | ||
643 | video_mem_end = 0xb2000; | ||
644 | display_desc = "*MDA"; | ||
645 | } | ||
646 | } | ||
647 | else /* If not, it is color. */ | ||
648 | { | ||
649 | video_mem_start = 0xb8000; | ||
650 | video_port_reg = 0x3d4; | ||
651 | video_port_val = 0x3d5; | ||
652 | if ((ORIG_VIDEO_EGA_BX & 0xff) != 0x10) | ||
653 | { | ||
654 | video_type = VIDEO_TYPE_EGAC; | ||
655 | video_mem_end = 0xbc000; | ||
656 | display_desc = "EGAc"; | ||
657 | } | ||
658 | else | ||
659 | { | ||
660 | video_type = VIDEO_TYPE_CGA; | ||
661 | video_mem_end = 0xba000; | ||
662 | display_desc = "*CGA"; | ||
663 | } | ||
664 | } | ||
665 | |||
666 | /* Let the user known what kind of display driver we are using */ | ||
667 | |||
668 | display_ptr = ((char *)video_mem_start) + video_size_row - 8; | ||
669 | while (*display_desc) | ||
670 | { | ||
671 | *display_ptr++ = *display_desc++; | ||
672 | display_ptr++; | ||
673 | } | ||
674 | |||
675 | /* Initialize the variables used for scrolling (mostly EGA/VGA) */ | ||
676 | |||
677 | origin = video_mem_start; | ||
678 | scr_end = video_mem_start + video_num_lines * video_size_row; | ||
679 | top = 0; | ||
680 | bottom = video_num_lines; | ||
681 | |||
682 | gotoxy(ORIG_X,ORIG_Y); | ||
683 | set_trap_gate(0x21,&keyboard_interrupt); | ||
684 | outb_p(inb_p(0x21)&0xfd,0x21); | ||
685 | a=inb_p(0x61); | ||
686 | outb_p(a|0x80,0x61); | ||
687 | outb(a,0x61); | ||
688 | } | ||
689 | /* from bsd-net-2: */ | ||
690 | |||
691 | void sysbeepstop(void) | ||
692 | { | ||
693 | /* disable counter 2 */ | ||
694 | outb(inb_p(0x61)&0xFC, 0x61); | ||
695 | } | ||
696 | |||
697 | int beepcount = 0; | ||
698 | |||
699 | static void sysbeep(void) | ||
700 | { | ||
701 | /* enable counter 2 */ | ||
702 | outb_p(inb_p(0x61)|3, 0x61); | ||
703 | /* set command for counter 2, 2 byte write */ | ||
704 | outb_p(0xB6, 0x43); | ||
705 | /* send 0x637 for 750 HZ */ | ||
706 | outb_p(0x37, 0x42); | ||
707 | outb(0x06, 0x42); | ||
708 | /* 1/8 second */ | ||
709 | beepcount = HZ/8; | ||
710 | } | ||