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