summaryrefslogtreecommitdiff
path: root/sys/src/9/kw/cga.c
diff options
context:
space:
mode:
authorTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
committerTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
commite5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch)
treed8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/9/kw/cga.c
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/9/kw/cga.c')
-rwxr-xr-xsys/src/9/kw/cga.c132
1 files changed, 132 insertions, 0 deletions
diff --git a/sys/src/9/kw/cga.c b/sys/src/9/kw/cga.c
new file mode 100755
index 000000000..f9cba1904
--- /dev/null
+++ b/sys/src/9/kw/cga.c
@@ -0,0 +1,132 @@
+#include "u.h"
+#include "../port/lib.h"
+#include "mem.h"
+#include "dat.h"
+#include "fns.h"
+#include "../port/error.h"
+
+enum {
+ Black,
+ Blue,
+ Green,
+ Cyan,
+ Red,
+ Magenta,
+ Brown,
+ Grey,
+
+ Bright = 0x08,
+ Blinking = 0x80,
+
+ Yellow = Bright|Brown,
+ White = Bright|Grey,
+};
+
+enum {
+ Width = 80*2,
+ Height = 25,
+
+ Attr = (Black<<4)|Grey, /* high nibble background
+ * low foreground
+ */
+};
+
+#define CGASCREENBASE ((uchar*)KADDR(0xB8000))
+
+#define inb(x) 0 /* TODO */
+#define outb(x, y) /* TODO */
+
+static int cgapos;
+static Lock cgascreenlock;
+
+static uchar
+cgaregr(int index)
+{
+ USED(index);
+ outb(0x3D4, index);
+ return inb(0x3D4+1) & 0xFF;
+}
+
+static void
+cgaregw(int index, int data)
+{
+ USED(index, data);
+ outb(0x3D4, index);
+ outb(0x3D4+1, data);
+}
+
+static void
+movecursor(void)
+{
+ cgaregw(0x0E, (cgapos/2>>8) & 0xFF);
+ cgaregw(0x0F, cgapos/2 & 0xFF);
+ CGASCREENBASE[cgapos+1] = Attr;
+}
+
+static void
+cgascreenputc(int c)
+{
+ int i;
+ uchar *p;
+
+ if(c == '\n'){
+ cgapos = cgapos/Width;
+ cgapos = (cgapos+1)*Width;
+ }
+ else if(c == '\t'){
+ i = 8 - ((cgapos/2)&7);
+ while(i-->0)
+ cgascreenputc(' ');
+ }
+ else if(c == '\b'){
+ if(cgapos >= 2)
+ cgapos -= 2;
+ cgascreenputc(' ');
+ cgapos -= 2;
+ }
+ else{
+ CGASCREENBASE[cgapos++] = c;
+ CGASCREENBASE[cgapos++] = Attr;
+ }
+ if(cgapos >= Width*Height){
+ memmove(CGASCREENBASE, &CGASCREENBASE[Width], Width*(Height-1));
+ p = &CGASCREENBASE[Width*(Height-1)];
+ for(i=0; i<Width/2; i++){
+ *p++ = ' ';
+ *p++ = Attr;
+ }
+ cgapos = Width*(Height-1);
+ }
+ movecursor();
+}
+
+static void
+cgascreenputs(char* s, int n)
+{
+ if(!islo()){
+ /*
+ * Don't deadlock trying to
+ * print in an interrupt.
+ */
+ if(!canlock(&cgascreenlock))
+ return;
+ }
+ else
+ lock(&cgascreenlock);
+
+ while(n-- > 0)
+ cgascreenputc(*s++);
+
+ unlock(&cgascreenlock);
+}
+
+void
+screeninit(void)
+{
+
+ cgapos = cgaregr(0x0E)<<8;
+ cgapos |= cgaregr(0x0F);
+ cgapos *= 2;
+
+ screenputs = cgascreenputs;
+}