1 #include <u.h>
2 #include <libc.h>
3 #include "expand.h"
4
5 enum {
6 Black,
7 Blue,
8 Green,
9 Cyan,
10 Red,
11 Magenta,
12 Brown,
13 Grey,
14
15 Bright = 0x08,
16 Blinking = 0x80,
17
18 Yellow = Bright|Brown,
19 White = Bright|Grey,
20 };
21
22 enum {
23 Width = 80*2,
24 Height = 25,
25 Attr = (Black<<4)|Grey,
26 };
27
28 #define cga ((uchar*)0xB8000)
29 int cgapos;
30
31 static uchar
cgaregr(int index)32 cgaregr(int index)
33 {
34 outb(0x3D4, index);
35 return inb(0x3D4+1) & 0xFF;
36 }
37
38 static void
cgaregw(int index,int data)39 cgaregw(int index, int data)
40 {
41 outb(0x3D4, index);
42 outb(0x3D4+1, data);
43 }
44
45 static void
movecursor(void)46 movecursor(void)
47 {
48 cgaregw(0x0E, (cgapos/2>>8) & 0xFF);
49 cgaregw(0x0F, cgapos/2 & 0xFF);
50 cga[cgapos+1] = Attr;
51 }
52
53 void
cgaputc(int c)54 cgaputc(int c)
55 {
56 int i;
57 uchar *p;
58
59 if(c == '\n'){
60 cgapos = cgapos/Width;
61 cgapos = (cgapos+1)*Width;
62 }
63 else if(c == '\t'){
64 i = 8 - ((cgapos/2)&7);
65 while(i-->0)
66 cgaputc(' ');
67 }
68 else if(c == '\b'){
69 if(cgapos >= 2)
70 cgapos -= 2;
71 cgaputc(' ');
72 cgapos -= 2;
73 }
74 else{
75 cga[cgapos++] = c;
76 cga[cgapos++] = Attr;
77 }
78 if(cgapos >= Width*Height){
79 memmove(cga, &cga[Width], Width*(Height-1));
80 p = &cga[Width*(Height-1)];
81 for(i=0; i<Width/2; i++){
82 *p++ = ' ';
83 *p++ = Attr;
84 }
85 cgapos = Width*(Height-1);
86 }
87 movecursor();
88 }
89
90 void
cgainit(void)91 cgainit(void)
92 {
93 cgapos = cgaregr(0x0E)<<8;
94 cgapos |= cgaregr(0x0F);
95 cgapos *= 2;
96 }
97