xref: /inferno-os/os/boot/pc/cga.c (revision 74a4d8c26dd3c1e9febcb717cfd6cb6512991a7a)
1*74a4d8c2SCharles.Forsyth #include "u.h"
2*74a4d8c2SCharles.Forsyth #include "lib.h"
3*74a4d8c2SCharles.Forsyth #include "mem.h"
4*74a4d8c2SCharles.Forsyth #include "dat.h"
5*74a4d8c2SCharles.Forsyth #include "fns.h"
6*74a4d8c2SCharles.Forsyth 
7*74a4d8c2SCharles.Forsyth enum {
8*74a4d8c2SCharles.Forsyth 	Width		= 160,
9*74a4d8c2SCharles.Forsyth 	Height		= 25,
10*74a4d8c2SCharles.Forsyth 
11*74a4d8c2SCharles.Forsyth 	Attr		= 7,		/* white on black */
12*74a4d8c2SCharles.Forsyth };
13*74a4d8c2SCharles.Forsyth 
14*74a4d8c2SCharles.Forsyth #define CGASCREENBASE	((uchar*)KADDR(0xB8000))
15*74a4d8c2SCharles.Forsyth 
16*74a4d8c2SCharles.Forsyth static int pos;
17*74a4d8c2SCharles.Forsyth static int screeninitdone;
18*74a4d8c2SCharles.Forsyth 
19*74a4d8c2SCharles.Forsyth static uchar
cgaregr(int index)20*74a4d8c2SCharles.Forsyth cgaregr(int index)
21*74a4d8c2SCharles.Forsyth {
22*74a4d8c2SCharles.Forsyth 	outb(0x3D4, index);
23*74a4d8c2SCharles.Forsyth 	return inb(0x3D4+1) & 0xFF;
24*74a4d8c2SCharles.Forsyth }
25*74a4d8c2SCharles.Forsyth 
26*74a4d8c2SCharles.Forsyth static void
cgaregw(int index,int data)27*74a4d8c2SCharles.Forsyth cgaregw(int index, int data)
28*74a4d8c2SCharles.Forsyth {
29*74a4d8c2SCharles.Forsyth 	outb(0x3D4, index);
30*74a4d8c2SCharles.Forsyth 	outb(0x3D4+1, data);
31*74a4d8c2SCharles.Forsyth }
32*74a4d8c2SCharles.Forsyth 
33*74a4d8c2SCharles.Forsyth static void
movecursor(void)34*74a4d8c2SCharles.Forsyth movecursor(void)
35*74a4d8c2SCharles.Forsyth {
36*74a4d8c2SCharles.Forsyth 	cgaregw(0x0E, (pos/2>>8) & 0xFF);
37*74a4d8c2SCharles.Forsyth 	cgaregw(0x0F, pos/2 & 0xFF);
38*74a4d8c2SCharles.Forsyth 	CGASCREENBASE[pos+1] = Attr;
39*74a4d8c2SCharles.Forsyth }
40*74a4d8c2SCharles.Forsyth 
41*74a4d8c2SCharles.Forsyth static void
cgascreenputc(int c)42*74a4d8c2SCharles.Forsyth cgascreenputc(int c)
43*74a4d8c2SCharles.Forsyth {
44*74a4d8c2SCharles.Forsyth 	int i;
45*74a4d8c2SCharles.Forsyth 
46*74a4d8c2SCharles.Forsyth 	if(c == '\n'){
47*74a4d8c2SCharles.Forsyth 		pos = pos/Width;
48*74a4d8c2SCharles.Forsyth 		pos = (pos+1)*Width;
49*74a4d8c2SCharles.Forsyth 	}
50*74a4d8c2SCharles.Forsyth 	else if(c == '\t'){
51*74a4d8c2SCharles.Forsyth 		i = 8 - ((pos/2)&7);
52*74a4d8c2SCharles.Forsyth 		while(i-->0)
53*74a4d8c2SCharles.Forsyth 			cgascreenputc(' ');
54*74a4d8c2SCharles.Forsyth 	}
55*74a4d8c2SCharles.Forsyth 	else if(c == '\b'){
56*74a4d8c2SCharles.Forsyth 		if(pos >= 2)
57*74a4d8c2SCharles.Forsyth 			pos -= 2;
58*74a4d8c2SCharles.Forsyth 		cgascreenputc(' ');
59*74a4d8c2SCharles.Forsyth 		pos -= 2;
60*74a4d8c2SCharles.Forsyth 	}
61*74a4d8c2SCharles.Forsyth 	else{
62*74a4d8c2SCharles.Forsyth 		CGASCREENBASE[pos++] = c;
63*74a4d8c2SCharles.Forsyth 		CGASCREENBASE[pos++] = Attr;
64*74a4d8c2SCharles.Forsyth 	}
65*74a4d8c2SCharles.Forsyth 	if(pos >= Width*Height){
66*74a4d8c2SCharles.Forsyth 		memmove(CGASCREENBASE, &CGASCREENBASE[Width], Width*(Height-1));
67*74a4d8c2SCharles.Forsyth 		memset(&CGASCREENBASE[Width*(Height-1)], 0, Width);
68*74a4d8c2SCharles.Forsyth 		pos = Width*(Height-1);
69*74a4d8c2SCharles.Forsyth 	}
70*74a4d8c2SCharles.Forsyth 	movecursor();
71*74a4d8c2SCharles.Forsyth }
72*74a4d8c2SCharles.Forsyth 
73*74a4d8c2SCharles.Forsyth static void
screeninit(void)74*74a4d8c2SCharles.Forsyth screeninit(void)
75*74a4d8c2SCharles.Forsyth {
76*74a4d8c2SCharles.Forsyth 	if(screeninitdone == 0){
77*74a4d8c2SCharles.Forsyth 		pos = cgaregr(0x0E)<<8;
78*74a4d8c2SCharles.Forsyth 		pos |= cgaregr(0x0F);
79*74a4d8c2SCharles.Forsyth 		pos *= 2;
80*74a4d8c2SCharles.Forsyth 		screeninitdone = 1;
81*74a4d8c2SCharles.Forsyth 	}
82*74a4d8c2SCharles.Forsyth }
83*74a4d8c2SCharles.Forsyth 
84*74a4d8c2SCharles.Forsyth void
cgascreenputs(char * s,int n)85*74a4d8c2SCharles.Forsyth cgascreenputs(char* s, int n)
86*74a4d8c2SCharles.Forsyth {
87*74a4d8c2SCharles.Forsyth 	if(screeninitdone == 0)
88*74a4d8c2SCharles.Forsyth 		screeninit();
89*74a4d8c2SCharles.Forsyth 	while(n-- > 0)
90*74a4d8c2SCharles.Forsyth 		cgascreenputc(*s++);
91*74a4d8c2SCharles.Forsyth }
92