M pc/devconfig.c => pc/devconfig.c +6 -4
@@ 146,7 146,7 @@ long
configwrite(Chan *c, void *buf, long n, ulong offset)
{
char cbuf[20], *cp;
- int port, maxx, maxy;
+ int port, maxx, maxy, ldepth;
switch(c->qid.path&~CHDIR){
case Qdir:
@@ 165,10 165,12 @@ configwrite(Chan *c, void *buf, long n, ulong offset)
cp = cbuf;
maxx = strtoul(cp, &cp, 0);
maxy = strtoul(cp, &cp, 0);
- if (maxx == 0 || maxy == 0 ||
- maxx > 1280 || maxy > 1024)
+ ldepth = strtoul(cp, &cp, 0);
+ if(maxx == 0 || maxy == 0
+ || maxx > 1280 || maxy > 1024
+ || ldepth > 3 || ldepth < 0)
error(Ebadarg);
- setscreen(maxx, maxy, 1);
+ setscreen(maxx, maxy, ldepth);
return n;
case Qvgaport:
cp = buf;
M pc/l.s => pc/l.s +10 -14
@@ 662,25 662,21 @@ TEXT l1update(SB),$0
MOVL from+0(FP),SI
MOVL to+4(FP),DI
MOVL len+8(FP),CX
-l10:
- XORL DX,DX
- MOVB -2(SI)(CX*2),DL /* high order nibbles */
- MOVW l1revsep(SB)(DX*2),BX
- SHLW $4,BX
- MOVB -1(SI)(CX*2),DL /* low order nibbles */
- ORW l1revsep(SB)(DX*2),BX
- MOVB $(Smmask),AL /* write hi order bits to bit planes 0 & 2 */
+ MOVB $(Smmask),AL
MOVW $(SRX),DX
OUTB
- MOVB $0xA,AL
MOVW $(SR),DX
+l10:
+ XORL AX,AX
+ MOVB -2(SI)(CX*2),AL /* high order nibbles */
+ MOVW l1revsep(SB)(AX*2),BX
+ SHLW $4,BX
+ MOVB -1(SI)(CX*2),AL /* low order nibbles */
+ ORW l1revsep(SB)(AX*2),BX
+ MOVB $0xA,AL /* write hi order bits to bit planes 0 & 2 */
OUTB
MOVB BH,-1(DI)(CX*1)
- MOVB $(Smmask),AL /* write lo order bits to bit planes 1 & 3 */
- MOVW $(SRX),DX
- OUTB
- MOVB $0x5,AL
- MOVW $(SR),DX
+ MOVB $0x5,AL /* write lo order bits to bit planes 1 & 3 */
OUTB
MOVB BL,-1(DI)(CX*1)
LOOP l10
M pc/vga.c => pc/vga.c +17 -6
@@ 233,24 233,31 @@ setscreen(int maxx, int maxy, int ldepth)
mbb = NULLMBB;
/*
- * zero hard screen
+ * zero hard screen and setup a bitmap for the new size
*/
memset((void*)SCREENMEM, 0xff, 64*1024);
- vgascreen.ldepth = 0;
+ if(ldepth == 3)
+ vgascreen.ldepth = 3;
+ else
+ 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
+ * setup new soft screen, free memory for old screen
*/
gscreen.ldepth = ldepth;
gscreen.width = (maxx*(1<<ldepth))/32;
gscreen.r.max = Pt(maxx, maxy);
gscreen.clipr.max = gscreen.r.max;
len = gscreen.width * 4 * maxy;
- gscreen.base = ((ulong*)malloc(len+2*1024))+256;
+ if(gscreen.base){
+ free(gscreen.base);
+ gscreen.base = ((ulong*)smalloc(len+2*1024))+256;
+ } else
+ gscreen.base = ((ulong*)malloc(len+2*1024))+256;
memset((char*)gscreen.base, 0xff, len);
/*
@@ 334,7 341,7 @@ void
screenupdate(void)
{
uchar *sp, *hp;
- int y, len, incs, inch;
+ int y, len, incs, inch, bits;
Rectangle r;
r = mbb;
@@ 352,9 359,10 @@ screenupdate(void)
if(r.max.y > gscreen.r.max.y)
r.max.y = gscreen.r.max.y;
+ bits = 1<<vgascreen.ldepth;
sp = (uchar*)gaddr(&gscreen, r.min);
hp = (uchar*)gaddr(&vgascreen, r.min);
- len = (r.max.x + 31)/32 - r.min.x/32;
+ len = (r.max.x*bits + 31)/32 - (r.min.x*bits)/32;
len *= BY2WD;
if(len <= 0)
return;
@@ 364,6 372,8 @@ screenupdate(void)
switch(gscreen.ldepth){
case 0:
+ case 3:
+ /* reverse the bits */
for (y = r.min.y; y < r.max.y; y++){
l0update(sp, hp, len);
sp += incs;
@@ 371,6 381,7 @@ screenupdate(void)
}
break;
case 1:
+ /* reverse the bits and split into 2 bitmaps */
for (y = r.min.y; y < r.max.y; y++){
l1update(sp, hp, len);
sp += incs;