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