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