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