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