summaryrefslogtreecommitdiff
path: root/sys/src/9/alphapc/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/alphapc/cga.c
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/9/alphapc/cga.c')
-rwxr-xr-xsys/src/9/alphapc/cga.c113
1 files changed, 113 insertions, 0 deletions
diff --git a/sys/src/9/alphapc/cga.c b/sys/src/9/alphapc/cga.c
new file mode 100755
index 000000000..c216617b7
--- /dev/null
+++ b/sys/src/9/alphapc/cga.c
@@ -0,0 +1,113 @@
+#include "u.h"
+#include "../port/lib.h"
+#include "mem.h"
+#include "dat.h"
+#include "fns.h"
+#include "../port/error.h"
+#include "io.h"
+
+enum {
+ Width = 160,
+ Height = 25,
+
+ Attr = 0x4f, /* white on blue */
+};
+
+static ulong cgabase;
+#define CGASCREENBASE ((uchar*)cgabase)
+
+static int cgapos;
+static int screeninitdone;
+static Lock cgascreenlock;
+
+static uchar
+cgaregr(int index)
+{
+ outb(0x3D4, index);
+ return inb(0x3D4+1) & 0xFF;
+}
+
+static void
+cgaregw(int index, int 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;
+
+ 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));
+ for (i = Width*(Height-1); i < Width*Height;) {
+ CGASCREENBASE[i++] = 0x20;
+ CGASCREENBASE[i++] = Attr;
+ }
+ cgapos = Width*(Height-1);
+ }
+ movecursor();
+}
+
+void
+screeninit(void)
+{
+ cgabase = (ulong)arch->pcimem(0xB8000, 0x8000);
+
+ cgapos = cgaregr(0x0E)<<8;
+ cgapos |= cgaregr(0x0F);
+ cgapos *= 2;
+ screeninitdone = 1;
+}
+
+static void
+cgascreenputs(char* s, int n)
+{
+ if(!screeninitdone)
+ return;
+ 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 (*screenputs)(char*, int) = cgascreenputs;