+// This algorithm goes from left to right, storing each 4BPP pixel
+// in an entire byte.
+void FASTCALL
+vgaReadScan ( int x, int y, int w, void *b )
+{
+ unsigned char *vp, *vpP;
+ unsigned char data, mask, maskP;
+ unsigned char *bp;
+ unsigned char plane_mask;
+ int byte_per_line = SCREEN_X >> 3;
+ int plane, i;
+
+ ASSIGNVP4(x, y, vpP)
+ ASSIGNMK4(x, y, maskP)
+ get_masks(x, w);
+ WRITE_PORT_USHORT((PUSHORT)GRA_I, 0x0005); // read mode 0
+ WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x04); // read map select
+
+ memset ( b, 0, w );
+
+ for ( plane=0, plane_mask=1; plane < 4; plane++, plane_mask<<=1 )
+ {
+ WRITE_PORT_UCHAR((PUCHAR)GRA_D, plane); // read map select
+
+ vp = vpP;
+ bp = b;
+ if ( leftMask )
+ {
+ mask = maskP;
+ data = *vp++;
+ do
+ {
+ if (data & mask)
+ *bp |= plane_mask;
+ bp++;
+ mask >>= 1;
+ } while (mask & leftMask);
+
+ }
+ if (byteCounter)
+ {
+ for (i=byteCounter; i>0; i--)
+ {
+ data = *vp++;
+ if (data & 0x80) *bp |= plane_mask;
+ bp++;
+ if (data & 0x40) *bp |= plane_mask;
+ bp++;
+ if (data & 0x20) *bp |= plane_mask;
+ bp++;
+ if (data & 0x10) *bp |= plane_mask;
+ bp++;
+ if (data & 0x08) *bp |= plane_mask;
+ bp++;
+ if (data & 0x04) *bp |= plane_mask;
+ bp++;
+ if (data & 0x02) *bp |= plane_mask;
+ bp++;
+ if (data & 0x01) *bp |= plane_mask;
+ bp++;
+ }
+ }
+ if (rightMask)
+ {
+ mask = 0x80;
+ data = *vp;
+ do
+ {
+ if (data & mask)
+ *bp |= plane_mask;
+ bp++;
+ mask >>= 1;
+ } while (mask & rightMask);
+ }
+ }
+
+ // We don't need this if the next call is a DFB blt to VGA (as in the case of moving the mouse pointer)
+ //WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x05); // write mode 2
+ //WRITE_PORT_UCHAR((PUCHAR)GRA_D, 0x02);
+ //WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x03); // replace
+ //WRITE_PORT_UCHAR((PUCHAR)GRA_D, 0x00);
+}
+
+// This algorithm goes from left to right
+// It stores each 4BPP pixel in an entire byte.
+void FASTCALL
+vgaWriteScan ( int x, int y, int w, void *b )
+{
+ unsigned char *bp;
+ unsigned char *vp;
+ unsigned char init_mask;
+ volatile unsigned char dummy;
+ int byte_per_line;
+ int i, j, off, init_off = x&7;
+
+ bp = b;
+ ASSIGNVP4(x, y, vp)
+ ASSIGNMK4(x, y, init_mask)
+ byte_per_line = SCREEN_X >> 3;
+
+ WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x05); // write mode 2
+ WRITE_PORT_UCHAR((PUCHAR)GRA_D, 0x02);
+ WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x03); // replace
+ WRITE_PORT_UCHAR((PUCHAR)GRA_D, 0x00);
+ WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x08); // bit mask
+
+ //DbgPrint("vgaWriteScan(%i,%i,%i...)\n",x,y,w);
+ for ( j = 0; j < 8; j++ )
+ {
+ unsigned int mask = 0x80 >> j;
+ //DbgPrint("j=%i\n",j);
+ WRITE_PORT_UCHAR ( (PUCHAR)GRA_D, (unsigned char)mask );
+ i = j - init_off;
+ off = 0;
+ if ( j < init_off )
+ i += 8, off++;
+ while ( i < w )
+ {
+ //DbgPrint("(%i)",i);
+ dummy = vp[off];
+ //DbgPrint(".");
+ dummy = bp[i];
+ //DbgPrint(".");
+ vp[off] = dummy;
+ //DbgPrint(".");
+ i += 8;
+ off++;
+ }
+ //DbgPrint("\n");
+ }
+}
+