FreeBSD/Linux Kernel Cross Reference
sys/pc/cga.c
1 #include "u.h"
2 #include "../port/lib.h"
3 #include "mem.h"
4 #include "dat.h"
5 #include "fns.h"
6 #include "../port/error.h"
7
8 enum {
9 Black,
10 Blue,
11 Green,
12 Cyan,
13 Red,
14 Magenta,
15 Brown,
16 Grey,
17
18 Bright = 0x08,
19 Blinking = 0x80,
20
21 Yellow = Bright|Brown,
22 White = Bright|Grey,
23 };
24
25 enum {
26 Width = 80*2,
27 Height = 25,
28
29 Attr = (Black<<4)|Grey, /* high nibble background
30 * low foreground
31 */
32 };
33
34 #define CGASCREENBASE ((uchar*)KADDR(0xB8000))
35
36 static int cgapos;
37 static Lock cgascreenlock;
38
39 static uchar
40 cgaregr(int index)
41 {
42 outb(0x3D4, index);
43 return inb(0x3D4+1) & 0xFF;
44 }
45
46 static void
47 cgaregw(int index, int data)
48 {
49 outb(0x3D4, index);
50 outb(0x3D4+1, data);
51 }
52
53 static void
54 movecursor(void)
55 {
56 cgaregw(0x0E, (cgapos/2>>8) & 0xFF);
57 cgaregw(0x0F, cgapos/2 & 0xFF);
58 CGASCREENBASE[cgapos+1] = Attr;
59 }
60
61 static void
62 cgascreenputc(int c)
63 {
64 int i;
65 uchar *p;
66
67 if(c == '\n'){
68 cgapos = cgapos/Width;
69 cgapos = (cgapos+1)*Width;
70 }
71 else if(c == '\t'){
72 i = 8 - ((cgapos/2)&7);
73 while(i-->0)
74 cgascreenputc(' ');
75 }
76 else if(c == '\b'){
77 if(cgapos >= 2)
78 cgapos -= 2;
79 cgascreenputc(' ');
80 cgapos -= 2;
81 }
82 else{
83 CGASCREENBASE[cgapos++] = c;
84 CGASCREENBASE[cgapos++] = Attr;
85 }
86 if(cgapos >= Width*Height){
87 memmove(CGASCREENBASE, &CGASCREENBASE[Width], Width*(Height-1));
88 p = &CGASCREENBASE[Width*(Height-1)];
89 for(i=0; i<Width/2; i++){
90 *p++ = ' ';
91 *p++ = Attr;
92 }
93 cgapos = Width*(Height-1);
94 }
95 movecursor();
96 }
97
98 static void
99 cgascreenputs(char* s, int n)
100 {
101 if(!islo()){
102 /*
103 * Don't deadlock trying to
104 * print in an interrupt.
105 */
106 if(!canlock(&cgascreenlock))
107 return;
108 }
109 else
110 lock(&cgascreenlock);
111
112 while(n-- > 0)
113 cgascreenputc(*s++);
114
115 unlock(&cgascreenlock);
116 }
117
118 void
119 screeninit(void)
120 {
121
122 cgapos = cgaregr(0x0E)<<8;
123 cgapos |= cgaregr(0x0F);
124 cgapos *= 2;
125
126 screenputs = cgascreenputs;
127 }
Cache object: 01614d8548c201091ca085fd4b198c95
|