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 #define inb(x) 0 /* TODO */
37 #define outb(x, y) /* TODO */
38
39 static int cgapos;
40 static Lock cgascreenlock;
41
42 static uchar
cgaregr(int index)43 cgaregr(int index)
44 {
45 USED(index);
46 outb(0x3D4, index);
47 return inb(0x3D4+1) & 0xFF;
48 }
49
50 static void
cgaregw(int index,int data)51 cgaregw(int index, int data)
52 {
53 USED(index, data);
54 outb(0x3D4, index);
55 outb(0x3D4+1, data);
56 }
57
58 static void
movecursor(void)59 movecursor(void)
60 {
61 cgaregw(0x0E, (cgapos/2>>8) & 0xFF);
62 cgaregw(0x0F, cgapos/2 & 0xFF);
63 CGASCREENBASE[cgapos+1] = Attr;
64 }
65
66 static void
cgascreenputc(int c)67 cgascreenputc(int c)
68 {
69 int i;
70 uchar *p;
71
72 if(c == '\n'){
73 cgapos = cgapos/Width;
74 cgapos = (cgapos+1)*Width;
75 }
76 else if(c == '\t'){
77 i = 8 - ((cgapos/2)&7);
78 while(i-->0)
79 cgascreenputc(' ');
80 }
81 else if(c == '\b'){
82 if(cgapos >= 2)
83 cgapos -= 2;
84 cgascreenputc(' ');
85 cgapos -= 2;
86 }
87 else{
88 CGASCREENBASE[cgapos++] = c;
89 CGASCREENBASE[cgapos++] = Attr;
90 }
91 if(cgapos >= Width*Height){
92 memmove(CGASCREENBASE, &CGASCREENBASE[Width], Width*(Height-1));
93 p = &CGASCREENBASE[Width*(Height-1)];
94 for(i=0; i<Width/2; i++){
95 *p++ = ' ';
96 *p++ = Attr;
97 }
98 cgapos = Width*(Height-1);
99 }
100 movecursor();
101 }
102
103 static void
cgascreenputs(char * s,int n)104 cgascreenputs(char* s, int n)
105 {
106 if(!islo()){
107 /*
108 * Don't deadlock trying to
109 * print in an interrupt.
110 */
111 if(!canlock(&cgascreenlock))
112 return;
113 }
114 else
115 lock(&cgascreenlock);
116
117 while(n-- > 0)
118 cgascreenputc(*s++);
119
120 unlock(&cgascreenlock);
121 }
122
123 void
screeninit(void)124 screeninit(void)
125 {
126
127 cgapos = cgaregr(0x0E)<<8;
128 cgapos |= cgaregr(0x0F);
129 cgapos *= 2;
130
131 screenputs = cgascreenputs;
132 }
133