1*9ef1f84bSDavid du Colombier #include "u.h"
2*9ef1f84bSDavid du Colombier #include "../port/lib.h"
3*9ef1f84bSDavid du Colombier #include "mem.h"
4*9ef1f84bSDavid du Colombier #include "dat.h"
5*9ef1f84bSDavid du Colombier #include "fns.h"
6*9ef1f84bSDavid du Colombier
7*9ef1f84bSDavid du Colombier enum {
8*9ef1f84bSDavid du Colombier Black = 0x00,
9*9ef1f84bSDavid du Colombier Blue = 0x01,
10*9ef1f84bSDavid du Colombier Green = 0x02,
11*9ef1f84bSDavid du Colombier Cyan = 0x03,
12*9ef1f84bSDavid du Colombier Red = 0x04,
13*9ef1f84bSDavid du Colombier Magenta = 0x05,
14*9ef1f84bSDavid du Colombier Brown = 0x06,
15*9ef1f84bSDavid du Colombier Grey = 0x07,
16*9ef1f84bSDavid du Colombier
17*9ef1f84bSDavid du Colombier Bright = 0x08,
18*9ef1f84bSDavid du Colombier Blinking = 0x80,
19*9ef1f84bSDavid du Colombier
20*9ef1f84bSDavid du Colombier Attr = (Black<<4)|Grey, /* (background<<4)|foreground */
21*9ef1f84bSDavid du Colombier };
22*9ef1f84bSDavid du Colombier
23*9ef1f84bSDavid du Colombier enum {
24*9ef1f84bSDavid du Colombier Index = 0x3d4,
25*9ef1f84bSDavid du Colombier Data = Index+1,
26*9ef1f84bSDavid du Colombier
27*9ef1f84bSDavid du Colombier Width = 80*2,
28*9ef1f84bSDavid du Colombier Height = 25,
29*9ef1f84bSDavid du Colombier
30*9ef1f84bSDavid du Colombier Poststrlen = 0,
31*9ef1f84bSDavid du Colombier Postcodelen = 2,
32*9ef1f84bSDavid du Colombier Postlen = Poststrlen+Postcodelen,
33*9ef1f84bSDavid du Colombier };
34*9ef1f84bSDavid du Colombier
35*9ef1f84bSDavid du Colombier #define CGA (BIOSSEG(0xb800))
36*9ef1f84bSDavid du Colombier
37*9ef1f84bSDavid du Colombier static Lock cgalock;
38*9ef1f84bSDavid du Colombier static int cgapos;
39*9ef1f84bSDavid du Colombier static int cgainitdone;
40*9ef1f84bSDavid du Colombier
41*9ef1f84bSDavid du Colombier static int
cgaregr(int index)42*9ef1f84bSDavid du Colombier cgaregr(int index)
43*9ef1f84bSDavid du Colombier {
44*9ef1f84bSDavid du Colombier outb(Index, index);
45*9ef1f84bSDavid du Colombier return inb(Data) & 0xff;
46*9ef1f84bSDavid du Colombier }
47*9ef1f84bSDavid du Colombier
48*9ef1f84bSDavid du Colombier static void
cgaregw(int index,int data)49*9ef1f84bSDavid du Colombier cgaregw(int index, int data)
50*9ef1f84bSDavid du Colombier {
51*9ef1f84bSDavid du Colombier outb(Index, index);
52*9ef1f84bSDavid du Colombier outb(Data, data);
53*9ef1f84bSDavid du Colombier }
54*9ef1f84bSDavid du Colombier
55*9ef1f84bSDavid du Colombier static void
cgacursor(void)56*9ef1f84bSDavid du Colombier cgacursor(void)
57*9ef1f84bSDavid du Colombier {
58*9ef1f84bSDavid du Colombier uchar *cga;
59*9ef1f84bSDavid du Colombier
60*9ef1f84bSDavid du Colombier cgaregw(0x0e, (cgapos/2>>8) & 0xff);
61*9ef1f84bSDavid du Colombier cgaregw(0x0f, cgapos/2 & 0xff);
62*9ef1f84bSDavid du Colombier
63*9ef1f84bSDavid du Colombier cga = CGA;
64*9ef1f84bSDavid du Colombier cga[cgapos+1] = Attr;
65*9ef1f84bSDavid du Colombier }
66*9ef1f84bSDavid du Colombier
67*9ef1f84bSDavid du Colombier static void
cgaputc(int c)68*9ef1f84bSDavid du Colombier cgaputc(int c)
69*9ef1f84bSDavid du Colombier {
70*9ef1f84bSDavid du Colombier int i;
71*9ef1f84bSDavid du Colombier uchar *cga, *p;
72*9ef1f84bSDavid du Colombier
73*9ef1f84bSDavid du Colombier cga = CGA;
74*9ef1f84bSDavid du Colombier
75*9ef1f84bSDavid du Colombier if(c == '\n'){
76*9ef1f84bSDavid du Colombier cgapos = cgapos/Width;
77*9ef1f84bSDavid du Colombier cgapos = (cgapos+1)*Width;
78*9ef1f84bSDavid du Colombier }
79*9ef1f84bSDavid du Colombier else if(c == '\t'){
80*9ef1f84bSDavid du Colombier i = 8 - ((cgapos/2)&7);
81*9ef1f84bSDavid du Colombier while(i-- > 0)
82*9ef1f84bSDavid du Colombier cgaputc(' ');
83*9ef1f84bSDavid du Colombier }
84*9ef1f84bSDavid du Colombier else if(c == '\b'){
85*9ef1f84bSDavid du Colombier if(cgapos >= 2)
86*9ef1f84bSDavid du Colombier cgapos -= 2;
87*9ef1f84bSDavid du Colombier cgaputc(' ');
88*9ef1f84bSDavid du Colombier cgapos -= 2;
89*9ef1f84bSDavid du Colombier }
90*9ef1f84bSDavid du Colombier else{
91*9ef1f84bSDavid du Colombier cga[cgapos++] = c;
92*9ef1f84bSDavid du Colombier cga[cgapos++] = Attr;
93*9ef1f84bSDavid du Colombier }
94*9ef1f84bSDavid du Colombier if(cgapos >= (Width*Height)-Postlen*2){
95*9ef1f84bSDavid du Colombier memmove(cga, &cga[Width], Width*(Height-1));
96*9ef1f84bSDavid du Colombier p = &cga[Width*(Height-1)-Postlen*2];
97*9ef1f84bSDavid du Colombier for(i = 0; i < Width/2; i++){
98*9ef1f84bSDavid du Colombier *p++ = ' ';
99*9ef1f84bSDavid du Colombier *p++ = Attr;
100*9ef1f84bSDavid du Colombier }
101*9ef1f84bSDavid du Colombier cgapos -= Width;
102*9ef1f84bSDavid du Colombier }
103*9ef1f84bSDavid du Colombier cgacursor();
104*9ef1f84bSDavid du Colombier }
105*9ef1f84bSDavid du Colombier
106*9ef1f84bSDavid du Colombier void
cgaconsputs(char * s,int n)107*9ef1f84bSDavid du Colombier cgaconsputs(char* s, int n)
108*9ef1f84bSDavid du Colombier {
109*9ef1f84bSDavid du Colombier ilock(&cgalock);
110*9ef1f84bSDavid du Colombier while(n-- > 0)
111*9ef1f84bSDavid du Colombier cgaputc(*s++);
112*9ef1f84bSDavid du Colombier iunlock(&cgalock);
113*9ef1f84bSDavid du Colombier }
114*9ef1f84bSDavid du Colombier
115*9ef1f84bSDavid du Colombier void
cgapost(int code)116*9ef1f84bSDavid du Colombier cgapost(int code)
117*9ef1f84bSDavid du Colombier {
118*9ef1f84bSDavid du Colombier uchar *cga;
119*9ef1f84bSDavid du Colombier
120*9ef1f84bSDavid du Colombier static char hex[] = "0123456789ABCDEF";
121*9ef1f84bSDavid du Colombier
122*9ef1f84bSDavid du Colombier cga = CGA;
123*9ef1f84bSDavid du Colombier cga[Width*Height-Postcodelen*2] = hex[(code>>4) & 0x0f];
124*9ef1f84bSDavid du Colombier cga[Width*Height-Postcodelen*2+1] = Attr;
125*9ef1f84bSDavid du Colombier cga[Width*Height-Postcodelen*2+2] = hex[code & 0x0f];
126*9ef1f84bSDavid du Colombier cga[Width*Height-Postcodelen*2+3] = Attr;
127*9ef1f84bSDavid du Colombier }
128*9ef1f84bSDavid du Colombier
129*9ef1f84bSDavid du Colombier void
cgainit(void)130*9ef1f84bSDavid du Colombier cgainit(void)
131*9ef1f84bSDavid du Colombier {
132*9ef1f84bSDavid du Colombier ilock(&cgalock);
133*9ef1f84bSDavid du Colombier cgapos = cgaregr(0x0e)<<8;
134*9ef1f84bSDavid du Colombier cgapos |= cgaregr(0x0f);
135*9ef1f84bSDavid du Colombier cgapos *= 2;
136*9ef1f84bSDavid du Colombier cgainitdone = 1;
137*9ef1f84bSDavid du Colombier iunlock(&cgalock);
138*9ef1f84bSDavid du Colombier }
139