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