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