17dd7cddfSDavid du Colombier #include "u.h"
27dd7cddfSDavid du Colombier #include "../port/lib.h"
37dd7cddfSDavid du Colombier #include "mem.h"
47dd7cddfSDavid du Colombier #include "dat.h"
57dd7cddfSDavid du Colombier #include "fns.h"
67dd7cddfSDavid du Colombier #include "../port/error.h"
77dd7cddfSDavid du Colombier
87dd7cddfSDavid du Colombier enum {
97dd7cddfSDavid du Colombier Black,
107dd7cddfSDavid du Colombier Blue,
117dd7cddfSDavid du Colombier Green,
127dd7cddfSDavid du Colombier Cyan,
137dd7cddfSDavid du Colombier Red,
147dd7cddfSDavid du Colombier Magenta,
157dd7cddfSDavid du Colombier Brown,
167dd7cddfSDavid du Colombier Grey,
177dd7cddfSDavid du Colombier
187dd7cddfSDavid du Colombier Bright = 0x08,
197dd7cddfSDavid du Colombier Blinking = 0x80,
207dd7cddfSDavid du Colombier
217dd7cddfSDavid du Colombier Yellow = Bright|Brown,
227dd7cddfSDavid du Colombier White = Bright|Grey,
237dd7cddfSDavid du Colombier };
247dd7cddfSDavid du Colombier
257dd7cddfSDavid du Colombier enum {
267dd7cddfSDavid du Colombier Width = 80*2,
277dd7cddfSDavid du Colombier Height = 25,
287dd7cddfSDavid du Colombier
297dd7cddfSDavid du Colombier Attr = (Black<<4)|Grey, /* high nibble background
307dd7cddfSDavid du Colombier * low foreground
317dd7cddfSDavid du Colombier */
32*1045bea1SDavid du Colombier
33*1045bea1SDavid du Colombier Poststrlen = 0,
34*1045bea1SDavid du Colombier Postcodelen = 2,
35*1045bea1SDavid du Colombier Postlen = Poststrlen+Postcodelen,
367dd7cddfSDavid du Colombier };
377dd7cddfSDavid du Colombier
387dd7cddfSDavid du Colombier #define CGASCREENBASE ((uchar*)KADDR(0xB8000))
39*1045bea1SDavid du Colombier #define CGA CGASCREENBASE
407dd7cddfSDavid du Colombier
417dd7cddfSDavid du Colombier static int cgapos;
427dd7cddfSDavid du Colombier static Lock cgascreenlock;
437dd7cddfSDavid du Colombier
447dd7cddfSDavid du Colombier static uchar
cgaregr(int index)457dd7cddfSDavid du Colombier cgaregr(int index)
467dd7cddfSDavid du Colombier {
477dd7cddfSDavid du Colombier outb(0x3D4, index);
487dd7cddfSDavid du Colombier return inb(0x3D4+1) & 0xFF;
497dd7cddfSDavid du Colombier }
507dd7cddfSDavid du Colombier
517dd7cddfSDavid du Colombier static void
cgaregw(int index,int data)527dd7cddfSDavid du Colombier cgaregw(int index, int data)
537dd7cddfSDavid du Colombier {
547dd7cddfSDavid du Colombier outb(0x3D4, index);
557dd7cddfSDavid du Colombier outb(0x3D4+1, data);
567dd7cddfSDavid du Colombier }
577dd7cddfSDavid du Colombier
587dd7cddfSDavid du Colombier static void
movecursor(void)597dd7cddfSDavid du Colombier movecursor(void)
607dd7cddfSDavid du Colombier {
617dd7cddfSDavid du Colombier cgaregw(0x0E, (cgapos/2>>8) & 0xFF);
627dd7cddfSDavid du Colombier cgaregw(0x0F, cgapos/2 & 0xFF);
637dd7cddfSDavid du Colombier CGASCREENBASE[cgapos+1] = Attr;
647dd7cddfSDavid du Colombier }
657dd7cddfSDavid du Colombier
667dd7cddfSDavid du Colombier static void
cgascreenputc(int c)677dd7cddfSDavid du Colombier cgascreenputc(int c)
687dd7cddfSDavid du Colombier {
697dd7cddfSDavid du Colombier int i;
707dd7cddfSDavid du Colombier uchar *p;
717dd7cddfSDavid du Colombier
727dd7cddfSDavid du Colombier if(c == '\n'){
737dd7cddfSDavid du Colombier cgapos = cgapos/Width;
747dd7cddfSDavid du Colombier cgapos = (cgapos+1)*Width;
757dd7cddfSDavid du Colombier }
767dd7cddfSDavid du Colombier else if(c == '\t'){
777dd7cddfSDavid du Colombier i = 8 - ((cgapos/2)&7);
787dd7cddfSDavid du Colombier while(i-->0)
797dd7cddfSDavid du Colombier cgascreenputc(' ');
807dd7cddfSDavid du Colombier }
817dd7cddfSDavid du Colombier else if(c == '\b'){
827dd7cddfSDavid du Colombier if(cgapos >= 2)
837dd7cddfSDavid du Colombier cgapos -= 2;
847dd7cddfSDavid du Colombier cgascreenputc(' ');
857dd7cddfSDavid du Colombier cgapos -= 2;
867dd7cddfSDavid du Colombier }
877dd7cddfSDavid du Colombier else{
887dd7cddfSDavid du Colombier CGASCREENBASE[cgapos++] = c;
897dd7cddfSDavid du Colombier CGASCREENBASE[cgapos++] = Attr;
907dd7cddfSDavid du Colombier }
917dd7cddfSDavid du Colombier if(cgapos >= Width*Height){
927dd7cddfSDavid du Colombier memmove(CGASCREENBASE, &CGASCREENBASE[Width], Width*(Height-1));
937dd7cddfSDavid du Colombier p = &CGASCREENBASE[Width*(Height-1)];
947dd7cddfSDavid du Colombier for(i=0; i<Width/2; i++){
957dd7cddfSDavid du Colombier *p++ = ' ';
967dd7cddfSDavid du Colombier *p++ = Attr;
977dd7cddfSDavid du Colombier }
987dd7cddfSDavid du Colombier cgapos = Width*(Height-1);
997dd7cddfSDavid du Colombier }
1007dd7cddfSDavid du Colombier movecursor();
1017dd7cddfSDavid du Colombier }
1027dd7cddfSDavid du Colombier
1037dd7cddfSDavid du Colombier static void
cgascreenputs(char * s,int n)1047dd7cddfSDavid du Colombier cgascreenputs(char* s, int n)
1057dd7cddfSDavid du Colombier {
1067dd7cddfSDavid du Colombier if(!islo()){
1077dd7cddfSDavid du Colombier /*
1087dd7cddfSDavid du Colombier * Don't deadlock trying to
1097dd7cddfSDavid du Colombier * print in an interrupt.
1107dd7cddfSDavid du Colombier */
1117dd7cddfSDavid du Colombier if(!canlock(&cgascreenlock))
1127dd7cddfSDavid du Colombier return;
1137dd7cddfSDavid du Colombier }
1147dd7cddfSDavid du Colombier else
1157dd7cddfSDavid du Colombier lock(&cgascreenlock);
1167dd7cddfSDavid du Colombier
1177dd7cddfSDavid du Colombier while(n-- > 0)
1187dd7cddfSDavid du Colombier cgascreenputc(*s++);
1197dd7cddfSDavid du Colombier
1207dd7cddfSDavid du Colombier unlock(&cgascreenlock);
1217dd7cddfSDavid du Colombier }
1227dd7cddfSDavid du Colombier
123*1045bea1SDavid du Colombier char hex[] = "0123456789ABCDEF";
124*1045bea1SDavid du Colombier
125*1045bea1SDavid du Colombier void
cgapost(int code)126*1045bea1SDavid du Colombier cgapost(int code)
127*1045bea1SDavid du Colombier {
128*1045bea1SDavid du Colombier uchar *cga;
129*1045bea1SDavid du Colombier
130*1045bea1SDavid du Colombier cga = CGA;
131*1045bea1SDavid du Colombier cga[Width*Height-Postcodelen*2] = hex[(code>>4) & 0x0F];
132*1045bea1SDavid du Colombier cga[Width*Height-Postcodelen*2+1] = Attr;
133*1045bea1SDavid du Colombier cga[Width*Height-Postcodelen*2+2] = hex[code & 0x0F];
134*1045bea1SDavid du Colombier cga[Width*Height-Postcodelen*2+3] = Attr;
135*1045bea1SDavid du Colombier }
136*1045bea1SDavid du Colombier
1379a747e4fSDavid du Colombier void
screeninit(void)1389a747e4fSDavid du Colombier screeninit(void)
1399a747e4fSDavid du Colombier {
1409a747e4fSDavid du Colombier
1419a747e4fSDavid du Colombier cgapos = cgaregr(0x0E)<<8;
1429a747e4fSDavid du Colombier cgapos |= cgaregr(0x0F);
1439a747e4fSDavid du Colombier cgapos *= 2;
1449a747e4fSDavid du Colombier
1459a747e4fSDavid du Colombier screenputs = cgascreenputs;
1469a747e4fSDavid du Colombier }
147