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