]> git.lizzy.rs Git - plan9front.git/blob - sys/src/9/kw/cga.c
pass Ureg* argument to note handler in R0 register on arm
[plan9front.git] / sys / src / 9 / kw / 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
8 enum {
9         Black,
10         Blue,
11         Green,
12         Cyan,
13         Red,
14         Magenta,
15         Brown,
16         Grey,
17
18         Bright = 0x08,
19         Blinking = 0x80,
20
21         Yellow = Bright|Brown,
22         White = Bright|Grey,
23 };
24         
25 enum {
26         Width           = 80*2,
27         Height          = 25,
28
29         Attr            = (Black<<4)|Grey,      /* high nibble background
30                                                  * low foreground
31                                                  */
32 };
33
34 #define CGASCREENBASE   ((uchar*)KADDR(0xB8000))
35
36 #define inb(x)          0       /* TODO */
37 #define outb(x, y)                      /* TODO */
38
39 static int cgapos;
40 static Lock cgascreenlock;
41
42 static uchar
43 cgaregr(int index)
44 {
45         USED(index);
46         outb(0x3D4, index);
47         return inb(0x3D4+1) & 0xFF;
48 }
49
50 static void
51 cgaregw(int index, int data)
52 {
53         USED(index, data);
54         outb(0x3D4, index);
55         outb(0x3D4+1, data);
56 }
57
58 static void
59 movecursor(void)
60 {
61         cgaregw(0x0E, (cgapos/2>>8) & 0xFF);
62         cgaregw(0x0F, cgapos/2 & 0xFF);
63         CGASCREENBASE[cgapos+1] = Attr;
64 }
65
66 static void
67 cgascreenputc(int c)
68 {
69         int i;
70         uchar *p;
71
72         if(c == '\n'){
73                 cgapos = cgapos/Width;
74                 cgapos = (cgapos+1)*Width;
75         }
76         else if(c == '\t'){
77                 i = 8 - ((cgapos/2)&7);
78                 while(i-->0)
79                         cgascreenputc(' ');
80         }
81         else if(c == '\b'){
82                 if(cgapos >= 2)
83                         cgapos -= 2;
84                 cgascreenputc(' ');
85                 cgapos -= 2;
86         }
87         else{
88                 CGASCREENBASE[cgapos++] = c;
89                 CGASCREENBASE[cgapos++] = Attr;
90         }
91         if(cgapos >= Width*Height){
92                 memmove(CGASCREENBASE, &CGASCREENBASE[Width], Width*(Height-1));
93                 p = &CGASCREENBASE[Width*(Height-1)];
94                 for(i=0; i<Width/2; i++){
95                         *p++ = ' ';
96                         *p++ = Attr;
97                 }
98                 cgapos = Width*(Height-1);
99         }
100         movecursor();
101 }
102
103 static void
104 cgascreenputs(char* s, int n)
105 {
106         if(!islo()){
107                 /*
108                  * Don't deadlock trying to
109                  * print in an interrupt.
110                  */
111                 if(!canlock(&cgascreenlock))
112                         return;
113         }
114         else
115                 lock(&cgascreenlock);
116
117         while(n-- > 0)
118                 cgascreenputc(*s++);
119
120         unlock(&cgascreenlock);
121 }
122
123 void
124 screeninit(void)
125 {
126
127         cgapos = cgaregr(0x0E)<<8;
128         cgapos |= cgaregr(0x0F);
129         cgapos *= 2;
130
131         screenputs = cgascreenputs;
132 }