xref: /plan9-contrib/sys/src/9k/k10/cga.c (revision 9ef1f84b659abcb917c5c090acbce0772e494f21)
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