@@ 20,23 20,23 @@ struct{
int bwid;
}out;
+int islittle = 1; /* little endian bit ordering in bytes */
+
+extern Cursor arrow;
+extern uchar cswizzle[256];
+
+
/*
* screen dimensions
*/
-
#define MAXX 640
#define MAXY 480
-GBitmap gscreen =
-{
- (ulong*)SCREENMEM,
- 0,
- 640/32,
- 0,
- { 0, 0, MAXX, MAXY, },
- { 0, 0, MAXX, MAXY, },
- 0
-};
+/*
+ * 'soft' screen bitmap
+ */
+GBitmap gscreen;
+GBitmap vgascreen;
typedef struct VGAmode VGAmode;
struct VGAmode
@@ 71,6 71,8 @@ VGAmode mode12 =
0x01, 0x10, 0x0f, 0x00, 0x00,
};
+static Rectangle mbb;
+static Rectangle NULLMBB = {10000, 10000, -10000, -10000};
void
genout(int reg, int val)
@@ 224,14 226,36 @@ dumpmodes(void) {
#endif
void
-setscreen(int maxx, int maxy, int bpp)
+setscreen(int maxx, int maxy, int ldepth)
{
- USED(bpp);
- gbitblt(&gscreen, Pt(0, 0), &gscreen, gscreen.r, flipD[S]);
- gscreen.width = maxx/32;
+ int len;
+
+ mbb = NULLMBB;
+
+ /*
+ * zero hard screen
+ */
+ memset((void*)SCREENMEM, 0xff, 64*1024);
+ vgascreen.ldepth = 0;
+ vgascreen.base = (void*)SCREENMEM;
+ vgascreen.width = (maxx*(1<<ldepth))/32;
+ vgascreen.r.max = Pt(maxx, maxy);
+ vgascreen.clipr.max = vgascreen.r.max;
+
+ /*
+ * setup new soft screen
+ */
+ gscreen.ldepth = ldepth;
+ gscreen.width = (maxx*(1<<ldepth))/32;
gscreen.r.max = Pt(maxx, maxy);
gscreen.clipr.max = gscreen.r.max;
- gbitblt(&gscreen, Pt(0, 0), &gscreen, gscreen.r, flipD[0]);
+ len = gscreen.width * 4 * maxy;
+ gscreen.base = malloc(len);
+ memset((void*)gscreen.base, 0xff, len);
+
+ /*
+ * set string pointer to upper left
+ */
out.pos.x = MINX;
out.pos.y = 0;
out.bwid = defont0.info[' '].width;
@@ 246,26 270,77 @@ screeninit(void)
setmode(&mode12);
/*
- * swizzle the font longs.
- * we do it here since the font is initialized with big
- * endian longs.
+ * arrow is defined as a big endian
+ */
+ bitreverse(arrow.set, 2*16);
+ bitreverse(arrow.clr, 2*16);
+
+ /*
+ * swizzle the font longs. we do both byte and bit swizzling
+ * since the font is initialized with big endian longs.
*/
defont = &defont0;
l = defont->bits->base;
for(i = defont->bits->width*Dy(defont->bits->r); i > 0; i--, l++)
*l = (*l<<24) | ((*l>>8)&0x0000ff00) | ((*l<<8)&0x00ff0000) | (*l>>24);
- setscreen(MAXX, MAXY, 1);
+ bitreverse((uchar*)defont->bits->base,
+ defont->bits->width*BY2WD*Dy(defont->bits->r));
+
+ /*
+ * set up 'soft' and hard screens
+ */
+ if(conf.maxx == 0)
+ conf.maxx = MAXX;
+ if(conf.maxy == 0)
+ conf.maxy = MAXY;
+
+ setscreen(conf.maxx, conf.maxy, conf.ldepth);
+}
+
+/*
+ * collect changes to the 'soft' screen
+ */
+void
+mbbrect(Rectangle r)
+{
+ if (r.min.x < mbb.min.x)
+ mbb.min.x = r.min.x;
+ if (r.min.y < mbb.min.y)
+ mbb.min.y = r.min.y;
+ if (r.max.x > mbb.max.x)
+ mbb.max.x = r.max.x;
+ if (r.max.y > mbb.max.y)
+ mbb.max.y = r.max.y;
+ screenupdate();
+}
+
+void
+mbbpt(Point p)
+{
+ if (p.x < mbb.min.x)
+ mbb.min.x = p.x;
+ if (p.y < mbb.min.y)
+ mbb.min.y = p.y;
+ if (p.x >= mbb.max.x)
+ mbb.max.x = p.x+1;
+ if (p.y >= mbb.max.y)
+ mbb.max.y = p.y+1;
+ screenupdate();
}
void
screenputnl(void)
{
+ Rectangle r;
+
out.pos.x = MINX;
out.pos.y += defont0.height;
if(out.pos.y > gscreen.r.max.y-defont0.height)
out.pos.y = gscreen.r.min.y;
- gbitblt(&gscreen, Pt(0, out.pos.y), &gscreen,
- Rect(0, out.pos.y, gscreen.r.max.x, out.pos.y+2*defont0.height), flipD[0]);
+ r = Rect(0, out.pos.y, gscreen.r.max.x, out.pos.y+2*defont0.height);
+ gbitblt(&gscreen, r.min, &gscreen, r, flipD[0]);
+ mbbrect(r);
+ screenupdate();
}
Lock screenlock;
@@ 275,8 350,10 @@ screenputs(char *s, int n)
{
Rune r;
int i;
+ Rectangle rs;
char buf[4];
+ rs.min = Pt(0, out.pos.y);
while(n > 0){
i = chartorune(&r, s);
if(i == 0){
@@ 305,6 382,10 @@ screenputs(char *s, int n)
out.pos = gsubfstring(&gscreen, out.pos, defont, buf, flipD[S]);
}
}
+ rs.max = Pt(gscreen.r.max.x, out.pos.y+defont0.height);
+ unlock(&screenlock);
+ mbbrect(rs);
+ screenupdate();
}
int
@@ 313,6 394,44 @@ screenbits(void)
return 1; /* bits per pixel */
}
+
+/*
+ * copy litte endian soft screen to big endian hard screen
+ */
+void
+screenupdate(void)
+{
+ uchar *sp, *hp, *se;
+ int y, len, inc;
+ Rectangle r=mbb;
+
+ if(Dy(r) < 0)
+ return;
+
+ sp = (uchar*)gaddr(&gscreen, r.min);
+ hp = (uchar*)gaddr(&vgascreen, r.min);
+
+ len = (r.max.x * (1<<gscreen.ldepth) + 31)/32
+ - (r.min.x * (1<<gscreen.ldepth))/32;
+ len *= BY2WD;
+
+ inc = gscreen.width * BY2WD - len;
+
+ for (y = r.min.y; y < r.max.y; y++){
+ for(se = sp + len; sp < se;)
+ *hp++ = cswizzle[*sp++];
+ sp += inc;
+ hp += inc;
+ }
+ mbb = NULLMBB;
+}
+
+void
+mousescreenupdate(void)
+{
+ screenupdate();
+}
+
void
getcolor(ulong p, ulong *pr, ulong *pg, ulong *pb)
{
@@ 374,56 493,11 @@ Cursor fatarrow = {
0x61, 0xf0, 0x60, 0xe0, 0x40, 0x40, 0x00, 0x00,
},
};
+
void
bigcursor(void)
{
- extern Cursor arrow;
-
memmove(&arrow, &fatarrow, sizeof(fatarrow));
+ bitreverse(arrow.set, 2*16);
+ bitreverse(arrow.clr, 2*16);
}
-
-/*
- * collect changes to the 'soft' screen
- */
-static Rectangle mbb;
-
-void
-mbbrect(Rectangle r)
-{
- if(!islcd)
- return;
- if (r.min.x < mbb.min.x)
- mbb.min.x = r.min.x;
- if (r.min.y < mbb.min.y)
- mbb.min.y = r.min.y;
- if (r.max.x > mbb.max.x)
- mbb.max.x = r.max.x;
- if (r.max.y > mbb.max.y)
- mbb.max.y = r.max.y;
-}
-
-void
-mbbpt(Point p)
-{
- if(!islcd)
- return;
- if (p.x < mbb.min.x)
- mbb.min.x = p.x;
- if (p.y < mbb.min.y)
- mbb.min.y = p.y;
- if (p.x >= mbb.max.x)
- mbb.max.x = p.x+1;
- if (p.y >= mbb.max.y)
- mbb.max.y = p.y+1;
-}
-
-void
-screenupdate(void)
-{
-}
-
-void
-mousescreenupdate(void)
-{
-}
-
@@ 108,6 108,7 @@ Mouseinfo mouse;
Cursorinfo cursor;
int mouseshifted;
int mousetype;
+int islittle;
Cursor arrow =
{
@@ 745,6 746,8 @@ bitread(Chan *c, void *va, long n, ulong offset)
q = (uchar*)gaddr(src, Pt(src->r.min.x, y));
q += (src->r.min.x&((sizeof(ulong))*ws-1))/ws;
memmove(p, q, l);
+ if(islittle)
+ bitreverse(p, l);
if(bit.rid==0 && flipping)
/* is screen, so must be word aligned */
for(x=0; x<l; x+=sizeof(ulong),p+=sizeof(ulong))
@@ 936,6 939,10 @@ bitwrite(Chan *c, void *va, long n, ulong offset)
curs.offset.y = BGLONG(p+5);
memmove(curs.clr, p+9, 2*16);
memmove(curs.set, p+41, 2*16);
+ if(islittle){
+ bitreverse(curs.clr, 2*16);
+ bitreverse(curs.set, 2*16);
+ }
if(!isoff){
cursoroff(1);
isoff = 1;
@@ 1468,6 1475,8 @@ bitwrite(Chan *c, void *va, long n, ulong offset)
oq = (uchar*)gaddr(dst, Pt(dst->r.min.x, y));
q = oq + (dst->r.min.x&((sizeof(ulong))*ws-1))/ws;
memmove(q, p, l);
+ if(islittle)
+ bitreverse(q, l);
if(v==0 && flipping){ /* flip bits */
/* we know it's all word aligned */
lp = (ulong*)oq;
@@ 2075,3 2084,51 @@ mousechanged(void *m)
USED(m);
return mouse.changed;
}
+
+/*
+ * swizzle a bitmap
+ */
+uchar cswizzle[] = {
+ 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
+ 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
+ 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
+ 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
+ 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
+ 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
+ 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
+ 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
+ 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
+ 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
+ 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
+ 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
+ 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
+ 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
+ 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
+ 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
+ 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
+ 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
+ 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
+ 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
+ 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
+ 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
+ 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
+ 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
+ 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
+ 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
+ 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
+ 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
+ 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
+ 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
+ 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
+ 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
+};
+
+void
+bitreverse(uchar *p, int l)
+{
+ uchar *e;
+
+ e = p + l;
+ for(; p < e; p++)
+ *p = cswizzle[*p];
+}