vgavideo.c
来自「一个类似windows」· C语言 代码 · 共 1,029 行 · 第 1/2 页
C
1,029 行
LONG x2 = x + w;
LONG y2 = y + h;
ULONG offset;
UCHAR a;
for (i = x; i < x2; i++)
{
pb = opb;
offset = xconv[i] + y80[y];
WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x08); // set the mask
WRITE_PORT_UCHAR((PUCHAR)GRA_D, maskbit[i]);
if (StartMod == ((i - x) % 2))
{
for (j = y; j < y2; j++)
{
a = READ_REGISTER_UCHAR(vidmem + offset);
WRITE_REGISTER_UCHAR(vidmem + offset, (*pb & 0xf0) >> 4);
offset += 80;
pb += Source_lDelta;
}
}
else
{
for (j = y; j < y2; j++)
{
a = READ_REGISTER_UCHAR(vidmem + offset);
WRITE_REGISTER_UCHAR(vidmem + offset, *pb & 0x0f);
offset += 80;
pb += Source_lDelta;
}
}
if (StartMod != ((i - x) % 2))
{
opb++;
}
}
}
/* DIB blt to the VGA. */
void DIB_BltToVGAWithXlate(int x, int y, int w, int h, void *b, int Source_lDelta, XLATEOBJ* Xlate)
{
PBYTE pb, opb = b;
ULONG i, j;
ULONG x2 = x + w;
ULONG y2 = y + h;
ULONG offset;
UCHAR a;
for (i = x; i < x2; i++)
{
pb = opb;
offset = xconv[i] + y80[y];
WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x08); // set the mask
WRITE_PORT_UCHAR((PUCHAR)GRA_D, maskbit[i]);
if (0 == ((i - x) % 2))
{
for (j = y; j < y2; j++)
{
a = READ_REGISTER_UCHAR(vidmem + offset);
WRITE_REGISTER_UCHAR(vidmem + offset, XLATEOBJ_iXlate(Xlate, (*pb & 0xf0) >> 4));
offset += 80;
pb += Source_lDelta;
}
}
else
{
for (j = y; j < y2; j++)
{
a = READ_REGISTER_UCHAR(vidmem + offset);
WRITE_REGISTER_UCHAR(vidmem + offset, XLATEOBJ_iXlate(Xlate, *pb & 0x0f));
offset += 80;
pb += Source_lDelta;
}
}
if (0 != ((i - x) % 2))
{
opb++;
}
}
}
void DIB_TransparentBltToVGA(int x, int y, int w, int h, void *b, int Source_lDelta, ULONG trans)
// DIB blt to the VGA.
// For now we just do slow writes -- pixel by pixel, packing each one into the correct 4BPP format.
{
PBYTE pb = b, opb = b;
BOOLEAN edgePixel = FALSE;
ULONG i, j;
ULONG x2 = x + w;
ULONG y2 = y + h;
BYTE b1, b2;
// Check if the width is odd
if(mod2(w)>0)
{
edgePixel = TRUE;
x2 -= 1;
}
for (j=y; j<y2; j++)
{
for (i=x; i<x2; i+=2)
{
b1 = (*pb & 0xf0) >> 4;
b2 = *pb & 0x0f;
if(b1 != trans) vgaPutPixel(i, j, b1);
if(b2 != trans) vgaPutPixel(i+1, j, b2);
pb++;
}
if(edgePixel == TRUE)
{
b1 = *pb;
if(b1 != trans) vgaPutPixel(x2, j, b1);
pb++;
}
opb += Source_lDelta;
pb = opb; // new test code
}
}
// 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 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");
}
}
void DFB_BltFromVGA(int x, int y, int w, int h, void *b, int bw)
// This algorithm goes from left to right, and inside that loop, top to bottom.
// It also stores each 4BPP pixel in an entire byte.
{
unsigned char *vp, *vpY, *vpP;
unsigned char data, mask, maskP;
unsigned char *bp, *bpY;
unsigned char plane_mask;
int byte_per_line = SCREEN_X >> 3;
int plane, i, j;
ASSIGNVP4(x, y, vpP)
ASSIGNMK4(x, y, maskP)
get_masks(x, w);
WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x05); // read mode 0
WRITE_PORT_UCHAR((PUCHAR)GRA_D, 0x00);
WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x04); // read map select
// clear buffer
bp=b;
for (j=h; j>0; j--)
{
memset(bp, 0, w);
bp += bw;
}
for ( plane=0, plane_mask=1; plane < 4; plane++, plane_mask<<=1 )
{
WRITE_PORT_UCHAR((PUCHAR)GRA_D, plane); // read map select
vpY = vpP;
bpY = b;
for ( j=h; j>0; j-- )
{
vp = vpY;
bp = bpY;
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);
}
bpY += bw;
vpY += byte_per_line;
}
}
// 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);
}
void DFB_BltToVGA(int x, int y, int w, int h, void *b, int bw)
// This algorithm goes from left to right, and inside that loop, top to bottom.
// It also stores each 4BPP pixel in an entire byte.
{
unsigned char *bp, *bpX;
unsigned char *vp, *vpX;
unsigned char mask;
volatile unsigned char dummy;
int byte_per_line;
int i, j;
bpX = b;
ASSIGNVP4(x, y, vpX)
ASSIGNMK4(x, y, 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
for (i=w; i>0; i--)
{
WRITE_PORT_UCHAR((PUCHAR)GRA_D, mask);
bp = bpX;
vp = vpX;
for (j=h; j>0; j--)
{
dummy = *vp;
*vp = *bp;
bp += bw;
vp += byte_per_line;
}
bpX++;
if ((mask >>= 1) == 0)
{
vpX++;
mask = 0x80;
}
}
}
void DFB_BltToVGA_Transparent(int x, int y, int w, int h, void *b, int bw, char Trans)
// This algorithm goes from goes from left to right, and inside that loop, top to bottom.
// It also stores each 4BPP pixel in an entire byte.
{
unsigned char *bp, *bpX;
unsigned char *vp, *vpX;
unsigned char mask;
volatile unsigned char dummy;
int byte_per_line;
int i, j;
bpX = b;
ASSIGNVP4(x, y, vpX)
ASSIGNMK4(x, y, 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
for (i=w; i>0; i--)
{
WRITE_PORT_UCHAR((PUCHAR)GRA_D, mask);
bp = bpX;
vp = vpX;
for (j=h; j>0; j--)
{
if (*bp != Trans)
{
dummy = *vp;
*vp = *bp;
}
bp += bw;
vp += byte_per_line;
}
bpX++;
if ((mask >>= 1) == 0)
{
vpX++;
mask = 0x80;
}
}
}
void DFB_BltToDIB(int x, int y, int w, int h, void *b, int bw, void *bdib, int dibw)
// This algorithm converts a DFB into a DIB
// WARNING: This algorithm is buggy
{
unsigned char *bp, *bpX, *dib, *dibTmp;
int i, j, dib_shift;
bpX = b;
dib = (unsigned char *)bdib + y * dibw + (x / 2);
for (i=w; i>0; i--) {
// determine the bit shift for the DIB pixel
dib_shift = mod2(w-i);
if(dib_shift > 0) dib_shift = 4;
dibTmp = dib;
bp = bpX;
for (j=h; j>0; j--) {
*dibTmp = *bp << dib_shift | *(bp + 1);
dibTmp += dibw;
bp += bw;
}
bpX++;
if(dib_shift == 0) dib++;
}
}
void DIB_BltToDFB(int x, int y, int w, int h, void *b, int bw, void *bdib, int dibw)
// This algorithm converts a DIB into a DFB
{
unsigned char *bp, *bpX, *dib, *dibTmp;
int i, j, dib_shift, dib_and;
bpX = b;
dib = (unsigned char *)bdib + y * dibw + (x / 2);
for (i=w; i>0; i--) {
// determine the bit shift for the DIB pixel
dib_shift = mod2(w-i);
if(dib_shift > 0) {
dib_shift = 0;
dib_and = 0x0f;
} else {
dib_shift = 4;
dib_and = 0xf0;
}
dibTmp = dib;
bp = bpX;
for (j=h; j>0; j--) {
*bp = (*dibTmp & dib_and) >> dib_shift;
dibTmp += dibw;
bp += bw;
}
bpX++;
if(dib_shift == 0) dib++;
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?