xref: /plan9/sys/src/9/pcboot/cga.tiny.c (revision 25210b069a6ed8c047fa67220cf1dff32812f121)
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