FreeBSD/Linux Kernel Cross Reference
sys/alphapc/cga.c
1 #include "u.h"
2 #include "../port/lib.h"
3 #include "mem.h"
4 #include "dat.h"
5 #include "fns.h"
6 #include "../port/error.h"
7 #include "io.h"
8
9 enum {
10 Width = 160,
11 Height = 25,
12
13 Attr = 0x4f, /* white on blue */
14 };
15
16 static ulong cgabase;
17 #define CGASCREENBASE ((uchar*)cgabase)
18
19 static int cgapos;
20 static int screeninitdone;
21 static Lock cgascreenlock;
22
23 static uchar
24 cgaregr(int index)
25 {
26 outb(0x3D4, index);
27 return inb(0x3D4+1) & 0xFF;
28 }
29
30 static void
31 cgaregw(int index, int data)
32 {
33 outb(0x3D4, index);
34 outb(0x3D4+1, data);
35 }
36
37 static void
38 movecursor(void)
39 {
40 cgaregw(0x0E, (cgapos/2>>8) & 0xFF);
41 cgaregw(0x0F, cgapos/2 & 0xFF);
42 CGASCREENBASE[cgapos+1] = Attr;
43 }
44
45 static void
46 cgascreenputc(int c)
47 {
48 int i;
49
50 if(c == '\n'){
51 cgapos = cgapos/Width;
52 cgapos = (cgapos+1)*Width;
53 }
54 else if(c == '\t'){
55 i = 8 - ((cgapos/2)&7);
56 while(i-->0)
57 cgascreenputc(' ');
58 }
59 else if(c == '\b'){
60 if(cgapos >= 2)
61 cgapos -= 2;
62 cgascreenputc(' ');
63 cgapos -= 2;
64 }
65 else{
66 CGASCREENBASE[cgapos++] = c;
67 CGASCREENBASE[cgapos++] = Attr;
68 }
69 if(cgapos >= Width*Height){
70 memmove(CGASCREENBASE, &CGASCREENBASE[Width], Width*(Height-1));
71 for (i = Width*(Height-1); i < Width*Height;) {
72 CGASCREENBASE[i++] = 0x20;
73 CGASCREENBASE[i++] = Attr;
74 }
75 cgapos = Width*(Height-1);
76 }
77 movecursor();
78 }
79
80 void
81 screeninit(void)
82 {
83 cgabase = (ulong)arch->pcimem(0xB8000, 0x8000);
84
85 cgapos = cgaregr(0x0E)<<8;
86 cgapos |= cgaregr(0x0F);
87 cgapos *= 2;
88 screeninitdone = 1;
89 }
90
91 static void
92 cgascreenputs(char* s, int n)
93 {
94 if(!screeninitdone)
95 return;
96 if(!islo()){
97 /*
98 * Don't deadlock trying to
99 * print in an interrupt.
100 */
101 if(!canlock(&cgascreenlock))
102 return;
103 }
104 else
105 lock(&cgascreenlock);
106
107 while(n-- > 0)
108 cgascreenputc(*s++);
109
110 unlock(&cgascreenlock);
111 }
112
113 void (*screenputs)(char*, int) = cgascreenputs;
Cache object: d35aa8394eb86cb4d9e17c7b181a6c47
|