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