]> git.lizzy.rs Git - plan9front.git/blob - sys/src/9/alphapc/cga.c
syscallfmt: use up->syserrstr instead of up->errstr (import from sources)
[plan9front.git] / sys / src / 9 / 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;